You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ariatosca.apache.org by em...@apache.org on 2017/07/24 20:17:21 UTC

[1/2] incubator-ariatosca git commit: ARIA-277 Support for Type Qualified Name [Forced Update!]

Repository: incubator-ariatosca
Updated Branches:
  refs/heads/ARIA-321-clearwater e1ad58915 -> e8f15b449 (forced update)


ARIA-277 Support for Type Qualified Name


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

Branch: refs/heads/ARIA-321-clearwater
Commit: c2b8e65b41c013bfd4ee14ea47268083f8b20822
Parents: 67a0675
Author: djay87 <d....@ericsson.com>
Authored: Wed Jul 19 12:26:19 2017 +0300
Committer: max-orlov <ma...@gigaspaces.com>
Committed: Wed Jul 19 12:38:12 2017 +0300

----------------------------------------------------------------------
 .../workflows/core/events_handler.py            |   3 +-
 examples/hello-world/helloworld.yaml            |   2 +-
 .../simple_v1_0/assignments.py                  |  15 ++-
 .../simple_v1_0/definitions.py                  |  25 +++--
 .../aria_extension_tosca/simple_v1_0/misc.py    |   8 +-
 .../simple_v1_0/modeling/data_types.py          |   6 +-
 .../simple_v1_0/modeling/policies.py            |   8 +-
 .../presentation/field_validators.py            |  18 +--
 .../simple_v1_0/presentation/types.py           |  14 ++-
 .../simple_v1_0/templates.py                    |  20 ++--
 .../aria_extension_tosca/simple_v1_0/types.py   |  42 ++++---
 tests/parser/service_templates.py               |  13 +++
 tests/parser/test_tosca_simple_v1_0.py          | 112 -------------------
 tests/parser/test_tosca_simple_v1_0/__init__.py |  14 +++
 .../presentation/__init__.py                    |   0
 .../presentation/test_types.py                  |  23 ++++
 .../test_tosca_simple_v1_0/test_end2end.py      | 112 +++++++++++++++++++
 .../types/shorthand-1/shorthand-1.yaml          |  23 ++++
 .../types/typequalified-1/typequalified-1.yaml  |  23 ++++
 19 files changed, 286 insertions(+), 195 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c2b8e65b/aria/orchestrator/workflows/core/events_handler.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/core/events_handler.py b/aria/orchestrator/workflows/core/events_handler.py
index 219d2df..473475e 100644
--- a/aria/orchestrator/workflows/core/events_handler.py
+++ b/aria/orchestrator/workflows/core/events_handler.py
@@ -155,7 +155,8 @@ def _update_node_state_if_necessary(ctx, is_transitional=False):
     # and also will *never* be the type name
     node = ctx.task.node if ctx.task is not None else None
     if (node is not None) and \
-        (ctx.task.interface_name in ('Standard', 'tosca.interfaces.node.lifecycle.Standard')):
+        (ctx.task.interface_name in ('Standard', 'tosca.interfaces.node.lifecycle.Standard',
+                                     'tosca:Standard')):
         state = node.determine_state(op_name=ctx.task.operation_name,
                                      is_transitional=is_transitional)
         if state:

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c2b8e65b/examples/hello-world/helloworld.yaml
----------------------------------------------------------------------
diff --git a/examples/hello-world/helloworld.yaml b/examples/hello-world/helloworld.yaml
index d3369b7..2fdc4d4 100644
--- a/examples/hello-world/helloworld.yaml
+++ b/examples/hello-world/helloworld.yaml
@@ -3,7 +3,7 @@ tosca_definitions_version: tosca_simple_yaml_1_0
 node_types:
 
   WebServer:
-    derived_from: tosca.nodes.Root
+    derived_from: tosca:Root
     capabilities:
       host:
         type: tosca.capabilities.Container

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c2b8e65b/extensions/aria_extension_tosca/simple_v1_0/assignments.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/assignments.py b/extensions/aria_extension_tosca/simple_v1_0/assignments.py
index 2cfc9e5..d507042 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/assignments.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/assignments.py
@@ -29,8 +29,8 @@ from .presentation.field_validators import (node_template_or_type_validator,
                                             relationship_template_or_type_validator,
                                             capability_definition_or_type_validator,
                                             node_filter_validator)
-from .presentation.types import (convert_shorthand_to_full_type_name,
-                                 get_type_by_full_or_shorthand_name)
+from .presentation.types import (convert_name_to_full_type_name, get_type_by_name)
+
 
 
 @implements_specification('3.5.9', 'tosca-simple-1.0')
@@ -201,7 +201,7 @@ class RelationshipAssignment(ExtensiblePresentation):
                                                           'relationship_templates', type_name)
             if the_type is not None:
                 return the_type, 'relationship_template'
-            the_type = get_type_by_full_or_shorthand_name(context, type_name, 'relationship_types')
+            the_type = get_type_by_name(context, type_name, 'relationship_types')
             if the_type is not None:
                 return the_type, 'relationship_type'
         return None, None
@@ -283,7 +283,7 @@ class RequirementAssignment(ExtensiblePresentation):
                                                                'node_templates', node)
             if node_template is not None:
                 return node_template, 'node_template'
-            node_type = get_type_by_full_or_shorthand_name(context, node, 'node_types')
+            node_type = get_type_by_name(context, node, 'node_types')
             if node_type is not None:
                 return node_type, 'node_type'
 
@@ -299,8 +299,7 @@ class RequirementAssignment(ExtensiblePresentation):
                 capabilities = node._get_capabilities(context)
                 if capability in capabilities:
                     return capabilities[capability], 'capability_assignment'
-            capability_type = get_type_by_full_or_shorthand_name(context, capability,
-                                                                 'capability_types')
+            capability_type = get_type_by_name(context, capability, 'capability_types')
             if capability_type is not None:
                 return capability_type, 'capability_type'
 
@@ -375,7 +374,7 @@ class ArtifactAssignment(ExtensiblePresentation):
     #DEFN_ENTITY_ARTIFACT_DEF>`__
     """
 
-    @field_validator(type_validator('artifact type', convert_shorthand_to_full_type_name,
+    @field_validator(type_validator('artifact type', convert_name_to_full_type_name,
                                     'artifact_types'))
     @primitive_field(str, required=True)
     def type(self):
@@ -431,7 +430,7 @@ class ArtifactAssignment(ExtensiblePresentation):
 
     @cachedmethod
     def _get_type(self, context):
-        return get_type_by_full_or_shorthand_name(context, self.type, 'artifact_types')
+        return get_type_by_name(context, self.type, 'artifact_types')
 
     @cachedmethod
     def _get_repository(self, context):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c2b8e65b/extensions/aria_extension_tosca/simple_v1_0/definitions.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/definitions.py b/extensions/aria_extension_tosca/simple_v1_0/definitions.py
index eaa1ac9..9158776 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/definitions.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/definitions.py
@@ -28,8 +28,7 @@ from .presentation.extensible import ExtensiblePresentation
 from .presentation.field_getters import data_type_class_getter
 from .presentation.field_validators import (data_type_validator, data_value_validator,
                                             entry_schema_validator)
-from .presentation.types import (convert_shorthand_to_full_type_name,
-                                 get_type_by_full_or_shorthand_name)
+from .presentation.types import (convert_name_to_full_type_name, get_type_by_name)
 from .modeling.data_types import get_data_type, get_property_constraints
 from .modeling.interfaces import (get_and_override_input_definitions_from_type,
                                   get_and_override_operation_definitions_from_type)
@@ -282,7 +281,7 @@ class InterfaceDefinition(ExtensiblePresentation):
     #DEFN_ELEMENT_INTERFACE_DEF>`__
     """
 
-    @field_validator(type_validator('interface type', convert_shorthand_to_full_type_name,
+    @field_validator(type_validator('interface type', convert_name_to_full_type_name,
                                     'interface_types'))
     @primitive_field(str)
     def type(self):
@@ -311,7 +310,7 @@ class InterfaceDefinition(ExtensiblePresentation):
 
     @cachedmethod
     def _get_type(self, context):
-        return get_type_by_full_or_shorthand_name(context, self.type, 'interface_types')
+        return get_type_by_name(context, self.type, 'interface_types')
 
     @cachedmethod
     def _get_inputs(self, context):
@@ -335,7 +334,7 @@ class RelationshipDefinition(ExtensiblePresentation):
     Relationship definition.
     """
 
-    @field_validator(type_validator('relationship type', convert_shorthand_to_full_type_name,
+    @field_validator(type_validator('relationship type', convert_name_to_full_type_name,
                                     'relationship_types'))
     @primitive_field(str, required=True)
     def type(self):
@@ -358,7 +357,8 @@ class RelationshipDefinition(ExtensiblePresentation):
 
     @cachedmethod
     def _get_type(self, context):
-        return get_type_by_full_or_shorthand_name(context, self.type, 'relationship_types')
+        return get_type_by_name(context, self.type, 'relationship_types')
+
 
 
 @short_form_field('capability')
@@ -378,7 +378,7 @@ class RequirementDefinition(ExtensiblePresentation):
     #DEFN_ELEMENT_REQUIREMENT_DEF>`__
     """
 
-    @field_validator(type_validator('capability type', convert_shorthand_to_full_type_name,
+    @field_validator(type_validator('capability type', convert_name_to_full_type_name,
                                     'capability_types'))
     @primitive_field(str, required=True)
     def capability(self):
@@ -389,7 +389,8 @@ class RequirementDefinition(ExtensiblePresentation):
         :type: :obj:`basestring`
         """
 
-    @field_validator(type_validator('node type', convert_shorthand_to_full_type_name, 'node_types'))
+    @field_validator(type_validator('node type', convert_name_to_full_type_name,
+                                    'node_types'))
     @primitive_field(str)
     def node(self):
         """
@@ -421,7 +422,7 @@ class RequirementDefinition(ExtensiblePresentation):
 
     @cachedmethod
     def _get_capability_type(self, context):
-        return get_type_by_full_or_shorthand_name(context, self.capability, 'capability_types')
+        return get_type_by_name(context, self.capability, 'capability_types')
 
     @cachedmethod
     def _get_node_type(self, context):
@@ -442,7 +443,7 @@ class CapabilityDefinition(ExtensiblePresentation):
     #DEFN_ELEMENT_CAPABILITY_DEFN>`__
     """
 
-    @field_validator(type_validator('capability type', convert_shorthand_to_full_type_name,
+    @field_validator(type_validator('capability type', convert_name_to_full_type_name,
                                     'capability_types'))
     @primitive_field(str, required=True)
     def type(self):
@@ -476,7 +477,7 @@ class CapabilityDefinition(ExtensiblePresentation):
         :type: {:obj:`basestring`: :class:`AttributeDefinition`}
         """
 
-    @field_validator(list_type_validator('node type', convert_shorthand_to_full_type_name,
+    @field_validator(list_type_validator('node type', convert_name_to_full_type_name,
                                          'node_types'))
     @primitive_list_field(str)
     def valid_source_types(self):
@@ -506,7 +507,7 @@ class CapabilityDefinition(ExtensiblePresentation):
 
     @cachedmethod
     def _get_type(self, context):
-        return get_type_by_full_or_shorthand_name(context, self.type, 'capability_types')
+        return get_type_by_name(context, self.type, 'capability_types')
 
     @cachedmethod
     def _get_parent(self, context):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c2b8e65b/extensions/aria_extension_tosca/simple_v1_0/misc.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/misc.py b/extensions/aria_extension_tosca/simple_v1_0/misc.py
index fb86157..23beb3c 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/misc.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/misc.py
@@ -33,8 +33,8 @@ from .presentation.field_validators import (constraint_clause_field_validator,
                                             constraint_clause_valid_values_validator,
                                             constraint_clause_pattern_validator,
                                             data_type_validator)
-from .presentation.types import (convert_shorthand_to_full_type_name,
-                                 get_type_by_full_or_shorthand_name)
+from .presentation.types import (convert_name_to_full_type_name, get_type_by_name)
+
 
 
 @implements_specification('3.5.1', 'tosca-simple-1.0')
@@ -410,7 +410,7 @@ class SubstitutionMappings(ExtensiblePresentation):
     Substitution mappings.
     """
 
-    @field_validator(type_validator('node type', convert_shorthand_to_full_type_name, 'node_types'))
+    @field_validator(type_validator('node type', convert_name_to_full_type_name, 'node_types'))
     @primitive_field(str, required=True)
     def node_type(self):
         """
@@ -431,7 +431,7 @@ class SubstitutionMappings(ExtensiblePresentation):
 
     @cachedmethod
     def _get_type(self, context):
-        return get_type_by_full_or_shorthand_name(context, self.node_type, 'node_types')
+        return get_type_by_name(context, self.node_type, 'node_types')
 
     def _validate(self, context):
         super(SubstitutionMappings, self)._validate(context)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c2b8e65b/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
index ba94c70..fbb8280 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
@@ -24,7 +24,7 @@ from aria.parser.presentation import (get_locator, validate_primitive)
 from aria.parser.validation import Issue
 
 from .functions import get_function
-from ..presentation.types import get_type_by_full_or_shorthand_name
+from ..presentation.types import get_type_by_name
 
 
 #
@@ -169,7 +169,7 @@ def get_data_type(context, presentation, field_name, allow_none=False):
         return None
 
     # Try complex data type
-    data_type = get_type_by_full_or_shorthand_name(context, type_name, 'data_types')
+    data_type = get_type_by_name(context, type_name, 'data_types')
     if data_type is not None:
         return data_type
 
@@ -322,7 +322,7 @@ def apply_constraint_to_value(context, presentation, constraint_clause, value):
 #
 
 def get_data_type_value(context, presentation, field_name, type_name):
-    the_type = get_type_by_full_or_shorthand_name(context, type_name, 'data_types')
+    the_type = get_type_by_name(context, type_name, 'data_types')
     if the_type is not None:
         value = getattr(presentation, field_name)
         if value is not None:

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c2b8e65b/extensions/aria_extension_tosca/simple_v1_0/modeling/policies.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/policies.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/policies.py
index 7dd803b..0376798 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/policies.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/policies.py
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from ..presentation.types import convert_shorthand_to_full_type_name
+from ..presentation.types import convert_name_to_full_type_name
 
 
 #
@@ -40,12 +40,10 @@ def get_inherited_targets(context, presentation):
 
         for our_target in our_targets:
             if our_target in all_node_types:
-                our_target = convert_shorthand_to_full_type_name(context, our_target,
-                                                                 all_node_types)
+                our_target = convert_name_to_full_type_name(context, our_target, all_node_types)
                 node_types.append(all_node_types[our_target])
             elif our_target in all_group_types:
-                our_target = convert_shorthand_to_full_type_name(context, our_target,
-                                                                 all_group_types)
+                our_target = convert_name_to_full_type_name(context, our_target, all_group_types)
                 group_types.append(all_group_types[our_target])
 
     return node_types, group_types

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c2b8e65b/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py b/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py
index fc9a9bc..e5853d8 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py
@@ -22,7 +22,8 @@ from aria.parser.validation import Issue
 
 from ..modeling.data_types import (get_primitive_data_type, get_data_type_name, coerce_value,
                                    get_container_data_type)
-from .types import get_type_by_full_or_shorthand_name, convert_shorthand_to_full_type_name
+from .types import (get_type_by_name, convert_name_to_full_type_name)
+
 
 
 #
@@ -88,7 +89,7 @@ def data_type_validator(type_name='data type'):
                     locator=presentation._get_child_locator('type'), level=Issue.BETWEEN_TYPES)
 
             # Can be a complex data type
-            if get_type_by_full_or_shorthand_name(context, value, 'data_types') is not None:
+            if get_type_by_name(context, value, 'data_types') is not None:
                 return True
 
             # Can be a primitive data type
@@ -170,7 +171,7 @@ def data_value_validator(field, presentation, context):
 #
 
 _data_type_validator = data_type_validator()
-_data_type_derived_from_validator = derived_from_validator(convert_shorthand_to_full_type_name,
+_data_type_derived_from_validator = derived_from_validator(convert_name_to_full_type_name,
                                                            'data_types')
 
 
@@ -349,7 +350,7 @@ def node_template_or_type_validator(field, presentation, context):
             context.presentation.get('service_template', 'topology_template', 'node_templates') \
             or {}
         if (value not in node_templates) and \
-            (get_type_by_full_or_shorthand_name(context, value, 'node_types') is None):
+            (get_type_by_name(context, value, 'node_types') is None):
             report_issue_for_unknown_type(context, presentation, 'node template or node type',
                                           field.name)
 
@@ -375,7 +376,7 @@ def capability_definition_or_type_validator(field, presentation, context):
             if value in capabilities:
                 return
 
-        if get_type_by_full_or_shorthand_name(context, value, 'capability_types') is not None:
+        if get_type_by_name(context, value, 'capability_types') is not None:
             if node is not None:
                 context.validation.report(
                     '"%s" refers to a capability type even though "node" has a value in "%s"'
@@ -438,7 +439,7 @@ def relationship_template_or_type_validator(field, presentation, context):
                                      'relationship_templates') \
             or {}
         if (value not in relationship_templates) and \
-            (get_type_by_full_or_shorthand_name(context, value, 'relationship_types') is None):
+            (get_type_by_name(context, value, 'relationship_types') is None):
             report_issue_for_unknown_type(context, presentation,
                                           'relationship template or relationship type', field.name)
 
@@ -460,9 +461,8 @@ def list_node_type_or_group_type_validator(field, presentation, context):
     values = getattr(presentation, field.name)
     if values is not None:
         for value in values:
-            if \
-                (get_type_by_full_or_shorthand_name(context, value, 'node_types') is None) and \
-                (get_type_by_full_or_shorthand_name(context, value, 'group_types') is None):
+            if (get_type_by_name(context, value, 'node_types') is None) and \
+                    (get_type_by_name(context, value, 'group_types') is None):
                 report_issue_for_unknown_type(context, presentation, 'node type or group type',
                                               field.name, value)
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c2b8e65b/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py b/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
index 2f30e0f..920ebed 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
@@ -14,9 +14,9 @@
 # limitations under the License.
 
 
-def convert_shorthand_to_full_type_name(context, name, types_dict): # pylint: disable=unused-argument
+def convert_name_to_full_type_name(context, name, types_dict): # pylint: disable=unused-argument
     """
-    Converts a shorthand type name to its full type name, or else returns it unchanged.
+    Converts a type name to its full type name, or else returns it unchanged.
 
     Works by checking for ``shorthand_name`` in the types' ``_extensions`` field. See also
     :class:`aria_extension_tosca.v1_0.presentation.extensible.ExtensiblePresentation`.
@@ -28,14 +28,15 @@ def convert_shorthand_to_full_type_name(context, name, types_dict): # pylint: di
     if (name is not None) and types_dict and (name not in types_dict):
         for full_name, the_type in types_dict.iteritems():
             if hasattr(the_type, '_extensions') and the_type._extensions \
-                and (the_type._extensions.get('shorthand_name') == name):
+                and ((the_type._extensions.get('shorthand_name') == name) \
+                     or (the_type._extensions.get('type_qualified_name') == name)):
                 return full_name
     return name
 
 
-def get_type_by_full_or_shorthand_name(context, name, *types_dict_names):
+def get_type_by_name(context, name, *types_dict_names):
     """
-    Gets a type either by its full name or its shorthand name.
+    Gets a type either by its full name or its shorthand name or typequalified name.
 
     Works by checking for ``shorthand_name`` in the types' ``_extensions`` field. See also
     :class:`~aria_extension_tosca.v1_0.presentation.extensible.ExtensiblePresentation`.
@@ -53,7 +54,8 @@ def get_type_by_full_or_shorthand_name(context, name, *types_dict_names):
                 return the_type
             for the_type in types_dict.itervalues():
                 if hasattr(the_type, '_extensions') and the_type._extensions \
-                    and (the_type._extensions.get('shorthand_name') == name):
+                    and ((the_type._extensions.get('shorthand_name') == name) \
+                         or (the_type._extensions.get('type_qualified_name') == name)):
                     # Shorthand name
                     return the_type
     return None

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c2b8e65b/extensions/aria_extension_tosca/simple_v1_0/templates.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/templates.py b/extensions/aria_extension_tosca/simple_v1_0/templates.py
index 9a44ea6..3c36bb8 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/templates.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/templates.py
@@ -35,8 +35,7 @@ from .modeling.policies import get_policy_targets
 from .modeling.copy import get_default_raw_from_copy
 from .presentation.extensible import ExtensiblePresentation
 from .presentation.field_validators import copy_validator, policy_targets_validator
-from .presentation.types import (convert_shorthand_to_full_type_name,
-                                 get_type_by_full_or_shorthand_name)
+from .presentation.types import (convert_name_to_full_type_name, get_type_by_name)
 from .types import (ArtifactType, DataType, CapabilityType, InterfaceType, RelationshipType,
                     NodeType, GroupType, PolicyType)
 
@@ -55,7 +54,7 @@ class NodeTemplate(ExtensiblePresentation):
     #DEFN_ENTITY_NODE_TEMPLATE>`__
     """
 
-    @field_validator(type_validator('node type', convert_shorthand_to_full_type_name, 'node_types'))
+    @field_validator(type_validator('node type', convert_name_to_full_type_name, 'node_types'))
     @primitive_field(str, required=True)
     def type(self):
         """
@@ -154,7 +153,7 @@ class NodeTemplate(ExtensiblePresentation):
 
     @cachedmethod
     def _get_type(self, context):
-        return get_type_by_full_or_shorthand_name(context, self.type, 'node_types')
+        return get_type_by_name(context, self.type, 'node_types')
 
     @cachedmethod
     def _get_property_values(self, context):
@@ -218,7 +217,7 @@ class RelationshipTemplate(ExtensiblePresentation):
     #DEFN_ENTITY_RELATIONSHIP_TEMPLATE>`__
     """
 
-    @field_validator(type_validator('relationship type', convert_shorthand_to_full_type_name,
+    @field_validator(type_validator('relationship type', convert_name_to_full_type_name,
                                     'relationship_types'))
     @primitive_field(str, required=True)
     def type(self):
@@ -278,7 +277,7 @@ class RelationshipTemplate(ExtensiblePresentation):
 
     @cachedmethod
     def _get_type(self, context):
-        return get_type_by_full_or_shorthand_name(context, self.type, 'relationship_types')
+        return get_type_by_name(context, self.type, 'relationship_types')
 
     @cachedmethod
     def _get_property_values(self, context):
@@ -315,7 +314,7 @@ class GroupTemplate(ExtensiblePresentation):
     #DEFN_ELEMENT_GROUP_DEF>`__
     """
 
-    @field_validator(type_validator('group type', convert_shorthand_to_full_type_name,
+    @field_validator(type_validator('group type', convert_name_to_full_type_name,
                                     'group_types'))
     @primitive_field(str, required=True)
     def type(self):
@@ -361,7 +360,7 @@ class GroupTemplate(ExtensiblePresentation):
 
     @cachedmethod
     def _get_type(self, context):
-        return get_type_by_full_or_shorthand_name(context, self.type, 'group_types')
+        return get_type_by_name(context, self.type, 'group_types')
 
     @cachedmethod
     def _get_property_values(self, context):
@@ -389,8 +388,7 @@ class PolicyTemplate(ExtensiblePresentation):
     #DEFN_ELEMENT_POLICY_DEF>`__
     """
 
-    @field_validator(type_validator('policy type', convert_shorthand_to_full_type_name,
-                                    'policy_types'))
+    @field_validator(type_validator('policy type', convert_name_to_full_type_name, 'policy_types'))
     @primitive_field(str, required=True)
     def type(self):
         """
@@ -426,7 +424,7 @@ class PolicyTemplate(ExtensiblePresentation):
 
     @cachedmethod
     def _get_type(self, context):
-        return get_type_by_full_or_shorthand_name(context, self.type, 'policy_types')
+        return get_type_by_name(context, self.type, 'policy_types')
 
     @cachedmethod
     def _get_property_values(self, context):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c2b8e65b/extensions/aria_extension_tosca/simple_v1_0/types.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/types.py b/extensions/aria_extension_tosca/simple_v1_0/types.py
index 47332f0..787aac2 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/types.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/types.py
@@ -43,7 +43,8 @@ from .presentation.field_validators import (data_type_derived_from_validator,
                                             data_type_constraints_validator,
                                             data_type_properties_validator,
                                             list_node_type_or_group_type_validator)
-from .presentation.types import convert_shorthand_to_full_type_name
+from .presentation.types import convert_name_to_full_type_name
+
 
 
 @has_fields
@@ -59,7 +60,7 @@ class ArtifactType(ExtensiblePresentation):
     #DEFN_ENTITY_ARTIFACT_TYPE>`__
     """
 
-    @field_validator(derived_from_validator(convert_shorthand_to_full_type_name, 'artifact_types'))
+    @field_validator(derived_from_validator(convert_name_to_full_type_name, 'artifact_types'))
     @primitive_field(str)
     def derived_from(self):
         """
@@ -111,7 +112,7 @@ class ArtifactType(ExtensiblePresentation):
 
     @cachedmethod
     def _get_parent(self, context):
-        return get_parent_presentation(context, self, convert_shorthand_to_full_type_name,
+        return get_parent_presentation(context, self, convert_name_to_full_type_name,
                                        'artifact_types')
 
     @cachedmethod
@@ -240,8 +241,7 @@ class CapabilityType(ExtensiblePresentation):
     #DEFN_ENTITY_CAPABILITY_TYPE>`__
     """
 
-    @field_validator(derived_from_validator(convert_shorthand_to_full_type_name,
-                                            'capability_types'))
+    @field_validator(derived_from_validator(convert_name_to_full_type_name, 'capability_types'))
     @primitive_field(str)
     def derived_from(self):
         """
@@ -284,8 +284,7 @@ class CapabilityType(ExtensiblePresentation):
         :type: {:obj:`basestring`: :class:`AttributeDefinition`}
         """
 
-    @field_validator(list_type_validator('node type', convert_shorthand_to_full_type_name,
-                                         'node_types'))
+    @field_validator(list_type_validator('node type', convert_name_to_full_type_name, 'node_types'))
     @primitive_list_field(str)
     def valid_source_types(self):
         """
@@ -297,7 +296,7 @@ class CapabilityType(ExtensiblePresentation):
 
     @cachedmethod
     def _get_parent(self, context):
-        return get_parent_presentation(context, self, convert_shorthand_to_full_type_name,
+        return get_parent_presentation(context, self, convert_name_to_full_type_name,
                                        'capability_types')
 
     @cachedmethod
@@ -343,7 +342,7 @@ class InterfaceType(ExtensiblePresentation):
     #DEFN_ENTITY_INTERFACE_TYPE>`__
     """
 
-    @field_validator(derived_from_validator(convert_shorthand_to_full_type_name, 'interface_types'))
+    @field_validator(derived_from_validator(convert_name_to_full_type_name, 'interface_types'))
     @primitive_field(str)
     def derived_from(self):
         """
@@ -384,7 +383,7 @@ class InterfaceType(ExtensiblePresentation):
 
     @cachedmethod
     def _get_parent(self, context):
-        return get_parent_presentation(context, self, convert_shorthand_to_full_type_name,
+        return get_parent_presentation(context, self, convert_name_to_full_type_name,
                                        'interface_types')
 
     @cachedmethod
@@ -422,8 +421,7 @@ class RelationshipType(ExtensiblePresentation):
     #DEFN_ENTITY_RELATIONSHIP_TYPE>`__
     """
 
-    @field_validator(derived_from_validator(convert_shorthand_to_full_type_name,
-                                            'relationship_types'))
+    @field_validator(derived_from_validator(convert_name_to_full_type_name, 'relationship_types'))
     @primitive_field(str)
     def derived_from(self):
         """
@@ -472,7 +470,7 @@ class RelationshipType(ExtensiblePresentation):
         :type: {:obj:`basestring`: :class:`InterfaceDefinition`}
         """
 
-    @field_validator(list_type_validator('capability type', convert_shorthand_to_full_type_name,
+    @field_validator(list_type_validator('capability type', convert_name_to_full_type_name,
                                          'capability_types'))
     @primitive_list_field(str)
     def valid_target_types(self):
@@ -485,7 +483,7 @@ class RelationshipType(ExtensiblePresentation):
 
     @cachedmethod
     def _get_parent(self, context):
-        return get_parent_presentation(context, self, convert_shorthand_to_full_type_name,
+        return get_parent_presentation(context, self, convert_name_to_full_type_name,
                                        'relationship_types')
 
     @cachedmethod
@@ -538,7 +536,7 @@ class NodeType(ExtensiblePresentation):
     #DEFN_ENTITY_NODE_TYPE>`__
     """
 
-    @field_validator(derived_from_validator(convert_shorthand_to_full_type_name, 'node_types'))
+    @field_validator(derived_from_validator(convert_name_to_full_type_name, 'node_types'))
     @primitive_field(str)
     def derived_from(self):
         """
@@ -617,8 +615,7 @@ class NodeType(ExtensiblePresentation):
 
     @cachedmethod
     def _get_parent(self, context):
-        return get_parent_presentation(context, self, convert_shorthand_to_full_type_name,
-                                       'node_types')
+        return get_parent_presentation(context, self, convert_name_to_full_type_name, 'node_types')
 
     @cachedmethod
     def _is_descendant(self, context, the_type):
@@ -695,7 +692,7 @@ class GroupType(ExtensiblePresentation):
     #DEFN_ENTITY_GROUP_TYPE>`__
     """
 
-    @field_validator(derived_from_validator(convert_shorthand_to_full_type_name, 'group_types'))
+    @field_validator(derived_from_validator(convert_name_to_full_type_name, 'group_types'))
     @primitive_field(str)
     def derived_from(self):
         """
@@ -728,8 +725,7 @@ class GroupType(ExtensiblePresentation):
         :type: {:obj:`basestring`: :class:`PropertyDefinition`}
         """
 
-    @field_validator(list_type_validator('node type', convert_shorthand_to_full_type_name,
-                                         'node_types'))
+    @field_validator(list_type_validator('node type', convert_name_to_full_type_name, 'node_types'))
     @primitive_list_field(str)
     def members(self):
         """
@@ -754,7 +750,7 @@ class GroupType(ExtensiblePresentation):
 
     @cachedmethod
     def _get_parent(self, context):
-        return get_parent_presentation(context, self, convert_shorthand_to_full_type_name,
+        return get_parent_presentation(context, self, convert_name_to_full_type_name,
                                        'group_types')
 
     @cachedmethod
@@ -802,7 +798,7 @@ class PolicyType(ExtensiblePresentation):
     #DEFN_ENTITY_POLICY_TYPE>`__
     """
 
-    @field_validator(derived_from_validator(convert_shorthand_to_full_type_name, 'policy_types'))
+    @field_validator(derived_from_validator(convert_name_to_full_type_name, 'policy_types'))
     @primitive_field(str)
     def derived_from(self):
         """
@@ -851,7 +847,7 @@ class PolicyType(ExtensiblePresentation):
 
     @cachedmethod
     def _get_parent(self, context):
-        return get_parent_presentation(context, self, convert_shorthand_to_full_type_name,
+        return get_parent_presentation(context, self, convert_name_to_full_type_name,
                                        'policy_types')
 
     @cachedmethod

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c2b8e65b/tests/parser/service_templates.py
----------------------------------------------------------------------
diff --git a/tests/parser/service_templates.py b/tests/parser/service_templates.py
index 13712df..55cd4ad 100644
--- a/tests/parser/service_templates.py
+++ b/tests/parser/service_templates.py
@@ -47,6 +47,19 @@ def consume_use_case(use_case_name, consumer_class_name='instance', cache=True):
     assert not context.validation.has_issues
     return context, dumper
 
+def consume_types_use_case(use_case_name, consumer_class_name='instance', cache=True):
+    cachedmethod.ENABLED = cache
+    uri = get_service_template_uri('tosca-simple-1.0', 'types', use_case_name,
+                                   '{0}.yaml'.format(use_case_name))
+    context = create_context(uri)
+    inputs_file = get_example_uri('tosca-simple-1.0', 'types', use_case_name, 'inputs.yaml')
+    if os.path.isfile(inputs_file):
+        context.args.append('--inputs={0}'.format(inputs_file))
+    consumer, dumper = create_consumer(context, consumer_class_name)
+    consumer.consume()
+    context.validation.dump_issues()
+    assert not context.validation.has_issues
+    return context, dumper
 
 def consume_node_cellar(consumer_class_name='instance', cache=True):
     cachedmethod.ENABLED = cache

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c2b8e65b/tests/parser/test_tosca_simple_v1_0.py
----------------------------------------------------------------------
diff --git a/tests/parser/test_tosca_simple_v1_0.py b/tests/parser/test_tosca_simple_v1_0.py
deleted file mode 100644
index a583db5..0000000
--- a/tests/parser/test_tosca_simple_v1_0.py
+++ /dev/null
@@ -1,112 +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 .service_templates import (consume_use_case, consume_node_cellar)
-
-
-# Use Cases
-
-def test_use_case_compute_1():
-    consume_use_case('compute-1', 'instance')
-
-
-def test_use_case_software_component_1():
-    consume_use_case('software-component-1', 'instance')
-
-
-def test_use_case_block_storage_1():
-    consume_use_case('block-storage-1', 'instance')
-
-
-def test_use_case_block_storage_2():
-    consume_use_case('block-storage-2', 'instance')
-
-
-def test_use_case_block_storage_3():
-    consume_use_case('block-storage-3', 'instance')
-
-
-def test_use_case_block_storage_4():
-    consume_use_case('block-storage-4', 'instance')
-
-
-def test_use_case_block_storage_5():
-    consume_use_case('block-storage-5', 'instance')
-
-
-def test_use_case_block_storage_6():
-    consume_use_case('block-storage-6', 'instance')
-
-
-def test_use_case_object_storage_1():
-    consume_use_case('object-storage-1', 'instance')
-
-
-def test_use_case_network_1():
-    consume_use_case('network-1', 'instance')
-
-
-def test_use_case_network_2():
-    consume_use_case('network-2', 'instance')
-
-
-def test_use_case_network_3():
-    consume_use_case('network-3', 'instance')
-
-
-def test_use_case_network_4():
-    consume_use_case('network-4', 'instance')
-
-
-def test_use_case_webserver_dbms_1():
-    consume_use_case('webserver-dbms-1', 'template')
-
-
-def test_use_case_webserver_dbms_2():
-    consume_use_case('webserver-dbms-2', 'instance')
-
-
-def test_use_case_multi_tier_1():
-    consume_use_case('multi-tier-1', 'instance')
-
-
-def test_use_case_container_1():
-    consume_use_case('container-1', 'template')
-
-
-# NodeCellar
-
-def test_node_cellar_validation():
-    consume_node_cellar('validate')
-
-
-def test_node_cellar_validation_no_cache():
-    consume_node_cellar('validate', False)
-
-
-def test_node_cellar_presentation():
-    consume_node_cellar('presentation')
-
-
-def test_node_cellar_model():
-    consume_node_cellar('template')
-
-
-def test_node_cellar_types():
-    consume_node_cellar('types')
-
-
-def test_node_cellar_instance():
-    consume_node_cellar('instance')

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c2b8e65b/tests/parser/test_tosca_simple_v1_0/__init__.py
----------------------------------------------------------------------
diff --git a/tests/parser/test_tosca_simple_v1_0/__init__.py b/tests/parser/test_tosca_simple_v1_0/__init__.py
new file mode 100644
index 0000000..ae1e83e
--- /dev/null
+++ b/tests/parser/test_tosca_simple_v1_0/__init__.py
@@ -0,0 +1,14 @@
+# 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.

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c2b8e65b/tests/parser/test_tosca_simple_v1_0/presentation/__init__.py
----------------------------------------------------------------------
diff --git a/tests/parser/test_tosca_simple_v1_0/presentation/__init__.py b/tests/parser/test_tosca_simple_v1_0/presentation/__init__.py
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c2b8e65b/tests/parser/test_tosca_simple_v1_0/presentation/test_types.py
----------------------------------------------------------------------
diff --git a/tests/parser/test_tosca_simple_v1_0/presentation/test_types.py b/tests/parser/test_tosca_simple_v1_0/presentation/test_types.py
new file mode 100644
index 0000000..cfd4d3c
--- /dev/null
+++ b/tests/parser/test_tosca_simple_v1_0/presentation/test_types.py
@@ -0,0 +1,23 @@
+# 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 tests.parser.service_templates import consume_types_use_case
+
+
+def test_use_case_shorthand_1_name():
+    consume_types_use_case('shorthand-1', 'types')
+
+def test_use_case_typequalified_1_name():
+    consume_types_use_case('typequalified-1', 'types')

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c2b8e65b/tests/parser/test_tosca_simple_v1_0/test_end2end.py
----------------------------------------------------------------------
diff --git a/tests/parser/test_tosca_simple_v1_0/test_end2end.py b/tests/parser/test_tosca_simple_v1_0/test_end2end.py
new file mode 100644
index 0000000..474d90e
--- /dev/null
+++ b/tests/parser/test_tosca_simple_v1_0/test_end2end.py
@@ -0,0 +1,112 @@
+# 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 ..service_templates import (consume_use_case, consume_node_cellar)
+
+
+# Use Cases
+
+def test_use_case_compute_1():
+    consume_use_case('compute-1', 'instance')
+
+
+def test_use_case_software_component_1():
+    consume_use_case('software-component-1', 'instance')
+
+
+def test_use_case_block_storage_1():
+    consume_use_case('block-storage-1', 'instance')
+
+
+def test_use_case_block_storage_2():
+    consume_use_case('block-storage-2', 'instance')
+
+
+def test_use_case_block_storage_3():
+    consume_use_case('block-storage-3', 'instance')
+
+
+def test_use_case_block_storage_4():
+    consume_use_case('block-storage-4', 'instance')
+
+
+def test_use_case_block_storage_5():
+    consume_use_case('block-storage-5', 'instance')
+
+
+def test_use_case_block_storage_6():
+    consume_use_case('block-storage-6', 'instance')
+
+
+def test_use_case_object_storage_1():
+    consume_use_case('object-storage-1', 'instance')
+
+
+def test_use_case_network_1():
+    consume_use_case('network-1', 'instance')
+
+
+def test_use_case_network_2():
+    consume_use_case('network-2', 'instance')
+
+
+def test_use_case_network_3():
+    consume_use_case('network-3', 'instance')
+
+
+def test_use_case_network_4():
+    consume_use_case('network-4', 'instance')
+
+
+def test_use_case_webserver_dbms_1():
+    consume_use_case('webserver-dbms-1', 'template')
+
+
+def test_use_case_webserver_dbms_2():
+    consume_use_case('webserver-dbms-2', 'instance')
+
+
+def test_use_case_multi_tier_1():
+    consume_use_case('multi-tier-1', 'instance')
+
+
+def test_use_case_container_1():
+    consume_use_case('container-1', 'template')
+
+
+# NodeCellar
+
+def test_node_cellar_validation():
+    consume_node_cellar('validate')
+
+
+def test_node_cellar_validation_no_cache():
+    consume_node_cellar('validate', False)
+
+
+def test_node_cellar_presentation():
+    consume_node_cellar('presentation')
+
+
+def test_node_cellar_model():
+    consume_node_cellar('template')
+
+
+def test_node_cellar_types():
+    consume_node_cellar('types')
+
+
+def test_node_cellar_instance():
+    consume_node_cellar('instance')

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c2b8e65b/tests/resources/service-templates/tosca-simple-1.0/types/shorthand-1/shorthand-1.yaml
----------------------------------------------------------------------
diff --git a/tests/resources/service-templates/tosca-simple-1.0/types/shorthand-1/shorthand-1.yaml b/tests/resources/service-templates/tosca-simple-1.0/types/shorthand-1/shorthand-1.yaml
new file mode 100644
index 0000000..b295f95
--- /dev/null
+++ b/tests/resources/service-templates/tosca-simple-1.0/types/shorthand-1/shorthand-1.yaml
@@ -0,0 +1,23 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >-
+  TOSCA simple profile that defines a compute instance and a block storage with the "shorthand type"
+
+topology_template:
+
+  node_templates:
+  
+    my_server:
+      type: Compute
+      requirements:
+        - local_storage:
+            node: my_block_storage           
+            relationship:
+              type: AttachesTo
+              properties:
+                location: /path1/path2
+  
+    my_block_storage:
+      type: BlockStorage
+      properties:
+        size: 10 GB

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c2b8e65b/tests/resources/service-templates/tosca-simple-1.0/types/typequalified-1/typequalified-1.yaml
----------------------------------------------------------------------
diff --git a/tests/resources/service-templates/tosca-simple-1.0/types/typequalified-1/typequalified-1.yaml b/tests/resources/service-templates/tosca-simple-1.0/types/typequalified-1/typequalified-1.yaml
new file mode 100644
index 0000000..5f11fd4
--- /dev/null
+++ b/tests/resources/service-templates/tosca-simple-1.0/types/typequalified-1/typequalified-1.yaml
@@ -0,0 +1,23 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >-
+  TOSCA simple profile that defines a compute instance and a block storage with the "typequalified type"
+
+topology_template:
+
+  node_templates:
+  
+    my_server:
+      type: tosca:Compute
+      requirements:
+        - local_storage:
+            node: my_block_storage           
+            relationship:
+              type: AttachesTo
+              properties:
+                location: /path1/path2
+  
+    my_block_storage:
+      type: tosca:BlockStorage
+      properties:
+        size: 10 GB


[2/2] incubator-ariatosca git commit: ARIA-321 Clearwater example

Posted by em...@apache.org.
ARIA-321 Clearwater example

This commit also fixes related bugs:

* Allows capabilities, interfaces, and properties to override parent
definition types only if the new type is a descendant of the overriden
type
* Fix bugs in model instrumentation (to allow ctx access to
capabilities)
* Doc fixes related to ARIA-277


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

Branch: refs/heads/ARIA-321-clearwater
Commit: e8f15b44960c81bab3631a1fa3f78354f697abc1
Parents: c2b8e65
Author: Tal Liron <ta...@gmail.com>
Authored: Tue Jul 18 17:25:27 2017 -0500
Committer: Tal Liron <ta...@gmail.com>
Committed: Mon Jul 24 15:16:40 2017 -0500

----------------------------------------------------------------------
 aria/modeling/functions.py                      |   4 +-
 aria/orchestrator/context/common.py             |   6 +-
 .../execution_plugin/ctx_proxy/server.py        |  39 +-
 aria/storage/collection_instrumentation.py      |  15 +-
 aria/storage/core.py                            |   2 +-
 .../clearwater/clearwater-single-static.yaml    |  69 ++++
 examples/clearwater/scripts/bono/create.sh      |   5 +
 examples/clearwater/scripts/bono/delete.sh      |   0
 examples/clearwater/scripts/dime/create.sh      |   5 +
 examples/clearwater/scripts/dime/delete.sh      |   0
 examples/clearwater/scripts/ellis/create.sh     |   5 +
 examples/clearwater/scripts/ellis/delete.sh     |   0
 examples/clearwater/scripts/homer/create.sh     |   5 +
 examples/clearwater/scripts/homer/delete.sh     |   0
 examples/clearwater/scripts/homestead/create.sh |   0
 examples/clearwater/scripts/homestead/delete.sh |   0
 examples/clearwater/scripts/host/configure.sh   | 139 +++++++
 examples/clearwater/scripts/ralf/create.sh      |   0
 examples/clearwater/scripts/ralf/delete.sh      |   0
 examples/clearwater/scripts/sprout/create.sh    |   8 +
 examples/clearwater/scripts/sprout/delete.sh    |   0
 examples/clearwater/scripts/velum/create.sh     |   8 +
 examples/clearwater/scripts/velum/delete.sh     |   0
 examples/clearwater/types/cassandra.yaml        |   0
 examples/clearwater/types/clearwater.yaml       | 285 ++++++++++++++
 examples/clearwater/types/ims.yaml              | 394 +++++++++++++++++++
 examples/hello-world/hello-world.yaml           |  38 ++
 examples/hello-world/helloworld.yaml            |  38 --
 .../simple_v1_0/modeling/capabilities.py        |  14 +-
 .../simple_v1_0/modeling/functions.py           |  18 +-
 .../simple_v1_0/modeling/interfaces.py          |  14 +-
 .../simple_v1_0/modeling/parameters.py          |  26 +-
 .../simple_v1_0/presentation/types.py           |   8 +-
 .../aria_extension_tosca/simple_v1_0/types.py   |  19 +
 34 files changed, 1073 insertions(+), 91 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/aria/modeling/functions.py
----------------------------------------------------------------------
diff --git a/aria/modeling/functions.py b/aria/modeling/functions.py
index 6544adf..d0ec0cf 100644
--- a/aria/modeling/functions.py
+++ b/aria/modeling/functions.py
@@ -20,6 +20,7 @@ Mechanism for evaluating intrinsic functions.
 from ..parser.consumption import ConsumptionContext
 from ..parser.exceptions import InvalidValueError
 from ..utils.collections import OrderedDict
+from ..utils.type import full_type_name
 from . import exceptions
 
 
@@ -89,7 +90,8 @@ def evaluate(value, container_holder, report_issues=False): # pylint: disable=to
             if (evaluation is None) \
                 or (not hasattr(evaluation, 'value')) \
                 or (not hasattr(evaluation, 'final')):
-                raise InvalidValueError('bad __evaluate__ implementation')
+                raise InvalidValueError('bad __evaluate__ implementation: {0}'
+                                        .format(full_type_name(value)))
 
             evaluated = True
             value = evaluation.value

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/aria/orchestrator/context/common.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/context/common.py b/aria/orchestrator/context/common.py
index f400142..c71edca 100644
--- a/aria/orchestrator/context/common.py
+++ b/aria/orchestrator/context/common.py
@@ -40,8 +40,12 @@ class BaseContext(object):
     INSTRUMENTATION_FIELDS = (
         modeling.models.Node.attributes,
         modeling.models.Node.properties,
+        # TODO: modeling.models.Capability.attributes,
+        modeling.models.Capability.properties,
         modeling.models.NodeTemplate.attributes,
-        modeling.models.NodeTemplate.properties
+        modeling.models.NodeTemplate.properties,
+        # TODO: modeling.models.CapabilityTemplate.attributes,
+        modeling.models.CapabilityTemplate.properties
     )
 
     class PrefixedLogger(object):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/aria/orchestrator/execution_plugin/ctx_proxy/server.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/execution_plugin/ctx_proxy/server.py b/aria/orchestrator/execution_plugin/ctx_proxy/server.py
index ca910e0..0e6cdf3 100644
--- a/aria/orchestrator/execution_plugin/ctx_proxy/server.py
+++ b/aria/orchestrator/execution_plugin/ctx_proxy/server.py
@@ -157,11 +157,11 @@ def _process_ctx_request(ctx, args):
     while index < num_args:
         arg = args[index]
         attr = _desugar_attr(current, arg)
-        if attr:
+        if attr is not None:
             current = getattr(current, attr)
         elif isinstance(current, collections.MutableMapping):
             key = arg
-            path_dict = _PathDictAccess(current)
+            path_dict = _PathAccess(current)
             if index + 1 == num_args:
                 # read dict prop by path
                 value = path_dict.get(key)
@@ -174,6 +174,8 @@ def _process_ctx_request(ctx, args):
             else:
                 raise RuntimeError('Illegal argument while accessing dict')
             break
+        elif hasattr(current, '__getitem__') and (arg in current): # *must* be after MutableMapping
+            current = current[arg]
         elif callable(current):
             kwargs = {}
             remaining_args = args[index:]
@@ -183,7 +185,7 @@ def _process_ctx_request(ctx, args):
             current = current(*remaining_args, **kwargs)
             break
         else:
-            raise RuntimeError('{0} cannot be processed in {1}'.format(arg, args))
+            raise RuntimeError('`{0}` cannot be processed in {1}'.format(arg, args))
         index += 1
     if callable(current):
         current = current()
@@ -201,8 +203,8 @@ def _desugar_attr(obj, attr):
     return None
 
 
-class _PathDictAccess(object):
-    pattern = re.compile(r"(.+)\[(\d+)\]")
+class _PathAccess(object):
+    ARRAY_PATTERN = re.compile(r"(.+)\[(\d+)\]")
 
     def __init__(self, obj):
         self.obj = obj
@@ -216,26 +218,35 @@ class _PathDictAccess(object):
         return value
 
     def _get_object_by_path(self, prop_path, fail_on_missing=True):
-        # when setting a nested object, make sure to also set all the
+        def has(name):
+            return (hasattr(current, '__iter__') and (name in current)) or hasattr(current, name)
+
+        def get(name):
+            if hasattr(current, '__iter__') and (name in current):
+                return current[name]
+            return getattr(current, name)
+        
+        # When setting a nested object, make sure to also set all the
         # intermediate path objects
         current = self.obj
         for prop_segment in prop_path.split('.'):
-            match = self.pattern.match(prop_segment)
-            if match:
-                index = int(match.group(2))
-                property_name = match.group(1)
-                if property_name not in current:
+            array_match = _PathAccess.ARRAY_PATTERN.match(prop_segment)
+            if array_match:
+                index = int(array_match.group(2))
+                property_name = array_match.group(1)
+                if not has(property_name):
                     self._raise_illegal(prop_path)
                 if not isinstance(current[property_name], list):
                     self._raise_illegal(prop_path)
-                current = current[property_name][index]
+                current = get(property_name)[index]
             else:
-                if prop_segment not in current:
+                if not has(prop_segment):
                     if fail_on_missing:
                         self._raise_illegal(prop_path)
                     else:
+                        # TODO: won't this change the model???
                         current[prop_segment] = {}
-                current = current[prop_segment]
+                current = get(prop_segment)
         return current
 
     def _get_parent_obj_prop_name_by_path(self, prop_path):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/aria/storage/collection_instrumentation.py
----------------------------------------------------------------------
diff --git a/aria/storage/collection_instrumentation.py b/aria/storage/collection_instrumentation.py
index c90cb18..dae884a 100644
--- a/aria/storage/collection_instrumentation.py
+++ b/aria/storage/collection_instrumentation.py
@@ -230,15 +230,20 @@ class _InstrumentedModel(_WrappedBase):
 
     def _apply_instrumentation(self):
         for field in self._instrumentation:
+            if field.parent.class_ != type(self._wrapped):
+                # Only apply fields of our class
+                continue
+
             field_name = field.key
             field_cls = field.mapper.class_
+
             field = getattr(self._wrapped, field_name)
 
             # Preserve the original value. e.g. original attributes would be located under
             # _attributes
             setattr(self, '_{0}'.format(field_name), field)
 
-            # set instrumented value
+            # Set instrumented value
             if isinstance(field, dict):
                 instrumentation_cls = _InstrumentedDict
             elif isinstance(field, list):
@@ -247,7 +252,7 @@ class _InstrumentedModel(_WrappedBase):
                 # TODO: raise proper error
                 raise exceptions.StorageError(
                     "ARIA supports instrumentation for dict and list. Field {field} of the "
-                    "class {model} is of {type} type.".format(
+                    "class `{model}` is of type `{type}`.".format(
                         field=field,
                         model=self._wrapped,
                         type=type(field)))
@@ -277,7 +282,7 @@ class _WrappedModel(_WrappedBase):
             return _create_instrumented_model(
                 value, instrumentation=self._instrumentation, **self._kwargs)
         elif hasattr(value, 'metadata') or isinstance(value, (dict, list)):
-            # Basically checks that the value is indeed an sqlmodel (it should have metadata)
+            # Basically checks that the value is indeed a SQLAlchemy model (it should have metadata)
             return _create_wrapped_model(
                 value, instrumentation=self._instrumentation, **self._kwargs)
         return value
@@ -291,6 +296,10 @@ class _WrappedModel(_WrappedBase):
     def __getitem__(self, item):
         return self._wrap(self._wrapped[item])
 
+    def __iter__(self):
+        for item in self._wrapped.__iter__():
+            yield self._wrap(item)
+
 
 def _create_instrumented_model(original_model, mapi, instrumentation):
     return type('Instrumented{0}'.format(original_model.__class__.__name__),

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/aria/storage/core.py
----------------------------------------------------------------------
diff --git a/aria/storage/core.py b/aria/storage/core.py
index 2a5745e..527272c 100644
--- a/aria/storage/core.py
+++ b/aria/storage/core.py
@@ -130,7 +130,7 @@ class ModelStorage(Storage):
         """
         model_name = model_cls.__modelname__
         if model_name in self.registered:
-            self.logger.debug('{name} in already storage {self!r}'.format(name=model_name,
+            self.logger.debug('{name} already in storage {self!r}'.format(name=model_name,
                                                                           self=self))
             return
         self.registered[model_name] = self.api(name=model_name,

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/clearwater-single-static.yaml
----------------------------------------------------------------------
diff --git a/examples/clearwater/clearwater-single-static.yaml b/examples/clearwater/clearwater-single-static.yaml
new file mode 100644
index 0000000..ccdcac3
--- /dev/null
+++ b/examples/clearwater/clearwater-single-static.yaml
@@ -0,0 +1,69 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >-
+  Project Clearwater is an open-source IMS core, developed by Metaswitch Networks and released under
+  the GNU GPLv3.
+
+metadata:
+  template_name: clearwater-local
+  template_author: ARIA
+  template_version: '1.0.0'
+  aria_version: '0.1'
+
+imports:
+  - types/clearwater.yaml
+  - aria-1.0
+
+topology_template:
+
+  inputs:
+    hosts.user:
+      type: string
+      default: ubuntu
+    hosts.password:
+      type: string
+      default: ubuntu
+    static_host.public_address:
+      type: string
+      default: 192.168.1.170
+    static_host.private_address:
+      type: string
+      default: 192.168.1.170
+
+  node_templates:
+    bono:
+      type: clearwater.Bono
+
+    sprout:
+      type: clearwater.Sprout
+  
+    dime:
+      type: clearwater.Dime
+
+    homestead:
+      type: clearwater.Homestead
+
+    ralf:
+      type: clearwater.Ralf
+
+    velum:
+      type: clearwater.Velum
+
+    homer:
+      type: clearwater.Homer
+
+    ellis:
+      type: clearwater.Ellis
+  
+    static_host:
+      type: clearwater.Host
+      attributes:
+        public_address: { get_input: static_host.public_address }
+        private_address: { get_input: static_host.private_address }
+      capabilities:
+        host:
+          properties:
+            ssh.user: { get_input: hosts.user }
+            ssh.password: { get_input: hosts.password }
+            max_log_directory_size: 50 MiB
+            reduce_cassandra_mem_usage: true

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/scripts/bono/create.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/bono/create.sh b/examples/clearwater/scripts/bono/create.sh
new file mode 100644
index 0000000..6e441c2
--- /dev/null
+++ b/examples/clearwater/scripts/bono/create.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -e
+
+yes | aptdcon --hide-terminal --install bono restund
+yes | aptdcon --hide-terminal --install clearwater-management

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/scripts/bono/delete.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/bono/delete.sh b/examples/clearwater/scripts/bono/delete.sh
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/scripts/dime/create.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/dime/create.sh b/examples/clearwater/scripts/dime/create.sh
new file mode 100644
index 0000000..584fcd0
--- /dev/null
+++ b/examples/clearwater/scripts/dime/create.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -e
+
+yes | aptdcon --hide-terminal --install dime clearwater-prov-tools
+yes | aptdcon --hide-terminal --install clearwater-management

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/scripts/dime/delete.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/dime/delete.sh b/examples/clearwater/scripts/dime/delete.sh
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/scripts/ellis/create.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/ellis/create.sh b/examples/clearwater/scripts/ellis/create.sh
new file mode 100644
index 0000000..f7fb151
--- /dev/null
+++ b/examples/clearwater/scripts/ellis/create.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -e
+
+yes | aptdcon --hide-terminal --install ellis
+yes | aptdcon --hide-terminal --install clearwater-management

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/scripts/ellis/delete.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/ellis/delete.sh b/examples/clearwater/scripts/ellis/delete.sh
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/scripts/homer/create.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/homer/create.sh b/examples/clearwater/scripts/homer/create.sh
new file mode 100644
index 0000000..4aa4893
--- /dev/null
+++ b/examples/clearwater/scripts/homer/create.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -e
+
+yes | aptdcon --hide-terminal --install homer
+yes | aptdcon --hide-terminal --install clearwater-management

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/scripts/homer/delete.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/homer/delete.sh b/examples/clearwater/scripts/homer/delete.sh
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/scripts/homestead/create.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/homestead/create.sh b/examples/clearwater/scripts/homestead/create.sh
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/scripts/homestead/delete.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/homestead/delete.sh b/examples/clearwater/scripts/homestead/delete.sh
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/scripts/host/configure.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/host/configure.sh b/examples/clearwater/scripts/host/configure.sh
new file mode 100644
index 0000000..73e81e8
--- /dev/null
+++ b/examples/clearwater/scripts/host/configure.sh
@@ -0,0 +1,139 @@
+#!/bin/bash
+set -e
+
+REPO_FILE=/etc/apt/sources.list.d/clearwater.list
+REPO_LINE="deb http://repo.cw-ngv.com/stable binary/"
+KEY_URL=http://repo.cw-ngv.com/repo_key
+
+# Clearwater repository
+if [ ! -f "$REPO_FILE" ]; then
+	echo "$REPO_LINE" > "$REPO_FILE"
+	curl -L "$KEY_URL" | apt-key add -
+	apt update
+fi
+
+if ! type aptdcon > /dev/null; then
+	apt install aptdaemon --yes
+fi
+
+# For cw-upload_shared_config
+yes | aptdcon --hide-terminal --install clearwater-config-manager
+
+
+GEOGRAPHICALLY_REDUNDANT=False
+PRIVATE_IP=$(ctx node attributes private_address)
+PUBLIC_IP=$(ctx node attributes public_address)
+MAX_LOG_DIRECTORY_SIZE=$(ctx node capabilities host properties max_log_directory_size.value)
+REDUCE_CASSANDRA_MEM_USAGE=$(ctx node capabilities host properties reduce_cassandra_mem_usage)
+PUBLIC_HOSTNAME=ubuntu
+SITE_NAME=aria
+ZONE=example.com
+SECRET=secret
+
+mkdir -p /etc/clearwater
+
+
+# Local configuration
+
+CONFIG_FILE=/etc/clearwater/local_config
+ETCD_CLUSTER=$PRIVATE_IP
+
+echo "# Created by ARIA on $(date -u)" > "$CONFIG_FILE"
+
+echo >> "$CONFIG_FILE"
+echo "# Local IP configuration" >> "$CONFIG_FILE"
+echo "local_ip=$PRIVATE_IP" >> "$CONFIG_FILE"
+echo "public_ip=$PUBLIC_IP" >> "$CONFIG_FILE"
+echo "public_hostname=$PUBLIC_HOSTNAME" >> "$CONFIG_FILE"
+echo "etcd_cluster=\"$ETCD_CLUSTER\"" >> "$CONFIG_FILE"
+
+if [ "$MAX_LOG_DIRECTORY_SIZE" != 0 ]; then
+	echo >> "$CONFIG_FILE"
+	echo "max_log_directory_size=$MAX_LOG_DIRECTORY_SIZE" >> "$CONFIG_FILE"
+fi
+
+if [ "$GEOGRAPHICALLY_REDUNDANT" = True ]; then
+	echo >> "$CONFIG_FILE"
+	echo "# Geographically redundant" >> "$CONFIG_FILE"
+	echo "local_site_name=$SITE_NAME" >> "$CONFIG_FILE"
+	
+	# On the first Vellum node in the second site, you should set remote_cassandra_seeds to the
+	# IP address of a Vellum node in the first site.
+	#echo "remote_cassandra_seeds=" >> "$CONFIG_FILE"
+fi
+
+
+# Shared configuration
+
+CONFIG_FILE=/etc/clearwater/shared_config
+SMTP_HOSTNAME=127.0.0.1
+SMTP_USERNAME=username
+SMTP_PASSWORD=password
+
+if [ "$GEOGRAPHICALLY_REDUNDANT" = True ]; then
+	SPROUT_HOSTNAME=sprout.$SITE_NAME.$ZONE
+	SPROUT_REGISTRATION_STORE=vellum.$SITE_NAME.$ZONE
+	HS_HOSTNAME=hs.$SITE_NAME.$ZONE:8888
+	HS_PROVISIONING_HOSTNAME=hs.$SITE_NAME.$ZONE:8889
+	RALF_HOSTNAME=ralf.$SITE_NAME.$ZONE:10888
+	RALF_SESSION_STORE=vellum.$ZONE
+	XDMS_HOSTNAME=homer.$SITE_NAME.$ZONE:7888
+	CHRONOS_HOSTNAME=vellum.$SITE_NAME.$ZONE
+	CASSANDRA_HOSTNAME=vellum.$SITE_NAME.$ZONE
+else
+	VELLUM_IP=$PRIVATE_IP
+	HOMESTEAD_IP=$PRIVATE_IP
+	HOMER_IP=$PRIVATE_IP
+
+	SPROUT_HOSTNAME=$PUBLIC_HOSTNAME
+	SPROUT_REGISTRATION_STORE=$VELLUM_IP
+	HS_HOSTNAME=$HOMESTEAD_IP:8888
+	HS_PROVISIONING_HOSTNAME=$HOMESTEAD_IP:8889
+	RALF_HOSTNAME=
+	RALF_SESSION_STORE=
+	XDMS_HOSTNAME=$HOMER_IP:7888
+	CHRONOS_HOSTNAME=
+	CASSANDRA_HOSTNAME=
+fi
+
+echo "# Created by ARIA on $(date -u)" > "$CONFIG_FILE"
+
+echo >> "$CONFIG_FILE"
+echo "# Deployment definitions" >> "$CONFIG_FILE"
+echo "home_domain=$ZONE" >> "$CONFIG_FILE"
+echo "sprout_hostname=$SPROUT_HOSTNAME" >> "$CONFIG_FILE"
+echo "sprout_registration_store=$SPROUT_REGISTRATION_STORE" >> "$CONFIG_FILE"
+echo "hs_hostname=$HS_HOSTNAME" >> "$CONFIG_FILE"
+echo "hs_provisioning_hostname=$HS_PROVISIONING_HOSTNAME" >> "$CONFIG_FILE"
+echo "ralf_hostname=$RALF_HOSTNAME" >> "$CONFIG_FILE"
+echo "ralf_session_store=$RALF_SESSION_STORE" >> "$CONFIG_FILE"
+echo "xdms_hostname=$XDMS_HOSTNAME" >> "$CONFIG_FILE"
+echo "chronos_hostname=$CHRONOS_HOSTNAME" >> "$CONFIG_FILE"
+echo "cassandra_hostname=$CASSANDRA_HOSTNAME" >> "$CONFIG_FILE"
+
+echo >> "$CONFIG_FILE"
+echo "# Email server configuration" >> "$CONFIG_FILE"
+echo "smtp_smarthost=$SMTP_HOSTNAME" >> "$CONFIG_FILE"
+echo "smtp_username=$SMTP_USERNAME" >> "$CONFIG_FILE"
+echo "smtp_password=$SMTP_PASSWORD" >> "$CONFIG_FILE"
+echo "email_recovery_sender=clearwater@$ZONE" >> "$CONFIG_FILE"
+
+echo >> "$CONFIG_FILE"
+echo "# I-CSCF/S-CSCF configuration" >> "$CONFIG_FILE"
+echo "upstream_hostname=scscf.$HOSTNAME" >> "$CONFIG_FILE"
+
+echo >> "$CONFIG_FILE"
+echo "# Keys" >> "$CONFIG_FILE"
+echo "signup_key=$SECRET" >> "$CONFIG_FILE"
+echo "turn_workaround=$SECRET" >> "$CONFIG_FILE"
+echo "ellis_api_key=$SECRET" >> "$CONFIG_FILE"
+echo "ellis_cookie_key=$SECRET" >> "$CONFIG_FILE"
+
+if [ "$REDUCE_CASSANDRA_MEM_USAGE" = True ]; then 
+	echo >> "$CONFIG_FILE"
+	echo "# $REDUCE_CASSANDRA_MEM_USAGE" >> "$CONFIG_FILE"
+	echo "reduce_cassandra_mem_usage=Y" >> "$CONFIG_FILE"
+fi
+
+# Copy to other hosts
+#cw-upload_shared_config

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/scripts/ralf/create.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/ralf/create.sh b/examples/clearwater/scripts/ralf/create.sh
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/scripts/ralf/delete.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/ralf/delete.sh b/examples/clearwater/scripts/ralf/delete.sh
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/scripts/sprout/create.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/sprout/create.sh b/examples/clearwater/scripts/sprout/create.sh
new file mode 100644
index 0000000..32f2a1a
--- /dev/null
+++ b/examples/clearwater/scripts/sprout/create.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+set -e
+
+yes | aptdcon --hide-terminal --install sprout
+yes | aptdcon --hide-terminal --install clearwater-management
+
+# Memento
+#yes | aptdcon --hide-terminal --install memento-as memento-nginx

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/scripts/sprout/delete.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/sprout/delete.sh b/examples/clearwater/scripts/sprout/delete.sh
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/scripts/velum/create.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/velum/create.sh b/examples/clearwater/scripts/velum/create.sh
new file mode 100644
index 0000000..ae22417
--- /dev/null
+++ b/examples/clearwater/scripts/velum/create.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+set -e
+
+yes | aptdcon --hide-terminal --install vellum
+yes | aptdcon --hide-terminal --install clearwater-management
+
+# Memento
+#yes | aptdcon --hide-terminal --install memento-cassandra

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/scripts/velum/delete.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/velum/delete.sh b/examples/clearwater/scripts/velum/delete.sh
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/types/cassandra.yaml
----------------------------------------------------------------------
diff --git a/examples/clearwater/types/cassandra.yaml b/examples/clearwater/types/cassandra.yaml
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/types/clearwater.yaml
----------------------------------------------------------------------
diff --git a/examples/clearwater/types/clearwater.yaml b/examples/clearwater/types/clearwater.yaml
new file mode 100644
index 0000000..37e5831
--- /dev/null
+++ b/examples/clearwater/types/clearwater.yaml
@@ -0,0 +1,285 @@
+# http://clearwater.readthedocs.io/en/stable/Clearwater_Architecture.html
+
+imports:
+  - ims.yaml
+
+dsl_definitions:
+
+  clearwater_operation_dependencies: &CLEARWATER_OPERATION_DEPENDENCIES
+    - "ssh.user > { get_property: [ HOST, host, ssh.user ] }"
+    - "ssh.password > { get_property: [ HOST, host, ssh.password ] }"
+    - "ssh.address > { get_attribute: [ HOST, public_address ] }"
+    - "ssh.use_sudo > true"
+
+capability_types:
+
+  clearwater.Container:
+    description: >-
+      Clearwater container capability.
+    derived_from: tosca.capabilities.Container
+    properties:
+      ssh.user:
+        type: string
+      ssh.password:
+        type: string
+      max_log_directory_size:
+        type: scalar-unit.size
+        default: 0 B # means no max size
+      reduce_cassandra_mem_usage:
+        type: boolean
+        default: false
+
+node_types:
+
+  clearwater.Host:
+    description: >-
+      Clearwater host.
+    derived_from: tosca.nodes.Compute
+    interfaces:
+      Standard:
+        type: tosca.interfaces.node.lifecycle.Standard
+        configure:
+          implementation:
+            primary: scripts/host/configure.sh
+            dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+    capabilities:
+      host: # override
+         type: clearwater.Container
+         valid_source_types: [ tosca.nodes.SoftwareComponent ]
+
+  clearwater.SoftwareComponent:
+    description: >-
+      Clearwater software components must be installed in a Clearwater-capable container.
+    derived_from: tosca.nodes.SoftwareComponent
+    requirements:
+      - host: # override
+          capability: clearwater.Container
+          node: tosca.nodes.Compute
+          relationship: tosca.relationships.HostedOn
+
+  clearwater.Bono:
+    description: >-
+      Clearwater edge proxy.
+
+      The Bono nodes form a horizontally scalable SIP edge proxy providing both a SIP IMS Gm
+      compliant interface and a WebRTC interface to clients. Client connections are load balanced
+      across the nodes. The Bono node provides the anchor point for the client's connection to the
+      Clearwater system, including support for various NAT traversal mechanisms. A client is
+      therefore anchored to a particular Bono node for the duration of its registration, but can
+      move to another Bono node if the connection or client fails.
+
+      Clients can connect to Bono using SIP/UDP or SIP/TCP. Bono supports any WebRTC client that
+      performs call setup signaling using SIP over WebSocket.
+
+      Alternatively, Clearwater can be deployed with a third party P-CSCF or Session Border
+      Controller implementing P-CSCF. In this case Bono nodes are not required.
+    derived_from: clearwater.SoftwareComponent
+    capabilities:
+      Gm: ims.capabilities.Gm
+    interfaces:
+      Standard:
+        type: tosca.interfaces.node.lifecycle.Standard
+        create:
+          implementation:
+            primary: scripts/bono/create.sh
+            dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+        delete:
+          implementation:
+            primary: scripts/bono/delete.sh
+            dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+
+  clearwater.Sprout:
+    description: >-
+      Clearwater SIP router.
+      
+      The Sprout nodes act as a horizontally scalable, combined SIP registrar and authoritative
+      routing proxy, and handle client authentication and the ISC interface to application servers.
+      The Sprout nodes also contain the in-built MMTEL application server. SIP transactions are load
+      balanced across the Sprout cluster, so there is no long-lived association between a client and
+      a particular Sprout node. Sprout does not store any long-lived data itself and instead uses
+      web service interfaces to Homestead and Homer to retrieve HSS configuration such as
+      authentication data/user profiles and MMTEL service settings APIs to Vellum for storing
+      subscriber registration data and for running timers.
+
+      Sprout is where the bulk of the I-CSCF and S-CSCF function resides, with the remainder
+      provided by Dime (and backed by the long-lived data stores on Vellum).            
+    derived_from: clearwater.SoftwareComponent
+    properties:
+      memento:
+        description: >-
+          Set to true if you want the Sprout node to include a Memento Application server.
+        type: boolean
+        default: false
+    interfaces:
+      Standard:
+        type: tosca.interfaces.node.lifecycle.Standard
+        create:
+          implementation:
+            primary: scripts/sprout/create.sh
+            dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+        delete:
+          implementation:
+            primary: scripts/sprout/delete.sh
+            dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+
+  clearwater.Dime:
+    description: >-
+      Clearwater Diameter gateway.
+      
+      Dime nodes run Clearwater's Homestead and Ralf components.
+    derived_from: clearwater.SoftwareComponent
+    capabilities:
+      host:
+         type: tosca.capabilities.Container
+         valid_source_types: [ clearwater.DimeSoftwareComponent ]
+    interfaces:
+      Standard:
+        type: tosca.interfaces.node.lifecycle.Standard
+        create:
+          implementation:
+            primary: scripts/dime/create.sh
+            dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+        delete:
+          implementation:
+            primary: scripts/dime/delete.sh
+            dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+
+  clearwater.DimeSoftwareComponent:
+    description: >-
+      Base type for Dime software components.
+    derived_from: clearwater.SoftwareComponent
+    requirements:
+      - host: # override
+          capability: tosca.capabilities.Container
+          node: clearwater.Dime
+
+  clearwater.Homestead:
+    description: >-
+      Clearwater HSS cache.
+      
+      Homestead provides a web services interface to Sprout for retrieving authentication
+      credentials and user profile information. It can either master the data (in which case it
+      exposes a web services provisioning interface) or can pull the data from an IMS compliant HSS
+      over the Cx interface. The Homestead nodes themselves are stateless - the mastered / cached
+      subscriber data is all stored on Vellum (via Cassandra’s Thrift interface).
+
+      In the IMS architecture, the HSS mirror function is considered to be part of the I-CSCF and
+      S-CSCF components, so in Clearwater I-CSCF and S-CSCF function is implemented with a
+      combination of Sprout and Dime clusters.
+    derived_from: clearwater.DimeSoftwareComponent
+    capabilities:
+      Cx: ims.capabilities.Cx
+    interfaces:
+      Standard:
+        type: tosca.interfaces.node.lifecycle.Standard
+        create:
+          implementation:
+            primary: scripts/homestead/create.sh
+            dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+        delete:
+          implementation:
+            primary: scripts/homestead/delete.sh
+            dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+
+  clearwater.Ralf:
+    description: >-
+      Clearwater CTF.
+      
+      Ralf provides an HTTP API that both Bono and Sprout can use to report billable events that
+      should be passed to the CDF (Charging Data Function) over the Rf billing interface. Ralf is
+      stateless, using Vellum to maintain the long lived session state and run the timers necessary
+      to enable it to conform to the Rf protocol.
+    derived_from: clearwater.DimeSoftwareComponent
+    capabilities:
+      Rf: ims.capabilities.Rf
+    interfaces:
+      Standard:
+        type: tosca.interfaces.node.lifecycle.Standard
+        create:
+          implementation:
+            primary: scripts/ralf/create.sh
+            dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+        delete:
+          implementation:
+            primary: scripts/ralf/delete.sh
+            dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+
+  clearwater.Velum:
+    description: >-
+      Clearwater state store.
+
+      Vellum is used to maintain all long-lived state in the deployment. It does this by running a
+      number of cloud optimized, distributed storage clusters.
+      
+      - Cassandra. Cassandra is used by Homestead to store authentication credentials and profile
+      information, and is used by Homer to store MMTEL service settings. Vellum exposes Cassandra's
+      Thrift API.
+      
+      - etcd. etcd is used by Vellum itself to share clustering information between Vellum nodes and
+      by other nodes in the deployment for shared configuration.
+      
+      - Chronos. Chronos is a distributed, redundant, reliable timer service developed by
+      Clearwater. It is used by Sprout and Ralf nodes to enable timers to be run (e.g. for SIP
+      Registration expiry) without pinning operations to a specific node (one node can set the timer
+      and another act on it when it pops). Chronos is accessed via an HTTP API.
+      
+      - Memcached / Astaire. Vellum also runs a Memcached cluster fronted by Astaire. Astaire is a
+      service developed by Clearwater that enabled more rapid scale up and scale down of memcached
+      clusters. This cluster is used by Sprout and Ralf for storing registration and session state.
+    derived_from: clearwater.SoftwareComponent
+    properties:
+      memento:
+        description: >-
+          Set to true if you want your Sprout node includes a Memento Application server.
+        type: boolean
+        default: false
+    interfaces:
+      Standard:
+        type: tosca.interfaces.node.lifecycle.Standard
+        create:
+          implementation:
+            primary: scripts/velum/create.sh
+            dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+        delete:
+          implementation:
+            primary: scripts/velum/delete.sh
+            dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+
+  clearwater.Homer:
+    description: >-
+      Clearwater XDMS.
+      
+      Homer is a standard XDMS used to store MMTEL service settings documents for each user of the
+      system. Documents are created, read, updated and deleted using a standard XCAP interface. As
+      with Homestead, the Homer nodes use Vellum as the data store for all long lived data.
+    derived_from: clearwater.SoftwareComponent
+    interfaces:
+      Standard:
+        type: tosca.interfaces.node.lifecycle.Standard
+        create:
+          implementation:
+            primary: scripts/homer/create.sh
+            dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+        delete:
+          implementation:
+            primary: scripts/homer/delete.sh
+            dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+
+  clearwater.Ellis:
+    description: >-
+      Ellis is a sample provisioning portal providing self sign-up, password management, line
+      management and control of MMTEL service settings. It is not intended to be a part of
+      production Clearwater deployments (it is not easy to horizontally scale because of the MySQL
+      underpinnings for one thing) but to make the system easy to use out of the box.
+    derived_from: clearwater.SoftwareComponent
+    interfaces:
+      Standard:
+        type: tosca.interfaces.node.lifecycle.Standard
+        create:
+          implementation:
+            primary: scripts/ellis/create.sh
+            dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+        delete:
+          implementation:
+            primary: scripts/ellis/delete.sh
+            dependencies: *CLEARWATER_OPERATION_DEPENDENCIES

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/clearwater/types/ims.yaml
----------------------------------------------------------------------
diff --git a/examples/clearwater/types/ims.yaml b/examples/clearwater/types/ims.yaml
new file mode 100644
index 0000000..6b9d8e3
--- /dev/null
+++ b/examples/clearwater/types/ims.yaml
@@ -0,0 +1,394 @@
+# https://en.wikipedia.org/wiki/IP_Multimedia_Subsystem#Interfaces_description
+
+capability_types:
+
+  # In IMS these are called "interfaces".
+
+  ims.capabilities.Diameter:
+    derived_from: tosca.capabilities.Root
+
+  ims.capabilities.TCP:
+    derived_from: tosca.capabilities.Root
+
+  ims.capabilities.SIP:
+    derived_from: tosca.capabilities.Root
+
+  ims.capabilities.RTP:
+    derived_from: tosca.capabilities.Root
+
+  ims.capabilities.H248:
+    derived_from: tosca.capabilities.Root
+
+  ims.capabilities.HTTP:
+    derived_from: tosca.capabilities.Root
+
+  ims.capabilities.MAP:
+    derived_from: tosca.capabilities.Root
+
+  ims.capabilities.Cr:
+    description: >-
+      Used by MRFC to fetch documents (e.g. scripts, announcement files, and other resources) from
+      an AS. Also used for media control related commands.    
+    derived_from: ims.capabilities.TCP
+
+  ims.capabilities.Cx:
+    description: >-
+      Used to send subscriber data to the S-CSCF; including filter criteria and their priority. Also
+      used to furnish CDF and/or OCF addresses.
+    derived_from: ims.capabilities.Diameter
+
+  ims.capabilities.Dh:
+    description: >-
+      Used by AS to find the HSS holding the user profile information in a multi-HSS environment.
+      DH_SLF_QUERY indicates an IMPU and DX_SLF_RESP return the HSS name.
+    derived_from: ims.capabilities.Diameter
+
+  ims.capabilities.Dx:
+    description: >-
+      Used by I-CSCF or S-CSCF to find a correct HSS in a multi-HSS environment. DX_SLF_QUERY
+      indicates an IMPU and DX_SLF_RESP return the HSS name.
+    derived_from: ims.capabilities.Diameter
+
+  ims.capabilities.Gm:
+    description: >-
+      Used to exchange messages between SIP user equipment (UE) or Voip gateway and P-CSCF.
+    derived_from: ims.capabilities.SIP
+
+  ims.capabilities.Go:
+    description: >-
+      Allows operators to control QoS in a user plane and exchange charging correlation
+      information between IMS and GPRS network.
+    derived_from: ims.capabilities.Diameter
+
+  ims.capabilities.Gq:
+    description: >-
+      Used to exchange policy decisions-related information between P-CSCF and PDF.
+    derived_from: ims.capabilities.Diameter
+    
+  ims.capabilities.Gx:
+    description: >-
+      Used to exchange policy decisions-related information between PCEF and PCRF.
+    derived_from: ims.capabilities.Diameter
+    
+  ims.capabilities.Gy:
+    description: >-
+      Used for online flow-based bearer charging. Functionally equivalent to Ro interface.
+    derived_from: ims.capabilities.Diameter
+
+  ims.capabilities.ISC:
+    description: >-
+      Reference point between S-CSCF and AS. Main functions are to:
+      * Notify the AS of the registered IMPU, registration state and UE capabilities
+      * Supply the AS with information to allow it to execute multiple services
+      * Convey charging function addresses
+    derived_from: ims.capabilities.SIP
+
+  ims.capabilities.Ici:
+    description: >-
+      Used to exchange messages between an IBCF and another IBCF belonging to a different IMS
+      network.
+    derived_from: ims.capabilities.SIP
+
+  ims.capabilities.Izi:
+    description: >-
+      Used to forward media streams from a TrGW to another TrGW belonging to a different IMS
+      network.
+    derived_from: ims.capabilities.RTP
+
+  ims.capabilities.Ma:
+    description: >-
+      Main functions are to:
+      * Forward SIP requests which are destined to a public service identity hosted by the AS
+      * Originate a session on behalf of a user or public service identity, if the AS has no
+        knowledge of a S-CSCF assigned to that user or public service identity
+      * Convey charging function addresses
+    derived_from: ims.capabilities.SIP
+
+  ims.capabilities.Mg:
+    description: >-
+      ISUP signalling to SIP signalling and forwards SIP signalling to I-CSCF.
+    derived_from: ims.capabilities.SIP
+
+  ims.capabilities.Mi:
+    description: >-
+      Used to exchange messages between S-CSCF and BGCF.
+    derived_from: ims.capabilities.SIP
+
+  ims.capabilities.Mj:
+    description: >-
+      Used for the interworking with the PSTN/CS domain, when the BGCF has determined that a
+      breakout should occur in the same IMS network to send SIP message from BGCF to MGCF.
+    derived_from: ims.capabilities.SIP
+
+  ims.capabilities.Mk:
+    description: >-
+      Used for the interworking with the PSTN/CS domain, when the BGCF has determined that a
+      breakout should occur in another IMS network to send SIP message from BGCF to the BGCF in the
+      other network.
+    derived_from: ims.capabilities.SIP
+
+  ims.capabilities.Mm:
+    description: >-
+      Used for exchanging messages between IMS and external IP networks.
+    derived_from: ims.capabilities.SIP
+
+  ims.capabilities.Mn:
+    description: >-
+      Allows control of user-plane resources.
+    derived_from: ims.capabilities.H248
+
+  ims.capabilities.Mp:
+    description: >-
+      Allows an MRFC to control media stream resources provided by an MRFP.
+    derived_from: ims.capabilities.H248
+
+  ims.capabilities.Mr:
+    description: >-
+      Used to exchange information between S-CSCF and MRFC.
+    derived_from: ims.capabilities.SIP
+
+  ims.capabilities.Mr2:
+    description: >-
+      Used to exchange session controls between AS and MRFC.
+    derived_from: ims.capabilities.SIP
+
+  ims.capabilities.Mw:
+    description: >-
+      Used to exchange messages between CSCFs. AGCF appears as a P-CSCF to the other CSCFs.
+    derived_from: ims.capabilities.SIP
+
+  ims.capabilities.Mx:
+    description: >-
+      Used for the interworking with another IMS network, when the BGCF has determined that a
+      breakout should occur in the other IMS network to send SIP message from BGCF to the IBCF in
+      the other network.
+    derived_from: ims.capabilities.SIP
+
+  ims.capabilities.P1:
+    description: >-
+      Used for call control services by AGCF to control H.248 A-MGW and residential gateways.
+    derived_from: ims.capabilities.H248
+
+  ims.capabilities.P2:
+    description: >-
+      Reference point between AGCF and CSCF.
+    derived_from: ims.capabilities.SIP
+
+  ims.capabilities.Rc:
+    description: >-
+      Used by the AS to request that media resources be assigned to a call when using MRB in-line
+      mode or in query mode.
+    derived_from: ims.capabilities.SIP
+
+  ims.capabilities.Rf:
+    description: >-
+      Used to exchange offline charging information with CDF.
+    derived_from: ims.capabilities.Diameter
+
+  ims.capabilities.Ro:
+    description: >-
+        Used to exchange online charging information with OCF.
+    derived_from: ims.capabilities.Diameter
+
+  ims.capabilities.Rx:
+    description: >-
+      Used to exchange policy and charging related information between P-CSCF and PCRF. Replacement
+      for the Gq reference point.
+    derived_from: ims.capabilities.Diameter
+
+  ims.capabilities.Sh:
+    description: >-
+      Used to exchange User Profile information (e.g., user-related data, group lists,
+      user-service-related information or user location information or charging function addresses
+      (used when the AS has not received the third-party REGISTER for a user)) between an AS (SIP
+      AS or OSA SCS) and HSS. Also allow AS to activate/deactivate filter criteria stored in the HSS
+      on a per-subscriber basis.
+    derived_from: ims.capabilities.Diameter
+
+  ims.capabilities.Si:
+    description: >-
+      Transports CAMEL subscription information, including triggers for use by CAMEL-based
+      application services information.
+    derived_from: ims.capabilities.MAP
+
+  ims.capabilities.Sr:
+    description: >-
+      Used by MRFC to fetch documents (scripts and other resources) from an AS.
+    derived_from: ims.capabilities.HTTP
+
+  ims.capabilities.Ut:
+    description: >-
+      Facilitates the management of subscriber information related to services and settings.
+    derived_from: ims.capabilities.HTTP
+
+  ims.capabilities.Z:
+    description: >-
+      Conversion of POTS services to SIP messages.
+    derived_from: tosca.capabilities.Root
+
+
+# https://en.wikipedia.org/wiki/IP_Multimedia_Subsystem#Core_network
+
+node_types:
+
+  # In IMS these are called "functions".
+
+  ims.nodes.HSS:
+    description: >-
+      The home subscriber server (HSS), or user profile server function (UPSF), is a master user
+      database that supports the IMS network entities that actually handle calls. It contains the
+      subscription-related information (subscriber profiles), performs authentication and
+      authorization of the user, and can provide information about the subscriber's location and IP
+      information. It is similar to the GSM home location register (HLR) and Authentication centre
+      (AuC).
+
+      A subscriber location function (SLF) is needed to map user addresses when multiple HSSs are
+      used.
+    derived_from: tosca.nodes.Root
+
+  ims.nodes.CSCF:
+    description: >-
+      Several roles of SIP servers or proxies, collectively called Call Session Control Function
+      (CSCF), are used to process SIP signalling packets in the IMS.
+    derived_from: tosca.nodes.Root
+
+  ims.nodes.P-CSCF:
+    description: >-
+      A Proxy-CSCF (P-CSCF) is a SIP proxy that is the first point of contact for the IMS terminal.
+      It can be located either in the visited network (in full IMS networks) or in the home network
+      (when the visited network is not IMS compliant yet). Some networks may use a Session Border
+      Controller (SBC) for this function. The P-CSCF is at its core a specialized SBC for the
+      User–network interface which not only protects the network, but also the IMS terminal. The use
+      of an additional SBC between the IMS terminal and the P-CSCF is unnecessary and infeasible due
+      to the signaling being encrypted on this leg. The terminal discovers its P-CSCF with either
+      DHCP, or it may be configured (e.g. during initial provisioning or via a 3GPP IMS Management
+      Object (MO)) or in the ISIM or assigned in the PDP Context (in General Packet Radio Service
+      (GPRS)). 
+    derived_from: ims.nodes.CSCF
+
+  ims.nodes.I-CSCF:
+    description: >-
+      An Interrogating-CSCF (I-CSCF) is another SIP function located at the edge of an
+      administrative domain. Its IP address is published in the Domain Name System (DNS) of the
+      domain (using NAPTR and SRV type of DNS records), so that remote servers can find it, and use
+      it as a forwarding point (e.g., registering) for SIP packets to this domain. 
+    derived_from: ims.nodes.CSCF
+    
+  ims.nodes.S-CSCF:
+    description: >-
+      A Serving-CSCF (S-CSCF) is the central node of the signalling plane. It is a SIP server, but
+      performs session control too. It is always located in the home network. It uses Diameter Cx
+      and Dx interfaces to the HSS to download user profiles and upload user-to-S-CSCF associations
+      (the user profile is only cached locally for processing reasons only and is not changed). All
+      necessary subscriber profile information is loaded from the HSS. 
+    derived_from: ims.nodes.CSCF
+
+  ims.nodes.AS:
+    description: >-
+      SIP Application servers (AS) host and execute services, and interface with the S-CSCF using
+      SIP. An example of an application server that is being developed in 3GPP is the Voice call
+      continuity Function (VCC Server). Depending on the actual service, the AS can operate in SIP
+      proxy mode, SIP UA (user agent) mode or SIP B2BUA mode. An AS can be located in the home
+      network or in an external third-party network. If located in the home network, it can query
+      the HSS with the Diameter Sh or Si interfaces (for a SIP-AS).
+    derived_from: tosca.nodes.Root
+
+  ims.nodes.SIP-AS:
+    description: >-
+      Host and execute IMS specific services.
+    derived_from: ims.nodes.AS
+
+  ims.nodes.IM-SSF:
+    description: >-
+      IP Multimedia Service Switching Function. Interfaces SIP to CAP to communicate with CAMEL
+      Application Servers.
+    derived_from: ims.nodes.AS
+
+  ims.nodes.OSA-SCS:
+    description: >-
+      OSA service capability server. Interfaces SIP to the OSA framework.
+    derived_from: ims.nodes.AS
+
+  ims.nodes.AS-ILCM:
+    description: >-
+      The AS-ILCM (Application Server - Incoming Leg Control Model) stores transaction state, and
+      may optionally store session state depending on the specific service being executed. The
+      AS-ILCM interfaces to the S-CSCF (ILCM) for an incoming leg. Application Logic provides the
+      service(s) and interacts between the AS-ILCM and AS-OLCM.
+    derived_from: ims.nodes.AS
+
+  ims.nodes.AS-OLCM:
+    description: >-
+      The AS-OLCM (Application Server - Outgoing Leg Control Model) stores transaction state, and
+      may optionally store session state depending on the specific service being executed. The
+      AS-OLCM interfaces to the S-CSCF (OLCM) for an outgoing leg. Application Logic provides the
+      service(s) and interacts between the AS-ILCM and AS-OLCM.
+    derived_from: ims.nodes.AS
+
+  ims.nodes.MRF:
+    description: >-
+      The Media Resource Function (MRF) provides media related functions such as media manipulation
+      (e.g. voice stream mixing) and playing of tones and announcements.
+
+      Each MRF is further divided into a media resource function controller (MRFC) and a media
+      resource function processor (MRFP).
+    derived_from: tosca.nodes.Root
+
+  ims.nodes.MRFC:
+    description: >-
+      The MRFC is a signalling plane node that interprets information coming from an AS and S-CSCF
+      to control the MRFP.
+    derived_from: tosca.nodes.Root
+
+  ims.nodes.MRFP:
+    description: >-
+      The MRFP is a media plane node used to mix, source or process media streams. It can also
+      manage access right to shared resources.
+    derived_from: tosca.nodes.Root
+    
+  ims.nodes.MRB:
+    description: >-
+      The Media Resource Broker (MRB) is a functional entity that is responsible for both collection
+      of appropriate published MRF information and supplying of appropriate MRF information to
+      consuming entities such as the AS. MRB can be used in two modes:
+      * Query mode: AS queries the MRB for media and sets up the call using the response of MRB
+      * In-Line Mode: AS sends a SIP INVITE to the MRB. The MRB sets up the call
+    derived_from: tosca.nodes.Root
+
+  ims.nodes.BGCF:
+    description: >-
+      A Breakout Gateway Control Function (BGCF) is a SIP proxy which processes requests for routing
+      from an S-CSCF when the S-CSCF has determined that the session cannot be routed using DNS or
+      ENUM/DNS. It includes routing functionality based on telephone numbers.
+    derived_from: tosca.nodes.Root
+
+  ims.nodes.PTSNGateway:
+    description: >-
+      A PSTN/CS gateway interfaces with PSTN circuit switched (CS) networks. For signalling, CS
+      networks use ISDN User Part (ISUP) (or BICC) over Message Transfer Part (MTP), while IMS uses
+      SIP over IP. For media, CS networks use Pulse-code modulation (PCM), while IMS uses Real-time
+      Transport Protocol (RTP).
+    derived_from: tosca.nodes.Root
+
+  ims.nodes.SGW:
+    description: >-
+      A signalling gateway (SGW) interfaces with the signalling plane of the CS. It transforms lower
+      layer protocols as Stream Control Transmission Protocol (SCTP, an IP protocol) into Message
+      Transfer Part (MTP, an Signalling System 7 (SS7) protocol), to pass ISDN User Part (ISUP) from
+      the MGCF to the CS network.
+    derived_from: ims.nodes.PTSNGateway
+  
+  ims.nodes.MGCF:
+    description: >-
+      A media gateway controller function (MGCF) is a SIP endpoint that does call control protocol
+      conversion between SIP and ISUP/BICC and interfaces with the SGW over SCTP. It also controls
+      the resources in a Media Gateway (MGW) across an H.248 interface.
+    derived_from: ims.nodes.PTSNGateway
+    
+  ims.nodes.MGW:
+    description: >-
+      A media gateway (MGW) interfaces with the media plane of the CS network, by converting between
+      RTP and PCM. It can also transcode when the codecs don't match (e.g., IMS might use AMR, PSTN
+      might use G.711).
+    derived_from: ims.nodes.PTSNGateway
+  
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/hello-world/hello-world.yaml
----------------------------------------------------------------------
diff --git a/examples/hello-world/hello-world.yaml b/examples/hello-world/hello-world.yaml
new file mode 100644
index 0000000..86e2ad0
--- /dev/null
+++ b/examples/hello-world/hello-world.yaml
@@ -0,0 +1,38 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+node_types:
+
+  WebServer:
+    derived_from: tosca:Root
+    capabilities:
+      host:
+        type: tosca:Container
+
+  WebApp:
+    derived_from: tosca:WebApplication
+    properties:
+      port:
+        type: integer
+
+topology_template:
+
+  node_templates:
+    web_server:
+      type: WebServer
+
+    web_app:
+      type: WebApp
+      properties:
+        port: 9090
+      requirements:
+        - host: web_server
+      interfaces:
+        Standard:
+          configure: scripts/configure.sh
+          start: scripts/start.sh
+          stop: scripts/stop.sh
+
+  outputs:
+    port:
+      type: integer
+      value: { get_property: [ web_app, port ] }

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/examples/hello-world/helloworld.yaml
----------------------------------------------------------------------
diff --git a/examples/hello-world/helloworld.yaml b/examples/hello-world/helloworld.yaml
deleted file mode 100644
index 2fdc4d4..0000000
--- a/examples/hello-world/helloworld.yaml
+++ /dev/null
@@ -1,38 +0,0 @@
-tosca_definitions_version: tosca_simple_yaml_1_0
-
-node_types:
-
-  WebServer:
-    derived_from: tosca:Root
-    capabilities:
-      host:
-        type: tosca.capabilities.Container
-
-  WebApp:
-    derived_from: tosca.nodes.WebApplication
-    properties:
-      port:
-        type: integer
-
-topology_template:
-
-  node_templates:
-    web_server:
-      type: WebServer
-
-    web_app:
-      type: WebApp
-      properties:
-        port: 9090
-      requirements:
-        - host: web_server
-      interfaces:
-        Standard:
-          configure: scripts/configure.sh
-          start: scripts/start.sh
-          stop: scripts/stop.sh
-
-  outputs:
-    port:
-      type: integer
-      value: { get_property: [ web_app, port ] }

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
index 5427c7e..6785225 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
@@ -68,12 +68,14 @@ def get_inherited_capability_definitions(context, presentation, for_presentation
                 capability_definition = capability_definitions[capability_name]
 
                 # Check if we changed the type
-                type1 = capability_definition.type
-                type2 = our_capability_definition.type
-                if type1 != type2:
+                type1 = capability_definition._get_type(context)
+                type2 = our_capability_definition._get_type(context)
+
+                if not type1._is_descendant(context, type2):
                     context.validation.report(
-                        'capability definition changes type from "{0}" to "{1}" in "{2}"'
-                        .format(type1, type2, presentation._fullname),
+                        'capability definition type "{0}" is not a descendant of overriden '
+                        'capability definition type "{1}"' \
+                        .format(type1._name, type2._name),
                         locator=our_capability_definition._locator, level=Issue.BETWEEN_TYPES)
 
                 merge_capability_definition(context, presentation, capability_definition,
@@ -168,6 +170,8 @@ def merge_capability_definition(context, presentation, capability_definition,
                                 from_capability_definition):
     raw_properties = OrderedDict()
 
+    capability_definition._raw['type'] = from_capability_definition.type
+
     # Merge properties from type
     from_property_defintions = from_capability_definition.properties
     merge_raw_parameter_definitions(context, presentation, raw_properties, from_property_defintions,

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/extensions/aria_extension_tosca/simple_v1_0/modeling/functions.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/functions.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/functions.py
index 590c6a0..b04fa18 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/functions.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/functions.py
@@ -200,21 +200,21 @@ class GetProperty(Function):
         for modelable_entity in modelable_entities:
             properties = None
 
-            if hasattr(modelable_entity, 'requirement_templates') \
+            if hasattr(modelable_entity, 'requirements') \
                 and modelable_entity.requirement_templates \
-                and (req_or_cap_name in [v.name for v in modelable_entity.requirement_templates]):
-                for requirement_template in modelable_entity.requirement_templates:
-                    if requirement_template.name == req_or_cap_name:
+                and (req_or_cap_name in [v.name for v in modelable_entity.requirements]):
+                for requirement in modelable_entity.requirements:
+                    if requirement.name == req_or_cap_name:
                         # First argument refers to a requirement
                         # TODO: should follow to matched capability in other node...
                         raise CannotEvaluateFunctionException()
                         # break
                 nested_property_name_or_index = self.nested_property_name_or_index[1:]
-            elif hasattr(modelable_entity, 'capability_templates') \
-                and modelable_entity.capability_templates \
-                and (req_or_cap_name in modelable_entity.capability_templates):
+            elif hasattr(modelable_entity, 'capabilities') \
+                and modelable_entity.capabilities \
+                and (req_or_cap_name in modelable_entity.capabilities):
                 # First argument refers to a capability
-                properties = modelable_entity.capability_templates[req_or_cap_name].properties
+                properties = modelable_entity.capabilities[req_or_cap_name].properties
                 nested_property_name_or_index = self.nested_property_name_or_index[1:]
             else:
                 properties = modelable_entity.properties
@@ -640,7 +640,7 @@ def get_target(container_holder, name, locator):
 
 def get_modelable_entity_parameter(modelable_entity, parameters, nested_parameter_name_or_index):
     if not parameters:
-        return False, True, None
+        return Evaluation(None, True)
 
     found = True
     final = True

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
index d5f447c..1535481 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
@@ -400,13 +400,15 @@ def merge_raw_operation_definitions(context, raw_operations, our_operations, int
 def merge_interface_definition(context, interface, our_source, presentation, type_name):
     if hasattr(our_source, 'type'):
         # Check if we changed the interface type
-        input_type1 = interface.type
-        input_type2 = our_source.type
-        if (input_type1 is not None) and (input_type2 is not None) and (input_type1 != input_type2):
+        type1 = interface._get_type(context)
+        type2 = our_source._get_type(context)
+
+        if not type1._is_descendant(context, type2):
             context.validation.report(
-                'interface definition "%s" changes type from "%s" to "%s" in "%s"'
-                % (interface._name, input_type1, input_type2, presentation._fullname),
-                locator=input_type2._locator, level=Issue.BETWEEN_TYPES)
+                'interface definition type "{0}" is not a descendant of overriden '
+                'interface definition type "{1}"' \
+                .format(type1._name, type2._name),
+                locator=our_source._locator, level=Issue.BETWEEN_TYPES)
 
     # Add/merge inputs
     our_interface_inputs = our_source._get_inputs(context) \

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py
index 87c1a3b..ce1a475 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py
@@ -18,7 +18,8 @@ from aria.utils.formatting import pluralize
 from aria.parser.presentation import Value
 from aria.parser.validation import Issue
 
-from .data_types import coerce_value
+from .data_types import (coerce_value, get_primitive_data_type)
+from ..presentation.types import get_type_by_name
 
 
 #
@@ -149,16 +150,21 @@ def validate_required_values(context, presentation, values, definitions):
 
 def merge_raw_parameter_definition(context, presentation, raw_property_definition,
                                    our_property_definition, field_name, property_name):
-    # Check if we changed the type
-    # TODO: allow a sub-type?
-    type1 = raw_property_definition.get('type')
-    type2 = our_property_definition.type
+    # Check if we changed the parameter type
+    type1_name = raw_property_definition.get('type')
+    type1 = get_type_by_name(context, type1_name, 'data_types')
+    if type1 is None:
+        type1 = get_primitive_data_type(type1_name)
+    type2 = our_property_definition._get_type(context)
+    
     if type1 != type2:
-        context.validation.report(
-            'override changes type from "%s" to "%s" for property "%s" in "%s"'
-            % (type1, type2, property_name, presentation._fullname),
-            locator=presentation._get_child_locator(field_name, property_name),
-            level=Issue.BETWEEN_TYPES)
+        if not hasattr(type1, '_is_descendant') or not type1._is_descendant(context, type2):
+            context.validation.report(
+                'interface definition type "{0}" is not a descendant of overriden '
+                'interface definition type "{1}"' \
+                .format(type1._name, type2._name),
+                locator=presentation._get_child_locator(field_name, property_name),
+                level=Issue.BETWEEN_TYPES)
 
     merge(raw_property_definition, our_property_definition._raw)
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py b/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
index 920ebed..5f9750e 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
@@ -18,7 +18,8 @@ def convert_name_to_full_type_name(context, name, types_dict): # pylint: disable
     """
     Converts a type name to its full type name, or else returns it unchanged.
 
-    Works by checking for ``shorthand_name`` in the types' ``_extensions`` field. See also
+    Works by checking for ``shorthand_name`` and ``type_qualified_name`` in the types'
+    ``_extensions`` field. See also
     :class:`aria_extension_tosca.v1_0.presentation.extensible.ExtensiblePresentation`.
 
     Can be used as the conversion function argument in ``type_validator`` and
@@ -36,9 +37,10 @@ def convert_name_to_full_type_name(context, name, types_dict): # pylint: disable
 
 def get_type_by_name(context, name, *types_dict_names):
     """
-    Gets a type either by its full name or its shorthand name or typequalified name.
+    Gets a type either by its full name or its shorthand name or type-qualified name.
 
-    Works by checking for ``shorthand_name`` in the types' ``_extensions`` field. See also
+    Works by checking for ``shorthand_name`` and ``type_qualified_name`` in the types'
+    ``_extensions`` field. See also
     :class:`~aria_extension_tosca.v1_0.presentation.extensible.ExtensiblePresentation`.
 
     The arguments from the third onwards are used to locate a nested field under

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e8f15b44/extensions/aria_extension_tosca/simple_v1_0/types.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/types.py b/extensions/aria_extension_tosca/simple_v1_0/types.py
index 787aac2..5556179 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/types.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/types.py
@@ -193,6 +193,17 @@ class DataType(ExtensiblePresentation):
         return get_data_type(context, self, 'derived_from', allow_none=True)
 
     @cachedmethod
+    def _is_descendant(self, context, the_type):
+        if the_type is None:
+            return False
+        if not hasattr(the_type, '_name'):
+            # Must be a primitive type
+            return self._get_primitive_ancestor(context) == the_type
+        if hasattr(the_type, '_name') and (the_type._name == self._name):
+            return True
+        return self._is_descendant(context, the_type._get_parent(context))
+
+    @cachedmethod
     def _get_primitive_ancestor(self, context):
         parent = self._get_parent(context)
         if parent is not None:
@@ -387,6 +398,14 @@ class InterfaceType(ExtensiblePresentation):
                                        'interface_types')
 
     @cachedmethod
+    def _is_descendant(self, context, the_type):
+        if the_type is None:
+            return False
+        elif the_type._name == self._name:
+            return True
+        return self._is_descendant(context, the_type._get_parent(context))
+
+    @cachedmethod
     def _get_inputs(self, context):
         return FrozenDict(get_inherited_parameter_definitions(context, self, 'inputs'))