Added routes to OMF nodes
[nepi.git] / src / nepi / util / parser / base.py
index b695745..eeaf594 100644 (file)
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: utf-8 -*-
 
 import sys
@@ -6,6 +5,13 @@ import sys
 class ExperimentData(object):
     def __init__(self):
         self.data = dict()
+    
+    def __repr__(self):
+        return "%s(%r)" % (self.__class__, self.data)
+    
+    def __str__(self):
+        from pprint import pformat
+        return "%s:%s" % (self.__class__, pformat(self.data))
 
     @property
     def guids(self):
@@ -23,7 +29,7 @@ class ExperimentData(object):
         box_data["factory_id"] = factory_id
         self.data[guid] = box_data
 
-    def add_graphical_info_data(self, guid, x, y, width, height, label):
+    def add_graphical_info_data(self, guid, x, y, width, height):
         data = self.data[guid]
         if not "graphical_info" in data:
             data["graphical_info"] = dict()
@@ -32,7 +38,6 @@ class ExperimentData(object):
         graphical_info_data["y"] = y
         graphical_info_data["width"] = width
         graphical_info_data["height"] = height
-        graphical_info_data["label"] = label
 
     def add_factory_attribute_data(self, guid, name, value):
         data = self.data[guid]
@@ -66,15 +71,13 @@ class ExperimentData(object):
         connection_data = connections_data[connector_type_name]
         connection_data[other_guid] = other_connector_type_name
 
-    def add_address_data(self, guid, autoconf, address, netprefix, 
+    def add_address_data(self, guid, address, netprefix, 
             broadcast):
         data = self.data[guid]
         if not "addresses" in data:
             data["addresses"] = list()
         addresses_data = data["addresses"]
         address_data = dict()
-        if autoconf:
-            address_data["AutoConfigure"] = autoconf
         if address:
             address_data["Address"] = address
         address_data["NetPrefix"] = netprefix
@@ -82,7 +85,7 @@ class ExperimentData(object):
             address_data["Broadcast"] = broadcast
         addresses_data.append(address_data)
 
-    def add_route_data(self, guid, destination, netprefix, nexthop): 
+    def add_route_data(self, guid, destination, netprefix, nexthop, metric, device):
         data = self.data[guid]
         if not "routes" in data:
             data["routes"] = list()
@@ -90,7 +93,9 @@ class ExperimentData(object):
         route_data = dict({
             "Destination": destination,
             "NetPrefix": netprefix, 
-            "NextHop": nexthop 
+            "NextHop": nexthop, 
+            "Metric": metric,
+            "Device": device
             })
         routes_data.append(route_data)
 
@@ -113,8 +118,7 @@ class ExperimentData(object):
         return (graphical_info_data["x"],
                 graphical_info_data["y"],
                 graphical_info_data["width"],
-                graphical_info_data["height"],
-                graphical_info_data["label"])
+                graphical_info_data["height"])
 
     def get_factory_attribute_data(self, guid):
         data = self.data[guid]
@@ -124,19 +128,32 @@ class ExperimentData(object):
         return [(name, value) for name, value \
                 in factory_attributes_data.iteritems()]
 
-    def get_attribute_data(self, guid):
+    def get_attribute_data(self, guid, attribute=None, default=None):
         data = self.data[guid]
         if not "attributes" in data:
-            return []
+            if attribute is None:
+                return []
+            else:
+                return None
         attributes_data = data["attributes"]
-        return [(name, value) for name, value \
-                in attributes_data.iteritems()]
+        if attribute is None:
+            return [(name, value) for name, value \
+                    in attributes_data.iteritems()]
+        else:
+            return attributes_data.get(attribute, default)
+
+    def set_attribute_data(self, guid, attribute, value):
+        data = self.data[guid]
+        if not "attributes" in data:
+            raise KeyError, "No attributes in reference OBJECT %r" % (guid,)
+        attributes_data = data["attributes"]
+        attributes_data[attribute] = value
 
     def get_trace_data(self, guid):
         data = self.data[guid]
         if not "traces" in data:
             return []
-        return [trace_id for trace_id in data["traces"]]
+        return data["traces"]
 
     def get_connection_data(self, guid):
         data = self.data[guid]
@@ -154,8 +171,7 @@ class ExperimentData(object):
         if not "addresses" in data:
             return []
         addresses_data = data["addresses"]
-        return [(data["AutoConfigure"] if "AutoConfigure" in data else None,
-                 data["Address"] if "Address" in data else None,
+        return [(data["Address"] if "Address" in data else None,
                  data["NetPrefix"] if "NetPrefix" in data else None,
                  data["Broadcast"] if "Broadcast" in data else None) \
                  for data in addresses_data]
@@ -167,7 +183,9 @@ class ExperimentData(object):
         routes_data = data["routes"]
         return [(data["Destination"],
                  data["NetPrefix"],
-                 data["NextHop"]) \
+                 data["NextHop"],
+                 data["Metric"],
+                 data["Device"]) \
                          for data in routes_data]
 
 class ExperimentParser(object):
@@ -189,15 +207,18 @@ class ExperimentParser(object):
                 self.attributes_to_data(data, box.guid, box.attributes)
                 self.traces_to_data(data, box.guid, box.traces)
                 self.connections_to_data(data, box.guid, box.connectors)
-                self.addresses_to_data(data, box.guid, box.addresses)
-                self.routes_to_data(data, box.guid, box.routes)
+                if hasattr(box, "addresses"):
+                    self.addresses_to_data(data, box.guid, box.addresses)
+                if hasattr(box, "routes"):
+                    self.routes_to_data(data, box.guid, box.routes)
         return data
 
     def graphical_info_to_data(self, data, guid, g_info):
         data.add_graphical_info_data(guid, g_info.x, g_info.y, g_info.width, 
-                g_info.height, g_info.label)
+                g_info.height)
 
     def factory_attributes_to_data(self, data, guid, factory_attributes):
