add rest api for network and monitoring
diff --git a/src/emuvim/api/rest/__init__.py b/src/emuvim/api/rest/__init__.py
old mode 100644
new mode 100755
diff --git a/src/emuvim/api/rest/compute.py b/src/emuvim/api/rest/compute.py
old mode 100644
new mode 100755
index 02ca9f2..1c9c892
--- a/src/emuvim/api/rest/compute.py
+++ b/src/emuvim/api/rest/compute.py
@@ -1,59 +1,12 @@
 import logging
-import threading
-from flask import Flask, request
-from flask_restful import Resource,Api
+from flask_restful import Resource
+from flask import request
 import json
 
-
-
 logging.basicConfig(level=logging.INFO)
 
-
 dcs = {}
 
-class RestApiEndpoint(object):
-
-    """
-    Simple API endpoint that offers a REST
-    interface. This interface will be used by the
-    default command line client.
-    """
-    global dcs
-
-    def __init__(self, listenip, port):
-        self.ip = listenip
-        self.port = port
-
-        # setup Flask
-        self.app = Flask(__name__)
-        self.api = Api(self.app)
-
-        # setup endpoints
-        self.api.add_resource(ComputeList, "/restapi/compute/<dc_label>")
-        self.api.add_resource(ComputeStart, "/restapi/compute/<dc_label>/<compute_name>/start")
-        self.api.add_resource(ComputeStop, "/restapi/compute/<dc_label>/<compute_name>/stop")
-        self.api.add_resource(ComputeStatus, "/restapi/compute/<dc_label>/<compute_name>")
-        self.api.add_resource(DatacenterList, "/restapi/datacenter")
-        self.api.add_resource(DatacenterStatus, "/restapi/datacenter/<dc_label>")
-
-        logging.debug("Created API endpoint %s(%s:%d)" % (self.__class__.__name__, self.ip, self.port))
-
-
-    def connectDatacenter(self, dc):
-        dcs[dc.label] = dc
-        logging.info("Connected DC(%s) to API endpoint %s(%s:%d)" % (dc.label, self.__class__.__name__, self.ip, self.port))
-
-    def start(self):
-        thread = threading.Thread(target= self._start_flask, args=())
-        thread.daemon = True
-        thread.start()
-        logging.info("Started API endpoint @ http://%s:%d" % (self.ip, self.port))
-
-
-    def _start_flask(self):
-        self.app.run(self.ip, self.port, debug=True, use_reloader=False)
-
-
 class ComputeStart(Resource):
     """
     Start a new compute instance: A docker container (note: zerorpc does not support keyword arguments)
@@ -62,7 +15,8 @@
     :param image: image name
     :param command: command to execute
     :param network: list of all interface of the vnf, with their parameters (id=id1,ip=x.x.x.x/x),...
-    :return: networks list({"id":"input","ip": "10.0.0.254/8"}, {"id":"output","ip": "11.0.0.254/24"})
+    example networks list({"id":"input","ip": "10.0.0.254/8"}, {"id":"output","ip": "11.0.0.254/24"})
+    :return: docker inspect dict of deployed docker
     """
     global dcs
 
@@ -76,7 +30,7 @@
             c = dcs.get(dc_label).startCompute(
                 compute_name, image= image, command= command, network= network)
             # return docker inspect dict
-            return  c. getStatus(), 200
+            return c.getStatus(), 200
         except Exception as ex:
             logging.exception("API error.")
             return ex.message, 500
diff --git a/src/emuvim/api/rest/monitor.py b/src/emuvim/api/rest/monitor.py
new file mode 100755
index 0000000..b1edbc3
--- /dev/null
+++ b/src/emuvim/api/rest/monitor.py
@@ -0,0 +1,72 @@
+import logging
+from flask_restful import Resource
+from flask import request
+import json
+
+logging.basicConfig(level=logging.INFO)
+
+net = None
+
+
+
+class MonitorInterfaceAction(Resource):
+    """
+    Monitor the counters of a VNF interface
+    :param vnf_name: name of the VNF to be monitored
+    :param vnf_interface: name of the VNF interface to be monitored
+    :param metric: tx_bytes, rx_bytes, tx_packets, rx_packets
+    :return: message string indicating if the monitor action is succesful or not
+    """
+    global net
+
+    def put(self, vnf_name, vnf_interface, metric):
+        logging.debug("REST CALL: start monitor VNF interface")
+        try:
+            c = net.monitor_agent.setup_metric(vnf_name, vnf_interface, metric)
+            # return monitor message response
+            return  str(c), 200
+        except Exception as ex:
+            logging.exception("API error.")
+            return ex.message, 500
+
+    def delete(self, vnf_name, vnf_interface, metric):
+        logging.debug("REST CALL: stop monitor VNF interface")
+        try:
+            c = net.monitor_agent.stop_metric(vnf_name, vnf_interface, metric)
+            # return monitor message response
+            return str(c), 200
+        except Exception as ex:
+            logging.exception("API error.")
+            return ex.message, 500
+
+
+class MonitorFlowAction(Resource):
+    """
+    Monitor the counters of a specific flow
+    :param vnf_name: name of the VNF to be monitored
+    :param vnf_interface: name of the VNF interface to be monitored
+    :param metric: tx_bytes, rx_bytes, tx_packets, rx_packets
+    :param cookie: specific identifier of flows to monitor
+    :return: message string indicating if the monitor action is succesful or not
+    """
+    global net
+
+    def put(self, vnf_name, vnf_interface, metric, cookie):
+        logging.debug("REST CALL: start monitor VNF interface")
+        try:
+            c = net.monitor_agent.setup_flow(vnf_name, vnf_interface, metric, cookie)
+            # return monitor message response
+            return str(c), 200
+        except Exception as ex:
+            logging.exception("API error.")
+            return ex.message, 500
+
+    def delete(self, vnf_name, vnf_interface, metric, cookie):
+        logging.debug("REST CALL: stop monitor VNF interface")
+        try:
+            c = net.monitor_agent.stop_flow(vnf_name, vnf_interface, metric, cookie)
+            # return monitor message response
+            return str(c), 200
+        except Exception as ex:
+            logging.exception("API error.")
+            return ex.message, 500
\ No newline at end of file
diff --git a/src/emuvim/api/rest/network.py b/src/emuvim/api/rest/network.py
new file mode 100755
index 0000000..4a0214f
--- /dev/null
+++ b/src/emuvim/api/rest/network.py
@@ -0,0 +1,60 @@
+import logging
+from flask_restful import Resource
+from flask import request
+import json
+
+logging.basicConfig(level=logging.INFO)
+
+net = None
+
+
+class NetworkAction(Resource):
+    """
+    Add or remove chains between VNFs. These chain links are implemented as flow entries in the networks' SDN switches.
+    :param vnf_src_name: VNF name of the source of the link
+    :param vnf_dst_name: VNF name of the destination of the link
+    :param vnf_src_interface: VNF interface name of the source of the link
+    :param vnf_dst_interface: VNF interface name of the destination of the link
+    :param weight: weight of the link (can be useful for routing calculations)
+    :param match: OpenFlow match format of the flow entry
+    :param bidirectional: boolean value if the link needs to be implemented from src to dst and back
+    :param cookie: cookie value, identifier of the flow entry to be installed.
+    :return: message string indicating if the chain action is succesful or not
+    """
+
+    global net
+
+    def put(self, vnf_src_name, vnf_dst_name):
+        logging.debug("REST CALL: network chain add")
+        command = 'add-flow'
+        return self._NetworkAction(vnf_src_name, vnf_dst_name, command=command)
+
+    def delete(self, vnf_src_name, vnf_dst_name):
+        logging.debug("REST CALL: network chain remove")
+        command = 'del-flows'
+        return self._NetworkAction(vnf_src_name, vnf_dst_name, command=command)
+
+    def _NetworkAction(self, vnf_src_name, vnf_dst_name, command=None):
+        # call DCNetwork method, not really datacenter specific API for now...
+        # no check if vnfs are really connected to this datacenter...
+        try:
+            vnf_src_interface = json.loads(request.json).get("vnf_src_interface")
+            vnf_dst_interface = json.loads(request.json).get("vnf_dst_interface")
+            weight = json.loads(request.json).get("weight")
+            match = json.loads(request.json).get("match")
+            bidirectional = json.loads(request.json).get("bidirectional")
+            cookie = json.loads(request.json).get("cookie")
+            c = net.setChain(
+                vnf_src_name, vnf_dst_name,
+                vnf_src_interface=vnf_src_interface,
+                vnf_dst_interface=vnf_dst_interface,
+                cmd=command,
+                weight=weight,
+                match=match,
+                bidirectional=bidirectional,
+                cookie=cookie)
+            # return setChain response
+            return str(c), 200
+        except Exception as ex:
+            logging.exception("API error.")
+            return ex.message, 500
\ No newline at end of file
diff --git a/src/emuvim/api/rest/rest_api_endpoint.py b/src/emuvim/api/rest/rest_api_endpoint.py
new file mode 100755
index 0000000..6c69a03
--- /dev/null
+++ b/src/emuvim/api/rest/rest_api_endpoint.py
@@ -0,0 +1,73 @@
+import logging
+import threading
+from flask import Flask
+from flask_restful import Api
+
+# need to import total module to set its global variable dcs
+import compute
+from compute import dcs, ComputeList, ComputeStart, ComputeStatus, ComputeStop, DatacenterList, DatacenterStatus
+
+# need to import total module to set its global variable net
+import network
+from network import NetworkAction
+
+import monitor
+from monitor import MonitorInterfaceAction, MonitorFlowAction
+
+logging.basicConfig(level=logging.INFO)
+
+
+
+class RestApiEndpoint(object):
+
+    """
+    Simple API endpoint that offers a REST
+    interface. This interface will be used by the
+    default command line client.
+    """
+
+    def __init__(self, listenip, port):
+        self.ip = listenip
+        self.port = port
+
+        # setup Flask
+        self.app = Flask(__name__)
+        self.api = Api(self.app)
+
+        # setup endpoints
+        self.api.add_resource(ComputeList, "/restapi/compute/<dc_label>")
+        self.api.add_resource(ComputeStart, "/restapi/compute/<dc_label>/<compute_name>/start")
+        self.api.add_resource(ComputeStop, "/restapi/compute/<dc_label>/<compute_name>/stop")
+        self.api.add_resource(ComputeStatus, "/restapi/compute/<dc_label>/<compute_name>")
+        self.api.add_resource(DatacenterList, "/restapi/datacenter")
+        self.api.add_resource(DatacenterStatus, "/restapi/datacenter/<dc_label>")
+
+        self.api.add_resource(NetworkAction, "/restapi/network/<vnf_src_name>/<vnf_dst_name>")
+
+        self.api.add_resource(MonitorInterfaceAction, "/restapi/monitor/<vnf_name>/<vnf_interface>/<metric>")
+        self.api.add_resource(MonitorFlowAction, "/restapi/monitor/<vnf_name>/<vnf_interface>/<metric>/<cookie>")
+
+        logging.debug("Created API endpoint %s(%s:%d)" % (self.__class__.__name__, self.ip, self.port))
+
+
+    def connectDatacenter(self, dc):
+        compute.dcs[dc.label] = dc
+        logging.info("Connected DC(%s) to API endpoint %s(%s:%d)" % (dc.label, self.__class__.__name__, self.ip, self.port))
+
+    def connectDCNetwork(self, DCnetwork):
+
+        network.net = DCnetwork
+        monitor.net = DCnetwork
+
+        logging.info("Connected DCNetwork to API endpoint %s(%s:%d)" % (
+            self.__class__.__name__, self.ip, self.port))
+
+    def start(self):
+        thread = threading.Thread(target= self._start_flask, args=())
+        thread.daemon = True
+        thread.start()
+        logging.info("Started API endpoint @ http://%s:%d" % (self.ip, self.port))
+
+
+    def _start_flask(self):
+        self.app.run(self.ip, self.port, debug=True, use_reloader=False)
\ No newline at end of file