From: Claudio-Daniel Freire Date: Wed, 27 Apr 2011 15:15:15 +0000 (+0200) Subject: Ticket #13: wildcards support in connector metadata, making the world better for... X-Git-Tag: nepi_v2~111 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=7d837305d315fc5aed6b30ebdf66f2829bbb1594;p=nepi.git Ticket #13: wildcards support in connector metadata, making the world better for cross-connectivity --- diff --git a/src/nepi/core/connector.py b/src/nepi/core/connector.py new file mode 100644 index 00000000..7cd415f6 --- /dev/null +++ b/src/nepi/core/connector.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Common connector base classes +""" + +import sys + +class ConnectorTypeBase(object): + def __init__(self, testbed_id, factory_id, name, max = -1, min = 0): + super(ConnectorTypeBase, self).__init__() + if max == -1: + max = sys.maxint + elif max <= 0: + raise RuntimeError, "The maximum number of connections allowed need to be more than 0" + if min < 0: + raise RuntimeError, "The minimum number of connections allowed needs to be at least 0" + # connector_type_id -- univoquely identifies a connector type + # across testbeds + self._connector_type_id = self.make_connector_type_id( + testbed_id, factory_id, name) + # name -- display name for the connector type + self._name = name + # max -- maximum amount of connections that this type support, + # -1 for no limit + self._max = max + # min -- minimum amount of connections required by this type of connector + self._min = min + + @property + def connector_type_id(self): + return self._connector_type_id + + @property + def name(self): + return self._name + + @property + def max(self): + return self._max + + @property + def min(self): + return self._min + + @staticmethod + def make_connector_type_id(testbed_id, factory_id, name): + testbed_id = testbed_id.lower() if testbed_id else None + factory_id = factory_id.lower() if factory_id else None + name = name.lower() if name else None + return (testbed_id, factory_id, name) + + @staticmethod + def _type_resolution_order(connector_type_id): + testbed_id, factory_id, name = connector_type_id + + # the key is always a candidate + yield connector_type_id + + # Try wildcard combinations + if (testbed_id, None, name) != connector_type_id: + yield (testbed_id, None, name) + if (None, factory_id, name) != connector_type_id: + yield (None, factory_id, name) + if (None, None, name) != connector_type_id: + yield (None, None, name) + + diff --git a/src/nepi/core/design.py b/src/nepi/core/design.py index cd0c3841..efdd9380 100644 --- a/src/nepi/core/design.py +++ b/src/nepi/core/design.py @@ -6,71 +6,43 @@ Experiment design API """ from nepi.core.attributes import AttributesMap, Attribute +from nepi.core.connector import ConnectorTypeBase from nepi.core.metadata import Metadata from nepi.util import validation from nepi.util.guid import GuidGenerator from nepi.util.graphical_info import GraphicalInfo from nepi.util.parser._xml import XmlExperimentParser import sys + + -class ConnectorType(object): +class ConnectorType(ConnectorTypeBase): def __init__(self, testbed_id, factory_id, name, help, max = -1, min = 0): - super(ConnectorType, self).__init__() - if max == -1: - max = sys.maxint - elif max <= 0: - raise RuntimeError( - "The maximum number of connections allowed need to be more than 0") - if min < 0: - raise RuntimeError( - "The minimum number of connections allowed needs to be at least 0") - # connector_type_id -- univoquely identifies a connector type - # across testbeds - self._connector_type_id = (testbed_id.lower(), factory_id.lower(), - name.lower()) - # name -- display name for the connector type - self._name = name + super(ConnectorType, self).__init__(testbed_id, factory_id, name, max, min) + # help -- help text self._help = help - # max -- maximum amount of connections that this type support, - # -1 for no limit - self._max = max - # min -- minimum amount of connections required by this type of connector - self._min = min + # allowed_connections -- keys in the dictionary correspond to the # connector_type_id for possible connections. The value indicates if # the connection is allowed accros different testbed instances self._allowed_connections = dict() - @property - def connector_type_id(self): - return self._connector_type_id - @property def help(self): return self._help - @property - def name(self): - return self._name - - @property - def max(self): - return self._max - - @property - def min(self): - return self._min - def add_allowed_connection(self, testbed_id, factory_id, name, can_cross): - self._allowed_connections[(testbed_id.lower(), - factory_id.lower(), name.lower())] = can_cross + type_id = self.make_connector_type_id(testbed_id, factory_id, name) + self._allowed_connections[type_id] = can_cross def can_connect(self, connector_type_id, testbed_guid1, testbed_guid2): - if not connector_type_id in self._allowed_connections.keys(): + for lookup_type_id in self._type_resolution_order(connector_type_id): + if lookup_type_id in self._allowed_connections: + can_cross = self._allowed_connections[lookup_type_id] + return can_cross or (testbed_guid1 == testbed_guid2) + else: return False - can_cross = self._allowed_connections[connector_type_id] - return can_cross or (testbed_guid1 == testbed_guid2) class Connector(object): """A Connector sepcifies the connection points in an Object""" diff --git a/src/nepi/core/execute.py b/src/nepi/core/execute.py index f977802b..2fa16c28 100644 --- a/src/nepi/core/execute.py +++ b/src/nepi/core/execute.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- from nepi.core.attributes import Attribute, AttributesMap +from nepi.core.connector import ConnectorTypeBase from nepi.util import proxy, validation from nepi.util.constants import STATUS_FINISHED, TIME_NOW from nepi.util.parser._xml import XmlExperimentParser @@ -15,28 +16,9 @@ ATTRIBUTE_PATTERN_BASE = re.compile(r"\{#\[(?P