ariatosca-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mxm...@apache.org
Subject [2/2] incubator-ariatosca git commit: removed any remaining consumptioncontext reporting for now, added dynamic model handler resolving and only coerce remains
Date Mon, 24 Jul 2017 15:04:34 GMT
removed any remaining consumptioncontext reporting for now, added dynamic model handler resolving and only coerce remains


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

Branch: refs/heads/ARIA-174-Refactor-instantiation-phase
Commit: 5c92ccad652a1bd2706363768d13f0509fc9d58f
Parents: 8e5fe10
Author: max-orlov <maxim@gigaspaces.com>
Authored: Mon Jul 24 18:04:29 2017 +0300
Committer: max-orlov <maxim@gigaspaces.com>
Committed: Mon Jul 24 18:04:29 2017 +0300

----------------------------------------------------------------------
 aria/modeling/functions.py                      |   7 +-
 aria/modeling/mixins.py                         |  23 +-
 aria/modeling/service_common.py                 |  16 --
 aria/modeling/service_instance.py               | 241 +++-------------
 aria/modeling/service_template.py               | 232 ++-------------
 aria/modeling/utils.py                          |  59 ----
 .../execution_plugin/instantiation.py           |  61 ++--
 aria/orchestrator/topology/__init__.py          | 113 +++++---
 aria/orchestrator/topology/common.py            |  16 +-
 aria/orchestrator/topology/instance.py          | 285 +++++++++++++++----
 aria/orchestrator/topology/template.py          | 224 ++++++++++++---
 aria/parser/consumption/consumer.py             |   3 +
 aria/parser/consumption/modeling.py             |  11 +-
 13 files changed, 603 insertions(+), 688 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/5c92ccad/aria/modeling/functions.py
----------------------------------------------------------------------
diff --git a/aria/modeling/functions.py b/aria/modeling/functions.py
index 6544adf..425b69b 100644
--- a/aria/modeling/functions.py
+++ b/aria/modeling/functions.py
@@ -17,7 +17,6 @@
 Mechanism for evaluating intrinsic functions.
 """
 
-from ..parser.consumption import ConsumptionContext
 from ..parser.exceptions import InvalidValueError
 from ..utils.collections import OrderedDict
 from . import exceptions
@@ -105,8 +104,10 @@ def evaluate(value, container_holder, report_issues=False): # pylint: disable=to
             pass
         except InvalidValueError as e:
             if report_issues:
-                context = ConsumptionContext.get_thread_local()
-                context.validation.report(e.issue)
+                # TODO: do not use the context for "reporting"
+                pass
+                # context = ConsumptionContext.get_thread_local()
+                # context.validation.report(e.issue)
 
     elif isinstance(value, list):
         evaluated_list = []

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/5c92ccad/aria/modeling/mixins.py
----------------------------------------------------------------------
diff --git a/aria/modeling/mixins.py b/aria/modeling/mixins.py
index 91fc5e3..fd31e3e 100644
--- a/aria/modeling/mixins.py
+++ b/aria/modeling/mixins.py
@@ -25,8 +25,7 @@ from sqlalchemy import (
     PickleType
 )
 
-from ..parser.consumption import ConsumptionContext
-from ..utils import console, collections, caching, formatting
+from ..utils import collections, caching
 from ..utils.type import canonical_type_name, full_type_name
 from . import utils, functions
 
@@ -132,15 +131,9 @@ class InstanceModelMixin(ModelMixin):
     def as_raw(self):
         raise NotImplementedError
 
-    def validate(self):
-        pass
-
     def coerce_values(self, report_issues):
         pass
 
-    def dump(self):
-        pass
-
 
 class TemplateModelMixin(InstanceModelMixin):
     """
@@ -313,20 +306,6 @@ class ParameterMixin(TemplateModelMixin, caching.HasCachedMethods):
                 # A final evaluation can safely replace the existing value
                 self._value = evaluation.value
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        if self.type_name is not None:
-            console.puts('{0}: {1} ({2})'.format(
-                context.style.property(self.name),
-                context.style.literal(formatting.as_raw(self.value)),
-                context.style.type(self.type_name)))
-        else:
-            console.puts('{0}: {1}'.format(
-                context.style.property(self.name),
-                context.style.literal(formatting.as_raw(self.value))))
-        if self.description:
-            console.puts(context.style.meta(self.description))
-
     @property
     def unwrapped(self):
         return self.name, self.value

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/5c92ccad/aria/modeling/service_common.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_common.py b/aria/modeling/service_common.py
index f735c6b..60c7330 100644
--- a/aria/modeling/service_common.py
+++ b/aria/modeling/service_common.py
@@ -25,11 +25,9 @@ from sqlalchemy import (
 )
 from sqlalchemy.ext.declarative import declared_attr
 
-from ..parser.consumption import ConsumptionContext
 from ..utils import (
     collections,
     formatting,
-    console,
 )
 from .mixins import InstanceModelMixin, TemplateModelMixin, ParameterMixin
 from . import relationship
@@ -553,14 +551,6 @@ class TypeBase(InstanceModelMixin):
     def coerce_values(self, report_issues):
         pass
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        if self.name:
-            console.puts(context.style.type(self.name))
-        with context.style.indent:
-            for child in self.children:
-                child.dump()
-
     def _append_raw_children(self, types):
         for child in self.children:
             raw_child = formatting.as_raw(child)
@@ -602,9 +592,3 @@ class MetadataBase(TemplateModelMixin):
 
     def coerce_values(self, report_issues):
         pass
