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 15:58:14 UTC

incubator-ariatosca git commit: validate + instantiate and tidy up

Repository: incubator-ariatosca
Updated Branches:
  refs/heads/ARIA-174-Refactor-instantiation-phase 0bc7993f8 -> 8e5fe109d


validate + instantiate and tidy up


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

Branch: refs/heads/ARIA-174-Refactor-instantiation-phase
Commit: 8e5fe109d9f8acb5752f739df1ab47dc4858d3d6
Parents: 0bc7993
Author: max-orlov <ma...@gigaspaces.com>
Authored: Sun Jul 23 18:58:08 2017 +0300
Committer: max-orlov <ma...@gigaspaces.com>
Committed: Sun Jul 23 18:58:08 2017 +0300

----------------------------------------------------------------------
 aria/modeling/service_instance.py      |  69 ----
 aria/modeling/service_template.py      |  75 -----
 aria/orchestrator/topology/__init__.py |  97 +++++-
 aria/orchestrator/topology/common.py   |  41 +++
 aria/orchestrator/topology/instance.py | 208 ++++++++++++
 aria/orchestrator/topology/template.py | 383 ++++++++++++++++++++++
 aria/orchestrator/topology/topology.py | 476 ----------------------------
 7 files changed, 728 insertions(+), 621 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/8e5fe109/aria/modeling/service_instance.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_instance.py b/aria/modeling/service_instance.py
index 58734b2..93d610b 100644
--- a/aria/modeling/service_instance.py
+++ b/aria/modeling/service_instance.py
@@ -289,17 +289,6 @@ class ServiceBase(InstanceModelMixin):
             ('outputs', formatting.as_raw_dict(self.outputs)),
             ('workflows', formatting.as_raw_list(self.workflows))))
 
-    def validate(self):
-        utils.validate_dict_values(self.meta_data)
-        utils.validate_dict_values(self.nodes)
-        utils.validate_dict_values(self.groups)
-        utils.validate_dict_values(self.policies)
-        if self.substitution is not None:
-            self.substitution.validate()
-        utils.validate_dict_values(self.inputs)
-        utils.validate_dict_values(self.outputs)
-        utils.validate_dict_values(self.workflows)
-
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.meta_data, report_issues)
         utils.coerce_dict_values(self.nodes, report_issues)
@@ -741,25 +730,6 @@ class NodeBase(InstanceModelMixin):
             ('capabilities', formatting.as_raw_list(self.capabilities)),
             ('relationships', formatting.as_raw_list(self.outbound_relationships))))
 
-    def validate(self):
-        context = ConsumptionContext.get_thread_local()
-        if len(self.name) > context.modeling.id_max_length:
-            context.validation.report('"{0}" has an ID longer than the limit of {1:d} characters: '
-                                      '{2:d}'.format(
-                                          self.name,
-                                          context.modeling.id_max_length,
-                                          len(self.name)),
-                                      level=validation.Issue.BETWEEN_INSTANCES)
-
-        # TODO: validate that node template is of type?
-
-        utils.validate_dict_values(self.properties)
-        utils.validate_dict_values(self.attributes)
-        utils.validate_dict_values(self.interfaces)
-        utils.validate_dict_values(self.artifacts)
-        utils.validate_dict_values(self.capabilities)
-        utils.validate_list_values(self.outbound_relationships)
-
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.properties, report_issues)
         utils.coerce_dict_values(self.attributes, report_issues)
@@ -897,10 +867,6 @@ class GroupBase(InstanceModelMixin):
             ('properties', formatting.as_raw_dict(self.properties)),
             ('interfaces', formatting.as_raw_list(self.interfaces))))
 
-    def validate(self):
-        utils.validate_dict_values(self.properties)
-        utils.validate_dict_values(self.interfaces)
-
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.properties, report_issues)
         utils.coerce_dict_values(self.interfaces, report_issues)
@@ -1031,9 +997,6 @@ class PolicyBase(InstanceModelMixin):
             ('type_name', self.type.name),
             ('properties', formatting.as_raw_dict(self.properties))))
 
-    def validate(self):
-        utils.validate_dict_values(self.properties)
-
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.properties, report_issues)
 
@@ -1131,9 +1094,6 @@ class SubstitutionBase(InstanceModelMixin):
             ('node_type_name', self.node_type.name),
             ('mappings', formatting.as_raw_dict(self.mappings))))
 
-    def validate(self):
-        utils.validate_dict_values(self.mappings)
-
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.mappings, report_issues)
 
@@ -1242,15 +1202,6 @@ class SubstitutionMappingBase(InstanceModelMixin):
     def coerce_values(self, report_issues):
         pass
 
-    def validate(self):
-        context = ConsumptionContext.get_thread_local()
-        if (self.capability is None) and (self.requirement_template is None):
-            context.validation.report('mapping "{0}" refers to neither capability nor a requirement'
-                                      ' in node: {1}'.format(
-                                          self.name,
-                                          formatting.safe_repr(self.node.name)),
-                                      level=validation.Issue.BETWEEN_TYPES)
-
     def dump(self):
         context = ConsumptionContext.get_thread_local()
         if self.capability is not None:
@@ -1453,10 +1404,6 @@ class RelationshipBase(InstanceModelMixin):
             ('properties', formatting.as_raw_dict(self.properties)),
             ('interfaces', formatting.as_raw_list(self.interfaces))))
 
-    def validate(self):
-        utils.validate_dict_values(self.properties)
-        utils.validate_dict_values(self.interfaces)
-
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.properties, report_issues)
         utils.coerce_dict_values(self.interfaces, report_issues)
@@ -1596,9 +1543,6 @@ class CapabilityBase(InstanceModelMixin):
             ('type_name', self.type.name),
             ('properties', formatting.as_raw_dict(self.properties))))
 
-    def validate(self):
-        utils.validate_dict_values(self.properties)
-
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.properties, report_issues)
 
@@ -1752,10 +1696,6 @@ class InterfaceBase(InstanceModelMixin):
             ('inputs', formatting.as_raw_dict(self.inputs)),
             ('operations', formatting.as_raw_list(self.operations))))
 
-    def validate(self):
-        utils.validate_dict_values(self.inputs)
-        utils.validate_dict_values(self.operations)
-
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.inputs, report_issues)
         utils.coerce_dict_values(self.operations, report_issues)
@@ -1995,12 +1935,6 @@ class OperationBase(InstanceModelMixin):
             ('dependencies', self.dependencies),
             ('inputs', formatting.as_raw_dict(self.inputs))))
 
-    def validate(self):
-        # TODO must be associated with either interface or service
-        utils.validate_dict_values(self.inputs)
-        utils.validate_dict_values(self.configurations)
-        utils.validate_dict_values(self.arguments)
-
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.inputs, report_issues)
         utils.coerce_dict_values(self.configurations, report_issues)
@@ -2154,9 +2088,6 @@ class ArtifactBase(InstanceModelMixin):
             ('repository_credential', formatting.as_agnostic(self.repository_credential)),
             ('properties', formatting.as_raw_dict(self.properties))))
 
-    def validate(self):
-        utils.validate_dict_values(self.properties)
-
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.properties, report_issues)
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/8e5fe109/aria/modeling/service_template.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_template.py b/aria/modeling/service_template.py
index 719a221..b505a06 100644
--- a/aria/modeling/service_template.py
+++ b/aria/modeling/service_template.py
@@ -327,31 +327,6 @@ class ServiceTemplateBase(TemplateModelMixin):
             ('interface_types', formatting.as_raw(self.interface_types)),
             ('artifact_types', formatting.as_raw(self.artifact_types))))
 
-    def validate(self):
-        utils.validate_dict_values(self.meta_data)
-        utils.validate_dict_values(self.node_templates)
-        utils.validate_dict_values(self.group_templates)
-        utils.validate_dict_values(self.policy_templates)
-        if self.substitution_template is not None:
-            self.substitution_template.validate()
-        utils.validate_dict_values(self.inputs)
-        utils.validate_dict_values(self.outputs)
-        utils.validate_dict_values(self.workflow_templates)
-        if self.node_types is not None:
-            self.node_types.validate()
-        if self.group_types is not None:
-            self.group_types.validate()
-        if self.policy_types is not None:
-            self.policy_types.validate()
-        if self.relationship_types is not None:
-            self.relationship_types.validate()
-        if self.capability_types is not None:
-            self.capability_types.validate()
-        if self.interface_types is not None:
-            self.interface_types.validate()
-        if self.artifact_types is not None:
-            self.artifact_types.validate()
-
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.meta_data, report_issues)
         utils.coerce_dict_values(self.node_templates, report_issues)
@@ -573,14 +548,6 @@ class NodeTemplateBase(TemplateModelMixin):
             ('capability_templates', formatting.as_raw_list(self.capability_templates)),
             ('requirement_templates', formatting.as_raw_list(self.requirement_templates))))
 
-    def validate(self):
-        utils.validate_dict_values(self.properties)
-        utils.validate_dict_values(self.attributes)
-        utils.validate_dict_values(self.interface_templates)
-        utils.validate_dict_values(self.artifact_templates)
-        utils.validate_dict_values(self.capability_templates)
-        utils.validate_list_values(self.requirement_templates)
-
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.properties, report_issues)
         utils.coerce_dict_values(self.attributes, report_issues)
@@ -801,10 +768,6 @@ class GroupTemplateBase(TemplateModelMixin):
             ('properties', formatting.as_raw_dict(self.properties)),
             ('interface_templates', formatting.as_raw_list(self.interface_templates))))
 
-    def validate(self):
-        utils.validate_dict_values(self.properties)
-        utils.validate_dict_values(self.interface_templates)
-
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.properties, report_issues)
         utils.coerce_dict_values(self.interface_templates, report_issues)
@@ -934,9 +897,6 @@ class PolicyTemplateBase(TemplateModelMixin):
             ('type_name', self.type.name),
             ('properties', formatting.as_raw_dict(self.properties))))
 
-    def validate(self):
-        utils.validate_dict_values(self.properties)
-
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.properties, report_issues)
 
@@ -1031,9 +991,6 @@ class SubstitutionTemplateBase(TemplateModelMixin):
             ('node_type_name', self.node_type.name),
             ('mappings', formatting.as_raw_dict(self.mappings))))
 
-    def validate(self):
-        utils.validate_dict_values(self.mappings)
-
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.mappings, report_issues)
 
@@ -1126,15 +1083,6 @@ class SubstitutionTemplateMappingBase(TemplateModelMixin):
     def coerce_values(self, report_issues):
         pass
 
-    def validate(self):
-        context = ConsumptionContext.get_thread_local()
-        if (self.capability_template is None) and (self.requirement_template is None):
-            context.validation.report('mapping "{0}" refers to neither capability nor a requirement'
-                                      ' in node template: {1}'.format(
-                                          self.name,
-                                          formatting.safe_repr(self.node_template.name)),
-                                      level=validation.Issue.BETWEEN_TYPES)
-
     def dump(self):
         context = ConsumptionContext.get_thread_local()
         if self.capability_template is not None:
@@ -1349,10 +1297,6 @@ class RequirementTemplateBase(TemplateModelMixin):
             ('target_capability_name', self.target_capability_name),
             ('relationship_template', formatting.as_raw(self.relationship_template))))
 
-    def validate(self):
-        if self.relationship_template:
-            self.relationship_template.validate()
-
     def coerce_values(self, report_issues):
         if self.relationship_template is not None:
             self.relationship_template.coerce_values(report_issues)
@@ -1468,11 +1412,6 @@ class RelationshipTemplateBase(TemplateModelMixin):
             ('properties', formatting.as_raw_dict(self.properties)),
             ('interface_templates', formatting.as_raw_list(self.interface_templates))))
 
-    def validate(self):
-        # TODO: either type or name must be set
-        utils.validate_dict_values(self.properties)
-        utils.validate_dict_values(self.interface_templates)
-
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.properties, report_issues)
         utils.coerce_dict_values(self.interface_templates, report_issues)
@@ -1626,9 +1565,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 validate(self):
-        utils.validate_dict_values(self.properties)
-
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.properties, report_issues)
 
@@ -1780,10 +1716,6 @@ class InterfaceTemplateBase(TemplateModelMixin):
             # TODO fix self.properties reference
             ('operation_templates', formatting.as_raw_list(self.operation_templates))))
 
-    def validate(self):
-        utils.validate_dict_values(self.inputs)
-        utils.validate_dict_values(self.operation_templates)
-
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.inputs, report_issues)
         utils.coerce_dict_values(self.operation_templates, report_issues)
@@ -1956,10 +1888,6 @@ class OperationTemplateBase(TemplateModelMixin):
             ('dependencies', self.dependencies),
             ('inputs', formatting.as_raw_dict(self.inputs))))
 
-    def validate(self):
-        utils.validate_dict_values(self.inputs)
-        utils.validate_dict_values(self.configurations)
-
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.inputs, report_issues)
         utils.coerce_dict_values(self.configurations, report_issues)
@@ -2103,9 +2031,6 @@ class ArtifactTemplateBase(TemplateModelMixin):
             ('repository_credential', formatting.as_agnostic(self.repository_credential)),
             ('properties', formatting.as_raw_dict(self.properties))))
 
-    def validate(self):
-        utils.validate_dict_values(self.properties)
-
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.properties, report_issues)
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/8e5fe109/aria/orchestrator/topology/__init__.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/__init__.py b/aria/orchestrator/topology/__init__.py
index c90f465..4109af6 100644
--- a/aria/orchestrator/topology/__init__.py
+++ b/aria/orchestrator/topology/__init__.py
@@ -13,4 +13,99 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from .topology import Handler, handler
+from ...modeling import models
+from . import (
+    template,
+    instance
+)
+
+class Handler(object):
+
+    _handlers = {
+        # Templates
+        models.ServiceTemplate: template.ServiceTemplate,
+        models.ArtifactTemplate: template.ArtifactTemplate,
+        models.CapabilityTemplate: template.CapabilityTemplate,
+        models.GroupTemplate: template.GroupTemplate,
+        models.InterfaceTemplate: template.InterfaceTemplate,
+        models.NodeTemplate: template.NodeTemplate,
+        models.PolicyTemplate: template.PolicyTemplate,
+        models.SubstitutionTemplate: template.SubstitutionTemplate,
+        models.SubstitutionTemplateMapping: template.SubstitutionMapping,
+        models.RelationshipTemplate: template.RelationshipTemplate,
+        models.OperationTemplate: template.OperationTemplate,
+        models.RequirementTemplate: template.RequirementTemplate,
+
+        # Instances
+        models.Artifact: instance.Artifact,
+        models.Capability: instance.Capability,
+        models.Group: instance.Group,
+        models.Interface: instance.Interface,
+        models.Node: instance.Node,
+        models.Operation: instance.Operation,
+        models.Policy: instance.Policy,
+        models.Relationship: instance.Relationship,
+        models.Service: instance.Service,
+        models.Substitution: instance.Substitution,
+        models.SubstitutionMapping: instance.SubstitutionMapping,
+        models.Metadata: instance.Metadata,
+
+        # Common
+        models.Attribute: instance.Parameter,
+        models.Property: instance.Parameter,
+        models.Input: instance.Parameter,
+        models.Output: instance.Parameter,
+        models.Configuration: instance.Parameter,
+        models.Argument: instance.Parameter,
+    }
+
+    _instance_mapping = {
+        # Templates
+        models.ServiceTemplate: models.Service,
+        models.ArtifactTemplate: models.Artifact,
+        models.CapabilityTemplate: models.Capability,
+        models.GroupTemplate: models.Group,
+        models.InterfaceTemplate: models.Interface,
+        models.NodeTemplate: models.Node,
+        models.PolicyTemplate: models.Policy,
+        models.SubstitutionTemplate: models.Substitution,
+        models.SubstitutionMapping: models.SubstitutionMapping,
+        models.RelationshipTemplate: models.Relationship,
+        models.OperationTemplate: models.Operation,
+        models.Metadata: models.Metadata,
+
+        models.Attribute: models.Attribute,
+        models.Property: models.Property,
+        models.Input: models.Input,
+        models.Output: models.Output,
+        models.Configuration: models.Configuration,
+        models.Argument: models.Argument,
+    }
+
+    def __init__(self, model_storage=None):
+        # TODO: model storage is required only for the list of plugins, can we get it
+        # somewhere else?
+        self._model_storage = model_storage
+
+    def instantiate(self, template, **kwargs):
+        if isinstance(template, dict):
+            return dict((name, self.instantiate(value, **kwargs))
+                        for name, value in template.iteritems())
+        elif isinstance(template, list):
+            return list(self.instantiate(value, **kwargs) for value in template)
+        elif template is not None:
+            handler = self._handlers.get(template.__class__)
+            instance_cls = self._instance_mapping[template.__class__]
+            return handler(self, template).instantiate(instance_cls, **kwargs)
+
+    def validate(self, template, **kwargs):
+        if isinstance(template, dict):
+            return self.validate(template.values())
+        elif isinstance(template, list):
+            return all(self.validate(value) for value in template)
+        elif template is not None:
+            handler = self._handlers.get(template.__class__)
+            return handler(self, template).validate(**kwargs)
+
+
+handler = Handler()

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/8e5fe109/aria/orchestrator/topology/common.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/common.py b/aria/orchestrator/topology/common.py
new file mode 100644
index 0000000..fb5cf50
--- /dev/null
+++ b/aria/orchestrator/topology/common.py
@@ -0,0 +1,41 @@
+# 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.
+
+
+class _TemplateEntity(object):
+    def __init__(self, topology, template):
+        self._topology = topology
+        self._template = template
+
+    def instantiate(self, **kwargs):
+        pass
+
+    def coerce(self):
+        raise NotImplementedError
+
+    def validate(self, **kwargs):
+        pass
+
+    def _validate(self, *templates, **kwargs):
+        for template in templates:
+            self._topology.validate(template)
+
+    def dump(self):
+        raise NotImplementedError
+
+
+class _InstanceEntity(_TemplateEntity):
+    def instantiate(self, **kwargs):
+        pass

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/8e5fe109/aria/orchestrator/topology/instance.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/instance.py b/aria/orchestrator/topology/instance.py
new file mode 100644
index 0000000..337c9d5
--- /dev/null
+++ b/aria/orchestrator/topology/instance.py
@@ -0,0 +1,208 @@
+# 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 . import common
+
+
+class Artifact(common._InstanceEntity):
+    def coerce(self):
+        pass
+
+    def validate(self, **kwargs):
+        self._topology.validate(self._template.properties)
+
+    def dump(self):
+        pass
+
+
+class Capability(common._InstanceEntity):
+    def coerce(self):
+        pass
+
+    def validate(self, **kwargs):
+        self._topology.validate(self._template.properties)
+
+    def dump(self):
+        pass
+
+
+class Group(common._InstanceEntity):
+    def coerce(self):
+        pass
+
+    def validate(self, **kwargs):
+        self._validate(self._template.properties,
+                       self._template.interfaces)
+
+    def dump(self):
+        pass
+
+
+class Interface(common._InstanceEntity):
+    def coerce(self):
+        pass
+
+    def validate(self, **kwargs):
+        self._validate(self._template.inputs,
+                       self._template.operations)
+
+    def dump(self):
+        pass
+
+
+class Node(common._InstanceEntity):
+    def coerce(self):
+        pass
+
+    def validate(self, **kwargs):
+        # TODO: fix the context
+        # context = ConsumptionContext.get_thread_local()
+        # if len(self._template.name) > context.modeling.id_max_length:
+        #     pass
+            # context.validation.report('"{0}" has an ID longer than the limit of {1:d} characters: '
+            #                           '{2:d}'.format(
+            #                               self.name,
+            #                               context.modeling.id_max_length,
+            #                               len(self.name)),
+            #                           level=validation.Issue.BETWEEN_INSTANCES)
+
+        self._validate(self._template.properties,
+                       self._template.attributes,
+                       self._template.interfaces,
+                       self._template.artifacts,
+                       self._template.capabilities,
+                       self._template.outbound_relationships)
+
+    def dump(self):
+        pass
+
+
+class Operation(common._InstanceEntity):
+    def coerce(self):
+        pass
+
+    def validate(self, **kwargs):
+        self._validate(self._template.inputs,
+                       self._template.configurations,
+                       self._template.arguments)
+
+    def dump(self):
+        pass
+
+
+class Policy(common._InstanceEntity):
+    def coerce(self):
+        pass
+
+    def validate(self, **kwargs):
+        self._topology.validate(self._template.properties)
+
+    def dump(self):
+        pass
+
+
+class Relationship(common._InstanceEntity):
+    def coerce(self):
+        pass
+
+    def validate(self, **kwargs):
+        self._validate(self._template.properties,
+                       self._template.interfaces)
+
+    def dump(self):
+        pass
+
+
+class Service(common._InstanceEntity):
+    def coerce(self):
+        pass
+
+    def validate(self, **kwargs):
+        self._validate(self._template.meta_data,
+                       self._template.nodes,
+                       self._template.groups,
+                       self._template.policies,
+                       self._template.substituion,
+                       self._template.inputs,
+                       self._template.outputs,
+                       self._template.workflows)
+
+    def dump(self):
+        pass
+
+
+class Substitution(common._InstanceEntity):
+    def coerce(self):
+        pass
+
+    def validate(self, **kwargs):
+        self._topology.validate(self._template.mappings)
+
+    def dump(self):
+        pass
+
+
+class SubstitutionMapping(common._InstanceEntity):
+    def coerce(self):
+        pass
+
+    def validate(self, **kwargs):
+        # context = ConsumptionContext.get_thread_local()
+        if (self._template.capability is None) and (self._template.requirement_template is None):
+            pass
+            # TODO: handler reports
+            # context.validation.report('mapping "{0}" refers to neither capability nor a requirement'
+            #                           ' in node: {1}'.format(
+            #                               self.name,
+            #                               formatting.safe_repr(self.node.name)),
+            #                           level=validation.Issue.BETWEEN_TYPES)
+
+    def dump(self):
+        pass
+
+
+class Metadata(common._InstanceEntity):
+
+    def dump(self):
+        pass
+
+    def coerce(self):
+        pass
+
+    def instantiate(self, instance_cls, **kwargs):
+        return instance_cls(name=self._template.name, value=self._template.value)
+
+    def validate(self):
+        pass
+
+
+class Parameter(common._InstanceEntity):
+
+    def dump(self):
+        pass
+
+    def coerce(self):
+        pass
+
+    def instantiate(self, instance_cls, **kwargs):
+        return instance_cls(
+            name=self._template.name,  # pylint: disable=unexpected-keyword-arg
+            type_name=self._template.type_name,
+            _value=self._template._value,
+            description=self._template.description
+        )
+
+    def validate(self):
+        pass

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/8e5fe109/aria/orchestrator/topology/template.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/template.py b/aria/orchestrator/topology/template.py
new file mode 100644
index 0000000..12fc23e
--- /dev/null
+++ b/aria/orchestrator/topology/template.py
@@ -0,0 +1,383 @@
+# 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 ...modeling import utils as modeling_utils
+from . import utils, common
+
+
+class ServiceTemplate(common._TemplateEntity):
+    def dump(self):
+        pass
+
+    def coerce(self):
+        pass
+
+    def instantiate(self, instance_cls, inputs=None):
+        now = datetime.now()
+        service = instance_cls(
+            created_at=now,
+            updated_at=now,
+            description=utils.deepcopy_with_locators(self._template.description),
+            service_template=self._template,
+            inputs=modeling_utils.merge_parameter_values(inputs, self._template.inputs)
+        )
+
+        for plugin_specification in self._template.plugin_specifications.itervalues():
+            if plugin_specification.enabled and self._topology._model_storage:
+                if utils.resolve_plugin_specification(plugin_specification,
+                                                      self._topology.model_storage.plugin.list()):
+                    plugin = plugin_specification.plugin
+                    service.plugins[plugin.name] = plugin
+                else:
+                    # TODO: fix the context report usage
+                    pass
+                    # self._context.validation.report('specified plugin not found: {0}'.format(
+                    #     plugin_specification.name), level=validation.Issue.EXTERNAL)
+        service.meta_data = self._topology.instantiate(self._template.meta_data)
+
+        for node_template in self._template.node_templates.itervalues():
+            for _ in range(node_template.scaling['default_instances']):
+                node = self._topology.instantiate(node_template)
+                service.nodes[node.name] = node
+
+        service.groups = self._topology.instantiate(self._template.group_templates)
+        service.policies = self._topology.instantiate(self._template.policy_templates)
+        service.workflows = self._topology.instantiate(self._template.workflow_templates)
+
+        if self._template.substitution_template is not None:
+            service.substitution = self._topology.instantiate(self._template.substitution_template)
+            service.outputs = self._topology.instantiate(self._template.outputs)
+
+        return service
+
+    def validate(self):
+        self._topology.validate(self._template.meta_data)
+        self._topology.validate(self._template.node_templates)
+        self._topology.validate(self._template.group_templates)
+        self._topology.validate(self._template.policy_templates)
+        self._topology.validate(self._template.substitution_template)
+        self._topology.validate(self._template.inputs)
+        self._topology.validate(self._template.outputs)
+        self._topology.validate(self._template.workflow_templates)
+        self._topology.validate(self._template.node_types)
+        self._topology.validate(self._template.group_types)
+        self._topology.validate(self._template.policy_types)
+        self._topology.validate(self._template.relationship_types)
+        self._topology.validate(self._template.capability_types)
+        self._topology.validate(self._template.interface_types)
+        self._topology.validate(self._template.artifact_types)
+
+
+class ArtifactTemplate(common._TemplateEntity):
+    def dump(self):
+        pass
+
+    def coerce(self):
+        pass
+
+    def instantiate(self, instance_cls):
+        return instance_cls(
+            name=self._template.name,
+            type=self._template.type,
+            description=utils.deepcopy_with_locators(self._template.description),
+            source_path=self._template.source_path,
+            target_path=self._template.target_path,
+            repository_url=self._template.repository_url,
+            repository_credential=self._template.repository_credential,
+            artifact_template=self._template)
+
+    def validate(self):
+        self._topology.validate(self._template.properties)
+
+
+class CapabilityTemplate(common._TemplateEntity):
+    def dump(self):
+        pass
+
+    def coerce(self):
+        pass
+
+    def instantiate(self, instance_cls):
+        return instance_cls(name=self._template.name,
+                            type=self._template.type,
+                            min_occurrences=self._template.min_occurrences,
+                            max_occurrences=self._template.max_occurrences,
+                            occurrences=0,
+                            capability_template=self._template)
+
+    def validate(self):
+        self._topology.validate(self._template.properties)
+
+
+class RequirementTemplate(common._TemplateEntity):
+    def dump(self):
+        pass
+
+    def coerce(self):
+        pass
+
+    def instantiate(self, instance_cls):
+        return instance_cls(name=self._template.name,
+                            type=self._template.type,
+                            min_occurrences=self._template.min_occurrences,
+                            max_occurrences=self._template.max_occurrences,
+                            occurrences=0,
+                            capability_template=self._template)
+
+    def validate(self):
+        self._topology.validate(self._template.relationship_template)
+
+
+class GroupTemplate(common._TemplateEntity):
+    def dump(self):
+        pass
+
+    def coerce(self):
+        pass
+
+    def instantiate(self, instance_cls):
+        group = instance_cls(
+            name=self._template.name,
+            type=self._template.type,
+            description=utils.deepcopy_with_locators(self._template.description),
+            group_template=self._template)
+        group.properties = self._topology.instantiate(self._template.properties)
+        group.interfaces = self._topology.instantiate(self._template.interface_templates)
+        if self._template.node_templates:
+            for node_template in self._template.node_templates:
+                group.nodes += node_template.nodes
+        return group
+
+    def validate(self):
+        self._validate(self._template.properties,
+                       self._template.interface_templates)
+
+
+class InterfaceTemplate(common._TemplateEntity):
+    def dump(self):
+        pass
+
+    def coerce(self):
+        pass
+
+    def instantiate(self, instance_cls):
+        interface = instance_cls(
+            name=self._template.name,
+            type=self._template.type,
+            description=utils.deepcopy_with_locators(self._template.description),
+            interface_template=self._template)
+        interface.inputs = self._topology.instantiate(self._template.inputs)
+        interface.operations = self._topology.instantiate(self._template.operation_templates)
+        return interface
+
+    def validate(self):
+        self._validate(self._template.inputs,
+                       self._template.operation_templates)
+
+
+class NodeTemplate(common._TemplateEntity):
+    def dump(self):
+        pass
+
+    def coerce(self):
+        pass
+
+    def instantiate(self, instance_cls):
+        node = instance_cls(
+            name=self._template._next_name,
+            type=self._template.type,
+            description=utils.deepcopy_with_locators(self._template.description),
+            node_template=self._template
+        )
+
+        node.properties = self._topology.instantiate(self._template.properties)
+        node.attributes = self._topology.instantiate(self._template.attributes)
+        node.interfaces = self._topology.instantiate(self._template.interface_templates)
+        node.artifacts = self._topology.instantiate(self._template.artifact_templates)
+        node.capabilities = self._topology.instantiate(self._template.capability_templates)
+
+        # Default attributes
+        if ('tosca_name' in node.attributes) \
+                and (node.attributes['tosca_name'].type_name == 'string'):
+            node.attributes['tosca_name'].value = self._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 validate(self):
+        self._validate(self._template.properties,
+                       self._template.attributes,
+                       self._template.interface_templates,
+                       self._template.artifact_templates,
+                       self._template.capability_templates,
+                       self._template.requirement_templates)
+
+
+class PolicyTemplate(common._TemplateEntity):
+    def dump(self):
+        pass
+
+    def coerce(self):
+        pass
+
+    def instantiate(self, instance_cls):
+        policy = instance_cls(
+            name=self._template.name,
+            type=self._template.type,
+            description=utils.deepcopy_with_locators(self._template.description),
+            policy_template=self._template)
+
+        policy.properties = self._topology.instantiate(self._template.properties)
+        if self._template.node_templates:
+            for node_template in self._template.node_templates:
+                policy.nodes += node_template.nodes
+        if self._template.group_templates:
+            for group_template in self._template.group_templates:
+                policy.groups += group_template.groups
+        return policy
+
+    def validate(self):
+        self._topology.validate(self._template.properties)
+
+
+class SubstitutionTemplate(common._TemplateEntity):
+
+    def dump(self):
+        pass
+
+    def coerce(self):
+        pass
+
+    def instantiate(self, instance_cls):
+        return instance_cls(node_type=self._template.node_type,
+                            substitution_template=self._template)
+
+    def validate(self):
+        self._topology.validate(self._template.mappings)
+
+
+class SubstitutionMapping(common._TemplateEntity):
+
+    def dump(self):
+        pass
+
+    def coerce(self):
+        pass
+
+    def instantiate(self, instance_cls):
+        substitution_mapping = instance_cls(
+            name=self._template.name,
+            requirement_template=self._template.requirement_template)
+
+        if self._template.capability_template is not None:
+            node_template = self._template.capability_template.node_template
+        else:
+            node_template = self._template.requirement_template.node_template
+        nodes = node_template.nodes
+        if len(nodes) == 0:
+            # TODO: manage the context report
+            # self._context.validation.report(
+            #     'mapping "{0}" refers to node template "{1}" but there are no node instances'.
+            #         format(self._template.mapped_name,
+            #                self._template.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
+        substitution_mapping.node = nodes[0]
+        if self._template.capability_template:
+            for a_capability in substitution_mapping.node.capabilities.itervalues():
+                if a_capability.capability_template.name == \
+                        self._template.capability_template.name:
+                    substitution_mapping.capability = a_capability
+
+        return substitution_mapping
+
+    def validate(self):
+        # context = ConsumptionContext.get_thread_local()
+        if all([
+                    self._template.capability_template is None,
+                    self._template.requirement_template is None
+        ]):
+            pass
+            # TODO: handle reporting
+            # context.validation.report('mapping "{0}" refers to neither capability nor a requirement'
+            #                           ' in node template: {1}'.format(
+            #                               self.name,
+            #                               formatting.safe_repr(self.node_template.name)),
+            #                           level=validation.Issue.BETWEEN_TYPES)
+
+
+class RelationshipTemplate(common._TemplateEntity):
+    def dump(self):
+        pass
+
+    def coerce(self):
+        pass
+
+    def instantiate(self, instance_cls):
+        relationship = instance_cls(
+            name=self._template.name,
+            type=self._template.type,
+            relationship_template=self._template)
+
+        relationship.properties = self._topology.instantiate(self._template.properties)
+        relationship.interfaces = self._topology.instantiate(self._template.interface_templates)
+        return relationship
+
+    def validate(self):
+        # TODO: either type or name must be set
+        self._validate(self._template.properties,
+                       self._template.interface_templates)
+
+
+class OperationTemplate(common._TemplateEntity):
+
+    def dump(self):
+        pass
+
+    def coerce(self):
+        pass
+
+    def instantiate(self, instance_cls):
+        operation = instance_cls(
+            name=self._template.name,
+            description=utils.deepcopy_with_locators(self._template.description),
+            relationship_edge=self._template.relationship_edge,
+            implementation=self._template.implementation,
+            dependencies=self._template.dependencies,
+            executor=self._template.executor,
+            function=self._template.function,
+            max_attempts=self._template.max_attempts,
+            retry_interval=self._template.retry_interval,
+            operation_template=self._template)
+
+        if (self._template.plugin_specification is not None and
+                self._template.plugin_specification.enabled):
+            operation.plugin = self._template.plugin_specification.plugin
+
+        operation.inputs = self._topology.instantiate(self._template.inputs)
+        operation.configurations = self._topology.instantiate(self._template.configurations)
+
+        return operation
+
+    def validate(self):
+        self._validate(self._template.inputs,
+                       self._template.configurations)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/8e5fe109/aria/orchestrator/topology/topology.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/topology.py b/aria/orchestrator/topology/topology.py
deleted file mode 100644
index c79c445..0000000
--- a/aria/orchestrator/topology/topology.py
+++ /dev/null
@@ -1,476 +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 datetime import datetime
-
-
-from ...modeling import (
-    utils as modeling_utils,
-    models
-)
-from . import utils
-
-
-class _Entity(object):
-    
-    def __init__(self, topology_initiator, template, _instance_cls):
-        self._topology = topology_initiator
-        self._template = template
-        self._instance_cls = _instance_cls
-    
-    def instantiate(self, **kwargs):
-        raise NotImplementedError
-    
-    def coerce(self):
-        raise NotImplementedError
-    
-    def validate(self):
-        raise NotImplementedError
-    
-    def dump(self):
-        raise NotImplementedError
-
-
-class Handler(object):
-    def __init__(self, model_storage=None):
-        # TODO: model storage is required only for the list of plugins, can we get it
-        # somewhere else?
-        self._model_storage = model_storage
-        self._handlers = {
-            models.ServiceTemplate: ServiceInstance,
-            models.ArtifactTemplate: Artifact,
-            models.CapabilityTemplate: Capability,
-            models.GroupTemplate: Group,
-            models.InterfaceTemplate: Interface,
-            models.NodeTemplate: Node,
-            models.PolicyTemplate: Policy,
-            models.SubstitutionTemplate: Substitution,
-            models.SubstitutionMapping: SubstitutionMapping,
-            models.RelationshipTemplate: Relationship,
-            models.OperationTemplate: Operation,
-            models.Metadata: Metadata,
-
-            models.Attribute: Parameter,
-            models.Property: Parameter,
-            models.Input: Parameter,
-            models.Output: Parameter,
-            models.Configuration: Parameter,
-            models.Argument: Parameter,
-
-        }
-
-    def instantiate(self, template, **kwargs):
-        if isinstance(template, dict):
-            return dict((name, self.instantiate(value, **kwargs))
-                        for name, value in template.iteritems())
-        elif isinstance(template, list):
-            return list(self.instantiate(value, **kwargs) for value in template)
-        else:
-            handler = self._handlers[template.__class__]
-            return handler(self, template).instantiate(**kwargs)
-
-
-class ServiceInstance(_Entity):
-
-    def __init__(self, *args, **kwargs):
-        super(ServiceInstance, self).__init__(*args, _instance_cls=models.Service, **kwargs)
-
-    def dump(self):
-        pass
-
-    def coerce(self):
-        pass
-
-    def instantiate(self, inputs=None):
-        now = datetime.now()
-        service = self._instance_cls(
-            created_at=now,
-            updated_at=now,
-            description=utils.deepcopy_with_locators(self._template.description),
-            service_template=self._template,
-            inputs=modeling_utils.merge_parameter_values(inputs, self._template.inputs)
-        )
-
-        for plugin_specification in self._template.plugin_specifications.itervalues():
-            if plugin_specification.enabled and self._topology._model_storage:
-                if utils.resolve_plugin_specification(plugin_specification,
-                                                      self._topology.model_storage.plugin.list()):
-                    plugin = plugin_specification.plugin
-                    service.plugins[plugin.name] = plugin
-                else:
-                    # TODO: fix the context report usage
-                    pass
-                    # self._context.validation.report('specified plugin not found: {0}'.format(
-                    #     plugin_specification.name), level=validation.Issue.EXTERNAL)
-        service.meta_data = self._topology.instantiate(self._template.meta_data)
-
-        for node_template in self._template.node_templates.itervalues():
-            for _ in range(node_template.scaling['default_instances']):
-                node = self._topology.instantiate(node_template)
-                service.nodes[node.name] = node
-
-        service.groups = self._topology.instantiate(self._template.group_templates)
-        service.policies = self._topology.instantiate(self._template.policy_templates)
-        service.workflows = self._topology.instantiate(self._template.workflow_templates)
-
-        if self._template.substitution_template is not None:
-            service.substitution = self._topology.instantiate(self._template.substitution_template)
-            service.outputs = self._topology.instantiate(self._template.outputs)
-
-        return service
-
-    def validate(self):
-        pass
-    
-    
-class Artifact(_Entity):
-
-    def __init__(self, *args, **kwargs):
-        super(Artifact, self).__init__(*args, _instance_cls=models.Artifact, **kwargs)
-
-    def dump(self):
-        pass
-
-    def coerce(self):
-        pass
-
-    def instantiate(self):
-        return self._instance_cls(
-            name=self._template.name,
-            type=self._template.type,
-            description=utils.deepcopy_with_locators(self._template.description),
-            source_path=self._template.source_path,
-            target_path=self._template.target_path,
-            repository_url=self._template.repository_url,
-            repository_credential=self._template.repository_credential,
-            artifact_template=self._template)
-
-    def validate(self):
-        pass
-    
-    
-class Capability(_Entity):
-    def __init__(self, *args, **kwargs):
-        super(Capability, self).__init__(*args, _instance_cls=models.Capability, **kwargs)
-
-    def dump(self):
-        pass
-
-    def coerce(self):
-        pass
-
-    def instantiate(self):
-        return self._instance_cls(name=self._template.name,
-                                  type=self._template.type,
-                                  min_occurrences=self._template.min_occurrences,
-                                  max_occurrences=self._template.max_occurrences,
-                                  occurrences=0,
-                                  capability_template=self._template)
-
-    def validate(self):
-        pass
-    
-
-class Group(_Entity):
-
-    def __init__(self, *args, **kwargs):
-        super(Group, self).__init__(*args, _instance_cls=models.Group, **kwargs)
-
-    def dump(self):
-        pass
-
-    def coerce(self):
-        pass
-
-    def instantiate(self):
-        group = self._instance_cls(
-            name=self._template.name,
-            type=self._template.type,
-            description=utils.deepcopy_with_locators(self._template.description),
-            group_template=self._template)
-        group.properties = self._topology.instantiate(self._template.properties)
-        group.interfaces = self._topology.instantiate(self._template.interface_templates)
-        if self._template.node_templates:
-            for node_template in self._template.node_templates:
-                group.nodes += node_template.nodes
-        return group
-
-    def validate(self):
-        pass
-    
-    
-class Interface(_Entity):
-
-    def __init__(self, *args, **kwargs):
-        super(Interface, self).__init__(*args, _instance_cls=models.Interface, **kwargs)
-
-    def dump(self):
-        pass
-
-    def coerce(self):
-        pass
-
-    def instantiate(self):
-        interface = self._instance_cls(
-            name=self._template.name,
-            type=self._template.type,
-            description=utils.deepcopy_with_locators(self._template.description),
-            interface_template=self._template)
-        interface.inputs = self._topology.instantiate(self._template.inputs)
-        interface.operations = self._topology.instantiate(self._template.operation_templates)
-        return interface
-
-    def validate(self):
-        pass
-
-
-class Node(_Entity):
-
-    def __init__(self, *args, **kwargs):
-        super(Node, self).__init__(*args, _instance_cls=models.Node, **kwargs)
-
-    def dump(self):
-        pass
-
-    def coerce(self):
-        pass
-
-    def instantiate(self):
-        node = self._instance_cls(
-            name=self._template._next_name,
-            type=self._template.type,
-            description=utils.deepcopy_with_locators(self._template.description),
-            state=models.Node.INITIAL,
-            node_template=self._template
-        )
-
-        node.properties = self._topology.instantiate(self._template.properties)
-        node.attributes = self._topology.instantiate(self._template.attributes)
-        node.interfaces = self._topology.instantiate(self._template.interface_templates)
-        node.artifacts = self._topology.instantiate(self._template.artifact_templates)
-        node.capabilities = self._topology.instantiate(self._template.capability_templates)
-
-        # Default attributes
-        if ('tosca_name' in node.attributes) \
-                and (node.attributes['tosca_name'].type_name == 'string'):
-            node.attributes['tosca_name'].value = self._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 validate(self):
-        pass
-
-
-class Policy(_Entity):
-
-    def __init__(self, *args, **kwargs):
-        super(Policy, self).__init__(*args, _instance_cls=models.Policy, **kwargs)
-
-    def dump(self):
-        pass
-
-    def coerce(self):
-        pass
-
-    def instantiate(self):
-        policy = self._instance_cls(
-            name=self._template.name,
-            type=self._template.type,
-            description=utils.deepcopy_with_locators(self._template.description),
-            policy_template=self._template)
-
-        policy.properties = self._topology.instantiate(self._template.properties)
-        if self._template.node_templates:
-            for node_template in self._template.node_templates:
-                policy.nodes += node_template.nodes
-        if self._template.group_templates:
-            for group_template in self._template.group_templates:
-                policy.groups += group_template.groups
-        return policy
-
-    def validate(self):
-        pass
-
-
-class Parameter(_Entity):
-    def __init__(self, topology_initiator, template, *args, **kwargs):
-        super(Parameter, self).__init__(
-            topology_initiator, template, *args, _instance_cls=template.__class__, **kwargs)
-
-    def dump(self):
-        pass
-
-    def coerce(self):
-        pass
-
-    def instantiate(self):
-        return self._instance_cls(
-            name=self._template.name,  # pylint: disable=unexpected-keyword-arg
-            type_name=self._template.type_name,
-            _value=self._template._value,
-            description=self._template.description
-        )
-
-    def validate(self):
-        pass
-
-
-class Substitution(_Entity):
-    def __init__(self, *args, **kwargs):
-        super(Substitution, self).__init__(_instance_cls=models.Substitution, *args, **kwargs)
-
-    def dump(self):
-        pass
-
-    def coerce(self):
-        pass
-
-    def instantiate(self):
-        return self._instance_cls(node_type=self._template.node_type,
-                                  substitution_template=self._template)
-
-    def validate(self):
-        pass
-
-
-class SubstitutionMapping(_Entity):
-
-    def __init__(self, *args, **kwargs):
-        super(SubstitutionMapping, self).__init__(
-            _instance_cls=models.SubstitutionMapping, *args, **kwargs)
-
-    def dump(self):
-        pass
-
-    def coerce(self):
-        pass
-
-    def instantiate(self):
-        substitution_mapping = self._instance_cls(
-            name=self._template.name,
-            requirement_template=self._template.requirement_template)
-
-        if self._template.capability_template is not None:
-            node_template = self._template.capability_template.node_template
-        else:
-            node_template = self._template.requirement_template.node_template
-        nodes = node_template.nodes
-        if len(nodes) == 0:
-            # TODO: manage the context report
-            # self._context.validation.report(
-            #     'mapping "{0}" refers to node template "{1}" but there are no node instances'.
-            #         format(self._template.mapped_name,
-            #                self._template.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
-        substitution_mapping.node = nodes[0]
-        if self._template.capability_template:
-            for a_capability in substitution_mapping.node.capabilities.itervalues():
-                if a_capability.capability_template.name == \
-                        self._template.capability_template.name:
-                    substitution_mapping.capability = a_capability
-
-        return substitution_mapping
-
-    def validate(self):
-        pass
-
-
-class Relationship(_Entity):
-
-    def __init__(self, *args, **kwargs):
-        super(Relationship, self).__init__(_instance_cls=models.Relationship, *args, **kwargs)
-
-    def dump(self):
-        pass
-
-    def coerce(self):
-        pass
-
-    def instantiate(self):
-        relationship = self._instance_cls(
-            name=self._template.name,
-            type=self._template.type,
-            relationship_template=self._template)
-
-        relationship.properties = self._topology.instantiate(self._template.properties)
-        relationship.interfaces = self._topology.instantiate(self._template.interface_templates)
-        return relationship
-
-    def validate(self):
-        pass
-
-
-class Operation(_Entity):
-
-    def __init__(self, *args, **kwargs):
-        super(Operation, self).__init__(_instance_cls=models.Operation, *args, **kwargs)
-
-    def dump(self):
-        pass
-
-    def coerce(self):
-        pass
-
-    def instantiate(self):
-        operation = self._instance_cls(
-            name=self._template.name,
-            description=utils.deepcopy_with_locators(self._template.description),
-            relationship_edge=self._template.relationship_edge,
-            implementation=self._template.implementation,
-            dependencies=self._template.dependencies,
-            executor=self._template.executor,
-            function=self._template.function,
-            max_attempts=self._template.max_attempts,
-            retry_interval=self._template.retry_interval,
-            operation_template=self._template)
-
-
-        if (self._template.plugin_specification is not None and
-            self._template.plugin_specification.enabled):
-            operation.plugin = self._template.plugin_specification.plugin
-
-        operation.inputs = self._topology.instantiate(self._template.inputs)
-        operation.configurations = self._topology.instantiate(self._template.configurations)
-
-        return operation
-
-    def validate(self):
-        pass
-
-
-class Metadata(_Entity):
-
-    def __init__(self, *args, **kwargs):
-        super(Metadata, self).__init__(_instance_cls=models.Metadata, *args, **kwargs)
-
-    def dump(self):
-        pass
-
-    def coerce(self):
-        pass
-
-    def instantiate(self):
-        return self._instance_cls(name=self._template.name, value=self._template.value)
-
-    def validate(self):
-        pass
-
-
-handler = Handler()