ariatosca-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mxm...@apache.org
Subject incubator-ariatosca git commit: wip
Date Thu, 13 Jul 2017 13:49:22 GMT
Repository: incubator-ariatosca
Updated Branches:
  refs/heads/topology_poc [created] 7d1cfbc42


wip


Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/7d1cfbc4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/7d1cfbc4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/7d1cfbc4

Branch: refs/heads/topology_poc
Commit: 7d1cfbc425d90da09862e4b846fa66b97f364d37
Parents: b841c01
Author: max-orlov <maxim@gigaspaces.com>
Authored: Thu Jul 13 16:49:15 2017 +0300
Committer: max-orlov <maxim@gigaspaces.com>
Committed: Thu Jul 13 16:49:15 2017 +0300

----------------------------------------------------------------------
 aria/core.py                      |   7 +-
 aria/modeling/mixins.py           |   6 -
 aria/modeling/service_template.py | 196 -----------------------
 aria/modeling/utils.py            |  11 +-
 aria/parser/topology/topoloy.py   | 280 +++++++++++++++++++++++++++++++++
 5 files changed, 293 insertions(+), 207 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/7d1cfbc4/aria/core.py
----------------------------------------------------------------------
diff --git a/aria/core.py b/aria/core.py
index e214b1a..54379ba 100644
--- a/aria/core.py
+++ b/aria/core.py
@@ -18,7 +18,7 @@ ARIA core module.
 """
 
 from . import exceptions
-from .parser import consumption
+from .parser import consumption, topology
 from .parser.loading.location import UriLocation
 
 
@@ -67,7 +67,7 @@ class Core(object):
         self.resource_storage.service_template.delete(entry_id=str(service_template.id))
 
     def create_service(self, service_template_id, inputs, service_name=None):
-
+        import pydevd; pydevd.settrace('localhost', suspend=False)
         service_template = self.model_storage.service_template.get(service_template_id)
 
         # creating an empty ConsumptionContext, initiating a threadlocal context
@@ -77,7 +77,8 @@ class Core(object):
         # setting no autoflush for the duration of instantiation - this helps avoid dependency
         # constraints as they're being set up
         with storage_session.no_autoflush:
-            service = service_template.instantiate(None, self.model_storage, inputs=inputs)
+            service = topology.Instantiation(self.model_storage).instantiate_service(
+                service_template, inputs=inputs)
 
             consumption.ConsumerChain(
                 context,

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/7d1cfbc4/aria/modeling/mixins.py
----------------------------------------------------------------------
diff --git a/aria/modeling/mixins.py b/aria/modeling/mixins.py
index 883ff4a..b2a0e0d 100644
--- a/aria/modeling/mixins.py
+++ b/aria/modeling/mixins.py
@@ -308,12 +308,6 @@ class ParameterMixin(TemplateModelMixin, caching.HasCachedMethods):
             ('value', self.value),
             ('description', self.description)))
 
-    def instantiate(self, container):
-        return self.__class__(name=self.name,  # pylint: disable=unexpected-keyword-arg
-                              type_name=self.type_name,
-                              _value=self._value,
-                              description=self.description)
-
     def coerce_values(self, report_issues):
         value = self._value
         if value is not None:

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/7d1cfbc4/aria/modeling/service_template.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_template.py b/aria/modeling/service_template.py
index 22912e2..8b26d15 100644
--- a/aria/modeling/service_template.py
+++ b/aria/modeling/service_template.py
@@ -331,49 +331,6 @@ class ServiceTemplateBase(TemplateModelMixin):
             ('interface_types', formatting.as_raw(self.interface_types)),
             ('artifact_types', formatting.as_raw(self.artifact_types))))
 
-    def instantiate(self, container, model_storage, inputs=None):  # pylint: disable=arguments-differ
-        from . import models
-        now = datetime.now()
-        service = models.Service(created_at=now,
-                                 updated_at=now,
-                                 description=deepcopy_with_locators(self.description),
-                                 service_template=self)
-
-        # TODO: we want to remove this use of the context
-        context = ConsumptionContext.get_thread_local()
-        context.modeling.instance = service
-
-        service.inputs = utils.merge_parameter_values(inputs, self.inputs, model_cls=models.Input)
-        # TODO: now that we have inputs, we should scan properties and inputs and evaluate
functions
-
-        for plugin_specification in self.plugin_specifications.itervalues():
-            if plugin_specification.enabled:
-                if plugin_specification.resolve(model_storage):
-                    plugin = plugin_specification.plugin
-                    service.plugins[plugin.name] = plugin
-                else:
-                    context = ConsumptionContext.get_thread_local()
-                    context.validation.report('specified plugin not found: {0}'.format(
-                        plugin_specification.name), level=validation.Issue.EXTERNAL)
-
-        utils.instantiate_dict(self, service.meta_data, self.meta_data)
-
-        for node_template in self.node_templates.itervalues():
-            for _ in range(node_template.scaling['default_instances']):
-                node = node_template.instantiate(container)
-                service.nodes[node.name] = node
-
-        utils.instantiate_dict(self, service.groups, self.group_templates)
-        utils.instantiate_dict(self, service.policies, self.policy_templates)
-        utils.instantiate_dict(self, service.workflows, self.workflow_templates)
-
-        if self.substitution_template is not None:
-            service.substitution = self.substitution_template.instantiate(container)
-
-        utils.instantiate_dict(self, service.outputs, self.outputs)
-
-        return service
-
     def validate(self):
         utils.validate_dict_values(self.meta_data)
         utils.validate_dict_values(self.node_templates)
@@ -620,29 +577,6 @@ class NodeTemplateBase(TemplateModelMixin):
             ('capability_templates', formatting.as_raw_list(self.capability_templates)),
             ('requirement_templates', formatting.as_raw_list(self.requirement_templates))))
 
-    def instantiate(self, container):
-        from . import models
-        node = models.Node(name=self._next_name,
-                           type=self.type,
-                           description=deepcopy_with_locators(self.description),
-                           state=models.Node.INITIAL,
-                           node_template=self)
-        utils.instantiate_dict(node, node.properties, self.properties)
-        utils.instantiate_dict(node, node.attributes, self.attributes)
-        utils.instantiate_dict(node, node.interfaces, self.interface_templates)
-        utils.instantiate_dict(node, node.artifacts, self.artifact_templates)
-        utils.instantiate_dict(node, node.capabilities, self.capability_templates)
-
-        # Default attributes
-        if ('tosca_name' in node.attributes) \
-            and (node.attributes['tosca_name'].type_name == 'string'):
-            node.attributes['tosca_name'].value = self.name
-        if 'tosca_id' in node.attributes \
-            and (node.attributes['tosca_id'].type_name == 'string'):
-            node.attributes['tosca_id'].value = node.name
-
-        return node
-
     def validate(self):
         utils.validate_dict_values(self.properties)
         utils.validate_dict_values(self.attributes)
@@ -871,19 +805,6 @@ class GroupTemplateBase(TemplateModelMixin):
             ('properties', formatting.as_raw_dict(self.properties)),
             ('interface_templates', formatting.as_raw_list(self.interface_templates))))
 
-    def instantiate(self, container):
-        from . import models
-        group = models.Group(name=self.name,
-                             type=self.type,
-                             description=deepcopy_with_locators(self.description),
-                             group_template=self)
-        utils.instantiate_dict(self, group.properties, self.properties)
-        utils.instantiate_dict(self, group.interfaces, self.interface_templates)
-        if self.node_templates:
-            for node_template in self.node_templates:
-                group.nodes += node_template.nodes
-        return group
-
     def validate(self):
         utils.validate_dict_values(self.properties)
         utils.validate_dict_values(self.interface_templates)
@@ -1017,21 +938,6 @@ class PolicyTemplateBase(TemplateModelMixin):
             ('type_name', self.type.name),
             ('properties', formatting.as_raw_dict(self.properties))))
 
-    def instantiate(self, container):
-        from . import models
-        policy = models.Policy(name=self.name,
-                               type=self.type,
-                               description=deepcopy_with_locators(self.description),
-                               policy_template=self)
-        utils.instantiate_dict(self, policy.properties, self.properties)
-        if self.node_templates:
-            for node_template in self.node_templates:
-                policy.nodes += node_template.nodes
-        if self.group_templates:
-            for group_template in self.group_templates:
-                policy.groups += group_template.groups
-        return policy
-
     def validate(self):
         utils.validate_dict_values(self.properties)
 
@@ -1129,13 +1035,6 @@ class SubstitutionTemplateBase(TemplateModelMixin):
             ('node_type_name', self.node_type.name),
             ('mappings', formatting.as_raw_dict(self.mappings))))
 
-    def instantiate(self, container):
-        from . import models
-        substitution = models.Substitution(node_type=self.node_type,
-                                           substitution_template=self)
-        utils.instantiate_dict(container, substitution.mappings, self.mappings)
-        return substitution
-
     def validate(self):
         utils.validate_dict_values(self.mappings)
 
@@ -1231,34 +1130,6 @@ class SubstitutionTemplateMappingBase(TemplateModelMixin):
     def coerce_values(self, report_issues):
         pass
 
-    def instantiate(self, container):
-        from . import models
-        context = ConsumptionContext.get_thread_local()
-        if self.capability_template is not None:
-            node_template = self.capability_template.node_template
-        else:
-            node_template = self.requirement_template.node_template
-        nodes = node_template.nodes
-        if len(nodes) == 0:
-            context.validation.report(
-                'mapping "{0}" refers to node template "{1}" but there are no '
-                'node instances'.format(self.mapped_name, self.node_template.name),
-                level=validation.Issue.BETWEEN_INSTANCES)
-            return None
-        # The TOSCA spec does not provide a way to choose the node,
-        # so we will just pick the first one
-        node = nodes[0]
-        capability = None
-        if self.capability_template:
-            for a_capability in node.capabilities.itervalues():
-                if a_capability.capability_template.name == self.capability_template.name:
-                    capability = a_capability
-        return models.SubstitutionMapping(name=self.name,
-                                          capability=capability,
-                                          requirement_template=self.requirement_template,
-                                          node=node)
-
-
     def validate(self):
         context = ConsumptionContext.get_thread_local()
         if (self.capability_template is None) and (self.requirement_template is None):
@@ -1601,15 +1472,6 @@ class RelationshipTemplateBase(TemplateModelMixin):
             ('properties', formatting.as_raw_dict(self.properties)),
             ('interface_templates', formatting.as_raw_list(self.interface_templates))))
 
-    def instantiate(self, container):
-        from . import models
-        relationship_model = models.Relationship(name=self.name,
-                                                 type=self.type,
-                                                 relationship_template=self)
-        utils.instantiate_dict(container, relationship_model.properties, self.properties)
-        utils.instantiate_dict(container, relationship_model.interfaces, self.interface_templates)
-        return relationship_model
-
     def validate(self):
         # TODO: either type or name must be set
         utils.validate_dict_values(self.properties)
@@ -1768,17 +1630,6 @@ class CapabilityTemplateBase(TemplateModelMixin):
             ('valid_source_node_types', [v.name for v in self.valid_source_node_types]),
             ('properties', formatting.as_raw_dict(self.properties))))
 
-    def instantiate(self, container):
-        from . import models
-        capability = models.Capability(name=self.name,
-                                       type=self.type,
-                                       min_occurrences=self.min_occurrences,
-                                       max_occurrences=self.max_occurrences,
-                                       occurrences=0,
-                                       capability_template=self)
-        utils.instantiate_dict(container, capability.properties, self.properties)
-        return capability
-
     def validate(self):
         utils.validate_dict_values(self.properties)
 
@@ -1933,16 +1784,6 @@ class InterfaceTemplateBase(TemplateModelMixin):
             # TODO fix self.properties reference
             ('operation_templates', formatting.as_raw_list(self.operation_templates))))
 
-    def instantiate(self, container):
-        from . import models
-        interface = models.Interface(name=self.name,
-                                     type=self.type,
-                                     description=deepcopy_with_locators(self.description),
-                                     interface_template=self)
-        utils.instantiate_dict(container, interface.inputs, self.inputs)
-        utils.instantiate_dict(container, interface.operations, self.operation_templates)
-        return interface
-
     def validate(self):
         utils.validate_dict_values(self.inputs)
         utils.validate_dict_values(self.operation_templates)
@@ -2119,30 +1960,6 @@ class OperationTemplateBase(TemplateModelMixin):
             ('dependencies', self.dependencies),
             ('inputs', formatting.as_raw_dict(self.inputs))))
 
-    def instantiate(self, container):
-        from . import models
-
-        plugin = self.plugin_specification.plugin \
-            if (self.plugin_specification is not None) and self.plugin_specification.enabled
\
-            else None
-
-        operation = models.Operation(name=self.name,
-                                     description=deepcopy_with_locators(self.description),
-                                     relationship_edge=self.relationship_edge,
-                                     implementation=self.implementation,
-                                     dependencies=self.dependencies,
-                                     executor=self.executor,
-                                     plugin=plugin,
-                                     function=self.function,
-                                     max_attempts=self.max_attempts,
-                                     retry_interval=self.retry_interval,
-                                     operation_template=self)
-
-        utils.instantiate_dict(container, operation.inputs, self.inputs)
-        utils.instantiate_dict(container, operation.configurations, self.configurations)
-
-        return operation
-
     def validate(self):
         utils.validate_dict_values(self.inputs)
         utils.validate_dict_values(self.configurations)
@@ -2290,19 +2107,6 @@ class ArtifactTemplateBase(TemplateModelMixin):
             ('repository_credential', formatting.as_agnostic(self.repository_credential)),
             ('properties', formatting.as_raw_dict(self.properties))))
 
-    def instantiate(self, container):
-        from . import models
-        artifact = models.Artifact(name=self.name,
-                                   type=self.type,
-                                   description=deepcopy_with_locators(self.description),
-                                   source_path=self.source_path,
-                                   target_path=self.target_path,
-                                   repository_url=self.repository_url,
-                                   repository_credential=self.repository_credential,
-                                   artifact_template=self)
-        utils.instantiate_dict(container, artifact.properties, self.properties)
-        return artifact
-
     def validate(self):
         utils.validate_dict_values(self.properties)
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/7d1cfbc4/aria/modeling/utils.py
----------------------------------------------------------------------
diff --git a/aria/modeling/utils.py b/aria/modeling/utils.py
index e0fd11b..9ba2cfa 100644
--- a/aria/modeling/utils.py
+++ b/aria/modeling/utils.py
@@ -64,7 +64,7 @@ class NodeTemplateContainerHolder(object):
         return self.container.service_template
 
 
-def merge_parameter_values(parameter_values, declared_parameters, model_cls):
+def merge_parameter_values(parameter_values, declared_parameters):
     """
     Merges parameter values according to those declared by a type.
 
