merged Factory from design and execute
authorAlina Quereilhac <alina.quereilhac@inria.fr>
Tue, 5 Jul 2011 13:39:29 +0000 (15:39 +0200)
committerAlina Quereilhac <alina.quereilhac@inria.fr>
Tue, 5 Jul 2011 13:39:29 +0000 (15:39 +0200)
src/nepi/core/design.py
src/nepi/core/execute.py
src/nepi/core/metadata.py
src/nepi/core/testbed_impl.py
src/nepi/util/parser/base.py

index 100fff9..46e54bd 100644 (file)
@@ -6,7 +6,6 @@ Experiment design API
 """
 
 from nepi.core.attributes import AttributesMap, Attribute
-from nepi.core.connector import ConnectorType
 from nepi.core.metadata import Metadata
 from nepi.util import validation
 from nepi.util.guid import GuidGenerator
@@ -84,15 +83,15 @@ class Connector(object):
         self._box = self._connectors = None
 
 class Trace(AttributesMap):
-    def __init__(self, trace_id, help, enabled = False):
+    def __init__(self, name, help, enabled = False):
         super(Trace, self).__init__()
-        self._trace_id = trace_id
+        self._name = name
         self._help = help       
         self._enabled = enabled
     
     @property
-    def trace_id(self):
-        return self._trace_id
+    def name(self):
+        return self._name
 
     @property
     def help(self):
@@ -179,9 +178,9 @@ class Box(AttributesMap):
         for connector_type in factory.connector_types:
             connector = Connector(self, connector_type)
             self._connectors[connector_type.name] = connector
-        for trace in factory.traces:
-            tr = Trace(trace.trace_id, trace.help, trace.enabled)
-            self._traces[trace.trace_id] = tr
+        for (name, help, enabled) in factory.traces:
+            trace = Trace(name, help, enabled)
+            self._traces[name] = trace
         for tag_id in factory.tags:
             self._tags.append(tag_id)
         for attr in factory.box_attributes.attributes:
@@ -220,7 +219,7 @@ class Box(AttributesMap):
         return self._traces.values()
 
     @property
-    def trace_names(self):
+    def traces_list(self):
         return self._traces.keys()
 
     @property
@@ -254,213 +253,6 @@ class Box(AttributesMap):
             t.destroy()
         self._connectors = self._traces = self._factory_attributes = None
 
-class AddressableMixin(object):
-    def __init__(self, guid, factory, testbed_guid, container = None):
-        super(AddressableMixin, self).__init__(guid, factory, testbed_guid, 
-                container)
-        max_addr =  self._factory_attributes["MaxAddresses"] \
-                if "MaxAddresses" in self._factory_attributes else 1
-        self._max_addresses = max_addr
-        self._addresses = list()
-
-    @property
-    def addresses(self):
-        return self._addresses
-
-    @property
-    def max_addresses(self):
-        return self._max_addresses
-
-class UserAddressableMixin(AddressableMixin):
-    def __init__(self, guid, factory, testbed_guid, container = None):
-        super(UserAddressableMixin, self).__init__(guid, factory, testbed_guid, 
-                container)
-
-    def add_address(self):
-        if len(self._addresses) == self.max_addresses:
-            raise RuntimeError("Maximun number of addresses for this box reached.")
-        address = Address()
-        self._addresses.append(address)
-        return address
-
-    def delete_address(self, address):
-        self._addresses.remove(address)
-        del address
-
-    def destroy(self):
-        super(UserAddressableMixin, self).destroy()
-        for address in list(self.addresses):
-            self.delete_address(address)
-        self._addresses = None
-
-class RoutableMixin(object):
-    def __init__(self, guid, factory, testbed_guid, container = None):
-        super(RoutableMixin, self).__init__(guid, factory, testbed_guid, 
-            container)
-        self._routes = list()
-
-    @property
-    def routes(self):
-        return self._routes
-
-class UserRoutableMixin(RoutableMixin):
-    def __init__(self, guid, factory, testbed_guid, container = None):
-        super(UserRoutableMixin, self).__init__(guid, factory, testbed_guid, 
-            container)
-
-    def add_route(self):
-        route = Route()
-        self._routes.append(route)
-        return route
-
-    def delete_route(self, route):
-        self._routes.remove(route)
-        del route
-
-    def destroy(self):
-        super(UserRoutableMixin, self).destroy()
-        for route in list(self.routes):
-            self.delete_route(route)
-        self._route = None
-
-def MixIn(MyClass, MixIn):
-    # Mixins are installed BEFORE "Box" because
-    # Box inherits from non-cooperative classes,
-    # so the MRO chain gets broken when it gets
-    # to Box.
-
-    # Install mixin
-    MyClass.__bases__ = (MixIn,) + MyClass.__bases__
-    
-    # Add properties
-    # Somehow it doesn't work automatically
-    for name in dir(MixIn):
-        prop = getattr(MixIn,name,None)
-        if isinstance(prop, property):
-            setattr(MyClass, name, prop)
-    
-    # Update name
-    MyClass.__name__ = MyClass.__name__.replace(
-        'Box',
-        MixIn.__name__.replace('MixIn','')+'Box',
-        1)
-
-class Factory(AttributesMap):
-    _box_class_cache = {}
-        
-    def __init__(self, factory_id, 
-            allow_addresses = False, has_addresses = False,
-            allow_routes = False, has_routes = False,
-            Help = None, category = None):
-        super(Factory, self).__init__()
-        self._factory_id = factory_id
-        self._allow_addresses = bool(allow_addresses)
-        self._allow_routes = bool(allow_routes)
-        self._has_addresses = bool(allow_addresses) or self._allow_addresses
-        self._has_routes = bool(allow_routes) or self._allow_routes
-        self._help = help
-        self._category = category
-        self._connector_types = list()
-        self._traces = list()
-        self._tags = list()
-        self._box_attributes = AttributesMap()
-        
-        if not self._has_addresses and not self._has_routes:
-            self._factory = Box
-        else:
-            addresses = 'w' if self._allow_addresses else ('r' if self._has_addresses else '-')
-            routes    = 'w' if self._allow_routes else ('r' if self._has_routes else '-')
-            key = addresses+routes
-            
-            if key in self._box_class_cache:
-                self._factory = self._box_class_cache[key]
-            else:
-                # Create base class
-                class _factory(Box):
-                    def __init__(self, guid, factory, testbed_guid, container = None):
-                        super(_factory, self).__init__(guid, factory, testbed_guid, container)
-                
-                # Add mixins, one by one
-                if allow_addresses:
-                    MixIn(_factory, UserAddressableMixin)
-                elif has_addresses:
-                    MixIn(_factory, AddressableMixin)
-                    
-                if allow_routes:
-                    MixIn(_factory, UserRoutableMixin)
-                elif has_routes:
-                    MixIn(_factory, RoutableMixin)
-                
-                # Put into cache
-                self._box_class_cache[key] = self._factory = _factory
-
-    @property
-    def factory_id(self):
-        return self._factory_id
-
-    @property
-    def allow_addresses(self):
-        return self._allow_addresses
-
-    @property
-    def allow_routes(self):
-        return self._allow_routes
-
-    @property
-    def has_addresses(self):
-        return self._has_addresses
-
-    @property
-    def has_routes(self):
-        return self._has_routes
-
-    @property
-    def help(self):
-        return self._help
-
-    @property
-    def category(self):
-        return self._category
-
-    @property
-    def connector_types(self):
-        return self._connector_types
-
-    @property
-    def traces(self):
-        return self._traces
-
-    @property
-    def tags(self):
-        return self._tags
-    
-    @property
-    def box_attributes(self):
-        return self._box_attributes
-
-    def add_connector_type(self, connector_type):
-        self._connector_types.append(connector_type)
-
-    def add_trace(self, trace_id, help, enabled = False):
-        trace = Trace(trace_id, help, enabled)
-        self._traces.append(trace)
-
-    def add_tag(self, tag_id):
-        self._tags.append(tag_id)
-
-    def add_box_attribute(self, name, help, type, value = None, range = None,
-        allowed = None, flags = Attribute.NoFlags, validation_function = None,
-        category = None):
-        self._box_attributes.add_attribute(name, help, type, value, range,
-                allowed, flags, validation_function, category)
-
-    def create(self, guid, testbed_description):
-        return self._factory(guid, self, testbed_description.guid)
-
-    def destroy(self):
-        super(Factory, self).destroy()
-        self._connector_types = None
-
 class FactoriesProvider(object):
     def __init__(self, testbed_id, testbed_version):
         super(FactoriesProvider, self).__init__()
@@ -469,7 +261,7 @@ class FactoriesProvider(object):
         self._factories = dict()
 
         metadata = Metadata(testbed_id, testbed_version) 
-        for factory in metadata.build_design_factories():
+        for factory in metadata.build_factories():
             self.add_factory(factory)
 
     @property
index 8c97638..55f4b1a 100644 (file)
@@ -17,109 +17,6 @@ ATTRIBUTE_PATTERN_BASE = re.compile(r"\{#\[(?P<label>[-a-zA-Z0-9._]*)\](?P<expr>
 ATTRIBUTE_PATTERN_GUID_SUB = r"{#[%(guid)s]%(expr)s#}"
 COMPONENT_PATTERN = re.compile(r"(?P<kind>[a-z]*)\[(?P<index>.*)\]")
 
-class Factory(AttributesMap):
-    def __init__(self, factory_id, create_function, start_function, 
-            stop_function, status_function, 
-            configure_function, preconfigure_function,
-            prestart_function,
-            allow_addresses = False, has_addresses = False,
-            allow_routes = False, has_routes = False):
-        super(Factory, self).__init__()
-        self._factory_id = factory_id
-        self._allow_addresses = bool(allow_addresses)
-        self._allow_routes = bool(allow_routes)
-        self._has_addresses = bool(has_addresses) or self._allow_addresses
-        self._has_routes = bool(has_routes) or self._allow_routes
-        self._create_function = create_function
-        self._start_function = start_function
-        self._stop_function = stop_function
-        self._status_function = status_function
-        self._configure_function = configure_function
-        self._preconfigure_function = preconfigure_function
-        self._prestart_function = prestart_function
-        self._connector_types = dict()
-        self._traces = list()
-        self._tags = list()
-        self._box_attributes = AttributesMap()
-
-    @property
-    def factory_id(self):
-        return self._factory_id
-
-    @property
-    def allow_addresses(self):
-        return self._allow_addresses
-
-    @property
-    def allow_routes(self):
-        return self._allow_routes
-
-    @property
-    def has_addresses(self):
-        return self._has_addresses
-
-    @property
-    def has_routes(self):
-        return self._has_routes
-
-    @property
-    def box_attributes(self):
-        return self._box_attributes
-
-    @property
-    def create_function(self):
-        return self._create_function
-
-    @property
-    def prestart_function(self):
-        return self._prestart_function
-
-    @property
-    def start_function(self):
-        return self._start_function
-
-    @property
-    def stop_function(self):
-        return self._stop_function
-
-    @property
-    def status_function(self):
-        return self._status_function
-
-    @property
-    def configure_function(self):
-        return self._configure_function
-
-    @property
-    def preconfigure_function(self):
-        return self._preconfigure_function
-
-    @property
-    def traces(self):
-        return self._traces
-
-    @property
-    def tags(self):
-        return self._tags
-
-    def connector_type(self, name):
-        return self._connector_types[name]
-
-    def add_connector_type(self, connector_type):
-        self._connector_types[connector_type.name] = connector_type
-
-    def add_trace(self, trace_id):
-        self._traces.append(trace_id)
-
-    def add_tag(self, tag_id):
-        self._tags.append(tag_id)
-
-    def add_box_attribute(self, name, help, type, value = None, range = None,
-        allowed = None, flags = Attribute.NoFlags, validation_function = None,
-        category = None):
-        self._box_attributes.add_attribute(name, help, type, value, range, 
-                allowed, flags, validation_function, category)
-
 class TestbedController(object):
     def __init__(self, testbed_id, testbed_version):
         self._testbed_id = testbed_id
index 894874d..3555617 100644 (file)
@@ -3,6 +3,7 @@
 
 from nepi.core.attributes import Attribute, AttributesMap
 from nepi.core.connector import ConnectorType
+from nepi.core.factory import Factory
 import sys
 import getpass
 from nepi.util import validation
@@ -383,37 +384,7 @@ class Metadata(object):
         
         return attributes
 
-    def build_design_factories(self):
-        from nepi.core.design import Factory
-        factories = list()
-        for factory_id, info in self._metadata.factories_info.iteritems():
-            help = info["help"]
-            category = info["category"]
-            allow_addresses = info.get("allow_addresses", False)
-            allow_routes = info.get("allow_routes", False)
-            has_addresses = info.get("has_addresses", False)
-            has_routes = info.get("has_routes", False)
-            factory = Factory(factory_id, 
-                    allow_addresses, has_addresses,
-                    allow_routes, has_routes,
-                    help, category)
-            
-            # standard attributes
-            self._add_standard_attributes(factory, info, True, True,
-                self.STANDARD_BOX_ATTRIBUTES)
-            
-            # custom attributes - they override standard ones
-            self._add_attributes(factory, info, "factory_attributes")
-            self._add_attributes(factory, info, "box_attributes", True)
-            
-            self._add_design_traces(factory, info)
-            self._add_tags(factory, info)
-            self._add_connector_types(factory, info)
-            factories.append(factory)
-        return factories
-
-    def build_execute_factories(self):
-        from nepi.core.execute import Factory
+    def build_factories(self):
         factories = list()
         for factory_id, info in self._metadata.factories_info.iteritems():
             create_function = info.get("create_function")
@@ -427,12 +398,22 @@ class Metadata(object):
             allow_routes = info.get("allow_routes", False)
             has_addresses = info.get("has_addresses", False)
             has_routes = info.get("has_routes", False)
-            factory = Factory(factory_id, create_function, start_function,
-                    stop_function, status_function, 
-                    configure_function, preconfigure_function,
+            help = info["help"]
+            category = info["category"]
+            factory = Factory(factory_id, 
+                    create_function, 
+                    start_function,
+                    stop_function, 
+                    status_function, 
+                    configure_function, 
+                    preconfigure_function,
                     prestart_function,
-                    allow_addresses, has_addresses,
-                    allow_routes, has_routes)
+                    help,
+                    category,
+                    allow_addresses, 
+                    has_addresses,
+                    allow_routes, 
+                    has_routes)
                     
             # standard attributes
             self._add_standard_attributes(factory, info, False, True,
@@ -442,7 +423,7 @@ class Metadata(object):
             self._add_attributes(factory, info, "factory_attributes")
             self._add_attributes(factory, info, "box_attributes", True)
             
-            self._add_execute_traces(factory, info)
+            self._add_traces(factory, info)
             self._add_tags(factory, info)
             self._add_connector_types(factory, info)
             factories.append(factory)
@@ -492,20 +473,13 @@ class Metadata(object):
                 factory.add_attribute(name, help, type, value, range, 
                         allowed, flags, validation_function, category)
 
-    def _add_design_traces(self, factory, info):
+    def _add_traces(self, factory, info):
         if "traces" in info:
-            for trace in info["traces"]:
-                trace_info = self._metadata.traces[trace]
-                trace_id = trace_info["name"]
+            for trace_id in info["traces"]:
+                trace_info = self._metadata.traces[trace_id]
+                name = trace_info["name"]
                 help = trace_info["help"]
-                factory.add_trace(trace_id, help)
-
-    def _add_execute_traces(self, factory, info):
-        if "traces" in info:
-            for trace in info["traces"]:
-                trace_info = self._metadata.traces[trace]
-                trace_id = trace_info["name"]
-                factory.add_trace(trace_id)
+                factory.add_trace(name, help)
 
     def _add_tags(self, factory, info):
         if "tags" in info:
index 4a19e47..fd76bf4 100644 (file)
@@ -41,7 +41,7 @@ class TestbedController(execute.TestbedController):
         self._elements = dict()
 
         self._metadata = Metadata(self._testbed_id, self._testbed_version)
-        for factory in self._metadata.build_execute_factories():
+        for factory in self._metadata.build_factories():
             self._factories[factory.factory_id] = factory
         self._attributes = self._metadata.testbed_attributes()
         self._root_directory = None
@@ -157,16 +157,16 @@ class TestbedController(execute.TestbedController):
                 (cross_guid, cross_testbed_guid, cross_testbed_id, 
                 cross_factory_id, cross_connector_type_name)
 
-    def defer_add_trace(self, guid, trace_id):
+    def defer_add_trace(self, guid, trace_name):
         if not guid in self._create:
             raise RuntimeError("Element guid %d doesn't exist" % guid)
         factory = self._get_factory(guid)
-        if not trace_id in factory.traces:
+        if not trace_name in factory.traces_list:
             raise RuntimeError("Element type '%s' has no trace '%s'" %
-                    (factory.factory_id, trace_id))
+                    (factory.factory_id, trace_name))
         if not guid in self._add_trace:
             self._add_trace[guid] = list()
-        self._add_trace[guid].append(trace_id)
+        self._add_trace[guid].append(trace_name)
 
     def defer_add_address(self, guid, address, netprefix, broadcast):
         if not guid in self._create:
index 5bdbcde..5cbd072 100644 (file)
@@ -153,7 +153,7 @@ class ExperimentData(object):
         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]
@@ -229,7 +229,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: