"""
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
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):
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:
return self._traces.values()
@property
- def trace_names(self):
+ def traces_list(self):
return self._traces.keys()
@property
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__()
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
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
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
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")
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,
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)
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:
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
(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:
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]
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: