added basic API registration and connection mechanism
authorpeusterm <manuel.peuster@uni-paderborn.de>
Wed, 6 Jan 2016 15:59:53 +0000 (16:59 +0100)
committerpeusterm <manuel.peuster@uni-paderborn.de>
Wed, 6 Jan 2016 15:59:53 +0000 (16:59 +0100)
README.md
emuvim/api/zerorpcapi.py [new file with mode: 0644]
emuvim/cli/__main__.py
emuvim/dcemulator/net.py
emuvim/dcemulator/node.py
emuvim/example_topology.py

index 0ee1d9e..63ed10e 100644 (file)
--- a/README.md
+++ b/README.md
@@ -5,11 +5,18 @@
 
 ## emu-vim
 
+### Requirements
+* needs the latest Dockernet to be installed in the system
+ * the wrapper uses standard Python imports to use the Dockernet modules
+* Uses ZeroMQ based RPC to open a cloud-like interface that can be used by a demo CLI client
+ * pip install import zerorpc
+ * This will be replaced / extended by a REST API later
+
 ### TODO
 
 * Add runtime API
-** call startAPI from topology definition and start it in a own thread?
-** make it possible to start different API endpoints for different DCs?
+ * call startAPI from topology definition and start it in a own thread?
+ * make it possible to start different API endpoints for different DCs?
 * Add resource constraints to datacenters
 * Add constraints to Links
 * Check if we can use the Mininet GUI to visualize our DCs?
\ No newline at end of file
diff --git a/emuvim/api/zerorpcapi.py b/emuvim/api/zerorpcapi.py
new file mode 100644 (file)
index 0000000..88d7740
--- /dev/null
@@ -0,0 +1,53 @@
+"""
+Distributed Cloud Emulator (dcemulator)
+(c) 2015 by Manuel Peuster <manuel.peuster@upb.de>
+"""
+
+import logging
+import threading
+import zerorpc
+
+logging.basicConfig(level=logging.DEBUG)
+
+
+class ZeroRpcApiEndpoint(object):
+
+    def __init__(self, listenip, port):
+        self.dcs = {}
+        self.ip = listenip
+        self.port = port
+        logging.debug("Created API endpoint %s(%s:%d)" % (
+            self.__class__.__name__, self.ip, self.port))
+
+    def connectDatacenter(self, dc):
+        self.dcs[dc.name] = dc
+        logging.info("Connected DC(%s) to API endpoint %s(%s:%d)" % (
+            dc.name, self.__class__.__name__, self.ip, self.port))
+
+    def start(self):
+        thread = threading.Thread(target=self._api_server_thread, args=())
+        thread.daemon = True
+        thread.start()
+        logging.debug("Started API endpoint %s(%s:%d)" % (
+            self.__class__.__name__, self.ip, self.port))
+
+    def _api_server_thread(self):
+        s = zerorpc.Server(MultiDatacenterApi(self.dcs))
+        s.bind("tcp://%s:%d" % (self.ip, self.port))
+        s.run()
+
+
+class MultiDatacenterApi(object):
+
+    def __init__(self, dcs):
+        self.dcs = dcs
+
+    def compute_action_start(self, dc_name, compute_name):
+        # TODO return UUID / IP ?
+        logging.info("compute start")
+
+    def compute_action_stop(self, dc_name, compute_name):
+        logging.info("compute stop")
+
+    def compute_list(self):
+        pass
index e69de29..771049b 100644 (file)
@@ -0,0 +1,24 @@
+"""
+ For now only a dummy client. Connects to the zerorpc interface of the
+ emulator and performs some actions (start/stop/list).
+"""
+import time
+import zerorpc
+
+
+def main():
+    print "Example CLI client"
+    # create connection to remote Mininet instance
+    c = zerorpc.Client()
+    c.connect("tcp://127.0.0.1:4242")
+
+    # do some API tests
+    print c.compute_action_start("dc2", "my_new_container1")
+
+    time.sleep(5)
+
+    print c.compute_action_stop("dc2", "my_new_container1")
+
+
+if __name__ == '__main__':
+    main()
index 8ea41a7..586b1e8 100644 (file)
@@ -69,7 +69,7 @@ class DCNetwork(object):
         # create link if everything is correct
         if (node1 is not None and isinstance(node1, OVSKernelSwitch)
                 and node2 is not None and isinstance(node2, OVSKernelSwitch)):
-            self.mnet.addLink(node1, node2)  # TODO we need TCLinks with user defined performance her
+            self.mnet.addLink(node1, node2)  # TODO we need TCLinks with user defined performance here
         else:
             raise Exception(
                 "one of the given nodes is not a Mininet switch or None")
index b12751f..b095e19 100644 (file)
@@ -29,7 +29,7 @@ class Datacenter(object):
         Each data center is represented by a single switch to which
         compute resources can be connected at run time.
 
-        TODO: This will be changes in the future to support multiple networks
+        TODO: This will be changed in the future to support multiple networks
         per data center
         """
         self.switch = self.net.mnet.addSwitch(
index f2be310..a21cdba 100644 (file)
@@ -7,11 +7,13 @@ script.
 """
 import logging
 from dcemulator.net import DCNetwork
+from api.zerorpcapi import ZeroRpcApiEndpoint
 
 logging.basicConfig(level=logging.DEBUG)
 
 
 def create_topology1():
+    # TODO add long comments to this example to show people how to use this
     # initialize network
     net = DCNetwork()
 
@@ -27,12 +29,24 @@ def create_topology1():
     net.addLink("dc1", s1)
     net.addLink(s1, "dc3")
     net.addLink(s1, dc4)
+
+    # create and start APIs (to access emulated cloud data centers)
+    zapi1 = ZeroRpcApiEndpoint("0.0.0.0", 4242)
+    zapi1.connectDatacenter(dc1)
+    zapi1.connectDatacenter(dc2)
+    zapi1.start()
+    # lets also create a second API endpoint on another port to
+    # demonstrate hat you can have one endpoint for each of
+    # your data centers
+    zapi2 = ZeroRpcApiEndpoint("0.0.0.0", 4343)
+    zapi2.connectDatacenter(dc3)
+    zapi2.connectDatacenter(dc4)
+    zapi2.start()
+
     # start network
     net.start()
     net.CLI()  # TODO remove this when we integrate APIs?
     net.stop()  # TODO remove this when we integrate APIs?
-    # start APIs (to access emulated cloud data centers)
-    pass  # TODO: how to reflect one API endpoint per DC?
 
 
 def main():