You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ariatosca.apache.org by mx...@apache.org on 2017/07/23 11:38:48 UTC

incubator-ariatosca git commit: fixed small bugs, moved topolgy to orchestrator [Forced Update!]

Repository: incubator-ariatosca
Updated Branches:
  refs/heads/ARIA-174-Refactor-instantiation-phase 67e7f4d74 -> 609d305d7 (forced update)


fixed small bugs, moved topolgy to orchestrator


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

Branch: refs/heads/ARIA-174-Refactor-instantiation-phase
Commit: 609d305d75c07af6d3028ba0cb9a2f98cbe87830
Parents: f31e3ea
Author: max-orlov <ma...@gigaspaces.com>
Authored: Sun Jul 23 14:33:23 2017 +0300
Committer: max-orlov <ma...@gigaspaces.com>
Committed: Sun Jul 23 14:38:43 2017 +0300

----------------------------------------------------------------------
 aria/core.py                                    |   4 +-
 aria/modeling/service_instance.py               |  14 +-
 aria/modeling/service_template.py               |   3 -
 aria/orchestrator/topology/__init__.py          |  16 +
 aria/orchestrator/topology/topology.py          | 293 +++++++++++++++++
 aria/orchestrator/topology/utils.py             |  48 +++
 aria/parser/consumption/modeling.py             |  31 +-
 aria/parser/reading/__init__.py                 |   4 +-
 aria/parser/reading/locator.py                  |  33 --
 aria/parser/topology/__init__.py                |  16 -
 aria/parser/topology/topology.py                | 319 -------------------
 .../simple_v1_0/modeling/__init__.py            |   4 +-
 tests/instantiation/test_configuration.py       |  11 +-
 13 files changed, 400 insertions(+), 396 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/609d305d/aria/core.py
----------------------------------------------------------------------
diff --git a/aria/core.py b/aria/core.py
index a12554e..c3fe96f 100644
--- a/aria/core.py
+++ b/aria/core.py
@@ -17,8 +17,9 @@
 ARIA core module.
 """
 
+from aria.orchestrator import topology
 from . import exceptions
-from .parser import consumption, topology
+from .parser import consumption
 from .parser.loading.location import UriLocation
 
 
@@ -67,7 +68,6 @@ 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)
 
         storage_session = self.model_storage._all_api_kwargs['session']

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/609d305d/aria/modeling/service_instance.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_instance.py b/aria/modeling/service_instance.py
index c34ace0..2eaead2 100644
--- a/aria/modeling/service_instance.py
+++ b/aria/modeling/service_instance.py
@@ -30,6 +30,11 @@ from sqlalchemy import DateTime
 from sqlalchemy.ext.declarative import declared_attr
 from sqlalchemy.ext.orderinglist import ordering_list
 
+from . import (
+    relationship,
+    utils,
+    types as modeling_types
+)
 from .mixins import InstanceModelMixin
 from ..orchestrator import execution_plugin
 from ..parser import validation
@@ -39,11 +44,6 @@ from ..utils import (
     formatting,
     console
 )
-from . import (
-    relationship,
-    utils,
-    types as modeling_types
-)
 
 
 class ServiceBase(InstanceModelMixin):
@@ -659,7 +659,7 @@ class NodeBase(InstanceModelMixin):
 
             if target_node is not None:
                 if requirement_template.relationship_template is not None:
-                    from ..parser import topology
+                    from aria.orchestrator import topology
                     relationship_model = topology.initiator.instantiate(requirement_template.relationship_template)
                 else:
                     relationship_model = models.Relationship()
@@ -1945,7 +1945,7 @@ class OperationBase(InstanceModelMixin):
     """)
 
     def configure(self):
-        from ..parser import topology
+        from aria.orchestrator import topology
         if (self.implementation is None) and (self.function is None):
             return
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/609d305d/aria/modeling/service_template.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_template.py b/aria/modeling/service_template.py
index 8b26d15..0cbfdb6 100644
--- a/aria/modeling/service_template.py
+++ b/aria/modeling/service_template.py
@@ -21,8 +21,6 @@ ARIA modeling service template module
 
 from __future__ import absolute_import  # so we can import standard 'types'
 