-
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        console.puts('{0}: {1}'.format(
-            context.style.property(self.name),
-            context.style.literal(self.value)))

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/5c92ccad/aria/modeling/service_instance.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_instance.py b/aria/modeling/service_instance.py
index 93d610b..03f8632 100644
--- a/aria/modeling/service_instance.py
+++ b/aria/modeling/service_instance.py
@@ -38,7 +38,6 @@ from . import (
 from .mixins import InstanceModelMixin
 from ..orchestrator import execution_plugin
 from ..parser import validation
-from ..parser.consumption import ConsumptionContext
 from ..utils import (
     collections,
     formatting,
@@ -300,29 +299,14 @@ class ServiceBase(InstanceModelMixin):
         utils.coerce_dict_values(self.outputs, report_issues)
         utils.coerce_dict_values(self.workflows, report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        if self.description is not None:
-            console.puts(context.style.meta(self.description))
-        utils.dump_dict_values(self.meta_data, 'Metadata')
-        for node in self.nodes.itervalues():
-            node.dump()
-        for group in self.groups.itervalues():
-            group.dump()
-        for policy in self.policies.itervalues():
-            policy.dump()
-        if self.substitution is not None:
-            self.substitution.dump()
-        utils.dump_dict_values(self.inputs, 'Inputs')
-        utils.dump_dict_values(self.outputs, 'Outputs')
-        utils.dump_dict_values(self.workflows, 'Workflows')
-
     def dump_graph(self):
         for node in self.nodes.itervalues():
             if not self.is_node_a_target(node):
                 self._dump_graph_node(node)
 
     def _dump_graph_node(self, node, capability=None):
+        from ..parser.consumption import ConsumptionContext
+
         context = ConsumptionContext.get_thread_local()
         console.puts(context.style.node(node.name))
         if capability is not None:
@@ -617,17 +601,20 @@ class NodeBase(InstanceModelMixin):
                                                      target_node_template,
                                                      requirement_template)
             else:
-                context = ConsumptionContext.get_thread_local()
-                context.validation.report('requirement "{0}" of node "{1}" has no target node '
-                                          'template'.format(requirement_template.name, self.name),
-                                          level=validation.Issue.BETWEEN_INSTANCES)
+                # TODO: fix
+
+                # context = ConsumptionContext.get_thread_local()
+                # context.validation.report('requirement "{0}" of node "{1}" has no target node '
+                #                           'template'.format(requirement_template.name, self.name),
+                #                           level=validation.Issue.BETWEEN_INSTANCES)
                 satisfied = False
         return satisfied
 
     def _satisfy_capability(self, target_node_capability, target_node_template,
                             requirement_template):
         from . import models
-        context = ConsumptionContext.get_thread_local()
+        # TODO: fix reporting
+        # context = ConsumptionContext.get_thread_local()
         # Find target nodes
         target_nodes = target_node_template.nodes
         if target_nodes:
@@ -660,35 +647,36 @@ class NodeBase(InstanceModelMixin):
                 self.outbound_relationships.append(relationship_model)
                 return True
             else:
-                context.validation.report('requirement "{0}" of node "{1}" targets node '
-                                          'template "{2}" but its instantiated nodes do not '
-                                          'have enough capacity'.format(
-                                              requirement_template.name,
-                                              self.name,
-                                              target_node_template.name),
-                                          level=validation.Issue.BETWEEN_INSTANCES)
+                # context.validation.report('requirement "{0}" of node "{1}" targets node '
+                #                           'template "{2}" but its instantiated nodes do not '
+                #                           'have enough capacity'.format(
+                #                               requirement_template.name,
+                #                               self.name,
+                #                               target_node_template.name),
+                #                           level=validation.Issue.BETWEEN_INSTANCES)
                 return False
         else:
-            context.validation.report('requirement "{0}" of node "{1}" targets node template '
-                                      '"{2}" but it has no instantiated nodes'.format(
-                                          requirement_template.name,
-                                          self.name,
-                                          target_node_template.name),
-                                      level=validation.Issue.BETWEEN_INSTANCES)
+            # context.validation.report('requirement "{0}" of node "{1}" targets node template '
+            #                           '"{2}" but it has no instantiated nodes'.format(
+            #                               requirement_template.name,
+            #                               self.name,
+            #                               target_node_template.name),
+            #                           level=validation.Issue.BETWEEN_INSTANCES)
             return False
 
     def validate_capabilities(self):
-        context = ConsumptionContext.get_thread_local()
+        # TODO: fix
+        # context = ConsumptionContext.get_thread_local()
         satisfied = False
         for capability in self.capabilities.itervalues():
             if not capability.has_enough_relationships:
-                context.validation.report('capability "{0}" of node "{1}" requires at least {2:d} '
-                                          'relationships but has {3:d}'.format(
-                                              capability.name,
-                                              self.name,
-                                              capability.min_occurrences,
-                                              capability.occurrences),
-                                          level=validation.Issue.BETWEEN_INSTANCES)
+                # context.validation.report('capability "{0}" of node "{1}" requires at least {2:d} '
+                #                           'relationships but has {3:d}'.format(
+                #                               capability.name,
+                #                               self.name,
+                #                               capability.min_occurrences,
+                #                               capability.occurrences),
+                #                           level=validation.Issue.BETWEEN_INSTANCES)
                 satisfied = False
         return satisfied
 
@@ -738,19 +726,6 @@ class NodeBase(InstanceModelMixin):
         utils.coerce_dict_values(self.capabilities, report_issues)
         utils.coerce_list_values(self.outbound_relationships, report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        console.puts('Node: {0}'.format(context.style.node(self.name)))
-        with context.style.indent:
-            console.puts('Type: {0}'.format(context.style.type(self.type.name)))
-            console.puts('Template: {0}'.format(context.style.node(self.node_template.name)))
-            utils.dump_dict_values(self.properties, 'Properties')
-            utils.dump_dict_values(self.attributes, 'Attributes')
-            utils.dump_interfaces(self.interfaces)
-            utils.dump_dict_values(self.artifacts, 'Artifacts')
-            utils.dump_dict_values(self.capabilities, 'Capabilities')
-            utils.dump_list_values(self.outbound_relationships, 'Relationships')
-
 
 class GroupBase(InstanceModelMixin):
     """
@@ -871,19 +846,6 @@ class GroupBase(InstanceModelMixin):
         utils.coerce_dict_values(self.properties, report_issues)
         utils.coerce_dict_values(self.interfaces, report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        console.puts('Group: {0}'.format(context.style.node(self.name)))
-        with context.style.indent:
-            console.puts('Type: {0}'.format(context.style.type(self.type.name)))
-            utils.dump_dict_values(self.properties, 'Properties')
-            utils.dump_interfaces(self.interfaces)
-            if self.nodes:
-                console.puts('Member nodes:')
-                with context.style.indent:
-                    for node in self.nodes:
-                        console.puts(context.style.node(node.name))
-
 
 class PolicyBase(InstanceModelMixin):
     """
@@ -1000,23 +962,6 @@ class PolicyBase(InstanceModelMixin):
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.properties, report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        console.puts('Policy: {0}'.format(context.style.node(self.name)))
-        with context.style.indent:
-            console.puts('Type: {0}'.format(context.style.type(self.type.name)))
-            utils.dump_dict_values(self.properties, 'Properties')
-            if self.nodes:
-                console.puts('Target nodes:')
-                with context.style.indent:
-                    for node in self.nodes:
-                        console.puts(context.style.node(node.name))
-            if self.groups:
-                console.puts('Target groups:')
-                with context.style.indent:
-                    for group in self.groups:
-                        console.puts(context.style.node(group.name))
-
 
 class SubstitutionBase(InstanceModelMixin):
     """
@@ -1097,13 +1042,6 @@ class SubstitutionBase(InstanceModelMixin):
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.mappings, report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        console.puts('Substitution:')
-        with context.style.indent:
-            console.puts('Node type: {0}'.format(context.style.type(self.node_type.name)))
-            utils.dump_dict_values(self.mappings, 'Mappings')
-
 
 class SubstitutionMappingBase(InstanceModelMixin):
     """
@@ -1202,19 +1140,6 @@ class SubstitutionMappingBase(InstanceModelMixin):
     def coerce_values(self, report_issues):
         pass
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        if self.capability is not None:
-            console.puts('{0} -> {1}.{2}'.format(
-                context.style.node(self.name),
-                context.style.node(self.capability.node.name),
-                context.style.node(self.capability.name)))
-        else:
-            console.puts('{0} -> {1}.{2}'.format(
-                context.style.node(self.name),
-                context.style.node(self.node.name),
-                context.style.node(self.requirement_template.name)))
-
 
 class RelationshipBase(InstanceModelMixin):
     """
@@ -1408,25 +1333,6 @@ class RelationshipBase(InstanceModelMixin):
         utils.coerce_dict_values(self.properties, report_issues)
         utils.coerce_dict_values(self.interfaces, report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        if self.name:
-            console.puts('{0} ->'.format(context.style.node(self.name)))
-        else:
-            console.puts('->')
-        with context.style.indent:
-            console.puts('Node: {0}'.format(context.style.node(self.target_node.name)))
-            if self.target_capability:
-                console.puts('Capability: {0}'.format(context.style.node(
-                    self.target_capability.name)))
-            if self.type is not None:
-                console.puts('Relationship type: {0}'.format(context.style.type(self.type.name)))
-            if (self.relationship_template is not None) and self.relationship_template.name:
-                console.puts('Relationship template: {0}'.format(
-                    context.style.node(self.relationship_template.name)))
-            utils.dump_dict_values(self.properties, 'Properties')
-            utils.dump_interfaces(self.interfaces, 'Interfaces')
-
 
 class CapabilityBase(InstanceModelMixin):
     """
@@ -1546,19 +1452,6 @@ class CapabilityBase(InstanceModelMixin):
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.properties, report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        console.puts(context.style.node(self.name))
-        with context.style.indent:
-            console.puts('Type: {0}'.format(context.style.type(self.type.name)))
-            console.puts('Occurrences: {0:d} ({1:d}{2})'.format(
-                self.occurrences,
-                self.min_occurrences or 0,
-                ' to {0:d}'.format(self.max_occurrences)
-                if self.max_occurrences is not None
-                else ' or more'))
-            utils.dump_dict_values(self.properties, 'Properties')
-
 
 class InterfaceBase(InstanceModelMixin):
     """
@@ -1700,16 +1593,6 @@ class InterfaceBase(InstanceModelMixin):
         utils.coerce_dict_values(self.inputs, report_issues)
         utils.coerce_dict_values(self.operations, report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        console.puts(context.style.node(self.name))
-        if self.description:
-            console.puts(context.style.meta(self.description))
-        with context.style.indent:
-            console.puts('Interface type: {0}'.format(context.style.type(self.type.name)))
-            utils.dump_dict_values(self.inputs, 'Inputs')
-            utils.dump_dict_values(self.operations, 'Operations')
-
 
 class OperationBase(InstanceModelMixin):
     """
@@ -1917,13 +1800,13 @@ class OperationBase(InstanceModelMixin):
         from ..orchestrator.decorators import OPERATION_DECORATOR_RESERVED_ARGUMENTS
         used_reserved_names = \
             OPERATION_DECORATOR_RESERVED_ARGUMENTS.intersection(self.arguments.keys())
-        if used_reserved_names:
-            context = ConsumptionContext.get_thread_local()
-            context.validation.report('using reserved arguments in operation "{0}": {1}'
-                                      .format(
-                                          self.name,
-                                          formatting.string_list_as_string(used_reserved_names)),
-                                      level=validation.Issue.EXTERNAL)
+        # if used_reserved_names:
+        #     # context = ConsumptionContext.get_thread_local()
+        #     context.validation.report('using reserved arguments in operation "{0}": {1}'
+        #                               .format(
+        #                                   self.name,
+        #                                   formatting.string_list_as_string(used_reserved_names)),
+        #                               level=validation.Issue.EXTERNAL)
 
 
     @property
@@ -1940,35 +1823,6 @@ class OperationBase(InstanceModelMixin):
         utils.coerce_dict_values(self.configurations, report_issues)
         utils.coerce_dict_values(self.arguments, report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        console.puts(context.style.node(self.name))
-        if self.description:
-            console.puts(context.style.meta(self.description))
-        with context.style.indent:
-            if self.implementation is not None:
-                console.puts('Implementation: {0}'.format(
-                    context.style.literal(self.implementation)))
-            if self.dependencies:
-                console.puts(
-                    'Dependencies: {0}'.format(
-                        ', '.join((str(context.style.literal(v)) for v in self.dependencies))))
-            utils.dump_dict_values(self.inputs, 'Inputs')
-            if self.executor is not None:
-                console.puts('Executor: {0}'.format(context.style.literal(self.executor)))
-            if self.max_attempts is not None:
-                console.puts('Max attempts: {0}'.format(context.style.literal(self.max_attempts)))
-            if self.retry_interval is not None:
-                console.puts('Retry interval: {0}'.format(
-                    context.style.literal(self.retry_interval)))
-            if self.plugin is not None:
-                console.puts('Plugin: {0}'.format(
-                    context.style.literal(self.plugin.name)))
-            utils.dump_dict_values(self.configurations, 'Configuration')
-            if self.function is not None:
-                console.puts('Function: {0}'.format(context.style.literal(self.function)))
-            utils.dump_dict_values(self.arguments, 'Arguments')
-
 
 class ArtifactBase(InstanceModelMixin):
     """
@@ -2091,20 +1945,3 @@ class ArtifactBase(InstanceModelMixin):
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.properties, report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        console.puts(context.style.node(self.name))
-        if self.description:
-            console.puts(context.style.meta(self.description))
-        with context.style.indent:
-            console.puts('Artifact type: {0}'.format(context.style.type(self.type.name)))
-            console.puts('Source path: {0}'.format(context.style.literal(self.source_path)))
-            if self.target_path is not None:
-                console.puts('Target path: {0}'.format(context.style.literal(self.target_path)))
-            if self.repository_url is not None:
-                console.puts('Repository URL: {0}'.format(
-                    context.style.literal(self.repository_url)))
-            if self.repository_credential:
-                console.puts('Repository credential: {0}'.format(
-                    context.style.literal(self.repository_credential)))
-            utils.dump_dict_values(self.properties, 'Properties')

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/5c92ccad/aria/modeling/service_template.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_template.py b/aria/modeling/service_template.py
index b505a06..665a4f1 100644
--- a/aria/modeling/service_template.py
+++ b/aria/modeling/service_template.py
@@ -31,8 +31,6 @@ from sqlalchemy import (
 )
 from sqlalchemy.ext.declarative import declared_attr
 
-from ..parser import validation
-from ..parser.consumption import ConsumptionContext
 from ..utils import (collections, formatting, console)
 from .mixins import TemplateModelMixin
 from . import (
@@ -338,23 +336,6 @@ class ServiceTemplateBase(TemplateModelMixin):
         utils.coerce_dict_values(self.outputs, report_issues)
         utils.coerce_dict_values(self.workflow_templates, report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        if self.description is not None:
-            console.puts(context.style.meta(self.description))
-        utils.dump_dict_values(self.meta_data, 'Metadata')
-        for node_template in self.node_templates.itervalues():
-            node_template.dump()
-        for group_template in self.group_templates.itervalues():
-            group_template.dump()
-        for policy_template in self.policy_templates.itervalues():
-            policy_template.dump()
-        if self.substitution_template is not None:
-            self.substitution_template.dump()
-        utils.dump_dict_values(self.inputs, 'Inputs')
-        utils.dump_dict_values(self.outputs, 'Outputs')
-        utils.dump_dict_values(self.workflow_templates, 'Workflow templates')
-
     def dump_types(self):
         if self.node_types.children:
             console.puts('Node types:')
@@ -556,20 +537,6 @@ class NodeTemplateBase(TemplateModelMixin):
         utils.coerce_dict_values(self.capability_templates, report_issues)
         utils.coerce_list_values(self.requirement_templates, report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        console.puts('Node template: {0}'.format(context.style.node(self.name)))
-        if self.description:
-            console.puts(context.style.meta(self.description))
-        with context.style.indent:
-            console.puts('Type: {0}'.format(context.style.type(self.type.name)))
-            utils.dump_dict_values(self.properties, 'Properties')
-            utils.dump_dict_values(self.attributes, 'Attributes')
-            utils.dump_interfaces(self.interface_templates)
-            utils.dump_dict_values(self.artifact_templates, 'Artifact templates')
-            utils.dump_dict_values(self.capability_templates, 'Capability templates')
-            utils.dump_list_values(self.requirement_templates, 'Requirement templates')
-
     @property
     def scaling(self):
         scaling = {}
@@ -614,14 +581,16 @@ class NodeTemplateBase(TemplateModelMixin):
                 (scaling['max_instances'] < scaling['min_instances']) or
                 (scaling['default_instances'] < scaling['min_instances']) or
                 (scaling['default_instances'] > scaling['max_instances'])):
-            context = ConsumptionContext.get_thread_local()
-            context.validation.report('invalid scaling parameters for node template "{0}": '
-                                      'min={1}, max={2}, default={3}'.format(
-                                          self.name,
-                                          scaling['min_instances'],
-                                          scaling['max_instances'],
-                                          scaling['default_instances']),
-                                      level=validation.Issue.BETWEEN_TYPES)
+            pass
+            # TODO: fix this
+            # context = ConsumptionContext.get_thread_local()
+            # context.validation.report('invalid scaling parameters for node template "{0}": '
+                                      # 'min={1}, max={2}, default={3}'.format(
+                                      #     self.name,
+                                      #     scaling['min_instances'],
+                                      #     scaling['max_instances'],
+                                      #     scaling['default_instances']),
+                                      # level=validation.Issue.BETWEEN_TYPES)
 
         return scaling
 
@@ -772,19 +741,6 @@ class GroupTemplateBase(TemplateModelMixin):
         utils.coerce_dict_values(self.properties, report_issues)
         utils.coerce_dict_values(self.interface_templates, report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        console.puts('Group template: {0}'.format(context.style.node(self.name)))
-        if self.description:
-            console.puts(context.style.meta(self.description))
-        with context.style.indent:
-            console.puts('Type: {0}'.format(context.style.type(self.type.name)))
-            utils.dump_dict_values(self.properties, 'Properties')
-            utils.dump_interfaces(self.interface_templates)
-            if self.node_templates:
-                console.puts('Member node templates: {0}'.format(', '.join(
-                    (str(context.style.node(v.name)) for v in self.node_templates))))
-
     def contains_node_template(self, name):
         for node_template in self.node_templates:
             if node_template.name == name:
@@ -900,21 +856,6 @@ class PolicyTemplateBase(TemplateModelMixin):
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.properties, report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        console.puts('Policy template: {0}'.format(context.style.node(self.name)))
-        if self.description:
-            console.puts(context.style.meta(self.description))
-        with context.style.indent:
-            console.puts('Type: {0}'.format(context.style.type(self.type.name)))
-            utils.dump_dict_values(self.properties, 'Properties')
-            if self.node_templates:
-                console.puts('Target node templates: {0}'.format(', '.join(
-                    (str(context.style.node(v.name)) for v in self.node_templates))))
-            if self.group_templates:
-                console.puts('Target group templates: {0}'.format(', '.join(
-                    (str(context.style.node(v.name)) for v in self.group_templates))))
-
     def is_for_node_template(self, name):
         for node_template in self.node_templates:
             if node_template.name == name:
@@ -994,13 +935,6 @@ class SubstitutionTemplateBase(TemplateModelMixin):
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.mappings, report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        console.puts('Substitution template:')
-        with context.style.indent:
-            console.puts('Node type: {0}'.format(context.style.type(self.node_type.name)))
-            utils.dump_dict_values(self.mappings, 'Mappings')
-
 
 class SubstitutionTemplateMappingBase(TemplateModelMixin):
     """
@@ -1083,19 +1017,6 @@ class SubstitutionTemplateMappingBase(TemplateModelMixin):
     def coerce_values(self, report_issues):
         pass
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        if self.capability_template is not None:
-            node_template = self.capability_template.node_template
-        else:
-            node_template = self.requirement_template.node_template
-        console.puts('{0} -> {1}.{2}'.format(
-            context.style.node(self.name),
-            context.style.node(node_template.name),
-            context.style.node(self.capability_template.name
-                               if self.capability_template
-                               else self.requirement_template.name)))
-
 
 class RequirementTemplateBase(TemplateModelMixin):
     """
@@ -1235,17 +1156,19 @@ class RequirementTemplateBase(TemplateModelMixin):
     """)
 
     def find_target(self, source_node_template):
-        context = ConsumptionContext.get_thread_local()
+        # context = ConsumptionContext.get_thread_local()
 
         # We might already have a specific node template, so we'll just verify it
         if self.target_node_template is not None:
             if not source_node_template.is_target_node_template_valid(self.target_node_template):
-                context.validation.report('requirement "{0}" of node template "{1}" is for node '
-                                          'template "{2}" but it does not match constraints'.format(
-                                              self.name,
-                                              self.target_node_template.name,
-                                              source_node_template.name),
-                                          level=validation.Issue.BETWEEN_TYPES)
+                # TODO: fix
+                pass
+                # context.validation.report('requirement "{0}" of node template "{1}" is for node '
+                                          # 'template "{2}" but it does not match constraints'.format(
+                                          #     self.name,
+                                          #     self.target_node_template.name,
+                                          #     source_node_template.name),
+                                          # level=validation.Issue.BETWEEN_TYPES)
             if (self.target_capability_type is not None) \
                 or (self.target_capability_name is not None):
                 target_node_capability = self.find_target_capability(source_node_template,
@@ -1301,35 +1224,6 @@ class RequirementTemplateBase(TemplateModelMixin):
         if self.relationship_template is not None:
             self.relationship_template.coerce_values(report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        if self.name:
-            console.puts(context.style.node(self.name))
-        else:
-            console.puts('Requirement:')
-        with context.style.indent:
-            if self.target_node_type is not None:
-                console.puts('Target node type: {0}'.format(
-                    context.style.type(self.target_node_type.name)))
-            elif self.target_node_template is not None:
-                console.puts('Target node template: {0}'.format(
-                    context.style.node(self.target_node_template.name)))
-            if self.target_capability_type is not None:
-                console.puts('Target capability type: {0}'.format(
-                    context.style.type(self.target_capability_type.name)))
-            elif self.target_capability_name is not None:
-                console.puts('Target capability name: {0}'.format(
-                    context.style.node(self.target_capability_name)))
-            if self.target_node_template_constraints:
-                console.puts('Target node template constraints:')
-                with context.style.indent:
-                    for constraint in self.target_node_template_constraints:
-                        console.puts(context.style.literal(constraint))
-            if self.relationship_template:
-                console.puts('Relationship:')
-                with context.style.indent:
-                    self.relationship_template.dump()
-
 
 class RelationshipTemplateBase(TemplateModelMixin):
     """
@@ -1416,19 +1310,6 @@ class RelationshipTemplateBase(TemplateModelMixin):
         utils.coerce_dict_values(self.properties, report_issues)
         utils.coerce_dict_values(self.interface_templates, report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        if self.type is not None:
-            console.puts('Relationship type: {0}'.format(context.style.type(self.type.name)))
-        else:
-            console.puts('Relationship template: {0}'.format(
-                context.style.node(self.name)))
-        if self.description:
-            console.puts(context.style.meta(self.description))
-        with context.style.indent:
-            utils.dump_dict_values(self.properties, 'Properties')
-            utils.dump_interfaces(self.interface_templates, 'Interface templates')
-
 
 class CapabilityTemplateBase(TemplateModelMixin):
     """
@@ -1568,25 +1449,6 @@ class CapabilityTemplateBase(TemplateModelMixin):
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.properties, report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        console.puts(context.style.node(self.name))
-        if self.description:
-            console.puts(context.style.meta(self.description))
-        with context.style.indent:
-            console.puts('Type: {0}'.format(context.style.type(self.type.name)))
-            console.puts(
-                'Occurrences: {0:d}{1}'.format(
-                    self.min_occurrences or 0,
-                    ' to {0:d}'.format(self.max_occurrences)
-                    if self.max_occurrences is not None
-                    else ' or more'))
-            if self.valid_source_node_types:
-                console.puts('Valid source node types: {0}'.format(
-                    ', '.join((str(context.style.type(v.name))
-                               for v in self.valid_source_node_types))))
-            utils.dump_dict_values(self.properties, 'Properties')
-
 
 class InterfaceTemplateBase(TemplateModelMixin):
     """
@@ -1720,16 +1582,6 @@ class InterfaceTemplateBase(TemplateModelMixin):
         utils.coerce_dict_values(self.inputs, report_issues)
         utils.coerce_dict_values(self.operation_templates, report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        console.puts(context.style.node(self.name))
-        if self.description:
-            console.puts(context.style.meta(self.description))
-        with context.style.indent:
-            console.puts('Interface type: {0}'.format(context.style.type(self.type.name)))
-            utils.dump_dict_values(self.inputs, 'Inputs')
-            utils.dump_dict_values(self.operation_templates, 'Operation templates')
-
 
 class OperationTemplateBase(TemplateModelMixin):
     """
@@ -1892,33 +1744,6 @@ class OperationTemplateBase(TemplateModelMixin):
         utils.coerce_dict_values(self.inputs, report_issues)
         utils.coerce_dict_values(self.configurations, report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        console.puts(context.style.node(self.name))
-        if self.description:
-            console.puts(context.style.meta(self.description))
-        with context.style.indent:
-            if self.implementation is not None:
-                console.puts('Implementation: {0}'.format(
-                    context.style.literal(self.implementation)))
-            if self.dependencies:
-                console.puts('Dependencies: {0}'.format(
-                    ', '.join((str(context.style.literal(v)) for v in self.dependencies))))
-            utils.dump_dict_values(self.inputs, 'Inputs')
-            if self.executor is not None:
-                console.puts('Executor: {0}'.format(context.style.literal(self.executor)))
-            if self.max_attempts is not None:
-                console.puts('Max attempts: {0}'.format(context.style.literal(self.max_attempts)))
-            if self.retry_interval is not None:
-                console.puts('Retry interval: {0}'.format(
-                    context.style.literal(self.retry_interval)))
-            if self.plugin_specification is not None:
-                console.puts('Plugin specification: {0}'.format(
-                    context.style.literal(self.plugin_specification.name)))
-            utils.dump_dict_values(self.configurations, 'Configuration')
-            if self.function is not None:
-                console.puts('Function: {0}'.format(context.style.literal(self.function)))
-
 
 class ArtifactTemplateBase(TemplateModelMixin):
     """
@@ -2034,25 +1859,6 @@ class ArtifactTemplateBase(TemplateModelMixin):
     def coerce_values(self, report_issues):
         utils.coerce_dict_values(self.properties, report_issues)
 
-    def dump(self):
-        context = ConsumptionContext.get_thread_local()
-        console.puts(context.style.node(self.name))
-        if self.description:
-            console.puts(context.style.meta(self.description))
-        with context.style.indent:
-            console.puts('Artifact type: {0}'.format(context.style.type(self.type.name)))
-            console.puts('Source path: {0}'.format(context.style.literal(self.source_path)))
-            if self.target_path is not None:
-                console.puts('Target path: {0}'.format(context.style.literal(self.target_path)))
-            if self.repository_url is not None:
-                console.puts('Repository URL: {0}'.format(
-                    context.style.literal(self.repository_url)))
-            if self.repository_credential:
-                console.puts('Repository credential: {0}'.format(
-                    context.style.literal(self.repository_credential)))
-            utils.dump_dict_values(self.properties, 'Properties')
-
-
 class PluginSpecificationBase(TemplateModelMixin):
     """
     Requirement for a :class:`Plugin`.

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/5c92ccad/aria/modeling/utils.py
----------------------------------------------------------------------
diff --git a/aria/modeling/utils.py b/aria/modeling/utils.py
index e50fb2f..1002d5a 100644
--- a/aria/modeling/utils.py
+++ b/aria/modeling/utils.py
@@ -22,8 +22,6 @@ from json import JSONEncoder
 from StringIO import StringIO
 
 from . import exceptions
-from ..parser.consumption import ConsumptionContext
-from ..utils.console import puts
 from ..utils.type import validate_value_type
 from ..utils.collections import OrderedDict
 from ..utils.formatting import string_list_as_string
@@ -155,63 +153,6 @@ def coerce_list_values(the_list, report_issues=False):
         value.coerce_values(report_issues)
 
 
-def validate_dict_values(the_dict):
-    if not the_dict:
-        return
-    validate_list_values(the_dict.itervalues())
-
-
-def validate_list_values(the_list):
-    if not the_list:
-        return
-    for value in the_list:
-        value.validate()
-
-
-def instantiate_dict(container, the_dict, from_dict):
-    if not from_dict:
-        return
-    for name, value in from_dict.iteritems():
-        value = value.instantiate(container)
-        if value is not None:
-            the_dict[name] = value
-
-
-def instantiate_list(container, the_list, from_list):
-    if not from_list:
-        return
-    for value in from_list:
-        value = value.instantiate(container)
-        if value is not None:
-            the_list.append(value)
-
-
-def dump_list_values(the_list, name):
-    if not the_list:
-        return
-    puts('%s:' % name)
-    context = ConsumptionContext.get_thread_local()
-    with context.style.indent:
-        for value in the_list:
-            value.dump()
-
-
-def dump_dict_values(the_dict, name):
-    if not the_dict:
-        return
-    dump_list_values(the_dict.itervalues(), name)
-
-
-def dump_interfaces(interfaces, name='Interfaces'):
-    if not interfaces:
-        return
-    puts('%s:' % name)
-    context = ConsumptionContext.get_thread_local()
-    with context.style.indent:
-        for interface in interfaces.itervalues():
-            interface.dump()
-
-
 def parameters_as_values(the_dict):
     return dict((k, v.value) for k, v in the_dict.iteritems())
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/5c92ccad/aria/orchestrator/execution_plugin/instantiation.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/execution_plugin/instantiation.py b/aria/orchestrator/execution_plugin/instantiation.py
index f55aa50..4390252 100644
--- a/aria/orchestrator/execution_plugin/instantiation.py
+++ b/aria/orchestrator/execution_plugin/instantiation.py
@@ -23,7 +23,6 @@ from ...utils.type import full_type_name
 from ...utils.formatting import safe_repr
 from ...utils.collections import OrderedDict
 from ...parser import validation
-from ...parser.consumption import ConsumptionContext
 from ...modeling.functions import Function
 
 
@@ -110,20 +109,24 @@ def _configure_remote(operation):
 
     # Make sure we have a user
     if fabric_env.get('user') is None:
-        context = ConsumptionContext.get_thread_local()
-        context.validation.report('must configure "ssh.user" for "{0}"'
-                                  .format(operation.implementation),
-                                  level=validation.Issue.BETWEEN_TYPES)
+        # TODO: fix
+        pass
+        # context = ConsumptionContext.get_thread_local()
+        # context.validation.report('must configure "ssh.user" for "{0}"'
+        #                           .format(operation.implementation),
+        #                           level=validation.Issue.BETWEEN_TYPES)
 
     # Make sure we have an authentication value
     if (fabric_env.get('password') is None) and \
         (fabric_env.get('key') is None) and \
         (fabric_env.get('key_filename') is None):
-        context = ConsumptionContext.get_thread_local()
-        context.validation.report('must configure "ssh.password", "ssh.key", or "ssh.key_filename" '
-                                  'for "{0}"'
-                                  .format(operation.implementation),
-                                  level=validation.Issue.BETWEEN_TYPES)
+        # TODO: fix
+        pass
+        # context = ConsumptionContext.get_thread_local()
+        # context.validation.report('must configure "ssh.password", "ssh.key", or "ssh.key_filename" '
+        #                           'for "{0}"'
+        #                           .format(operation.implementation),
+        #                           level=validation.Issue.BETWEEN_TYPES)
 
     operation.arguments['fabric_env'] = Argument.wrap('fabric_env', fabric_env,
                                                       'Fabric configuration.')
@@ -152,10 +155,12 @@ def _get_process(operation):
         elif k == 'env':
             _validate_type(v, dict, 'process.env')
         else:
-            context = ConsumptionContext.get_thread_local()
-            context.validation.report('unsupported configuration parameter: "process.{0}"'
-                                      .format(k),
-                                      level=validation.Issue.BETWEEN_TYPES)
+            # TODO: fix
+            pass
+            # context = ConsumptionContext.get_thread_local()
+            # context.validation.report('unsupported configuration parameter: "process.{0}"'
+            #                           .format(k),
+            #                           level=validation.Issue.BETWEEN_TYPES)
     return value
 
 
@@ -185,9 +190,11 @@ def _get_ssh(operation):
         elif k == 'address':
             _validate_type(v, basestring, 'ssh.address')
         else:
-            context = ConsumptionContext.get_thread_local()
-            context.validation.report('unsupported configuration parameter: "ssh.{0}"'.format(k),
-                                      level=validation.Issue.BETWEEN_TYPES)
+            # TODO: fix
+            pass
+            # context = ConsumptionContext.get_thread_local()
+            # context.validation.report('unsupported configuration parameter: "ssh.{0}"'.format(k),
+            #                           level=validation.Issue.BETWEEN_TYPES)
     return value
 
 
@@ -195,10 +202,12 @@ def _validate_type(value, the_type, name):
     if isinstance(value, Function):
         return
     if not isinstance(value, the_type):
-        context = ConsumptionContext.get_thread_local()
-        context.validation.report('"{0}" configuration is not a {1}: {2}'
-                                  .format(name, full_type_name(the_type), safe_repr(value)),
-                                  level=validation.Issue.BETWEEN_TYPES)
+        # TODO: fix
+        pass
+        # context = ConsumptionContext.get_thread_local()
+        # context.validation.report('"{0}" configuration is not a {1}: {2}'
+        #                           .format(name, full_type_name(the_type), safe_repr(value)),
+        #                           level=validation.Issue.BETWEEN_TYPES)
 
 
 def _coerce_bool(value, name):
@@ -212,10 +221,12 @@ def _coerce_bool(value, name):
     elif value == 'false':
         return False
     else:
-        context = ConsumptionContext.get_thread_local()
-        context.validation.report('"{0}" configuration is not "true" or "false": {1}'
-                                  .format(name, safe_repr(value)),
-                                  level=validation.Issue.BETWEEN_TYPES)
+        # TODO: fix
+        pass
+        # context = ConsumptionContext.get_thread_local()
+        # context.validation.report('"{0}" configuration is not "true" or "false": {1}'
+        #                           .format(name, safe_repr(value)),
+        #                           level=validation.Issue.BETWEEN_TYPES)
 
 
 def _dict_to_list_of_strings(the_dict, name):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/5c92ccad/aria/orchestrator/topology/__init__.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/__init__.py b/aria/orchestrator/topology/__init__.py
index 4109af6..4737ac1 100644
--- a/aria/orchestrator/topology/__init__.py
+++ b/aria/orchestrator/topology/__init__.py
@@ -13,54 +13,19 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from StringIO import StringIO
+
 from ...modeling import models
 from . import (
     template,
-    instance
+    instance,
+    common
 )
 
-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,
-    }
+class Handler(object):
 
-    _instance_mapping = {
-        # Templates
+    _init_map = {
         models.ServiceTemplate: models.Service,
         models.ArtifactTemplate: models.Artifact,
         models.CapabilityTemplate: models.Capability,
@@ -69,25 +34,67 @@ class Handler(object):
         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.RequirementTemplate: None,
+        models.SubstitutionTemplateMapping: models.SubstitutionMapping,
 
+        # Common
+        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,
+        models.Type: models.Type
     }
 
+    class TopologyStylizer(object):
+        def __init__(self, context):
+            self._context = context
+            self._str = StringIO()
+
+        def write(self, str_):
+            self._str.write(str_)
+
+        def __repr__(self):
+            return self._str.getvalue()
+
+        def __str__(self):
+            return repr(self)
+
+        def __getattr__(self, item):
+            try:
+                return getattr(self._context, item)
+            except AttributeError:
+                return super(Handler.TopologyStylizer, self).__getattribute__(item)
+
     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 = dict(self._init_handlers(instance), **self._init_handlers(template))
+
+    @staticmethod
+    def _init_handlers(module_):
+        handlers = {}
+        for attribute_name in dir(module_):
+            if attribute_name.startswith('_'):
+                continue
+            attribute = getattr(module_, attribute_name)
+            if isinstance(attribute, type) and issubclass(attribute, (common._TemplateHandler,
+                                                                      common._InstanceHandler)):
+                handlers[getattr(models, attribute_name)] = attribute
+        return handlers
 
     def instantiate(self, template, **kwargs):
+        """
+        all handlers used by instantiate should hold a tuple as value (handler, instnace_cls)
+        :param template:
+        :param kwargs:
+        :return:
+        """
         if isinstance(template, dict):
             return dict((name, self.instantiate(value, **kwargs))
                         for name, value in template.iteritems())
@@ -95,7 +102,7 @@ class Handler(object):
             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__]
+            instance_cls = self._init_map.get(template.__class__)
             return handler(self, template).instantiate(instance_cls, **kwargs)
 
     def validate(self, template, **kwargs):
@@ -107,5 +114,23 @@ class Handler(object):
             handler = self._handlers.get(template.__class__)
             return handler(self, template).validate(**kwargs)
 
+    def dump(self, template, context, **kwargs):
+        if not isinstance(context, self.TopologyStylizer):
+            # Wrap the context to contain a stringIO object
+            context = self.TopologyStylizer(context)
+
+        if isinstance(template, dict):
+            return self.dump(template.values(), context, **kwargs)
+        elif isinstance(template, list):
+            context.write('%s:' % template)
+            with context.style.indent:
+                for value in template:
+                    self.dump(value, context, **kwargs)
+        elif template is not None:
+            handler = self._handlers.get(template.__class__)
+            handler(self, template).dump(context, **kwargs)
+
+        return str(context)
+
 
 handler = Handler()

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/5c92ccad/aria/orchestrator/topology/common.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/common.py b/aria/orchestrator/topology/common.py
index fb5cf50..48e3c07 100644
--- a/aria/orchestrator/topology/common.py
+++ b/aria/orchestrator/topology/common.py
@@ -14,14 +14,11 @@
 # limitations under the License.
 
 
-class _TemplateEntity(object):
+class _Handler(object):
     def __init__(self, topology, template):
         self._topology = topology
         self._template = template
 
-    def instantiate(self, **kwargs):
-        pass
-
     def coerce(self):
         raise NotImplementedError
 
@@ -32,10 +29,15 @@ class _TemplateEntity(object):
         for template in templates:
             self._topology.validate(template)
 
-    def dump(self):
+    def dump(self, context):
         raise NotImplementedError
 
 
-class _InstanceEntity(_TemplateEntity):
+class _TemplateHandler(_Handler):
+
     def instantiate(self, **kwargs):
-        pass
+        raise NotImplementedError
+
+
+class _InstanceHandler(_Handler):
+    pass

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/5c92ccad/aria/orchestrator/topology/instance.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/instance.py b/aria/orchestrator/topology/instance.py
index 337c9d5..7fb8c23 100644
--- a/aria/orchestrator/topology/instance.py
+++ b/aria/orchestrator/topology/instance.py
@@ -15,30 +15,58 @@
 
 from . import common
 
+# TODO: this should this be here?
+from aria.utils import formatting
 
-class Artifact(common._InstanceEntity):
+
+class Artifact(common._InstanceHandler):
     def coerce(self):
         pass
 
     def validate(self, **kwargs):
         self._topology.validate(self._template.properties)
 
-    def dump(self):
-        pass
-
-
-class Capability(common._InstanceEntity):
+    def dump(self, context):
+        context.write(context.style.node(self._template.name))
+        if self._template.description:
+            context.write(context.style.meta(self._template.description))
+        with context.style.indent:
+            context.write('Artifact type: {0}'.format(context.style.type(self._template.type.name)))
+            context.write('Source path: {0}'.format(
+                context.style.literal(self._template.source_path)))
+            if self._template.target_path is not None:
+                context.write('Target path: {0}'.format(
+                    context.style.literal(self._template.target_path)))
+            if self._template.repository_url is not None:
+                context.write('Repository URL: {0}'.format(
+                    context.style.literal(self._template.repository_url)))
+            if self._template.repository_credential:
+                context.write('Repository credential: {0}'.format(
+                    context.style.literal(self._template.repository_credential)))
+            self._topology.dump(self._template.properties, context, 'Properties')
+            
+
+class Capability(common._InstanceHandler):
     def coerce(self):
         pass
 
     def validate(self, **kwargs):
         self._topology.validate(self._template.properties)
 
-    def dump(self):
-        pass
+    def dump(self, context):
+        context.write(context.style.node(self._template.name))
+        with context.style.indent:
+            context.write('Type: {0}'.format(context.style.type(self._template.type.name)))
+            context.write('Occurrences: {0:d} ({1:d}{2})'.format(
+                self._template.occurrences,
+                self._template.min_occurrences or 0,
+                ' to {0:d}'.format(self._template.max_occurrences)
+                if self._template.max_occurrences is not None
+                else ' or more'))
+            self._topology.dump(self._template.properties, context, 'Properties')
 
 
-class Group(common._InstanceEntity):
+class Group(common._InstanceHandler):
     def coerce(self):
         pass
 
@@ -46,11 +74,20 @@ class Group(common._InstanceEntity):
         self._validate(self._template.properties,
                        self._template.interfaces)
 
-    def dump(self):
-        pass
+    def dump(self, context):
+        context.write('Group: {0}'.format(context.style.node(self._template.name)))
+        with context.style.indent:
+            context.write('Type: {0}'.format(context.style.type(self._template.type.name)))
+            self._topology.dump(self._template.properties, context, 'Properties')
+            self._topology.dump(self._template.interfaces, context, 'Interfaces')
+            if self._template.nodes:
+                context.write('Member nodes:')
+                with context.style.indent:
+                    for node in self._template.nodes:
+                        context.write(context.style.node(node.name))
 
 
-class Interface(common._InstanceEntity):
+class Interface(common._InstanceHandler):
     def coerce(self):
         pass
 
@@ -58,11 +95,17 @@ class Interface(common._InstanceEntity):
         self._validate(self._template.inputs,
                        self._template.operations)
 
-    def dump(self):
-        pass
+    def dump(self, context):
+        context.write(context.style.node(self._template.name))
+        if self._template.description:
+            context.write(context.style.meta(self._template.description))
+        with context.style.indent:
+            context.write('Interface type: {0}'.format(context.style.type(self._template.type.name)))
+            self._topology.dump(self._template.inputs, context, 'Inputs')
+            self._topology.dump(self._template.operations, context, 'Operations')
 
 
-class Node(common._InstanceEntity):
+class Node(common._InstanceHandler):
     def coerce(self):
         pass
 
@@ -85,11 +128,20 @@ class Node(common._InstanceEntity):
                        self._template.capabilities,
                        self._template.outbound_relationships)
 
-    def dump(self):
-        pass
+    def dump(self, context):
+        context.write('Node: {0}'.format(context.style.node(self._template.name)))
+        with context.style.indent:
+            context.write('Type: {0}'.format(context.style.type(self._template.type.name)))
+            context.write('Template: {0}'.format(context.style.node(self._template.node_template.name)))
+            self._topology.dump(self._template.properties, context, 'Properties')
+            self._topology.dump(self._template.attributes, context, 'Attributes')
+            self._topology.dump(self._template.interfaces, context, 'Interfaces')
+            self._topology.dump(self._template.artifacts, context, 'Artifacts')
+            self._topology.dump(self._template.capabilities, context, 'Capabilities')
+            self._topology.dump(self._template.outbound_relationships, context, 'Relationships')
 
 
-class Operation(common._InstanceEntity):
+class Operation(common._InstanceHandler):
     def coerce(self):
         pass
 
@@ -98,22 +150,60 @@ class Operation(common._InstanceEntity):
                        self._template.configurations,
                        self._template.arguments)
 
-    def dump(self):
-        pass
-
-
-class Policy(common._InstanceEntity):
+    def dump(self, context):
+        context.write(context.style.node(self._template.name))
+        if self._template.description:
+            context.write(context.style.meta(self._template.description))
+        with context.style.indent:
+            if self._template.implementation is not None:
+                context.write('Implementation: {0}'.format(
+                    context.style.literal(self._template.implementation)))
+            if self._template.dependencies:
+                context.write(
+                    'Dependencies: {0}'.format(
+                        ', '.join((str(context.style.literal(v)) for v in self._template.dependencies))))
+            self._topology.dump(self._template.inputs, context, 'Inputs')
+            if self._template.executor is not None:
+                context.write('Executor: {0}'.format(context.style.literal(self._template.executor)))
+            if self._template.max_attempts is not None:
+                context.write('Max attempts: {0}'.format(context.style.literal(self._template.max_attempts)))
+            if self._template.retry_interval is not None:
+                context.write('Retry interval: {0}'.format(
+                    context.style.literal(self._template.retry_interval)))
+            if self._template.plugin is not None:
+                context.write('Plugin: {0}'.format(
+                    context.style.literal(self._template.plugin.name)))
+            self._topology.dump(self._template.configurations, context, 'Configuration')
+            if self._template.function is not None:
+                context.write('Function: {0}'.format(context.style.literal(self._template.function)))
+            self._topology.dump(self._template.arguments, context, 'Arguments')
+
+
+class Policy(common._InstanceHandler):
     def coerce(self):
         pass
 
     def validate(self, **kwargs):
         self._topology.validate(self._template.properties)
 
-    def dump(self):
-        pass
-
-
-class Relationship(common._InstanceEntity):
+    def dump(self, context):
+        context.write('Policy: {0}'.format(context.style.node(self._template.name)))
+        with context.style.indent:
+            context.write('Type: {0}'.format(context.style.type(self._template.type.name)))
+            self._topology.dump(self._template.properties, context, 'Properties')
+            if self._template.nodes:
+                context.write('Target nodes:')
+                with context.style.indent:
+                    for node in self._template.nodes:
+                        context.write(context.style.node(node.name))
+            if self._template.groups:
+                context.write('Target groups:')
+                with context.style.indent:
+                    for group in self._template.groups:
+                        context.write(context.style.node(group.name))
+
+
+class Relationship(common._InstanceHandler):
     def coerce(self):
         pass
 
@@ -121,11 +211,28 @@ class Relationship(common._InstanceEntity):
         self._validate(self._template.properties,
                        self._template.interfaces)
 
-    def dump(self):
-        pass
-
-
-class Service(common._InstanceEntity):
+    def dump(self, context):
+        if self._template.name:
+            context.write('{0} ->'.format(context.style.node(self._template.name)))
+        else:
+            context.write('->')
+        with context.style.indent:
+            context.write('Node: {0}'.format(context.style.node(self._template.target_node.name)))
+            if self._template.target_capability:
+                context.write('Capability: {0}'.format(context.style.node(
+                    self._template.target_capability.name)))
+            if self._template.type is not None:
+                context.write('Relationship type: {0}'.format(
+                    context.style.type(self._template.type.name)))
+            if (self._template.relationship_template is not None and
+                self._template.relationship_template.name):
+                context.write('Relationship template: {0}'.format(
+                    context.style.node(self._template.relationship_template.name)))
+            self._topology.dump(self._template.properties, context, 'Properties')
+            self._topology.dump(self._template.interfaces, context, 'Interfaces')
+
+
+class Service(common._InstanceHandler):
     def coerce(self):
         pass
 
@@ -134,27 +241,43 @@ class Service(common._InstanceEntity):
                        self._template.nodes,
                        self._template.groups,
                        self._template.policies,
-                       self._template.substituion,
+                       self._template.substitution,
                        self._template.inputs,
                        self._template.outputs,
                        self._template.workflows)
 
-    def dump(self):
-        pass
-
-
-class Substitution(common._InstanceEntity):
+    def dump(self, context):
+        if self._template.description is not None:
+            context.write(context.style.meta(self._template.description))
+        self._topology.dump(self._template.meta_data, context, 'Metadata')
+        for node in self._template.nodes.itervalues():
+            node.dump()
+        for group in self._template.groups.itervalues():
+            group.dump()
+        for policy in self._template.policies.itervalues():
+            policy.dump()
+        if self._template.substitution is not None:
+            self._template.substitution.dump()
+        self._topology.dump(self._template.inputs, context, 'Inputs')
+        self._topology.dump(self._template.outputs, context, 'Outputs')
+        self._topology.dump(self._template.workflows, context, 'Workflows')
+
+
+class Substitution(common._InstanceHandler):
     def coerce(self):
         pass
 
     def validate(self, **kwargs):
         self._topology.validate(self._template.mappings)
 
-    def dump(self):
-        pass
+    def dump(self, context):
+        context.write('Substitution:')
+        with context.style.indent:
+            context.write('Node type: {0}'.format(context.style.type(self._template.node_type.name)))
+            self._topology.dump(self._template.mappings, context, 'Mappings')
 
 
-class SubstitutionMapping(common._InstanceEntity):
+class SubstitutionMapping(common._InstanceHandler):
     def coerce(self):
         pass
 
@@ -169,14 +292,24 @@ class SubstitutionMapping(common._InstanceEntity):
             #                               formatting.safe_repr(self.node.name)),
             #                           level=validation.Issue.BETWEEN_TYPES)
 
-    def dump(self):
-        pass
-
-
-class Metadata(common._InstanceEntity):
-
-    def dump(self):
-        pass
+    def dump(self, context):
+        if self._template.capability is not None:
+            context.write('{0} -> {1}.{2}'.format(
+                context.style.node(self._template.name),
+                context.style.node(self._template.capability.node.name),
+                context.style.node(self._template.capability.name)))
+        else:
+            context.write('{0} -> {1}.{2}'.format(
+                context.style.node(self._template.name),
+                context.style.node(self._template.node.name),
+                context.style.node(self._template.requirement_template.name)))
+
+class Metadata(common._InstanceHandler):
+
+    def dump(self, context):
+        context.write('{0}: {1}'.format(
+            context.style.property(self._topology.name),
+            context.style.literal(self._topology.value)))
 
     def coerce(self):
         pass
@@ -188,10 +321,20 @@ class Metadata(common._InstanceEntity):
         pass
 
 
-class Parameter(common._InstanceEntity):
+class _Parameter(common._InstanceHandler):
 
-    def dump(self):
-        pass
+    def dump(self, context):
+        if self._template.type_name is not None:
+            context.write('{0}: {1} ({2})'.format(
+                context.style.property(self._template.name),
+                context.style.literal(formatting.as_raw(self._template.value)),
+                context.style.type(self._template.type_name)))
+        else:
+            context.write('{0}: {1}'.format(
+                context.style.property(self._template.name),
+                context.style.literal(formatting.as_raw(self._template.value))))
+        if self._template.description:
+            context.write(context.style.meta(self._template.description))
 
     def coerce(self):
         pass
@@ -206,3 +349,39 @@ class Parameter(common._InstanceEntity):
 
     def validate(self):
         pass
+
+
+class Attribute(_Parameter):
+    pass
+
+
+class Input(_Parameter):
+    pass
+
+
+class Output(_Parameter):
+    pass
+
+
+class Argument(_Parameter):
+    pass
+
+
+class Property(_Parameter):
+    pass
+
+
+class Configuration(_Parameter):
+    pass
+
+
+class Type(common._InstanceHandler):
+    def coerce(self):
+        pass
+
+    def dump(self, context):
+        if self._template.name:
+            context.write(context.style.type(self._template.name))
+        with context.style.indent:
+            for child in self._template.children:
+                self._topology.dump(context, child)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/5c92ccad/aria/orchestrator/topology/template.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/template.py b/aria/orchestrator/topology/template.py
index 12fc23e..5826a20 100644
--- a/aria/orchestrator/topology/template.py
+++ b/aria/orchestrator/topology/template.py
@@ -15,14 +15,26 @@
 
 from datetime import datetime
 
-
 from ...modeling import utils as modeling_utils
 from . import utils, common
 
 
-class ServiceTemplate(common._TemplateEntity):
-    def dump(self):
-        pass
+class ServiceTemplate(common._TemplateHandler):
+    def dump(self, context):
+        if self._template.description is not None:
+            context.write(context.style.meta(self._template.description))
+        self._topology.dump(self._template.meta_data, context, 'Metadata')
+        for node_template in self._template.node_templates.itervalues():
+            node_template.dump()
+        for group_template in self._template.group_templates.itervalues():
+            group_template.dump()
+        for policy_template in self._template.policy_templates.itervalues():
+            policy_template.dump()
+        if self._template.substitution_template is not None:
+            self._template.substitution_template.dump()
+        self._topology.dump(self._template.inputs, context, 'Inputs')
+        self._topology.dump(self._template.outputs, context, 'Outputs')
+        self._topology.dump(self._template.workflow_templates, context, 'Workflow templates')
 
     def coerce(self):
         pass
@@ -83,9 +95,23 @@ class ServiceTemplate(common._TemplateEntity):
         self._topology.validate(self._template.artifact_types)
 
 
-class ArtifactTemplate(common._TemplateEntity):
-    def dump(self):
-        pass
+class ArtifactTemplate(common._TemplateHandler):
+    def dump(self, context):
+        context.write(context.style.node(self._template.name))
+        if self._template.description:
+            context.write(context.style.meta(self._template.description))
+        with context.style.indent:
+            context.write('Artifact type: {0}'.format(context.style.type(self._template.type.name)))
+            context.write('Source path: {0}'.format(context.style.literal(self._template.source_path)))
+            if self._template.target_path is not None:
+                context.write('Target path: {0}'.format(context.style.literal(self._template.target_path)))
+            if self._template.repository_url is not None:
+                context.write('Repository URL: {0}'.format(
+                    context.style.literal(self._template.repository_url)))
+            if self._template.repository_credential:
+                context.write('Repository credential: {0}'.format(
+                    context.style.literal(self._template.repository_credential)))
+            self._topology.dump(self._template.properties, context, 'Properties')
 
     def coerce(self):
         pass
@@ -105,9 +131,25 @@ class ArtifactTemplate(common._TemplateEntity):
         self._topology.validate(self._template.properties)
 
 
-class CapabilityTemplate(common._TemplateEntity):
-    def dump(self):
-        pass
+class CapabilityTemplate(common._TemplateHandler):
+    def dump(self, context):
+        context.write(context.style.node(self._template.name))
+        if self._template.description:
+            context.write(context.style.meta(self._template.description))
+        with context.style.indent:
+            context.write('Type: {0}'.format(context.style.type(self._template.type.name)))
+            context.write(
+                'Occurrences: {0:d}{1}'.format(
+                    self._template.min_occurrences or 0,
+                    ' to {0:d}'.format(self._template.max_occurrences)
+                    if self._template.max_occurrences is not None
+                    else ' or more'))
+            if self._template.valid_source_node_types:
+                context.write('Valid source node types: {0}'.format(
+                    ', '.join((str(context.style.type(v.name))
+                               for v in self._template.valid_source_node_types))))
+            self._topology.dump(self._template.properties, contet, 'Properties')
+
 
     def coerce(self):
         pass
@@ -124,9 +166,34 @@ class CapabilityTemplate(common._TemplateEntity):
         self._topology.validate(self._template.properties)
 
 
-class RequirementTemplate(common._TemplateEntity):
-    def dump(self):
-        pass
+class RequirementTemplate(common._TemplateHandler):
+    def dump(self, context):
+        if self._template.name:
+            context.write(context.style.node(self._template.name))
+        else:
+            context.write('Requirement:')
+        with context.style.indent:
+            if self._template.target_node_type is not None:
+                context.write('Target node type: {0}'.format(
+                    context.style.type(self._template.target_node_type.name)))
+            elif self._template.target_node_template is not None:
+                context.write('Target node template: {0}'.format(
+                    context.style.node(self._template.target_node_template.name)))
+            if self._template.target_capability_type is not None:
+                context.write('Target capability type: {0}'.format(
+                    context.style.type(self._template.target_capability_type.name)))
+            elif self._template.target_capability_name is not None:
+                context.write('Target capability name: {0}'.format(
+                    context.style.node(self._template.target_capability_name)))
+            if self._template.target_node_template_constraints:
+                context.write('Target node template constraints:')
+                with context.style.indent:
+                    for constraint in self._template.target_node_template_constraints:
+                        context.write(context.style.literal(constraint))
+            if self._template.relationship_template:
+                context.write('Relationship:')
+                with context.style.indent:
+                    self._template.relationship_template.dump()
 
     def coerce(self):
         pass
@@ -143,9 +210,18 @@ class RequirementTemplate(common._TemplateEntity):
         self._topology.validate(self._template.relationship_template)
 
 
-class GroupTemplate(common._TemplateEntity):
-    def dump(self):
-        pass
+class GroupTemplate(common._TemplateHandler):
+    def dump(self, context):
+        context.write('Group template: {0}'.format(context.style.node(self._template.name)))
+        if self._template.description:
+            context.write(context.style.meta(self._template.description))
+        with context.style.indent:
+            context.write('Type: {0}'.format(context.style.type(self._template.type.name)))
+            self._topology.dump(self._template.properties, context, 'Properties')
+            self._topology.dump(self._template.interface_templates, context, 'Interface Templates')
+            if self._template.node_templates:
+                context.write('Member node templates: {0}'.format(', '.join(
+                    (str(context.style.node(v.name)) for v in self._template.node_templates))))
 
     def coerce(self):
         pass
@@ -168,9 +244,15 @@ class GroupTemplate(common._TemplateEntity):
                        self._template.interface_templates)
 
 
-class InterfaceTemplate(common._TemplateEntity):
-    def dump(self):
-        pass
+class InterfaceTemplate(common._TemplateHandler):
+    def dump(self, context):
+        context.write(context.style.node(self._template.name))
+        if self._template.description:
+            context.write(context.style.meta(self._template.description))
+        with context.style.indent:
+            context.write('Interface type: {0}'.format(context.style.type(self._template.type.name)))
+            self._topology.dump(self._template.inputs, context, 'Inputs')
+            self._topology.dump(self._template.operation_templates, context, 'Operation templates')
 
     def coerce(self):
         pass
@@ -190,9 +272,19 @@ class InterfaceTemplate(common._TemplateEntity):
                        self._template.operation_templates)
 
 
-class NodeTemplate(common._TemplateEntity):
-    def dump(self):
-        pass
+class NodeTemplate(common._TemplateHandler):
+    def dump(self, context):
+        context.write('Node template: {0}'.format(context.style.node(self._template.name)))
+        if self._template.description:
+            context.write(context.style.meta(self._template.description))
+        with context.style.indent:
+            context.write('Type: {0}'.format(context.style.type(self._template.type.name)))
+            self._topology.dump(self._template.properties, context, 'Properties')
+            self._topology.dump(self._template.attributes, context, 'Attributes')
+            self._topology.dump(self._template.interface_templates, context, 'Interface Templates')
+            self._topology.dump(self._template.artifact_templates, context, 'Artifact templates')
+            self._topology.dump(self._template.capability_templates, context, 'Capability templates')
+            self._topology.dump(self._template.requirement_templates, context, 'Requirement templates')
 
     def coerce(self):
         pass
@@ -230,10 +322,20 @@ class NodeTemplate(common._TemplateEntity):
                        self._template.requirement_templates)
 
 
-class PolicyTemplate(common._TemplateEntity):
-    def dump(self):
-        pass
-
+class PolicyTemplate(common._TemplateHandler):
+    def dump(self, context):
+        context.write('Policy template: {0}'.format(context.style.node(self._template.name)))
+        if self._template.description:
+            context.write(context.style.meta(self._template.description))
+        with context.style.indent:
+            context.write('Type: {0}'.format(context.style.type(self._template.type.name)))
+            self._topology.dump(self._template.properties, context, 'Properties')
+            if self._template.node_templates:
+                context.write('Target node templates: {0}'.format(', '.join(
+                    (str(context.style.node(v.name)) for v in self._template.node_templates))))
+            if self._template.group_templates:
+                context.write('Target group templates: {0}'.format(', '.join(
+                    (str(context.style.node(v.name)) for v in self._template.group_templates))))
     def coerce(self):
         pass
 