+        factory_attributes = factory_attributes or dict()
         for name, value in factory_attributes.iteritems():
             data.add_factory_attribute_data(guid, name, value)
 
@@ -209,7 +230,7 @@ class ExperimentParser(object):
     def traces_to_data(self, data, guid, traces):
         for trace in traces:
             if trace.enabled:
-                data.add_trace_data(guid, trace.trace_id)
+                data.add_trace_data(guid, trace.name)
 
     def connections_to_data(self, data, guid, connectors):
         for connector in connectors:
@@ -222,25 +243,26 @@ class ExperimentParser(object):
 
     def addresses_to_data(self, data, guid, addresses):
         for addr in addresses:
-             autoconf = addr.get_attribute_value("AutoConfigure")
              address = addr.get_attribute_value("Address")
              netprefix = addr.get_attribute_value("NetPrefix")
              broadcast = addr.get_attribute_value("Broadcast") \
                     if addr.has_attribute("Broadcast") and \
                     addr.is_attribute_modified("Broadcast") else None
-             data.add_address_data(guid, autoconf, address, netprefix, 
-                    broadcast)
+             data.add_address_data(guid, address, netprefix, broadcast)
 
     def routes_to_data(self, data, guid, routes):
         for route in routes:
              destination = route.get_attribute_value("Destination")
              netprefix = route.get_attribute_value("NetPrefix")
              nexthop = route.get_attribute_value("NextHop")
-             data.add_route_data(guid, destination, netprefix, nexthop)
+             metric = route.get_attribute_value("Metric")
+             device = route.get_attribute_value("Device")
+             data.add_route_data(guid, destination, netprefix, nexthop, 
+                     metric, device)
 
     def from_data(self, experiment_description, data):
         box_guids = list()
-        for guid in data.guids:
+        for guid in sorted(data.guids):
             if data.is_testbed_data(guid):
                 self.testbed_from_data(experiment_description, guid, data)
             else:
@@ -251,9 +273,13 @@ class ExperimentParser(object):
     def testbed_from_data(self, experiment_description, guid, data):
         from nepi.core.design import FactoriesProvider
         (testbed_id, testbed_version) = data.get_testbed_data(guid)
-        provider = FactoriesProvider(testbed_id, testbed_version)
-        experiment_description.add_testbed_description(provider)
+        provider = FactoriesProvider(testbed_id)
+        if provider.testbed_version != testbed_version:
+            raise RuntimeError("Bad testbed version on testbed %s. Asked for %s, got %s" % \
+                    (testbed_id, testbed_version, provider.testbed_version))
+        experiment_description.add_testbed_description(provider, guid)
         testbed_description = experiment_description.testbed_description(guid)
+        self.graphical_info_from_data(testbed_description, data)
         self.attributes_from_data(testbed_description, data)
 
     def box_from_data(self, experiment_description, guid, data):
@@ -262,7 +288,8 @@ class ExperimentParser(object):
                 testbed_guid)
         self.factory_attributes_from_data(testbed_description, factory_id,
                 guid, data)
-        box = testbed_description.create(factory_id)
+        box = testbed_description.create(factory_id, guid)
+
         self.graphical_info_from_data(box, data)
         self.attributes_from_data(box, data)
         self.traces_from_data(box, data)
@@ -270,13 +297,12 @@ class ExperimentParser(object):
         self.routes_from_data(box, data)
 
     def graphical_info_from_data(self, element, data):
-        (x, y, width, height, label) =  data.get_graphical_info_data(
+        (x, y, width, height) =  data.get_graphical_info_data(
                 element.guid)
         element.graphical_info.x = x
         element.graphical_info.y = y
         element.graphical_info.width = width
         element.graphical_info.height = height
-        element.graphical_info.label = label
 
     def factory_attributes_from_data(self, testbed_description, factory_id, 
             guid, data):
@@ -293,11 +319,8 @@ class ExperimentParser(object):
             box.enable_trace(name)
 
     def addresses_from_data(self, box, data):
-        for (autoconf, address, netprefix, broadcast) \
-                in data.get_address_data(box.guid):
+        for (address, netprefix, broadcast) in data.get_address_data(box.guid):
             addr = box.add_address()
-            if autoconf:
-                addr.set_attribute_value("AutoConfigure", autoconf)
             if address:
                 addr.set_attribute_value("Address", address)
             if netprefix != None:
@@ -306,12 +329,14 @@ class ExperimentParser(object):
                 addr.set_attribute_value("Broadcast", broadcast)
 
     def routes_from_data(self, box, data):
-         for (destination, netprefix, nexthop) \
+         for (destination, netprefix, nexthop, metric, device) \
                  in data.get_route_data(box.guid):
             addr = box.add_route()
             addr.set_attribute_value("Destination", destination)
             addr.set_attribute_value("NetPrefix", netprefix)
             addr.set_attribute_value("NextHop", nexthop)
+            addr.set_attribute_value("Metric", metric)
+            addr.set_attribute_value("Device", device)
 
     def connections_from_data(self, experiment_description, guids, data):
         for guid in guids: