experiment parsed to data and from data structure. (data being a dictionary of elemen...
authorAlina Quereilhac <alina.quereilhac@inria.fr>
Fri, 11 Feb 2011 17:29:20 +0000 (18:29 +0100)
committerAlina Quereilhac <alina.quereilhac@inria.fr>
Fri, 11 Feb 2011 17:29:20 +0000 (18:29 +0100)
examples/design1.py
src/nepi/core/attributes.py
src/nepi/core/description.py
src/nepi/core/experiment.py
src/nepi/util/parser/__init__.py [new file with mode: 0644]
src/nepi/util/parser/base.py [new file with mode: 0644]
src/nepi/util/parser/xml.py [new file with mode: 0644]

index 68c61fb..7f56ace 100644 (file)
@@ -27,30 +27,15 @@ app = netns.create("Application")
 app.set_attribute_value("command", "ping -qc10 10.0.0.2")
 app.connector("node").connect(node1.connector("apps"))
 
-print experiment.xml_description
+#from nepi.util.parser.base import Parser
+#p = Parser()
+#data = p.to_data(experiment)
+#print data
+#e2 = p.from_data(data)
+#data2 = p.to_data(e2)
+#print data2
+
+#print data == data2
+#print experiment.xml_description
 
-description = """
-<experiment>
-  <testbeds>
-    <testbed testbed_id="netns" testbed_version="1.0" guid="1">
-      <elements>
-        <element factory_id="Node" guid="2">
-          <construct-parameters>
-          </construct-parameters>
-          <attributes>
-          </attributes>
-          <traces>
-          </traces>
-          <addresses>
-          </addresses>
-          <routes>
-          </routes>
-        </element>
-      </elements>
-      <connections>
-      </connections>
-    </testbed>
-  </testbeds>
-</experiment>
-"""
 
index 5da6df4..187f43a 100644 (file)
@@ -8,9 +8,13 @@ class AttributesMap(object):
     def __init__(self):
         self._attributes = dict()
 
+    @property
+    def attributes(self):
+        return self._attributes.values()
+
     @property
     def attributes_name(self):
-        return set(self._attributes.keys())
+        return self._attributes.keys()
 
     def set_attribute_value(self, name, value):
         self._attributes[name].value = value
index 5fd0387..650aca8 100644 (file)
@@ -91,7 +91,10 @@ class Connector(object):
 
     def is_complete(self):
         """Return True if the connector has the minimum number of connections"""
-        return len(self.connections) >= self.connector_type.min 
+        return len(self.connections) >= self.connector_type.min
+
+    def is_connected(self, connector):
+        return connector._key in self._connections
 
     def connect(self, connector):
         if self.is_full() or connector.is_full():
@@ -223,7 +226,7 @@ class Box(AttributesMap):
             self.add_attribute(attr.name, attr.help, attr.type, attr.value, 
                     attr.range, attr.allowed, attr.readonly, 
                     attr.validation_function)
-        for attr in factory._attributes:
+        for attr in factory.attributes:
             self._factory_attributes.append(attr)
 
     @property
@@ -455,6 +458,9 @@ class TestbedDescription(AttributesMap):
     def boxes(self):
         return self._boxes.values()
 
+    def box(self, guid):
+        return self._boxes[guid] if guid in self._boxes else None
+
     def create(self, factory_id):
         guid = self._guid_generator.next()
         factory = self._provider.factory(factory_id)
index cc88386..a0db329 100644 (file)
@@ -1,7 +1,8 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 
-from nepi.util.guid import GuidGenerator 
+from nepi.util.guid import GuidGenerator
+from nepi.util.parser.xml import XmlParser
 import sys
 
 class ExperimentDescription(object):
@@ -11,9 +12,24 @@ class ExperimentDescription(object):
         self._testbed_descriptions = dict()
         self._testbed_providers = dict()
 
+    @property
+    def testbed_descriptions(self):
+        return self._testbed_descriptions.values()
+
     @property
     def xml_description(self):
-        raise NotImplementedError
+        parser = XmlParser()
+        return parser.to_xml(self)
+
+    def testbed_description(self, guid):
+        return self._testbed_descriptions[guid] \
+                if guid in self._testbed_descriptions else None
+
+    def box(self, guid):
+        for testbed_description in self._testbed_descriptions.values():
+            box = testbed_description.box(guid)
+            if box: return box
+        return None
 
     def add_testbed_description(self, testbed_id, testbed_version):
         testbed_module = self._testbed_module(testbed_id)
diff --git a/src/nepi/util/parser/__init__.py b/src/nepi/util/parser/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/nepi/util/parser/base.py b/src/nepi/util/parser/base.py
new file mode 100644 (file)
index 0000000..2f6b67a
--- /dev/null
@@ -0,0 +1,171 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from nepi.core.experiment import ExperimentDescription
+
+class Parser(object):
+    def to_data(self, experiment_description):
+        exp = dict()
+        for testbed_description in experiment_description.testbed_descriptions:
+            guid = testbed_description.guid
+            exp[guid] = self.testbed_to_data(testbed_description)
+            for box in testbed_description.boxes:
+                exp[box.guid] = self.box_to_data(guid, box)
+        return exp
+
+    def testbed_to_data(self, testbed_description):
+        elem = dict()
+        elem["testbed_id"] = testbed_description.testbed_id
+        elem["testbed_version"] = testbed_description.testbed_version
+        return elem 
+
+    def box_to_data(self, testbed_guid, box):
+        elem = dict()
+        elem["testbed_guid"] = testbed_guid
+        elem["factory_id"] = box.factory_id
+        fattrs = self.factory_attributes_to_data(box.factory_attributes)
+        if fattrs:
+            elem["factory_attributes"] = fattrs
+        attrs = self.attributes_to_data(box.attributes)
+        if attrs:
+            elem["attributes"] = attrs
+        traces = self.traces_to_data(box.traces)
+        if traces:
+            elem["traces"] = traces
+        connections = self.connections_to_data(box.connectors)
+        if connections:
+            elem["connections"] = connections
+        addresses = self.addresses_to_data(box.addresses)
+        if addresses:
+            elem["addresses"] = addresses
+        routes = self.routes_to_data(box.routes)
+        if routes:
+            elem["routes"] = routes
+        return elem
+
+    def factory_attributes_to_data(self, attributes):
+        fattrs = dict()
+        for attribute in attributes:
+            if attribute.modified:
+                fattrs[attribute.name] = attribute.value
+        return fattrs if len(fattrs) > 0 else None
+
+    def attributes_to_data(self, attributes):
+        attrs = dict()
+        for attribute in attributes:
+            if attribute.modified:
+                attrs[attribute.name] = attribute.value
+        return attrs if len(attrs) > 0 else None
+
+    def traces_to_data(self, traces):
+        trcs = list()
+        for trace in traces:
+            if trace.enabled:
+                trcs.append(trace.name)
+        return trcs if len(trcs) > 0 else None
+
+    def connections_to_data(self, connectors):
+        cnctrs = dict()
+        for connector in connectors:
+            cnxs = dict()
+            for other_connector in connector.connections:
+                guid = other_connector.box.guid
+                cnxs[guid] = other_connector.connector_type.name
+            if len(cnxs) > 0:
+                cnctrs[connector.connector_type.name] = cnxs
+        return cnctrs if len(cnctrs) > 0 else None
+
+    def addresses_to_data(self, addresses):
+        addrs = list()
+        for address in addresses:
+            addr = dict()
+            for attribute in address.attributes:
+                if attribute.modified:
+                    addr[attribute.name] = attribute.value
+            addrs.append(addr)
+        return addrs if len(addrs) > 0 else None
+
+    def routes_to_data(self, routes):
+        rts = list()
+        for route in routes:
+            rt = dict()
+            for attribute in route.attibutes:
+                if attribute.modified:
+                    rt[attribute.name] = attribute.value
+            rts.append(rt)
+        return rts if len(rts) > 0 else None
+
+    def from_data(self, data):
+        experiment = ExperimentDescription()
+        connections_data = dict()
+        for guid, elem_data in data.iteritems():
+            if "testbed_id" in elem_data:
+                self.testbed_from_data(experiment, elem_data)
+            else:
+                self.box_from_data(experiment, elem_data)
+                if "connections" in elem_data:
+                    connections_data[guid] = elem_data["connections"]
+        # Connections need all boxes to be created
+        self.connections_from_data(experiment, connections_data)
+        return experiment
+
+    def testbed_from_data(self, experiment, data):
+        testbed_id = data["testbed_id"]
+        testbed_version = data["testbed_version"]
+        experiment.add_testbed_description(testbed_id, testbed_version)
+
+    def box_from_data(self, experiment, data):
+        testbed_guid = data["testbed_guid"]
+        testbed_description = experiment.testbed_description(testbed_guid)
+        factory_id = data["factory_id"]
+        if "factory_attributes" in data:
+            self.factory_attributes_from_data(factory_id, testbed_description, 
+                    data["factory_attributes"])
+        box = testbed_description.create(factory_id)
+        if "attributes" in data:
+            self.attributes_from_data(box, data["attributes"])
+        if "traces" in data:
+            self.traces_from_data(box, data["traces"])
+        if "addresses" in data:
+            self.addresses_from_data(box, data["addresses"])
+        if "routes" in data:
+            self.routes_from_data(box, experiment, data["routes"])
+
+    def factory_attributes_from_data(self, factory_id, testbed_description, 
+            data):
+        factory = testbed_description.provider.factory(factory_id)
+        for name, value in data.iteritems():
+            factory.set_attribute_value(name, value)
+
+    def attributes_from_data(self, box, data):
+        for name, value in data.iteritems():
+            box.set_attribute_value(name, value)
+
+    def traces_from_data(self, box, data):
+        for name in data:
+            box.trace(name).enable()
+
+    def connections_from_data(self, experiment, data):
+        for guid, connector_data in data.iteritems():
+            box = experiment.box(guid)
+            for connector_type_name, connections in connector_data.iteritems():
+                for guid, other_connector_type_name in connections.iteritems():
+                    other_box = experiment.box(guid)
+                    connector = box.connector(connector_type_name)
+                    other_connector = other_box.connector(
+                            other_connector_type_name)
+                    if not connector.is_connected(other_connector):
+                        connector.connect(other_connector)
+
+    def addresses_from_data(self, box, data):
+        for address_attrs in data:
+            addr = box.add_address()
+            for name, value in address_attrs.iteritems():
+                addr.set_attribute_value(name, value)
+
+    def routes_from_data(self, box, experiment, data):
+        for route_attrs in data:
+            route = box.add_route()
+            for name, value in route_attrs.iteritems():
+                route.set_attribute_value(name, value)
+
diff --git a/src/nepi/util/parser/xml.py b/src/nepi/util/parser/xml.py
new file mode 100644 (file)
index 0000000..92da570
--- /dev/null
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+class XmlParser(object):
+    pass 
+
+description = """
+<experiment>
+  <testbeds>
+    <testbed testbed_id="netns" testbed_version="1.0" guid="1">
+      <elements>
+        <element factory_id="Node" guid="2">
+          <construct-parameters>
+          </construct-parameters>
+          <attributes>
+          </attributes>
+          <traces>
+          </traces>
+          <connections>
+          </connections>
+          <addresses>
+          </addresses>
+          <routes>
+          </routes>
+        </element>
+      </elements>
+    </testbed>
+  </testbeds>
+</experiment>
+"""
+