@@ -257,10 +359,13 @@ class PolicyTemplate(common._TemplateEntity):
         self._topology.validate(self._template.properties)
 
 
-class SubstitutionTemplate(common._TemplateEntity):
+class SubstitutionTemplate(common._TemplateHandler):
 
-    def dump(self):
-        pass
+    def dump(self, context):
+        context.write('Substitution template:')
+        with context.style.indent:
+            context.write('Node type: {0}'.format(context.style.type(self._template.node_type.name)))
+            self._topology.dump(self._template.mappings, context, 'Mappings')
 
     def coerce(self):
         pass
@@ -273,10 +378,19 @@ class SubstitutionTemplate(common._TemplateEntity):
         self._topology.validate(self._template.mappings)
 
 
-class SubstitutionMapping(common._TemplateEntity):
+class SubstitutionTemplateMapping(common._TemplateHandler):
 
-    def dump(self):
-        pass
+    def dump(self, context):
+        if self._topology.capability_template is not None:
+            node_template = self._topology.capability_template.node_template
+        else:
+            node_template = self._topology.requirement_template.node_template
+        context.write('{0} -> {1}.{2}'.format(
+            context.style.node(self._topology.name),
+            context.style.node(node_template.name),
+            context.style.node(self._topology.capability_template.name
+                               if self._topology.capability_template
+                               else self._topology.requirement_template.name)))
 
     def coerce(self):
         pass