-from datetime import datetime
-
 from sqlalchemy import (
     Column,
     Text,
@@ -35,7 +33,6 @@ from sqlalchemy.ext.declarative import declared_attr
 
 from ..parser import validation
 from ..parser.consumption import ConsumptionContext
-from ..parser.reading import deepcopy_with_locators
 from ..utils import (collections, formatting, console)
 from ..utils.versions import VersionString
 from .mixins import TemplateModelMixin

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/609d305d/aria/orchestrator/topology/__init__.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/__init__.py b/aria/orchestrator/topology/__init__.py
new file mode 100644
index 0000000..ae9c900
--- /dev/null
+++ b/aria/orchestrator/topology/__init__.py
@@ -0,0 +1,16 @@
+# 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 .topology import Instantiation, initiator

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/609d305d/aria/orchestrator/topology/topology.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/topology.py b/aria/orchestrator/topology/topology.py
new file mode 100644
index 0000000..abe8cd6
--- /dev/null
+++ b/aria/orchestrator/topology/topology.py
@@ -0,0 +1,293 @@
+# 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 datetime import datetime
+from functools import partial
+from contextlib import contextmanager
+
+
+from ...modeling import (
+    utils as modeling_utils,
+    models
+)
+from ...parser import validation, consumption
+from . import utils
+
+
+class Instantiation(object):
+
+    def __init__(self, context):
+        self._context = context or consumption.ConsumptionContext()
+        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
+            'argument': partial(self._instantiate_parameter, model_cls=models.Argument),
+
+            '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),
+
+        }
+        self._model_storage = None
+
+    @property
+    def _has_model_storage(self):
+        return self._model_storage is not None
+
+    @contextmanager
+    def push_model_storage(self, model_storage):
+        original_model_storage = self._model_storage
+        self._model_storage = model_storage
+        yield self
+        self._model_storage = original_model_storage
+
+    def instantiate_service(self, service_template, inputs=None):
+
+        now = datetime.now()
+        service = models.Service(
+            created_at=now,
+            updated_at=now,
+            description=utils.deepcopy_with_locators(service_template.description),
+            service_template=service_template
+        )
+
+        self._context.modeling.instance = service
+
+        service.inputs = modeling_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:
+                    self._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_ = {}
+                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=utils.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=utils.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=utils.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=utils.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=utils.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(
+            name=parameter_template.name,  # pylint: disable=unexpected-keyword-arg
+            type_name=parameter_template.type_name,
+            _value=parameter_template._value,
+            description=parameter_template.description
+        )
+
+    @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)
+
+    def _instantiate_substitution_mapping(self, substitution_mapping):
+        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:
+            self._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=utils.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
+
+
+initiator = Instantiation(consumption.ConsumptionContext.get_thread_local())

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/609d305d/aria/orchestrator/topology/utils.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/utils.py b/aria/orchestrator/topology/utils.py
new file mode 100644
index 0000000..ec74391
--- /dev/null
+++ b/aria/orchestrator/topology/utils.py
@@ -0,0 +1,48 @@
+# 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 copy import deepcopy
+
+
+def deepcopy_with_locators(value):
+    """
+    Like :func:`deepcopy`, but also copies over locators.
+    """
+
+    res = deepcopy(value)
+    copy_locators(res, value)
+    return res
+
+
+def copy_locators(target, source):
+    """
+    Copies over ``_locator`` for all elements, recursively.
+
+    Assumes that target and source have exactly the same list/dict structure.
+    """
+
+    locator = getattr(source, '_locator', None)
+    if locator is not None:
+        try:
+            setattr(target, '_locator', locator)
+        except AttributeError:
+            pass
+
+    if isinstance(target, list) and isinstance(source, list):
+        for i, _ in enumerate(target):
+            copy_locators(target[i], source[i])
+    elif isinstance(target, dict) and isinstance(source, dict):
+        for k, v in target.items():
+            copy_locators(v, source[k])

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/609d305d/aria/parser/consumption/modeling.py
----------------------------------------------------------------------
diff --git a/aria/parser/consumption/modeling.py b/aria/parser/consumption/modeling.py
index 8c46abf..e142327 100644
--- a/aria/parser/consumption/modeling.py
+++ b/aria/parser/consumption/modeling.py
@@ -13,8 +13,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from ...utils.formatting import json_dumps, yaml_dumps
 from .consumer import Consumer, ConsumerChain
+from ...utils.formatting import json_dumps, yaml_dumps
+from ... import exceptions
 
 
 class DeriveServiceTemplate(Consumer):
@@ -105,11 +106,29 @@ class InstantiateServiceInstance(Consumer):
             self.context.validation.report('InstantiateServiceInstance consumer: missing service '
                                            'template')
             return
-        from .. import topology
-        topology.initiator.instantiate_service(self.context.modeling.template,
-                                               inputs=dict(self.context.modeling.inputs))
-        # TODO: fix this, it looks bad.
-        self.context.modeling.instance = self.context.modeling.template.services[None]
+        from aria.orchestrator import topology
+
+        self.context.modeling.instance = topology.Instantiation(self.context).instantiate_service(
+            self.context.modeling.template,
+            inputs=dict(self.context.modeling.inputs)
+        )
+
+        ConsumerChain(
+            self.context,
+            (
+                CoerceServiceInstanceValues,
+                ValidateServiceInstance,
+                SatisfyRequirements,
+                CoerceServiceInstanceValues,
+                ValidateCapabilities,
+                FindHosts,
+                ConfigureOperations,
+                CoerceServiceInstanceValues
+            )).consume()
+
+        if self.context.validation.dump_issues():
+            raise exceptions.InstantiationError('Failed to instantiate service template `{0}`'
+                                                .format(self.context.modeling.template.name))
 
 
 class CoerceServiceInstanceValues(Consumer):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/609d305d/aria/parser/reading/__init__.py
----------------------------------------------------------------------
diff --git a/aria/parser/reading/__init__.py b/aria/parser/reading/__init__.py
index 065ca56..9fab5df 100644
--- a/aria/parser/reading/__init__.py
+++ b/aria/parser/reading/__init__.py
@@ -36,7 +36,7 @@ Reading package.
 from .raw import RawReader
 from .reader import Reader
 from .yaml import YamlReader
-from .locator import (Locator, deepcopy_with_locators, copy_locators)
+from .locator import Locator
 from .json import JsonReader
 from .jinja import JinjaReader
 from .context import ReadingContext
@@ -57,8 +57,6 @@ __all__ = (
     'ReadingContext',
     'RawReader',
     'Locator',
-    'deepcopy_with_locators',
-    'copy_locators',
     'YamlReader',
     'JsonReader',
     'JinjaReader')

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/609d305d/aria/parser/reading/locator.py
----------------------------------------------------------------------
diff --git a/aria/parser/reading/locator.py b/aria/parser/reading/locator.py
index 965164d..8bbb178 100644
--- a/aria/parser/reading/locator.py
+++ b/aria/parser/reading/locator.py
@@ -10,9 +10,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from copy import deepcopy
-
-
 from ...utils.console import puts, Colored, indent
 
 
@@ -122,33 +119,3 @@ class Locator(object):
         return '"%s":%d:%d' % (self.location, self.line, self.column)
 
 
