Change nfvbench git checkout to stable/fraser in Dockerfile
[nfvbench.git] / nfvbench / nfvbenchd.py
index 3ab30de..fa781af 100644 (file)
 #    under the License.
 #
 
+import json
+import Queue
+import uuid
+
 from flask import Flask
 from flask import jsonify
 from flask import render_template
@@ -21,16 +25,11 @@ from flask import request
 
 from flask_socketio import emit
 from flask_socketio import SocketIO
-from fluentd import FluentLogHandler
 from summarizer import NFVBenchSummarizer
 
-import json
 from log import LOG
-import Queue
-import traceback
 from utils import byteify
 from utils import RunLock
-import uuid
 
 # this global cannot reside in Ctx because of the @app and @socketio decorators
 app = None
@@ -137,7 +136,6 @@ def setup_flask(root_path):
     app.root_path = root_path
     socketio = SocketIO(app, async_mode='threading')
     busy_json = result_json(STATUS_ERROR, 'there is already an NFVbench request running')
-    config_is_null_json = result_json(STATUS_ERROR, 'configuration is missing')
     not_busy_json = result_json(STATUS_ERROR, 'no pending NFVbench run')
     not_found_msg = 'results not found'
     pending_msg = 'NFVbench run still pending'
@@ -145,43 +143,41 @@ def setup_flask(root_path):
     # --------- socketio requests ------------
 
     @socketio.on('start_run')
-    def socketio_start_run(config):
+    def _socketio_start_run(config):
         if not Ctx.is_busy():
             Ctx.enqueue(config, get_uuid(), from_socketio=True)
         else:
             emit('error', {'reason': 'there is already an NFVbench request running'})
 
     @socketio.on('echo')
-    def socketio_echo(config):
+    def _socketio_echo(config):
         emit('echo', config)
 
     # --------- HTTP requests ------------
 
     @app.route('/')
-    def index():
+    def _index():
         return render_template('index.html')
 
     @app.route('/echo', methods=['GET'])
-    def echo():
+    def _echo():
         config = request.json
         return jsonify(config)
 
     @app.route('/start_run', methods=['POST'])
-    def start_run():
+    def _start_run():
         config = load_json(request.json)
-        if config:
-            if Ctx.is_busy():
-                return jsonify(busy_json)
-            else:
-                request_id = get_uuid()
-                Ctx.enqueue(config, request_id)
-                return jsonify(result_json(STATUS_PENDING, pending_msg, request_id))
-        else:
-            return jsonify(config_is_null_json)
+        if not config:
+            config = {}
+        if Ctx.is_busy():
+            return jsonify(busy_json)
+        request_id = get_uuid()
+        Ctx.enqueue(config, request_id)
+        return jsonify(result_json(STATUS_PENDING, pending_msg, request_id))
 
     @app.route('/status', defaults={'request_id': None}, methods=['GET'])
     @app.route('/status/<request_id>', methods=['GET'])
-    def get_status(request_id):
+    def _get_status(request_id):
         if request_id:
             if Ctx.is_busy() and request_id == Ctx.get_current_request_id():
                 # task with request_id still pending
@@ -191,9 +187,8 @@ def setup_flask(root_path):
             if res:
                 # found result for given request_id
                 return jsonify(res)
-            else:
-                # result for given request_id not found
-                return jsonify(result_json(STATUS_NOT_FOUND, not_found_msg, request_id))
+            # result for given request_id not found
+            return jsonify(result_json(STATUS_NOT_FOUND, not_found_msg, request_id))
         else:
             if Ctx.is_busy():
                 # task still pending, return with request_id
@@ -204,8 +199,7 @@ def setup_flask(root_path):
             res = Ctx.get_result()
             if res:
                 return jsonify(res)
-            else:
-                return jsonify(not_busy_json)
+            return jsonify(not_busy_json)
 
 
 class WebSocketIoServer(object):
@@ -214,14 +208,10 @@ class WebSocketIoServer(object):
     of this class and pass a runner object then invoke the run method
     """
 
-    def __init__(self, http_root, runner, logger):
+    def __init__(self, http_root, runner, fluent_logger):
         self.nfvbench_runner = runner
         setup_flask(http_root)
-        self.fluent_logger = logger
-        self.result_fluent_logger = FluentLogHandler("resultnfvbench",
-                                                     fluentd_ip=self.fluent_logger.sender.host,
-                                                     fluentd_port=self.fluent_logger.sender.port) \
-            if self.fluent_logger else None
+        self.fluent_logger = fluent_logger
 
     def run(self, host='127.0.0.1', port=7556):
 
@@ -236,25 +226,32 @@ class WebSocketIoServer(object):
             # print 'main thread waiting for requests...'
             config = Ctx.dequeue()
             # print 'main thread processing request...'
-            print config
+            print config
             try:
                 # remove unfilled values as we do not want them to override default values with None
                 config = {k: v for k, v in config.items() if v is not None}
                 with RunLock():
+                    if self.fluent_logger:
+                        self.fluent_logger.start_new_run()
                     results = self.nfvbench_runner.run(config, config)
             except Exception as exc:
-                print 'NFVbench runner exception:'
-                traceback.print_exc()
                 results = result_json(STATUS_ERROR, str(exc))
-                LOG.exception()
+                LOG.exception('NFVbench runner exception:')
 
             if Ctx.request_from_socketio:
                 socketio.emit('run_end', results)
             else:
                 # this might overwrite a previously unfetched result
                 Ctx.set_result(results)
-            summary = NFVBenchSummarizer(results['result'], self.result_fluent_logger)
-            LOG.info(str(summary))
+            try:
+                summary = NFVBenchSummarizer(results['result'], self.fluent_logger)
+                LOG.info(str(summary))
+            except KeyError:
+                # in case of error, 'result' might be missing
+                if 'error_message' in results:
+                    LOG.error(results['error_message'])
+                else:
+                    LOG.error('REST request completed without results or error message')
             Ctx.release()
             if self.fluent_logger:
                 self.fluent_logger.send_run_summary(True)