@@ -325,9 +439,18 @@ class SubstitutionMapping(common._TemplateEntity):
             #                           level=validation.Issue.BETWEEN_TYPES)
 
 
-class RelationshipTemplate(common._TemplateEntity):
-    def dump(self):
-        pass
+class RelationshipTemplate(common._TemplateHandler):
+    def dump(self, context):
+        if self._template.type is not None:
+            context.write('Relationship type: {0}'.format(context.style.type(self._template.type.name)))
+        else:
+            context.write('Relationship template: {0}'.format(
+                context.style.node(self._template.name)))
+        if self._template.description:
+            context.write(context.style.meta(self._template.description))
+        with context.style.indent:
+            self._topology.dump(self._template.properties, context, 'Properties')
+            self._topology.dump(self._template.interface_templates, context, 'Interface Templates')
 
     def coerce(self):
         pass
@@ -348,10 +471,33 @@ class RelationshipTemplate(common._TemplateEntity):
                        self._template.interface_templates)
 
 
-class OperationTemplate(common._TemplateEntity):
-
-    def dump(self):
-        pass
+class OperationTemplate(common._TemplateHandler):
+
+    def dump(self, context):
+        context.write(context.style.node(self._template.name))
+        if self._template.description:
+            context.write(context.style.meta(self._template.description))
+        with context.style.indent:
+            if self._template.implementation is not None:
+                context.write('Implementation: {0}'.format(
+                    context.style.literal(self._template.implementation)))
+            if self._template.dependencies:
+                context.write('Dependencies: {0}'.format(
+                    ', '.join((str(context.style.literal(v)) for v in self._template.dependencies))))
+            self._topology.dump(self._template.inputs, context, 'Inputs')
+            if self._template.executor is not None:
+                context.write('Executor: {0}'.format(context.style.literal(self._template.executor)))
+            if self._template.max_attempts is not None:
+                context.write('Max attempts: {0}'.format(context.style.literal(self._template.max_attempts)))
+            if self._template.retry_interval is not None:
+                context.write('Retry interval: {0}'.format(
+                    context.style.literal(self._template.retry_interval)))
+            if self._template.plugin_specification is not None:
+                context.write('Plugin specification: {0}'.format(
+                    context.style.literal(self._template.plugin_specification.name)))
+            self._topology.dump(self._template.configurations, context, 'Configuration')
+            if self._template.function is not None:
+                context.write('Function: {0}'.format(context.style.literal(self._template.function)))
 
     def coerce(self):
         pass



Mime
View raw message