Remove dependency on context, modeling exceptions, some refactoring
Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/16a94538 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/16a94538 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/16a94538 Branch: refs/heads/ARIA-105-integrate-modeling Commit: 16a945383eb5cc6f8d4c97a3c6369e3bf235b1e8 Parents: dd5bfa9 Author: Tal Liron <[email protected]> Authored: Sun Mar 12 16:48:58 2017 -0500 Committer: Tal Liron <[email protected]> Committed: Sun Mar 12 16:48:58 2017 -0500 ---------------------------------------------------------------------- aria/cli/args_parser.py | 2 +- aria/cli/commands.py | 17 +- aria/cli/dry.py | 13 + aria/modeling/exceptions.py | 14 +- aria/modeling/mixins.py | 8 +- aria/modeling/service_common.py | 26 +- aria/modeling/service_instance.py | 304 ++++++++++++---------- aria/modeling/service_template.py | 373 ++++++++++++++------------- aria/modeling/utils.py | 84 ++---- aria/parser/consumption/__init__.py | 6 +- aria/parser/consumption/modeling.py | 83 +++--- aria/parser/reading/__init__.py | 4 +- aria/parser/reading/locator.py | 37 ++- tests/end2end/test_tosca_simple_v1_0.py | 6 +- tests/parser/utils.py | 14 +- 15 files changed, 538 insertions(+), 453 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/16a94538/aria/cli/args_parser.py ---------------------------------------------------------------------- diff --git a/aria/cli/args_parser.py b/aria/cli/args_parser.py index 1d18145..81ee513 100644 --- a/aria/cli/args_parser.py +++ b/aria/cli/args_parser.py @@ -91,7 +91,7 @@ def add_parse_parser(parse): 'consumer', nargs='?', default='validate', - help='"validate" (default), "presentation", "model", "types", "instance", or consumer ' + help='"validate" (default), "presentation", "template", "types", "instance", or consumer ' 'class name (full class path or short name)') parse.add_argument( '--loader-source', http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/16a94538/aria/cli/commands.py ---------------------------------------------------------------------- diff --git a/aria/cli/commands.py b/aria/cli/commands.py index a9079c5..f9d3053 100644 --- a/aria/cli/commands.py +++ b/aria/cli/commands.py @@ -36,10 +36,10 @@ from ..parser.consumption import ( ConsumerChain, Read, Validate, - Model, + ServiceTemplate, Types, Inputs, - Instance + ServiceInstance ) from ..parser.loading import LiteralLocation, UriLocation from ..utils.application import StorageManager @@ -157,14 +157,14 @@ class ParseCommand(BaseCommand): dumper = None elif consumer_class_name == 'presentation': dumper = consumer.consumers[0] - elif consumer_class_name == 'model': - consumer.append(Model) + elif consumer_class_name == 'template': + consumer.append(ServiceTemplate) elif consumer_class_name == 'types': - consumer.append(Model, Types) + consumer.append(ServiceTemplate, Types) elif consumer_class_name == 'instance': - consumer.append(Model, Inputs, Instance) + consumer.append(ServiceTemplate, Inputs, ServiceInstance) else: - consumer.append(Model, Inputs, Instance) + consumer.append(ServiceTemplate, Inputs, ServiceInstance) consumer.append(import_fullname(consumer_class_name)) if dumper is None: @@ -220,7 +220,8 @@ class WorkflowCommand(BaseCommand): # Parse context = ConsumptionContext() context.presentation.location = UriLocation(uri) - consumer = ConsumerChain(context, (Read, Validate, Model, Inputs, Instance)) + consumer = ConsumerChain(context, (Read, Validate, ServiceTemplate, Inputs, + ServiceInstance)) consumer.consume() if context.validation.dump_issues(): http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/16a94538/aria/cli/dry.py ---------------------------------------------------------------------- diff --git a/aria/cli/dry.py b/aria/cli/dry.py index 98b7217..114ab7a 100644 --- a/aria/cli/dry.py +++ b/aria/cli/dry.py @@ -26,6 +26,11 @@ _TERMINAL_LOCK = RLock() def convert_to_dry(service): + """ + Converts all operations on the service (on workflows, node interfaces, and relationship + interfaces) to run dryly. + """ + for workflow in service.workflows: convert_operation_to_dry(workflow) @@ -40,6 +45,10 @@ def convert_to_dry(service): def convert_operation_to_dry(oper): + """ + Converts a single :class:`Operation` to run dryly. + """ + plugin = oper.plugin_specification.name \ if oper.plugin_specification is not None else None if oper.inputs is None: @@ -56,6 +65,10 @@ def convert_operation_to_dry(oper): @operation def dry_operation(ctx, _plugin, _implementation, **kwargs): + """ + The dry operation simply prints out information about the operation to the console. + """ + with _TERMINAL_LOCK: print ctx.name if hasattr(ctx, 'relationship'): http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/16a94538/aria/modeling/exceptions.py ---------------------------------------------------------------------- diff --git a/aria/modeling/exceptions.py b/aria/modeling/exceptions.py index df29a21..6931c78 100644 --- a/aria/modeling/exceptions.py +++ b/aria/modeling/exceptions.py @@ -16,7 +16,19 @@ from ..exceptions import AriaException -class CannotEvaluateFunctionException(AriaException): +class ModelingException(AriaException): + """ + ARIA modeling exception. + """ + + +class ValueFormatException(ModelingException): + """ + ARIA modeling exception: the value is in the wrong format. + """ + + +class CannotEvaluateFunctionException(ModelingException): """ ARIA modeling exception: cannot evaluate the function at this time. """ http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/16a94538/aria/modeling/mixins.py ---------------------------------------------------------------------- diff --git a/aria/modeling/mixins.py b/aria/modeling/mixins.py index 04497b5..b9e5079 100644 --- a/aria/modeling/mixins.py +++ b/aria/modeling/mixins.py @@ -384,13 +384,13 @@ class InstanceModelMixin(ModelMixin): def as_raw(self): raise NotImplementedError - def validate(self, context): + def validate(self): pass - def coerce_values(self, context, container, report_issues): + def coerce_values(self, container, report_issues): pass - def dump(self, context): + def dump(self): pass @@ -401,5 +401,5 @@ class TemplateModelMixin(InstanceModelMixin): All model models can be instantiated into :class:`ServiceInstance` models. """ - def instantiate(self, context, container): + def instantiate(self, container): raise NotImplementedError http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/16a94538/aria/modeling/service_common.py ---------------------------------------------------------------------- diff --git a/aria/modeling/service_common.py b/aria/modeling/service_common.py index b3535a6..e6b3c8d 100644 --- a/aria/modeling/service_common.py +++ b/aria/modeling/service_common.py @@ -25,11 +25,12 @@ from sqlalchemy import ( ) from sqlalchemy.ext.declarative import declared_attr -from ..storage import exceptions +from ..parser.consumption import ConsumptionContext from ..utils import collections, formatting, console from .mixins import InstanceModelMixin, TemplateModelMixin from .types import List from . import utils +from . import exceptions class ParameterBase(TemplateModelMixin): @@ -68,8 +69,8 @@ class ParameterBase(TemplateModelMixin): try: return pickle.loads(self._value) except BaseException: - raise exceptions.StorageError('bad format for parameter of type "{0}": {1}'.format( - self.type_name, self._value)) + raise exceptions.ValueFormatException('bad format for parameter of type "{0}": {1}' + .format(self.type_name, self._value)) @value.setter def value(self, value): @@ -83,19 +84,20 @@ class ParameterBase(TemplateModelMixin): .format(self.type_name, value)) self._value = pickle.dumps(str(value)) - def instantiate(self, context, container): + def instantiate(self, container): from . import models return models.Parameter(name=self.name, type_name=self.type_name, _value=self._value, description=self.description) - def coerce_values(self, context, container, report_issues): + def coerce_values(self, container, report_issues): if self.value is not None: - self.value = utils.coerce_value(context, container, self.value, + self.value = utils.coerce_value(container, self.value, report_issues) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() if self.type_name is not None: console.puts('{0}: {1} ({2})'.format( context.style.property(self.name), @@ -189,12 +191,13 @@ class TypeBase(InstanceModelMixin): self._append_raw_children(types) return types - def dump(self, context): + def dump(self,): + context = ConsumptionContext.get_thread_local() if self.name: console.puts(context.style.type(self.name)) with context.style.indent: for child in self.children: - child.dump(context) + child.dump() def _append_raw_children(self, types): for child in self.children: @@ -224,12 +227,13 @@ class MetadataBase(TemplateModelMixin): ('name', self.name), ('value', self.value))) - def instantiate(self, context, container): + def instantiate(self, container): from . import models return models.Metadata(name=self.name, value=self.value) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() console.puts('{0}: {1}'.format( context.style.property(self.name), context.style.literal(self.value))) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/16a94538/aria/modeling/service_instance.py ---------------------------------------------------------------------- diff --git a/aria/modeling/service_instance.py b/aria/modeling/service_instance.py index ba18f73..613b371 100644 --- a/aria/modeling/service_instance.py +++ b/aria/modeling/service_instance.py @@ -26,6 +26,7 @@ from sqlalchemy.ext.declarative import declared_attr from .mixins import InstanceModelMixin from ..parser import validation +from ..parser.consumption import ConsumptionContext from ..utils import collections, formatting, console from . import ( @@ -157,17 +158,17 @@ class ServiceBase(InstanceModelMixin): # pylint: disable=too-many-public-methods # endregion - def satisfy_requirements(self, context): + def satisfy_requirements(self): satisfied = True for node in self.nodes: - if not node.satisfy_requirements(context): + if not node.satisfy_requirements(): satisfied = False return satisfied - def validate_capabilities(self, context): + def validate_capabilities(self): satisfied = True for node in self.nodes: - if not node.validate_capabilities(context): + if not node.validate_capabilities(): satisfied = False return satisfied @@ -192,21 +193,21 @@ class ServiceBase(InstanceModelMixin): # pylint: disable=too-many-public-methods return collections.FrozenList((group.name for group in self.find_groups(group_template_name))) - def is_node_a_target(self, context, target_node): + def is_node_a_target(self, target_node): for node in self.nodes: - if self._is_node_a_target(context, node, target_node): + if self._is_node_a_target(node, target_node): return True return False - def _is_node_a_target(self, context, source_node, target_node): - if source_node.relationships: - for relationship in source_node.relationships: - if relationship.target_node_id == target_node.name: + def _is_node_a_target(self, source_node, target_node): + if source_node.outbound_relationships: + for relationship in source_node.outbound_relationships: + if relationship.target_node.name == target_node.name: return True else: - node = context.modeling.instance.nodes.get(relationship.target_node_id) + node = relationship.target_node if node is not None: - if self._is_node_a_target(context, node, target_node): + if self._is_node_a_target(node, target_node): return True return False @@ -223,67 +224,74 @@ class ServiceBase(InstanceModelMixin): # pylint: disable=too-many-public-methods ('outputs', formatting.as_raw_dict(self.outputs)), ('workflows', formatting.as_raw_list(self.workflows)))) - def validate(self, context): - utils.validate_dict_values(context, self.meta_data) - utils.validate_list_values(context, self.nodes) - utils.validate_list_values(context, self.groups) - utils.validate_list_values(context, self.policies) + def validate(self): + utils.validate_dict_values(self.meta_data) + utils.validate_list_values(self.nodes) + utils.validate_list_values(self.groups) + utils.validate_list_values(self.policies) if self.substitution is not None: - self.substitution.validate(context) - utils.validate_dict_values(context, self.inputs) - utils.validate_dict_values(context, self.outputs) - utils.validate_dict_values(context, self.workflows) - - def coerce_values(self, context, container, report_issues): - utils.coerce_dict_values(context, container, self.meta_data, report_issues) - utils.coerce_list_values(context, container, self.nodes, report_issues) - utils.coerce_list_values(context, container, self.groups, report_issues) - utils.coerce_list_values(context, container, self.policies, report_issues) + self.substitution.validate() + utils.validate_dict_values(self.inputs) + utils.validate_dict_values(self.outputs) + utils.validate_dict_values(self.workflows) + + def coerce_values(self, container, report_issues): + utils.coerce_dict_values(container, self.meta_data, report_issues) + utils.coerce_list_values(container, self.nodes, report_issues) + utils.coerce_list_values(container, self.groups, report_issues) + utils.coerce_list_values(container, self.policies, report_issues) if self.substitution is not None: - self.substitution.coerce_values(context, container, report_issues) - utils.coerce_dict_values(context, container, self.inputs, report_issues) - utils.coerce_dict_values(context, container, self.outputs, report_issues) - utils.coerce_dict_values(context, container, self.workflows, report_issues) + self.substitution.coerce_values(container, report_issues) + utils.coerce_dict_values(container, self.inputs, report_issues) + utils.coerce_dict_values(container, self.outputs, report_issues) + utils.coerce_dict_values(container, self.workflows, report_issues) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() if self.description is not None: console.puts(context.style.meta(self.description)) - utils.dump_dict_values(context, self.meta_data, 'Metadata') + utils.dump_dict_values(self.meta_data, 'Metadata') for node in self.nodes: - node.dump(context) + node.dump() for group in self.groups: - group.dump(context) + group.dump() for policy in self.policies: - policy.dump(context) + policy.dump() if self.substitution is not None: - self.substitution.dump(context) - utils.dump_dict_values(context, self.inputs, 'Inputs') - utils.dump_dict_values(context, self.outputs, 'Outputs') - utils.dump_dict_values(context, self.workflows, 'Workflows') + self.substitution.dump() + utils.dump_dict_values(self.inputs, 'Inputs') + utils.dump_dict_values(self.outputs, 'Outputs') + utils.dump_dict_values(self.workflows, 'Workflows') - def dump_graph(self, context): - for node in self.nodes.itervalues(): - if not self.is_node_a_target(context, node): - self._dump_graph_node(context, node) + def dump_graph(self): + for node in self.nodes: + if not self.is_node_a_target(node): + self._dump_graph_node(node) - def _dump_graph_node(self, context, node): + def _dump_graph_node(self, node): + context = ConsumptionContext.get_thread_local() console.puts(context.style.node(node.name)) - if node.relationships: + if node.outbound_relationships: with context.style.indent: - for relationship in node.relationships: - relationship_name = (context.style.node(relationship.template_name) - if relationship.template_name is not None - else context.style.type(relationship.type_name)) - capability_name = (context.style.node(relationship.target_capability_name) - if relationship.target_capability_name is not None - else None) + for relationship in node.outbound_relationships: + if relationship.relationship_template is not None: + relationship_name = context.style.node( + relationship.relationship_template.name) + elif relationship.type is not None: + relationship_name = context.style.type(relationship.type.name) + else: + relationship_name = '?' + if relationship.target_capability is not None: + capability_name = context.style.node(relationship.target_capability.name) + else: + capability_name = None if capability_name is not None: console.puts('-> {0} {1}'.format(relationship_name, capability_name)) else: console.puts('-> {0}'.format(relationship_name)) - target_node = self.nodes.get(relationship.target_node_id) + target_node = relationship.target_node with console.indent(3): - self._dump_graph_node(context, target_node) + self._dump_graph_node(target_node) class NodeBase(InstanceModelMixin): # pylint: disable=too-many-public-methods @@ -443,28 +451,29 @@ class NodeBase(InstanceModelMixin): # pylint: disable=too-many-public-methods # endregion - def satisfy_requirements(self, context): + def satisfy_requirements(self): node_template = self.node_template satisfied = True for requirement_template in node_template.requirement_templates: # Find target template target_node_template, target_node_capability = \ - requirement_template.find_target(context, node_template) + requirement_template.find_target(node_template) if target_node_template is not None: - satisfied = self._satisfy_capability(context, - target_node_capability, + satisfied = self._satisfy_capability(target_node_capability, target_node_template, requirement_template) else: + context = ConsumptionContext.get_thread_local() context.validation.report('requirement "{0}" of node "{1}" has no target node ' 'template'.format(requirement_template.name, self.name), level=validation.Issue.BETWEEN_INSTANCES) satisfied = False return satisfied - def _satisfy_capability(self, context, target_node_capability, target_node_template, + def _satisfy_capability(self, target_node_capability, target_node_template, requirement_template): from . import models + context = ConsumptionContext.get_thread_local() # Find target nodes target_nodes = context.modeling.instance.find_nodes(target_node_template.name) if target_nodes: @@ -485,7 +494,7 @@ class NodeBase(InstanceModelMixin): # pylint: disable=too-many-public-methods if target_node is not None: if requirement_template.relationship_template is not None: relationship = \ - requirement_template.relationship_template.instantiate(context, self) + requirement_template.relationship_template.instantiate(self) else: relationship = models.Relationship(target_capability=target_capability) relationship.name = requirement_template.name @@ -511,7 +520,8 @@ class NodeBase(InstanceModelMixin): # pylint: disable=too-many-public-methods level=validation.Issue.BETWEEN_INSTANCES) return False - def validate_capabilities(self, context): + def validate_capabilities(self): + context = ConsumptionContext.get_thread_local() satisfied = False for capability in self.capabilities.itervalues(): if not capability.has_enough_relationships: @@ -536,7 +546,8 @@ class NodeBase(InstanceModelMixin): # pylint: disable=too-many-public-methods ('capabilities', formatting.as_raw_list(self.capabilities)), ('relationships', formatting.as_raw_list(self.outbound_relationships)))) - def validate(self, context): + def validate(self): + context = ConsumptionContext.get_thread_local() if len(self.name) > context.modeling.id_max_length: context.validation.report('"{0}" has an ID longer than the limit of {1:d} characters: ' '{2:d}'.format( @@ -547,29 +558,30 @@ class NodeBase(InstanceModelMixin): # pylint: disable=too-many-public-methods # TODO: validate that node template is of type? - utils.validate_dict_values(context, self.properties) - utils.validate_dict_values(context, self.interfaces) - utils.validate_dict_values(context, self.artifacts) - utils.validate_dict_values(context, self.capabilities) - utils.validate_list_values(context, self.outbound_relationships) - - def coerce_values(self, context, container, report_issues): - utils.coerce_dict_values(context, self, self.properties, report_issues) - utils.coerce_dict_values(context, self, self.interfaces, report_issues) - utils.coerce_dict_values(context, self, self.artifacts, report_issues) - utils.coerce_dict_values(context, self, self.capabilities, report_issues) - utils.coerce_list_values(context, self, self.outbound_relationships, report_issues) - - def dump(self, context): + utils.validate_dict_values(self.properties) + utils.validate_dict_values(self.interfaces) + utils.validate_dict_values(self.artifacts) + utils.validate_dict_values(self.capabilities) + utils.validate_list_values(self.outbound_relationships) + + def coerce_values(self, container, report_issues): + utils.coerce_dict_values(self, self.properties, report_issues) + utils.coerce_dict_values(self, self.interfaces, report_issues) + utils.coerce_dict_values(self, self.artifacts, report_issues) + utils.coerce_dict_values(self, self.capabilities, report_issues) + utils.coerce_list_values(self, self.outbound_relationships, report_issues) + + def dump(self): + context = ConsumptionContext.get_thread_local() console.puts('Node: {0}'.format(context.style.node(self.name))) with context.style.indent: console.puts('Type: {0}'.format(context.style.type(self.type.name))) console.puts('Template: {0}'.format(context.style.node(self.node_template.name))) - utils.dump_dict_values(context, self.properties, 'Properties') - utils.dump_interfaces(context, self.interfaces) - utils.dump_dict_values(context, self.artifacts, 'Artifacts') - utils.dump_dict_values(context, self.capabilities, 'Capabilities') - utils.dump_list_values(context, self.outbound_relationships, 'Relationships') + utils.dump_dict_values(self.properties, 'Properties') + utils.dump_interfaces(self.interfaces) + utils.dump_dict_values(self.artifacts, 'Artifacts') + utils.dump_dict_values(self.capabilities, 'Capabilities') + utils.dump_list_values(self.outbound_relationships, 'Relationships') class GroupBase(InstanceModelMixin): @@ -652,20 +664,21 @@ class GroupBase(InstanceModelMixin): ('properties', formatting.as_raw_dict(self.properties)), ('interfaces', formatting.as_raw_list(self.interfaces)))) - def validate(self, context): - utils.validate_dict_values(context, self.properties) - utils.validate_dict_values(context, self.interfaces) + def validate(self): + utils.validate_dict_values(self.properties) + utils.validate_dict_values(self.interfaces) - def coerce_values(self, context, container, report_issues): - utils.coerce_dict_values(context, container, self.properties, report_issues) - utils.coerce_dict_values(context, container, self.interfaces, report_issues) + def coerce_values(self, container, report_issues): + utils.coerce_dict_values(container, self.properties, report_issues) + utils.coerce_dict_values(container, self.interfaces, report_issues) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() console.puts('Group: {0}'.format(context.style.node(self.name))) with context.style.indent: console.puts('Type: {0}'.format(context.style.type(self.type.name))) - utils.dump_dict_values(context, self.properties, 'Properties') - utils.dump_interfaces(context, self.interfaces) + utils.dump_dict_values(self.properties, 'Properties') + utils.dump_interfaces(self.interfaces) if self.nodes: console.puts('Member nodes:') with context.style.indent: @@ -751,17 +764,18 @@ class PolicyBase(InstanceModelMixin): ('type_name', self.type_name), ('properties', formatting.as_raw_dict(self.properties)))) - def validate(self, context): - utils.validate_dict_values(context, self.properties) + def validate(self): + utils.validate_dict_values(self.properties) - def coerce_values(self, context, container, report_issues): - utils.coerce_dict_values(context, container, self.properties, report_issues) + def coerce_values(self, container, report_issues): + utils.coerce_dict_values(container, self.properties, report_issues) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() console.puts('Policy: {0}'.format(context.style.node(self.name))) with context.style.indent: console.puts('Type: {0}'.format(context.style.type(self.type.name))) - utils.dump_dict_values(context, self.properties, 'Properties') + utils.dump_dict_values(self.properties, 'Properties') if self.nodes: console.puts('Target nodes:') with context.style.indent: @@ -828,17 +842,18 @@ class SubstitutionBase(InstanceModelMixin): ('node_type_name', self.node_type_name), ('mappings', formatting.as_raw_dict(self.mappings)))) - def validate(self, context): - utils.validate_dict_values(context, self.mappings) + def validate(self): + utils.validate_dict_values(self.mappings) - def coerce_values(self, context, container, report_issues): - utils.coerce_dict_values(context, container, self.mappings, report_issues) + def coerce_values(self, container, report_issues): + utils.coerce_dict_values(container, self.mappings, report_issues) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() console.puts('Substitution:') with context.style.indent: console.puts('Node type: {0}'.format(context.style.type(self.node_type.name))) - utils.dump_dict_values(context, self.mappings, 'Mappings') + utils.dump_dict_values(self.mappings, 'Mappings') class SubstitutionMappingBase(InstanceModelMixin): @@ -910,7 +925,8 @@ class SubstitutionMappingBase(InstanceModelMixin): return collections.OrderedDict(( ('name', self.name))) - def validate(self, context): + def validate(self): + context = ConsumptionContext.get_thread_local() if (self.capability is None) and (self.requirement_template is None): context.validation.report('mapping "{0}" refers to neither capability nor a requirement' ' in node: {1}'.format( @@ -918,7 +934,8 @@ class SubstitutionMappingBase(InstanceModelMixin): formatting.safe_repr(self.node.name)), level=validation.Issue.BETWEEN_TYPES) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() console.puts('{0} -> {1}.{2}'.format( context.style.node(self.name), context.style.node(self.node.name), @@ -1046,15 +1063,16 @@ class RelationshipBase(InstanceModelMixin): ('properties', formatting.as_raw_dict(self.properties)), ('interfaces', formatting.as_raw_list(self.interfaces)))) - def validate(self, context): - utils.validate_dict_values(context, self.properties) - utils.validate_dict_values(context, self.interfaces) + def validate(self): + utils.validate_dict_values(self.properties) + utils.validate_dict_values(self.interfaces) - def coerce_values(self, context, container, report_issues): - utils.coerce_dict_values(context, container, self.properties, report_issues) - utils.coerce_dict_values(context, container, self.interfaces, report_issues) + def coerce_values(self, container, report_issues): + utils.coerce_dict_values(container, self.properties, report_issues) + utils.coerce_dict_values(container, self.interfaces, report_issues) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() if self.name: console.puts('{0} ->'.format(context.style.node(self.name))) else: @@ -1069,8 +1087,8 @@ class RelationshipBase(InstanceModelMixin): if (self.relationship_template is not None) and self.relationship_template.name: console.puts('Relationship template: {0}'.format( context.style.node(self.relationship_template.name))) - utils.dump_dict_values(context, self.properties, 'Properties') - utils.dump_interfaces(context, self.interfaces, 'Interfaces') + utils.dump_dict_values(self.properties, 'Properties') + utils.dump_interfaces(self.interfaces, 'Interfaces') class CapabilityBase(InstanceModelMixin): @@ -1164,13 +1182,14 @@ class CapabilityBase(InstanceModelMixin): ('type_name', self.type_name), ('properties', formatting.as_raw_dict(self.properties)))) - def validate(self, context): - utils.validate_dict_values(context, self.properties) + def validate(self): + utils.validate_dict_values(self.properties) - def coerce_values(self, context, container, report_issues): - utils.coerce_dict_values(context, container, self.properties, report_issues) + def coerce_values(self, container, report_issues): + utils.coerce_dict_values(container, self.properties, report_issues) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() console.puts(context.style.node(self.name)) with context.style.indent: console.puts('Type: {0}'.format(context.style.type(self.type.name))) @@ -1180,7 +1199,7 @@ class CapabilityBase(InstanceModelMixin): ' to {0:d}'.format(self.max_occurrences) if self.max_occurrences is not None else ' or more')) - utils.dump_dict_values(context, self.properties, 'Properties') + utils.dump_dict_values(self.properties, 'Properties') class InterfaceBase(InstanceModelMixin): @@ -1275,22 +1294,23 @@ class InterfaceBase(InstanceModelMixin): ('inputs', formatting.as_raw_dict(self.inputs)), ('operations', formatting.as_raw_list(self.operations)))) - def validate(self, context): - utils.validate_dict_values(context, self.inputs) - utils.validate_dict_values(context, self.operations) + def validate(self): + utils.validate_dict_values(self.inputs) + utils.validate_dict_values(self.operations) - def coerce_values(self, context, container, report_issues): - utils.coerce_dict_values(context, container, self.inputs, report_issues) - utils.coerce_dict_values(context, container, self.operations, report_issues) + def coerce_values(self, container, report_issues): + utils.coerce_dict_values(container, self.inputs, report_issues) + utils.coerce_dict_values(container, self.operations, report_issues) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() console.puts(context.style.node(self.name)) if self.description: console.puts(context.style.meta(self.description)) with context.style.indent: console.puts('Interface type: {0}'.format(context.style.type(self.type.name))) - utils.dump_dict_values(context, self.inputs, 'Inputs') - utils.dump_dict_values(context, self.operations, 'Operations') + utils.dump_dict_values(self.inputs, 'Inputs') + utils.dump_dict_values(self.operations, 'Operations') class OperationBase(InstanceModelMixin): @@ -1391,14 +1411,15 @@ class OperationBase(InstanceModelMixin): ('retry_interval', self.retry_interval), ('inputs', formatting.as_raw_dict(self.inputs)))) - def validate(self, context): + def validate(self): # TODO must be associated with interface or service - utils.validate_dict_values(context, self.inputs) + utils.validate_dict_values(self.inputs) - def coerce_values(self, context, container, report_issues): - utils.coerce_dict_values(context, container, self.inputs, report_issues) + def coerce_values(self, container, report_issues): + utils.coerce_dict_values(container, self.inputs, report_issues) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() console.puts(context.style.node(self.name)) if self.description: console.puts(context.style.meta(self.description)) @@ -1417,7 +1438,7 @@ class OperationBase(InstanceModelMixin): if self.retry_interval is not None: console.puts('Retry interval: {0}'.format( context.style.literal(self.retry_interval))) - utils.dump_dict_values(context, self.inputs, 'Inputs') + utils.dump_dict_values(self.inputs, 'Inputs') class ArtifactBase(InstanceModelMixin): @@ -1505,13 +1526,14 @@ class ArtifactBase(InstanceModelMixin): ('repository_credential', formatting.as_agnostic(self.repository_credential)), ('properties', formatting.as_raw_dict(self.properties)))) - def validate(self, context): - utils.validate_dict_values(context, self.properties) + def validate(self): + utils.validate_dict_values(self.properties) - def coerce_values(self, context, container, report_issues): - utils.coerce_dict_values(context, container, self.properties, report_issues) + def coerce_values(self, container, report_issues): + utils.coerce_dict_values(container, self.properties, report_issues) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() console.puts(context.style.node(self.name)) if self.description: console.puts(context.style.meta(self.description)) @@ -1526,4 +1548,4 @@ class ArtifactBase(InstanceModelMixin): if self.repository_credential: console.puts('Repository credential: {0}'.format( context.style.literal(self.repository_credential))) - utils.dump_dict_values(context, self.properties, 'Properties') + utils.dump_dict_values(self.properties, 'Properties') http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/16a94538/aria/modeling/service_template.py ---------------------------------------------------------------------- diff --git a/aria/modeling/service_template.py b/aria/modeling/service_template.py index c9a02eb..09da8e1 100644 --- a/aria/modeling/service_template.py +++ b/aria/modeling/service_template.py @@ -29,6 +29,8 @@ from sqlalchemy import ( from sqlalchemy.ext.declarative import declared_attr from ..parser import validation +from ..parser.consumption import ConsumptionContext +from ..parser.reading import deepcopy_with_locators from ..utils import collections, formatting, console from .mixins import TemplateModelMixin from . import ( @@ -267,33 +269,34 @@ class ServiceTemplateBase(TemplateModelMixin): # pylint: disable=too-many-public ('interface_types', formatting.as_raw(self.interface_types)), ('artifact_types', formatting.as_raw(self.artifact_types)))) - def instantiate(self, context, container): + def instantiate(self, container): from . import models + context = ConsumptionContext.get_thread_local() now = datetime.now() service = models.Service(created_at=now, updated_at=now, - description=utils.deepcopy_with_locators(self.description), + description=deepcopy_with_locators(self.description), service_template=self) #service.name = '{0}_{1}'.format(self.name, service.id) context.modeling.instance = service - utils.instantiate_dict(context, self, service.meta_data, self.meta_data) + utils.instantiate_dict(self, service.meta_data, self.meta_data) for node_template in self.node_templates: for _ in range(node_template.default_instances): - node = node_template.instantiate(context, container) + node = node_template.instantiate(container) service.nodes.append(node) - utils.instantiate_list(context, self, service.groups, self.group_templates) - utils.instantiate_list(context, self, service.policies, self.policy_templates) - utils.instantiate_dict(context, self, service.workflows, self.workflow_templates) + utils.instantiate_list(self, service.groups, self.group_templates) + utils.instantiate_list(self, service.policies, self.policy_templates) + utils.instantiate_dict(self, service.workflows, self.workflow_templates) if self.substitution_template is not None: - service.substitution = self.substitution_template.instantiate(context, container) + service.substitution = self.substitution_template.instantiate(container) - utils.instantiate_dict(context, self, service.inputs, self.inputs) - utils.instantiate_dict(context, self, service.outputs, self.outputs) + utils.instantiate_dict(self, service.inputs, self.inputs) + utils.instantiate_dict(self, service.outputs, self.outputs) for name, the_input in context.modeling.inputs.iteritems(): if name not in service.inputs: @@ -303,83 +306,81 @@ class ServiceTemplateBase(TemplateModelMixin): # pylint: disable=too-many-public return service - def validate(self, context): - utils.validate_dict_values(context, self.meta_data) - utils.validate_list_values(context, self.node_templates) - utils.validate_list_values(context, self.group_templates) - utils.validate_list_values(context, self.policy_templates) + def validate(self): + utils.validate_dict_values(self.meta_data) + utils.validate_list_values(self.node_templates) + utils.validate_list_values(self.group_templates) + utils.validate_list_values(self.policy_templates) if self.substitution_template is not None: - self.substitution_template.validate(context) - utils.validate_dict_values(context, self.inputs) - utils.validate_dict_values(context, self.outputs) - utils.validate_dict_values(context, self.workflow_templates) + self.substitution_template.validate() + utils.validate_dict_values(self.inputs) + utils.validate_dict_values(self.outputs) + utils.validate_dict_values(self.workflow_templates) if self.node_types is not None: - self.node_types.validate(context) + self.node_types.validate() if self.group_types is not None: - self.group_types.validate(context) + self.group_types.validate() if self.policy_types is not None: - self.policy_types.validate(context) + self.policy_types.validate() if self.relationship_types is not None: - self.relationship_types.validate(context) + self.relationship_types.validate() if self.capability_types is not None: - self.capability_types.validate(context) + self.capability_types.validate() if self.interface_types is not None: - self.interface_types.validate(context) + self.interface_types.validate() if self.artifact_types is not None: - self.artifact_types.validate(context) + self.artifact_types.validate() - def coerce_values(self, context, container, report_issues): - utils.coerce_dict_values(context, container, self.meta_data, report_issues) - utils.coerce_list_values(context, container, self.node_templates, report_issues) - utils.coerce_list_values(context, container, self.group_templates, report_issues) - utils.coerce_list_values(context, container, self.policy_templates, report_issues) + def coerce_values(self, container, report_issues): + utils.coerce_dict_values(container, self.meta_data, report_issues) + utils.coerce_list_values(container, self.node_templates, report_issues) + utils.coerce_list_values(container, self.group_templates, report_issues) + utils.coerce_list_values(container, self.policy_templates, report_issues) if self.substitution_template is not None: - self.substitution_template.coerce_values(context, container, report_issues) - utils.coerce_dict_values(context, container, self.inputs, report_issues) - utils.coerce_dict_values(context, container, self.outputs, report_issues) - utils.coerce_dict_values(context, container, self.workflow_templates, report_issues) + self.substitution_template.coerce_values(container, report_issues) + utils.coerce_dict_values(container, self.inputs, report_issues) + utils.coerce_dict_values(container, self.outputs, report_issues) + utils.coerce_dict_values(container, self.workflow_templates, report_issues) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() if self.description is not None: console.puts(context.style.meta(self.description)) - utils.dump_dict_values(context, self.meta_data, 'Metadata') + utils.dump_dict_values(self.meta_data, 'Metadata') for node_template in self.node_templates: - node_template.dump(context) + node_template.dump() for group_template in self.group_templates: - group_template.dump(context) + group_template.dump() for policy_template in self.policy_templates: - policy_template.dump(context) + policy_template.dump() if self.substitution_template is not None: - self.substitution_template.dump(context) - utils.dump_dict_values(context, self.inputs, 'Inputs') - utils.dump_dict_values(context, self.outputs, 'Outputs') - utils.dump_dict_values(context, self.workflow_templates, 'Workflow templates') + self.substitution_template.dump() + utils.dump_dict_values(self.inputs, 'Inputs') + utils.dump_dict_values(self.outputs, 'Outputs') + utils.dump_dict_values(self.workflow_templates, 'Workflow templates') - def dump_types(self, context): + def dump_types(self): if self.node_types.children: console.puts('Node types:') - self.node_types.dump(context) + self.node_types.dump() if self.group_types.children: console.puts('Group types:') - self.group_types.dump(context) + self.group_types.dump() if self.capability_types.children: console.puts('Capability types:') - self.capability_types.dump(context) + self.capability_types.dump() if self.relationship_types.children: console.puts('Relationship types:') - self.relationship_types.dump(context) + self.relationship_types.dump() if self.policy_types.children: console.puts('Policy types:') - self.policy_types.dump(context) - if self.policy_trigger_types.children: - console.puts('Policy trigger types:') - self.policy_trigger_types.dump(context) + self.policy_types.dump() if self.artifact_types.children: console.puts('Artifact types:') - self.artifact_types.dump(context) + self.artifact_types.dump() if self.interface_types.children: console.puts('Interface types:') - self.interface_types.dump(context) + self.interface_types.dump() class NodeTemplateBase(TemplateModelMixin): @@ -505,35 +506,37 @@ class NodeTemplateBase(TemplateModelMixin): ('capability_templates', formatting.as_raw_list(self.capability_templates)), ('requirement_templates', formatting.as_raw_list(self.requirement_templates)))) - def instantiate(self, context, *args, **kwargs): + def instantiate(self, container): + context = ConsumptionContext.get_thread_local() from . import models name = context.modeling.generate_node_id(self.name) node = models.Node(name=name, type=self.type, - description=utils.deepcopy_with_locators(self.description), + description=deepcopy_with_locators(self.description), state='', node_template=self) - utils.instantiate_dict(context, node, node.properties, self.properties) - utils.instantiate_dict(context, node, node.interfaces, self.interface_templates) - utils.instantiate_dict(context, node, node.artifacts, self.artifact_templates) - utils.instantiate_dict(context, node, node.capabilities, self.capability_templates) + utils.instantiate_dict(node, node.properties, self.properties) + utils.instantiate_dict(node, node.interfaces, self.interface_templates) + utils.instantiate_dict(node, node.artifacts, self.artifact_templates) + utils.instantiate_dict(node, node.capabilities, self.capability_templates) return node - def validate(self, context): - utils.validate_dict_values(context, self.properties) - utils.validate_dict_values(context, self.interface_templates) - utils.validate_dict_values(context, self.artifact_templates) - utils.validate_dict_values(context, self.capability_templates) - utils.validate_list_values(context, self.requirement_templates) - - def coerce_values(self, context, container, report_issues): - utils.coerce_dict_values(context, self, self.properties, report_issues) - utils.coerce_dict_values(context, self, self.interface_templates, report_issues) - utils.coerce_dict_values(context, self, self.artifact_templates, report_issues) - utils.coerce_dict_values(context, self, self.capability_templates, report_issues) - utils.coerce_list_values(context, self, self.requirement_templates, report_issues) - - def dump(self, context): + def validate(self): + utils.validate_dict_values(self.properties) + utils.validate_dict_values(self.interface_templates) + utils.validate_dict_values(self.artifact_templates) + utils.validate_dict_values(self.capability_templates) + utils.validate_list_values(self.requirement_templates) + + def coerce_values(self, container, report_issues): + utils.coerce_dict_values(self, self.properties, report_issues) + utils.coerce_dict_values(self, self.interface_templates, report_issues) + utils.coerce_dict_values(self, self.artifact_templates, report_issues) + utils.coerce_dict_values(self, self.capability_templates, report_issues) + utils.coerce_list_values(self, self.requirement_templates, report_issues) + + def dump(self): + context = ConsumptionContext.get_thread_local() console.puts('Node template: {0}'.format(context.style.node(self.name))) if self.description: console.puts(context.style.meta(self.description)) @@ -545,11 +548,11 @@ class NodeTemplateBase(TemplateModelMixin): ' to {0:d}'.format(self.max_instances) if self.max_instances is not None else ' or more')) - utils.dump_dict_values(context, self.properties, 'Properties') - utils.dump_interfaces(context, self.interface_templates) - utils.dump_dict_values(context, self.artifact_templates, 'Artifact templates') - utils.dump_dict_values(context, self.capability_templates, 'Capability templates') - utils.dump_list_values(context, self.requirement_templates, 'Requirement templates') + utils.dump_dict_values(self.properties, 'Properties') + utils.dump_interfaces(self.interface_templates) + utils.dump_dict_values(self.artifact_templates, 'Artifact templates') + utils.dump_dict_values(self.capability_templates, 'Capability templates') + utils.dump_list_values(self.requirement_templates, 'Requirement templates') class GroupTemplateBase(TemplateModelMixin): @@ -626,35 +629,36 @@ class GroupTemplateBase(TemplateModelMixin): ('properties', formatting.as_raw_dict(self.properties)), ('interface_templates', formatting.as_raw_list(self.interface_templates)))) - def instantiate(self, context, *args, **kwargs): + def instantiate(self, container): from . import models group = models.Group(name=self.name, type=self.type, - description=utils.deepcopy_with_locators(self.description), + description=deepcopy_with_locators(self.description), group_template=self) - utils.instantiate_dict(context, self, group.properties, self.properties) - utils.instantiate_dict(context, self, group.interfaces, self.interface_templates) + utils.instantiate_dict(self, group.properties, self.properties) + utils.instantiate_dict(self, group.interfaces, self.interface_templates) if self.node_templates: for node_template in self.node_templates: group.nodes += node_template.nodes.all() return group - def validate(self, context): - utils.validate_dict_values(context, self.properties) - utils.validate_dict_values(context, self.interface_templates) + def validate(self): + utils.validate_dict_values(self.properties) + utils.validate_dict_values(self.interface_templates) - def coerce_values(self, context, container, report_issues): - utils.coerce_dict_values(context, self, self.properties, report_issues) - utils.coerce_dict_values(context, self, self.interface_templates, report_issues) + def coerce_values(self, container, report_issues): + utils.coerce_dict_values(self, self.properties, report_issues) + utils.coerce_dict_values(self, self.interface_templates, report_issues) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() console.puts('Group template: {0}'.format(context.style.node(self.name))) if self.description: console.puts(context.style.meta(self.description)) with context.style.indent: console.puts('Type: {0}'.format(context.style.type(self.type.name))) - utils.dump_dict_values(context, self.properties, 'Properties') - utils.dump_interfaces(context, self.interface_templates) + utils.dump_dict_values(self.properties, 'Properties') + utils.dump_interfaces(self.interface_templates) if self.node_templates: console.puts('Member node templates: {0}'.format(', '.join( (str(context.style.node(v.name)) for v in self.node_templates)))) @@ -730,13 +734,13 @@ class PolicyTemplateBase(TemplateModelMixin): ('type_name', self.type.name), ('properties', formatting.as_raw_dict(self.properties)))) - def instantiate(self, context, *args, **kwargs): + def instantiate(self, container): from . import models policy = models.Policy(name=self.name, type=self.type, - description=utils.deepcopy_with_locators(self.description), + description=deepcopy_with_locators(self.description), policy_template=self) - utils.instantiate_dict(context, self, policy.properties, self.properties) + utils.instantiate_dict(self, policy.properties, self.properties) if self.node_templates: for node_template in self.node_templates: policy.nodes += node_template.nodes.all() @@ -745,19 +749,20 @@ class PolicyTemplateBase(TemplateModelMixin): policy.groups += group_template.groups.all() return policy - def validate(self, context): - utils.validate_dict_values(context, self.properties) + def validate(self): + utils.validate_dict_values(self.properties) - def coerce_values(self, context, container, report_issues): - utils.coerce_dict_values(context, self, self.properties, report_issues) + def coerce_values(self, container, report_issues): + utils.coerce_dict_values(self, self.properties, report_issues) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() console.puts('Policy template: {0}'.format(context.style.node(self.name))) if self.description: console.puts(context.style.meta(self.description)) with context.style.indent: console.puts('Type: {0}'.format(context.style.type(self.type.name))) - utils.dump_dict_values(context, self.properties, 'Properties') + utils.dump_dict_values(self.properties, 'Properties') if self.node_templates: console.puts('Target node templates: {0}'.format(', '.join( (str(context.style.node(v.name)) for v in self.node_templates)))) @@ -809,24 +814,25 @@ class SubstitutionTemplateBase(TemplateModelMixin): ('node_type_name', self.node_type.name), ('mappings', formatting.as_raw_dict(self.mappings)))) - def instantiate(self, context, container): + def instantiate(self, container): from . import models substitution = models.Substitution(node_type=self.node_type, substitution_template=self) - utils.instantiate_dict(context, container, substitution.mappings, self.mappings) + utils.instantiate_dict(container, substitution.mappings, self.mappings) return substitution - def validate(self, context): - utils.validate_dict_values(context, self.mappings) + def validate(self): + utils.validate_dict_values(self.mappings) - def coerce_values(self, context, container, report_issues): - utils.coerce_dict_values(context, self, self.mappings, report_issues) + def coerce_values(self, container, report_issues): + utils.coerce_dict_values(self, self.mappings, report_issues) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() console.puts('Substitution template:') with context.style.indent: console.puts('Node type: {0}'.format(context.style.type(self.node_type.name))) - utils.dump_dict_values(context, self.mappings, 'Mappings') + utils.dump_dict_values(self.mappings, 'Mappings') class SubstitutionTemplateMappingBase(TemplateModelMixin): @@ -896,8 +902,9 @@ class SubstitutionTemplateMappingBase(TemplateModelMixin): return collections.OrderedDict(( ('name', self.name))) - def instantiate(self, context, *args, **kwargs): + def instantiate(self, container): from . import models + context = ConsumptionContext.get_thread_local() nodes = context.modeling.instance.find_nodes(self.node_template.name) if len(nodes) == 0: context.validation.report( @@ -918,7 +925,8 @@ class SubstitutionTemplateMappingBase(TemplateModelMixin): capability=capability, requirement_template=self.requirement_template) - def validate(self, context): + def validate(self): + context = ConsumptionContext.get_thread_local() if (self.capability_template is None) and (self.requirement_template is None): context.validation.report('mapping "{0}" refers to neither capability nor a requirement' ' in node template: {1}'.format( @@ -926,7 +934,8 @@ class SubstitutionTemplateMappingBase(TemplateModelMixin): formatting.safe_repr(self.node_template.name)), level=validation.Issue.BETWEEN_TYPES) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() console.puts('{0} -> {1}.{2}'.format( context.style.node(self.name), context.style.node(self.node_template.name), @@ -1025,7 +1034,9 @@ class RequirementTemplateBase(TemplateModelMixin): # endregion - def find_target(self, context, source_node_template): + def find_target(self, source_node_template): + context = ConsumptionContext.get_thread_local() + # We might already have a specific node template, so we'll just verify it if self.target_node_template is not None: if not source_node_template.is_target_node_valid(self.target_node_template): @@ -1037,8 +1048,7 @@ class RequirementTemplateBase(TemplateModelMixin): level=validation.Issue.BETWEEN_TYPES) if (self.target_capability_type is not None) \ or (self.target_capability_name is not None): - target_node_capability = self.find_target_capability(context, - source_node_template, + target_node_capability = self.find_target_capability(source_node_template, self.target_node_template) if target_node_capability is None: return None, None @@ -1056,8 +1066,7 @@ class RequirementTemplateBase(TemplateModelMixin): if not source_node_template.is_target_node_valid(target_node_template): continue - target_node_capability = self.find_target_capability(context, - source_node_template, + target_node_capability = self.find_target_capability(source_node_template, target_node_template) if target_node_capability is None: continue @@ -1066,10 +1075,9 @@ class RequirementTemplateBase(TemplateModelMixin): return None, None - def find_target_capability(self, context, source_node_template, target_node_template): + def find_target_capability(self, source_node_template, target_node_template): for capability_template in target_node_template.capability_templates.itervalues(): - if capability_template.satisfies_requirement(context, - source_node_template, + if capability_template.satisfies_requirement(source_node_template, self, target_node_template): return capability_template @@ -1085,15 +1093,16 @@ class RequirementTemplateBase(TemplateModelMixin): ('target_capability_name', self.target_capability_name), ('relationship_template', formatting.as_raw(self.relationship_template)))) - def validate(self, context): + def validate(self): if self.relationship_template: - self.relationship_template.validate(context) + self.relationship_template.validate() - def coerce_values(self, context, container, report_issues): + def coerce_values(self, container, report_issues): if self.relationship_template is not None: - self.relationship_template.coerce_values(context, container, report_issues) + self.relationship_template.coerce_values(container, report_issues) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() if self.name: console.puts(context.style.node(self.name)) else: @@ -1119,7 +1128,7 @@ class RequirementTemplateBase(TemplateModelMixin): if self.relationship_template: console.puts('Relationship:') with context.style.indent: - self.relationship_template.dump(context) + self.relationship_template.dump() class RelationshipTemplateBase(TemplateModelMixin): @@ -1185,26 +1194,27 @@ class RelationshipTemplateBase(TemplateModelMixin): ('properties', formatting.as_raw_dict(self.properties)), ('interface_templates', formatting.as_raw_list(self.interface_templates)))) - def instantiate(self, context, container): + def instantiate(self, container): from . import models relationship = models.Relationship(type=self.type, relationship_template=self) - utils.instantiate_dict(context, container, + utils.instantiate_dict(container, relationship.properties, self.properties) - utils.instantiate_dict(context, container, + utils.instantiate_dict(container, relationship.interfaces, self.interface_templates) return relationship - def validate(self, context): + def validate(self): # TODO: either type or name must be set - utils.validate_dict_values(context, self.properties) - utils.validate_dict_values(context, self.interface_templates) + utils.validate_dict_values(self.properties) + utils.validate_dict_values(self.interface_templates) - def coerce_values(self, context, container, report_issues): - utils.coerce_dict_values(context, self, self.properties, report_issues) - utils.coerce_dict_values(context, self, self.interface_templates, report_issues) + def coerce_values(self, container, report_issues): + utils.coerce_dict_values(self, self.properties, report_issues) + utils.coerce_dict_values(self, self.interface_templates, report_issues) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() if self.type is not None: console.puts('Relationship type: {0}'.format(context.style.type(self.type.name))) else: @@ -1213,8 +1223,8 @@ class RelationshipTemplateBase(TemplateModelMixin): if self.description: console.puts(context.style.meta(self.description)) with context.style.indent: - utils.dump_dict_values(context, self.properties, 'Properties') - utils.dump_interfaces(context, self.interface_templates, 'Interface templates') + utils.dump_dict_values(self.properties, 'Properties') + utils.dump_interfaces(self.interface_templates, 'Interface templates') class CapabilityTemplateBase(TemplateModelMixin): @@ -1282,7 +1292,6 @@ class CapabilityTemplateBase(TemplateModelMixin): # endregion def satisfies_requirement(self, - context, # pylint: disable=unused-argument source_node_template, requirement, target_node_template): @@ -1316,7 +1325,7 @@ class CapabilityTemplateBase(TemplateModelMixin): ('valid_source_node_type_names', self.valid_source_node_type_names), ('properties', formatting.as_raw_dict(self.properties)))) - def instantiate(self, context, container): + def instantiate(self, container): from . import models capability = models.Capability(name=self.name, type=self.type, @@ -1324,16 +1333,17 @@ class CapabilityTemplateBase(TemplateModelMixin): max_occurrences=self.max_occurrences, occurrences=0, capability_template=self) - utils.instantiate_dict(context, container, capability.properties, self.properties) + utils.instantiate_dict(container, capability.properties, self.properties) return capability - def validate(self, context): - utils.validate_dict_values(context, self.properties) + def validate(self): + utils.validate_dict_values(self.properties) - def coerce_values(self, context, container, report_issues): - utils.coerce_dict_values(context, self, self.properties, report_issues) + def coerce_values(self, container, report_issues): + utils.coerce_dict_values(self, self.properties, report_issues) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() console.puts(context.style.node(self.name)) if self.description: console.puts(context.style.meta(self.description)) @@ -1349,7 +1359,7 @@ class CapabilityTemplateBase(TemplateModelMixin): console.puts('Valid source node types: {0}'.format( ', '.join((str(context.style.type(v.name)) for v in self.valid_source_node_types)))) - utils.dump_dict_values(context, self.properties, 'Properties') + utils.dump_dict_values(self.properties, 'Properties') class InterfaceTemplateBase(TemplateModelMixin): @@ -1432,32 +1442,33 @@ class InterfaceTemplateBase(TemplateModelMixin): # TODO fix self.properties reference ('operation_templates', formatting.as_raw_list(self.operation_templates)))) - def instantiate(self, context, container): + def instantiate(self, container): from . import models interface = models.Interface(name=self.name, type=self.type, - description=utils.deepcopy_with_locators(self.description), + description=deepcopy_with_locators(self.description), interface_template=self) - utils.instantiate_dict(context, container, interface.inputs, self.inputs) - utils.instantiate_dict(context, container, interface.operations, self.operation_templates) + utils.instantiate_dict(container, interface.inputs, self.inputs) + utils.instantiate_dict(container, interface.operations, self.operation_templates) return interface - def validate(self, context): - utils.validate_dict_values(context, self.inputs) - utils.validate_dict_values(context, self.operation_templates) + def validate(self): + utils.validate_dict_values(self.inputs) + utils.validate_dict_values(self.operation_templates) - def coerce_values(self, context, container, report_issues): - utils.coerce_dict_values(context, container, self.inputs, report_issues) - utils.coerce_dict_values(context, container, self.operation_templates, report_issues) + def coerce_values(self, container, report_issues): + utils.coerce_dict_values(container, self.inputs, report_issues) + utils.coerce_dict_values(container, self.operation_templates, report_issues) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() console.puts(context.style.node(self.name)) if self.description: console.puts(context.style.meta(self.description)) with context.style.indent: console.puts('Interface type: {0}'.format(context.style.type(self.type.name))) - utils.dump_dict_values(context, self.inputs, 'Inputs') - utils.dump_dict_values(context, self.operation_templates, 'Operation templates') + utils.dump_dict_values(self.inputs, 'Inputs') + utils.dump_dict_values(self.operation_templates, 'Operation templates') class OperationTemplateBase(TemplateModelMixin): @@ -1548,10 +1559,10 @@ class OperationTemplateBase(TemplateModelMixin): ('retry_interval', self.retry_interval), ('inputs', formatting.as_raw_dict(self.inputs)))) - def instantiate(self, context, container): + def instantiate(self, container): from . import models operation = models.Operation(name=self.name, - description=utils.deepcopy_with_locators(self.description), + description=deepcopy_with_locators(self.description), implementation=self.implementation, dependencies=self.dependencies, plugin_specification=self.plugin_specification, @@ -1559,16 +1570,17 @@ class OperationTemplateBase(TemplateModelMixin): max_retries=self.max_retries, retry_interval=self.retry_interval, operation_template=self) - utils.instantiate_dict(context, container, operation.inputs, self.inputs) + utils.instantiate_dict(container, operation.inputs, self.inputs) return operation - def validate(self, context): - utils.validate_dict_values(context, self.inputs) + def validate(self): + utils.validate_dict_values(self.inputs) - def coerce_values(self, context, container, report_issues): - utils.coerce_dict_values(context, container, self.inputs, report_issues) + def coerce_values(self, container, report_issues): + utils.coerce_dict_values(container, self.inputs, report_issues) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() console.puts(context.style.node(self.name)) if self.description: console.puts(context.style.meta(self.description)) @@ -1586,7 +1598,7 @@ class OperationTemplateBase(TemplateModelMixin): if self.retry_interval is not None: console.puts('Retry interval: {0}'.format( context.style.literal(self.retry_interval))) - utils.dump_dict_values(context, self.inputs, 'Inputs') + utils.dump_dict_values(self.inputs, 'Inputs') class ArtifactTemplateBase(TemplateModelMixin): @@ -1662,26 +1674,27 @@ class ArtifactTemplateBase(TemplateModelMixin): ('repository_credential', formatting.as_agnostic(self.repository_credential)), ('properties', formatting.as_raw_dict(self.properties)))) - def instantiate(self, context, container): + def instantiate(self, container): from . import models artifact = models.Artifact(name=self.name, type=self.type, - description=utils.deepcopy_with_locators(self.description), + description=deepcopy_with_locators(self.description), source_path=self.source_path, target_path=self.target_path, repository_url=self.repository_url, repository_credential=self.repository_credential, artifact_template=self) - utils.instantiate_dict(context, container, artifact.properties, self.properties) + utils.instantiate_dict(container, artifact.properties, self.properties) return artifact - def validate(self, context): - utils.validate_dict_values(context, self.properties) + def validate(self): + utils.validate_dict_values(self.properties) - def coerce_values(self, context, container, report_issues): - utils.coerce_dict_values(context, container, self.properties, report_issues) + def coerce_values(self, container, report_issues): + utils.coerce_dict_values(container, self.properties, report_issues) - def dump(self, context): + def dump(self): + context = ConsumptionContext.get_thread_local() console.puts(context.style.node(self.name)) if self.description: console.puts(context.style.meta(self.description)) @@ -1696,4 +1709,4 @@ class ArtifactTemplateBase(TemplateModelMixin): if self.repository_credential: console.puts('Repository credential: {0}'.format( context.style.literal(self.repository_credential))) - utils.dump_dict_values(context, self.properties, 'Properties') + utils.dump_dict_values(self.properties, 'Properties') http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/16a94538/aria/modeling/utils.py ---------------------------------------------------------------------- diff --git a/aria/modeling/utils.py b/aria/modeling/utils.py index a071d69..762754f 100644 --- a/aria/modeling/utils.py +++ b/aria/modeling/utils.py @@ -13,8 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from copy import deepcopy - +from ..parser.consumption import ConsumptionContext from ..parser.exceptions import InvalidValueError from ..parser.presentation import Value from ..utils.collections import OrderedDict @@ -22,19 +21,20 @@ from ..utils.console import puts from .exceptions import CannotEvaluateFunctionException -def coerce_value(context, container, value, report_issues=False): +def coerce_value(container, value, report_issues=False): if isinstance(value, Value): value = value.value if isinstance(value, list): - return [coerce_value(context, container, v, report_issues) for v in value] + return [coerce_value(container, v, report_issues) for v in value] elif isinstance(value, dict): - return OrderedDict((k, coerce_value(context, container, v, report_issues)) + return OrderedDict((k, coerce_value(container, v, report_issues)) for k, v in value.items()) elif hasattr(value, '_evaluate'): + context = ConsumptionContext.get_thread_local() try: value = value._evaluate(context, container) - value = coerce_value(context, container, value, report_issues) + value = coerce_value(container, value, report_issues) except CannotEvaluateFunctionException: pass except InvalidValueError as e: @@ -43,106 +43,74 @@ def coerce_value(context, container, value, report_issues=False): return value -def validate_dict_values(context, the_dict): +def validate_dict_values(the_dict): if not the_dict: return - validate_list_values(context, the_dict.itervalues()) + validate_list_values(the_dict.itervalues()) -def validate_list_values(context, the_list): +def validate_list_values(the_list): if not the_list: return for value in the_list: - value.validate(context) + value.validate() -def coerce_dict_values(context, container, the_dict, report_issues=False): +def coerce_dict_values(container, the_dict, report_issues=False): if not the_dict: return - coerce_list_values(context, container, the_dict.itervalues(), report_issues) + coerce_list_values(container, the_dict.itervalues(), report_issues) -def coerce_list_values(context, container, the_list, report_issues=False): +def coerce_list_values(container, the_list, report_issues=False): if not the_list: return for value in the_list: - value.coerce_values(context, container, report_issues) + value.coerce_values(container, report_issues) -def instantiate_dict(context, container, the_dict, from_dict): +def instantiate_dict(container, the_dict, from_dict): if not from_dict: return for name, value in from_dict.iteritems(): - value = value.instantiate(context, container) + value = value.instantiate(container) if value is not None: the_dict[name] = value -def instantiate_list(context, container, the_list, from_list): +def instantiate_list(container, the_list, from_list): if not from_list: return for value in from_list: - value = value.instantiate(context, container) + value = value.instantiate(container) if value is not None: the_list.append(value) -def dump_list_values(context, the_list, name): +def dump_list_values(the_list, name): if not the_list: return puts('%s:' % name) + context = ConsumptionContext.get_thread_local() with context.style.indent: for value in the_list: - value.dump(context) + value.dump() -def dump_dict_values(context, the_dict, name): +def dump_dict_values(the_dict, name): if not the_dict: return - dump_list_values(context, the_dict.itervalues(), name) + dump_list_values(the_dict.itervalues(), name) -def dump_interfaces(context, interfaces, name='Interfaces'): +def dump_interfaces(interfaces, name='Interfaces'): if not interfaces: return puts('%s:' % name) + context = ConsumptionContext.get_thread_local() with context.style.indent: for interface in interfaces.itervalues(): - interface.dump(context) - - - - -def deepcopy_with_locators(value): - """ - Like :code:`deepcopy`, but also copies over locators. - """ - - res = deepcopy(value) - copy_locators(res, value) - return res - - -def copy_locators(target, source): - """ - Copies over :code:`_locator` for all elements, recursively. - - Assumes that target and source have exactly the same list/dict structure. - """ - - locator = getattr(source, '_locator', None) - if locator is not None: - try: - setattr(target, '_locator', locator) - except AttributeError: - pass - - if isinstance(target, list) and isinstance(source, list): - for i, _ in enumerate(target): - copy_locators(target[i], source[i]) - elif isinstance(target, dict) and isinstance(source, dict): - for k, v in target.items(): - copy_locators(v, source[k]) + interface.dump() class classproperty(object): # pylint: disable=invalid-name http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/16a94538/aria/parser/consumption/__init__.py ---------------------------------------------------------------------- diff --git a/aria/parser/consumption/__init__.py b/aria/parser/consumption/__init__.py index 7b7590e..7da8490 100644 --- a/aria/parser/consumption/__init__.py +++ b/aria/parser/consumption/__init__.py @@ -20,7 +20,7 @@ from .style import Style from .consumer import Consumer, ConsumerChain from .presentation import Read from .validation import Validate -from .modeling import Model, Types, Instance +from .modeling import ServiceTemplate, Types, ServiceInstance from .inputs import Inputs __all__ = ( @@ -31,7 +31,7 @@ __all__ = ( 'ConsumerChain', 'Read', 'Validate', - 'Model', + 'ServiceTemplate', 'Types', - 'Instance', + 'ServiceInstance', 'Inputs')
