From: Alina Quereilhac Date: Fri, 11 Feb 2011 17:29:20 +0000 (+0100) Subject: experiment parsed to data and from data structure. (data being a dictionary of elemen... X-Git-Tag: nepi_v2~204 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=30c5e9219c0aa0c1e87e8a8da1ac7c4073b67aac;p=nepi.git experiment parsed to data and from data structure. (data being a dictionary of elements in the experiment) --- diff --git a/examples/design1.py b/examples/design1.py index 68c61fba..7f56ace3 100644 --- a/examples/design1.py +++ b/examples/design1.py @@ -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 = """ - - - - - - - - - - - - - - - - - - - - - - -""" diff --git a/src/nepi/core/attributes.py b/src/nepi/core/attributes.py index 5da6df40..187f43af 100644 --- a/src/nepi/core/attributes.py +++ b/src/nepi/core/attributes.py @@ -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 diff --git a/src/nepi/core/description.py b/src/nepi/core/description.py index 5fd0387f..650aca8a 100644 --- a/src/nepi/core/description.py +++ b/src/nepi/core/description.py @@ -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) diff --git a/src/nepi/core/experiment.py b/src/nepi/core/experiment.py index cc883863..a0db3293 100644 --- a/src/nepi/core/experiment.py +++ b/src/nepi/core/experiment.py @@ -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 index 00000000..e69de29b diff --git a/src/nepi/util/parser/base.py b/src/nepi/util/parser/base.py new file mode 100644 index 00000000..2f6b67a1 --- /dev/null +++ b/src/nepi/util/parser/base.py @@ -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 index 00000000..92da570f --- /dev/null +++ b/src/nepi/util/parser/xml.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +class XmlParser(object): + pass + +description = """ + + + + + + + + + + + + + + + + + + + + + + +""" +