-def deepcopy_with_locators(value):
-    """
-    Like :func:`deepcopy`, but also copies over locators.
-    """
-
-    res = deepcopy(value)
-    copy_locators(res, value)
-    return res
-
-
-def copy_locators(target, source):
-    """
-    Copies over ``_locator`` for all elements, recursively.
-
-    Assumes that target and source have exactly the same list/dict structure.
-    """
-
-    locator = getattr(source, '_locator', None)
-    if locator is not None:
-        try:
-            setattr(target, '_locator', locator)
-        except AttributeError:
-            pass
-
-    if isinstance(target, list) and isinstance(source, list):
-        for i, _ in enumerate(target):
-            copy_locators(target[i], source[i])
-    elif isinstance(target, dict) and isinstance(source, dict):
-        for k, v in target.items():
-            copy_locators(v, source[k])

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/609d305d/aria/parser/topology/__init__.py
----------------------------------------------------------------------
diff --git a/aria/parser/topology/__init__.py b/aria/parser/topology/__init__.py
deleted file mode 100644
index 7bc09e7..0000000
--- a/aria/parser/topology/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# 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 .topology import initiator

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/609d305d/aria/parser/topology/topology.py
----------------------------------------------------------------------
diff --git a/aria/parser/topology/topology.py b/aria/parser/topology/topology.py
deleted file mode 100644
index d91a96f..0000000
--- a/aria/parser/topology/topology.py
+++ /dev/null
@@ -1,319 +0,0 @@
-# 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 contextlib import contextmanager
-from datetime import datetime
-from functools import partial
-
-from aria import exceptions
-
-from ... modeling import (
-    utils,
-    models
-)
-from .. import (
-    reading,
-    consumption,
-    validation,
-)
-
-
-class _Instantiation(object):
-
-    def __init__(self):
-        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
-            'argument': partial(self._instantiate_parameter, model_cls=models.Argument),
-
-            '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),
-
-        }
-        self._model_storage = None
-
-    @property
-    def _has_model_storage(self):
-        return self._model_storage is not None
-
-    @contextmanager
-    def push_model_storage(self, model_storage):
-        original_model_storage = self._model_storage
-        self._model_storage = model_storage
-        yield self
-        self._model_storage = original_model_storage
-
-    def instantiate_service(self, service_template, inputs=None):
-
-        # creating an empty ConsumptionContext, initiating a threadlocal context
-        context = consumption.ConsumptionContext(set_thread_local=True)
-
-        now = datetime.now()
-        service = models.Service(
-            created_at=now,
-            updated_at=now,
-            description=reading.deepcopy_with_locators(service_template.description),
-            service_template=service_template
-        )
-
-        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)
-
-        consumption.ConsumerChain(
-            context,
-            (
-                consumption.CoerceServiceInstanceValues,
-                consumption.ValidateServiceInstance,
-                consumption.SatisfyRequirements,
-                consumption.CoerceServiceInstanceValues,
-                consumption.ValidateCapabilities,
-                consumption.FindHosts,
-                consumption.ConfigureOperations,
-                consumption.CoerceServiceInstanceValues
-            )).consume()
-
-        if context.validation.dump_issues():
-            raise exceptions.InstantiationError('Failed to instantiate service template `{0}`'
-                                                .format(service_template.name))
-
-        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(
-            name=parameter_template.name,  # pylint: disable=unexpected-keyword-arg
-            type_name=parameter_template.type_name,
-            _value=parameter_template._value,
-            description=parameter_template.description
-        )
-
-    @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
-
-
-initiator = _Instantiation()

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/609d305d/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
index 4d8e1db..4704f1b 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
@@ -515,8 +515,8 @@ def create_plugin_specification_model(context, policy):
 
 
 def create_workflow_operation_template_model(context, service_template, policy):
-    model = OperationTemplate(name=policy._name,
-                              service_template=service_template)
+    model = OperationTemplate(name=policy._name)
+    service_template.workflow_templates[model.name] = model
 
     if policy.description:
         model.description = policy.description.value

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/609d305d/tests/instantiation/test_configuration.py
----------------------------------------------------------------------
diff --git a/tests/instantiation/test_configuration.py b/tests/instantiation/test_configuration.py
index 6ac0c9c..659e334 100644
--- a/tests/instantiation/test_configuration.py
+++ b/tests/instantiation/test_configuration.py
@@ -165,8 +165,9 @@ def test_remote(service):
 
 
 def test_reserved_arguments(broken_service_issues):
-    assert len(broken_service_issues) == 1
-    message = broken_service_issues[0].message
-    assert message.startswith('using reserved arguments in operation "operation":')
-    assert '"ctx"' in message
-    assert '"toolbelt"' in message
+    assert len(broken_service_issues) == 2
+    assert any(
+        all([issue.message.startswith('using reserved arguments in operation "operation":'),
+             'ctx' in issue.message,
+             'toolbelt' in issue.message])
+        for issue in broken_service_issues)