@@ -94,6 +94,7 @@ def merge_parameter_values(parameter_values, declared_parameters, model_cls):
                     string_list_as_string(declared_parameters.keys())))
 
     parameters = OrderedDict()
+    model_cls = get_class_from_relationship(declared_parameters)
 
     missing_names = []
     wrong_type_values = OrderedDict()
@@ -121,7 +122,7 @@ def merge_parameter_values(parameter_values, declared_parameters, model_cls):
                 value=value)
         elif declared_parameter.value is not None:
             # Copy default value from declaration
-            parameters[declared_parameter_name] = declared_parameter.instantiate(None)
+            parameters[declared_parameter_name] = model_cls(**declared_parameter.as_raw)
         else:
             # Required value has not been provided
             missing_names.append(declared_parameter_name)
@@ -241,3 +242,9 @@ def fix_doc(cls):
     cls.__doc__ = cls.__bases__[-1].__doc__
 
     return cls
+
+
+def get_class_from_relationship(property):
+    class_ = property._sa_adapter.owner_state.class_
+    prop_name = property._sa_adapter.attr.key
+    return getattr(class_, prop_name).property.mapper.class_

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/7d1cfbc4/aria/parser/topology/topoloy.py
----------------------------------------------------------------------
diff --git a/aria/parser/topology/topoloy.py b/aria/parser/topology/topoloy.py
new file mode 100644
index 0000000..943d25a
--- /dev/null
+++ b/aria/parser/topology/topoloy.py
@@ -0,0 +1,280 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from collections import namedtuple
+from datetime import datetime
+from functools import partial
+
+from ... modeling import (
+    utils,
+    models
+)
+from .. import (
+    reading,
+    consumption,
+    validation,
+)
+
+
+
+
+
+class Instantiation(object):
+
+    def __init__(self, model_storage):
+        self._model_storage = model_storage
+        self._initiators = {
+            'meta_data': self._instantiate_metadata,
+            'node_template': self._instantiate_node,
+            'substitution_template': self._instantiate_substitution,
+            'workflow_templates': self._instantiate_operation,
+            'operation_templates': self._instantiate_operation,
+            'interface_templates': self._instantiate_interface,
+            'artifact_templates': self._instantiate_artifact,
+            'capability_templates': self._instantiate_capability,
+            'group_templates': self._instantiate_group,
+            'policy_templates': self._instantiate_policy,
+            'relationship_template': self._instantiate_relationship,
+
+            # Parameter-Based instantiations
+            'inputs': partial(self._instantiate_parameter, model_cls=models.Input),
+            'outputs': partial(self._instantiate_parameter, model_cls=models.Output),
+            'properties': partial(self._instantiate_parameter, model_cls=models.Property),
+            'attributes': partial(self._instantiate_parameter, model_cls=models.Attribute),
+            'configurations': partial(self._instantiate_parameter, model_cls=models.Configuration),
+        }
+
+    def instantiate_service(self, service_template, inputs=None):
+        now = datetime.now()
+        service = models.Service(
+            created_at=now,
+            updated_at=now,
+            description=reading.deepcopy_with_locators(service_template.description),
+            service_template=service_template
+        )
+
+        # TODO: we want to remove this use of the context
+        context = consumption.ConsumptionContext.get_thread_local()
+        context.modeling.instance = service
+
+        service.inputs = utils.merge_parameter_values(inputs, service_template.inputs)
+        # TODO: now that we have inputs, we should scan properties and inputs and evaluate
functions
+
+        for plugin_specification in service_template.plugin_specifications.itervalues():
+            if plugin_specification.enabled:
+                if plugin_specification.resolve(self._model_storage):
+                    plugin = plugin_specification.plugin
+                    service.plugins[plugin.name] = plugin
+                else:
+                    context = consumption.ConsumptionContext.get_thread_local()
+                    context.validation.report('specified plugin not found: {0}'.format(
+                        plugin_specification.name), level=validation.Issue.EXTERNAL)
+
+        service.meta_data = self._instantiate(service_template.meta_data)
+
+        for node_template in service_template.node_templates.itervalues():
+            for _ in range(node_template.scaling['default_instances']):
+                node = self._instantiate(node_template)
+                service.nodes[node.name] = node
+
+        service.groups = self._instantiate(service_template.group_templates)
+        service.policies = self._instantiate(service_template.policy_templates)
+        service.workflows = self._instantiate(service_template.workflow_templates)
+
+        if service_template.substitution_template is not None:
+            service.substitution = self._instantiate(service_template.substitution_template)
+            service.outputs = self._instantiate(service_template.outputs)
+
+        return service
+
+    def _instantiate(self, source_template):
+        if isinstance(source_template, (dict, list)):
+            initiator = self._initiators[source_template._sa_adapter.attr.key]
+            if isinstance(source_template, dict):
+                dict_ = utils.OrderedDict()
+                for name, value in source_template.iteritems():
+                    value = initiator(value)
+                    if value is not None:
+                        dict_[name] = value
+                return dict_
+            elif isinstance(source_template, list):
+                list_ = []
+                for value in source_template:
+                    value = initiator(value)
+                    if value is not None:
+                        list_.append(value)
+                return list_
+        else:
+            return self._initiators[source_template.__tablename__](source_template)
+
+    @staticmethod
+    def _instantiate_artifact(artifact_template):
+        artifact = models.Artifact(
+            name=artifact_template.name,
+            type=artifact_template.type,
+            description=reading.deepcopy_with_locators(artifact_template.description),
+            source_path=artifact_template.source_path,
+            target_path=artifact_template.target_path,
+            repository_url=artifact_template.repository_url,
+            repository_credential=artifact_template.repository_credential,
+            artifact_template=artifact_template)
+        return artifact
+
+    @staticmethod
+    def _instantiate_capability(capability_template):
+        capability = models.Capability(name=capability_template.name,
+                                       type=capability_template.type,
+                                       min_occurrences=capability_template.min_occurrences,
+                                       max_occurrences=capability_template.max_occurrences,
+                                       occurrences=0,
+                                       capability_template=capability_template)
+        return capability
+
+    def _instantiate_group(self, group_template):
+        group = models.Group(name=group_template.name,
+                             type=group_template.type,
+                             description=reading.deepcopy_with_locators(group_template.description),
+                             group_template=group_template)
+        group.properties = self._instantiate(group_template.properties)
+        group.interfaces = self._instantiate(group_template.interface_templates)
+        if group_template.node_templates:
+            for node_template in group_template.node_templates:
+                group.nodes += node_template.nodes
+        return group
+
+    def _instantiate_interface(self, interface_template):
+        interface = models.Interface(
+            name=interface_template.name,
+            type=interface_template.type,
+            description=reading.deepcopy_with_locators(interface_template.description),
+            interface_template=interface_template)
+        interface.inputs = self._instantiate(interface_template.inputs)
+        interface.operations = self._instantiate(interface_template.operation_templates)
+        return interface
+
+    def _instantiate_node(self, node_template):
+        node = models.Node(
+            name=node_template._next_name,
+            type=node_template.type,
+            description=reading.deepcopy_with_locators(node_template.description),
+            state=models.Node.INITIAL,
+            node_template=node_template
+        )
+        node.properties = self._instantiate(node_template.properties)
+        node.attributes = self._instantiate(node_template.attributes)
+        node.interfaces = self._instantiate(node_template.interface_templates)
+        node.artifacts = self._instantiate(node_template.artifact_templates)
+        node.capabilities = self._instantiate(node_template.capability_templates)
+
+        # Default attributes
+        if ('tosca_name' in node.attributes) \
+            and (node.attributes['tosca_name'].type_name == 'string'):
+            node.attributes['tosca_name'].value = node_template.name
+        if 'tosca_id' in node.attributes \
+            and (node.attributes['tosca_id'].type_name == 'string'):
+            node.attributes['tosca_id'].value = node.name
+
+        return node
+
+    def _instantiate_policy(self, policy_template):
+        policy = models.Policy(
+            name=policy_template.name,
+            type=policy_template.type,
+            description=reading.deepcopy_with_locators(policy_template.description),
+            policy_template=policy_template)
+        policy.properties = self._instantiate(policy_template.properties)
+        if policy_template.node_templates:
+            for node_template in policy_template.node_templates:
+                policy.nodes += node_template.nodes
+        if policy_template.group_templates:
+            for group_template in policy_template.group_templates:
+                policy.groups += group_template.groups
+        return policy
+
+    @staticmethod
+    def _instantiate_parameter(parameter_template, model_cls):
+        return model_cls(**parameter_template.as_raw)
+
+    @staticmethod
+    def _instantiate_substitution(substitution_template):
+        substitution = models.Substitution(node_type=substitution_template.node_type,
+                                           substitution_template=substitution_template)
+        return substitution
+
+    @staticmethod
+    def _instantiate_metadata(metadata_template):
+        return models.Metadata(name=metadata_template.name, value=metadata_template.value)
+
+    @staticmethod
+    def _instantiate_substitution_mapping(substitution_mapping):
+        context = consumption.ConsumptionContext.get_thread_local()
+        if substitution_mapping.capability_template is not None:
+            node_template = substitution_mapping.capability_template.node_template
+        else:
+            node_template = substitution_mapping.requirement_template.node_template
+        nodes = node_template.nodes
+        if len(nodes) == 0:
+            context.validation.report(
+                'mapping "{0}" refers to node template "{1}" but there are no node instances'.
+                    format(substitution_mapping.mapped_name,
+                           substitution_mapping.node_template.name),
+                level=validation.Issue.BETWEEN_INSTANCES)
+            return None
+        # The TOSCA spec does not provide a way to choose the node,
+        # so we will just pick the first one
+        node = nodes[0]
+        capability = None
+        if substitution_mapping.capability_template:
+            for a_capability in node.capabilities.itervalues():
+                if a_capability.capability_template.name == \
+                        substitution_mapping.capability_template.name:
+                    capability = a_capability
+        return models.SubstitutionMapping(
+            name=substitution_mapping.name,
+            capability=capability,
+            requirement_template=substitution_mapping.requirement_template,
+            node=node)
+
+    def _instantiate_relationship(self, relationship_template):
+        relationship_model = models.Relationship(name=relationship_template.name,
+                                                 type=relationship_template.type,
+                                                 relationship_template=relationship_template)
+        relationship_model.properties = self._instantiate(relationship_template.properties)
+        relationship_model.interfaces = self._instantiate(relationship_template.interface_templates)
+        return relationship_model
+
+    def _instantiate_operation(self, operation_template):
+        plugin = None
+        if (operation_template.plugin_specification is not None and
+            operation_template.plugin_specification.enabled):
+            plugin = operation_template.plugin_specification.plugin
+
+        operation = models.Operation(
+            name=operation_template.name,
+            description=reading.deepcopy_with_locators(operation_template.description),
+            relationship_edge=operation_template.relationship_edge,
+            implementation=operation_template.implementation,
+            dependencies=operation_template.dependencies,
+            executor=operation_template.executor,
+            plugin=plugin,
+            function=operation_template.function,
+            max_attempts=operation_template.max_attempts,
+            retry_interval=operation_template.retry_interval,
+            operation_template=operation_template)
+
+        operation.inputs = self._instantiate(operation_template.inputs)
+        operation.configurations = self._instantiate(operation_template.configurations)
+
+        return operation


Mime
View raw message