Repository: incubator-ariatosca Updated Branches: refs/heads/topology_poc 7d1cfbc42 -> d38e6f8a4
wip - nodecellar e2e passing Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/d38e6f8a Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/d38e6f8a Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/d38e6f8a Branch: refs/heads/topology_poc Commit: d38e6f8a408222cb1e5a64da1dfd784ef54b7ff3 Parents: 7d1cfbc Author: max-orlov <[email protected]> Authored: Tue Jul 18 13:17:07 2017 +0300 Committer: max-orlov <[email protected]> Committed: Tue Jul 18 13:17:22 2017 +0300 ---------------------------------------------------------------------- aria/core.py | 23 +------- aria/modeling/service_common.py | 5 -- aria/modeling/service_instance.py | 16 ++--- aria/modeling/utils.py | 4 +- aria/parser/topology/__init__.py | 16 +++++ aria/parser/topology/topoloy.py | 103 +++++++++++++++++++++++---------- tests/storage/__init__.py | 2 - 7 files changed, 100 insertions(+), 69 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/d38e6f8a/aria/core.py ---------------------------------------------------------------------- diff --git a/aria/core.py b/aria/core.py index 54379ba..a12554e 100644 --- a/aria/core.py +++ b/aria/core.py @@ -70,31 +70,12 @@ class Core(object): import pydevd; pydevd.settrace('localhost', suspend=False) service_template = self.model_storage.service_template.get(service_template_id) - # creating an empty ConsumptionContext, initiating a threadlocal context - context = consumption.ConsumptionContext() - storage_session = self.model_storage._all_api_kwargs['session'] # setting no autoflush for the duration of instantiation - this helps avoid dependency # constraints as they're being set up with storage_session.no_autoflush: - service = topology.Instantiation(self.model_storage).instantiate_service( - service_template, inputs=inputs) - - consumption.ConsumerChain( - context, - ( - consumption.CoerceServiceInstanceValues, - consumption.ValidateServiceInstance, - consumption.SatisfyRequirements, - consumption.CoerceServiceInstanceValues, - consumption.ValidateCapabilities, - consumption.FindHosts, - consumption.ConfigureOperations, - consumption.CoerceServiceInstanceValues - )).consume() - if context.validation.dump_issues(): - raise exceptions.InstantiationError('Failed to instantiate service template `{0}`' - .format(service_template.name)) + with topology.initiator.push_model_storage(self._model_storage) as initiator: + service = initiator.instantiate_service(service_template, inputs=inputs) storage_session.flush() # flushing so service.id would auto-populate service.name = service_name or '{0}_{1}'.format(service_template.name, service.id) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/d38e6f8a/aria/modeling/service_common.py ---------------------------------------------------------------------- diff --git a/aria/modeling/service_common.py b/aria/modeling/service_common.py index b533a88..f735c6b 100644 --- a/aria/modeling/service_common.py +++ b/aria/modeling/service_common.py @@ -603,11 +603,6 @@ class MetadataBase(TemplateModelMixin): def coerce_values(self, report_issues): pass - def instantiate(self, container): - from . import models - return models.Metadata(name=self.name, - value=self.value) - def dump(self): context = ConsumptionContext.get_thread_local() console.puts('{0}: {1}'.format( http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/d38e6f8a/aria/modeling/service_instance.py ---------------------------------------------------------------------- diff --git a/aria/modeling/service_instance.py b/aria/modeling/service_instance.py index 889465c..c34ace0 100644 --- a/aria/modeling/service_instance.py +++ b/aria/modeling/service_instance.py @@ -659,8 +659,8 @@ class NodeBase(InstanceModelMixin): if target_node is not None: if requirement_template.relationship_template is not None: - relationship_model = \ - requirement_template.relationship_template.instantiate(self) + from ..parser import topology + relationship_model = topology.initiator.instantiate(requirement_template.relationship_template) else: relationship_model = models.Relationship() relationship_model.name = requirement_template.name @@ -1945,6 +1945,7 @@ class OperationBase(InstanceModelMixin): """) def configure(self): + from ..parser import topology if (self.implementation is None) and (self.function is None): return @@ -1956,19 +1957,20 @@ class OperationBase(InstanceModelMixin): # In the future plugins may be able to add their own "configure_operation" hook that # can validate the configuration and otherwise create specially derived arguments. For # now, we just send all configuration parameters as arguments without validation. - utils.instantiate_dict(self, self.arguments, - utils.dict_as_arguments(self.configurations)) + for key, conf in self.configurations.items(): + self.arguments[key] = topology.initiator.instantiate(conf.as_argument()) if self.interface is not None: # Send all interface inputs as extra arguments # ("interface" is None for workflow operations) # Note that they will override existing arguments of the same names - utils.instantiate_dict(self, self.arguments, - utils.dict_as_arguments(self.interface.inputs)) + for key, input in self.interface.inputs.items(): + self.arguments[key] = topology.initiator.instantiate(input.as_argument()) # Send all inputs as extra arguments # Note that they will override existing arguments of the same names - utils.instantiate_dict(self, self.arguments, utils.dict_as_arguments(self.inputs)) + for key, input in self.inputs.items(): + self.arguments[key] = topology.initiator.instantiate(input.as_argument()) # Check for reserved arguments from ..orchestrator.decorators import OPERATION_DECORATOR_RESERVED_ARGUMENTS http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/d38e6f8a/aria/modeling/utils.py ---------------------------------------------------------------------- diff --git a/aria/modeling/utils.py b/aria/modeling/utils.py index 9ba2cfa..e50fb2f 100644 --- a/aria/modeling/utils.py +++ b/aria/modeling/utils.py @@ -64,7 +64,7 @@ class NodeTemplateContainerHolder(object): return self.container.service_template -def merge_parameter_values(parameter_values, declared_parameters): +def merge_parameter_values(parameter_values, declared_parameters, model_cls=None): """ Merges parameter values according to those declared by a type. @@ -94,7 +94,7 @@ def merge_parameter_values(parameter_values, declared_parameters): string_list_as_string(declared_parameters.keys()))) parameters = OrderedDict() - model_cls = get_class_from_relationship(declared_parameters) + model_cls = model_cls or get_class_from_relationship(declared_parameters) missing_names = [] wrong_type_values = OrderedDict() http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/d38e6f8a/aria/parser/topology/__init__.py ---------------------------------------------------------------------- diff --git a/aria/parser/topology/__init__.py b/aria/parser/topology/__init__.py new file mode 100644 index 0000000..9effdfe --- /dev/null +++ b/aria/parser/topology/__init__.py @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from .topoloy import initiator http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/d38e6f8a/aria/parser/topology/topoloy.py ---------------------------------------------------------------------- diff --git a/aria/parser/topology/topoloy.py b/aria/parser/topology/topoloy.py index 943d25a..8a5fa0c 100644 --- a/aria/parser/topology/topoloy.py +++ b/aria/parser/topology/topoloy.py @@ -12,11 +12,12 @@ # 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 collections import namedtuple +from contextlib import contextmanager from datetime import datetime from functools import partial +from aria import exceptions + from ... modeling import ( utils, models @@ -28,13 +29,9 @@ from .. import ( ) +class _Instantiation(object): - - -class Instantiation(object): - - def __init__(self, model_storage): - self._model_storage = model_storage + def __init__(self): self._initiators = { 'meta_data': self._instantiate_metadata, 'node_template': self._instantiate_node, @@ -49,12 +46,27 @@ class Instantiation(object): 'relationship_template': self._instantiate_relationship, # Parameter-Based instantiations + 'argument': partial(self._instantiate_parameter, model_cls=models.Argument), + 'inputs': partial(self._instantiate_parameter, model_cls=models.Input), 'outputs': partial(self._instantiate_parameter, model_cls=models.Output), 'properties': partial(self._instantiate_parameter, model_cls=models.Property), 'attributes': partial(self._instantiate_parameter, model_cls=models.Attribute), 'configurations': partial(self._instantiate_parameter, model_cls=models.Configuration), + } + self._model_storage = None + + @property + def _has_model_storage(self): + return self._model_storage is not None + + @contextmanager + def push_model_storage(self, model_storage): + original_model_storage = self._model_storage + self._model_storage = model_storage + yield self + self._model_storage = original_model_storage def instantiate_service(self, service_template, inputs=None): now = datetime.now() @@ -66,7 +78,7 @@ class Instantiation(object): ) # TODO: we want to remove this use of the context - context = consumption.ConsumptionContext.get_thread_local() + context = consumption.ConsumptionContext() context.modeling.instance = service service.inputs = utils.merge_parameter_values(inputs, service_template.inputs) @@ -82,24 +94,43 @@ class Instantiation(object): context.validation.report('specified plugin not found: {0}'.format( plugin_specification.name), level=validation.Issue.EXTERNAL) - service.meta_data = self._instantiate(service_template.meta_data) + service.meta_data = self.instantiate(service_template.meta_data) for node_template in service_template.node_templates.itervalues(): for _ in range(node_template.scaling['default_instances']): - node = self._instantiate(node_template) + node = self.instantiate(node_template) service.nodes[node.name] = node - service.groups = self._instantiate(service_template.group_templates) - service.policies = self._instantiate(service_template.policy_templates) - service.workflows = self._instantiate(service_template.workflow_templates) + service.groups = self.instantiate(service_template.group_templates) + service.policies = self.instantiate(service_template.policy_templates) + service.workflows = self.instantiate(service_template.workflow_templates) if service_template.substitution_template is not None: - service.substitution = self._instantiate(service_template.substitution_template) - service.outputs = self._instantiate(service_template.outputs) + service.substitution = self.instantiate(service_template.substitution_template) + service.outputs = self.instantiate(service_template.outputs) + + # creating an empty ConsumptionContext, initiating a threadlocal context + + consumption.ConsumerChain( + context, + ( + consumption.CoerceServiceInstanceValues, + consumption.ValidateServiceInstance, + consumption.SatisfyRequirements, + consumption.CoerceServiceInstanceValues, + consumption.ValidateCapabilities, + consumption.FindHosts, + consumption.ConfigureOperations, + consumption.CoerceServiceInstanceValues + )).consume() + + if context.validation.dump_issues(): + raise exceptions.InstantiationError('Failed to instantiate service template `{0}`' + .format(service_template.name)) return service - def _instantiate(self, source_template): + def instantiate(self, source_template): if isinstance(source_template, (dict, list)): initiator = self._initiators[source_template._sa_adapter.attr.key] if isinstance(source_template, dict): @@ -147,8 +178,8 @@ class Instantiation(object): type=group_template.type, description=reading.deepcopy_with_locators(group_template.description), group_template=group_template) - group.properties = self._instantiate(group_template.properties) - group.interfaces = self._instantiate(group_template.interface_templates) + group.properties = self.instantiate(group_template.properties) + group.interfaces = self.instantiate(group_template.interface_templates) if group_template.node_templates: for node_template in group_template.node_templates: group.nodes += node_template.nodes @@ -160,8 +191,8 @@ class Instantiation(object): type=interface_template.type, description=reading.deepcopy_with_locators(interface_template.description), interface_template=interface_template) - interface.inputs = self._instantiate(interface_template.inputs) - interface.operations = self._instantiate(interface_template.operation_templates) + interface.inputs = self.instantiate(interface_template.inputs) + interface.operations = self.instantiate(interface_template.operation_templates) return interface def _instantiate_node(self, node_template): @@ -172,11 +203,11 @@ class Instantiation(object): state=models.Node.INITIAL, node_template=node_template ) - node.properties = self._instantiate(node_template.properties) - node.attributes = self._instantiate(node_template.attributes) - node.interfaces = self._instantiate(node_template.interface_templates) - node.artifacts = self._instantiate(node_template.artifact_templates) - node.capabilities = self._instantiate(node_template.capability_templates) + node.properties = self.instantiate(node_template.properties) + node.attributes = self.instantiate(node_template.attributes) + node.interfaces = self.instantiate(node_template.interface_templates) + node.artifacts = self.instantiate(node_template.artifact_templates) + node.capabilities = self.instantiate(node_template.capability_templates) # Default attributes if ('tosca_name' in node.attributes) \ @@ -194,7 +225,7 @@ class Instantiation(object): type=policy_template.type, description=reading.deepcopy_with_locators(policy_template.description), policy_template=policy_template) - policy.properties = self._instantiate(policy_template.properties) + policy.properties = self.instantiate(policy_template.properties) if policy_template.node_templates: for node_template in policy_template.node_templates: policy.nodes += node_template.nodes @@ -205,7 +236,12 @@ class Instantiation(object): @staticmethod def _instantiate_parameter(parameter_template, model_cls): - return model_cls(**parameter_template.as_raw) + return model_cls( + name=parameter_template.name, # pylint: disable=unexpected-keyword-arg + type_name=parameter_template.type_name, + _value=parameter_template._value, + description=parameter_template.description + ) @staticmethod def _instantiate_substitution(substitution_template): @@ -251,8 +287,8 @@ class Instantiation(object): relationship_model = models.Relationship(name=relationship_template.name, type=relationship_template.type, relationship_template=relationship_template) - relationship_model.properties = self._instantiate(relationship_template.properties) - relationship_model.interfaces = self._instantiate(relationship_template.interface_templates) + relationship_model.properties = self.instantiate(relationship_template.properties) + relationship_model.interfaces = self.instantiate(relationship_template.interface_templates) return relationship_model def _instantiate_operation(self, operation_template): @@ -274,7 +310,10 @@ class Instantiation(object): retry_interval=operation_template.retry_interval, operation_template=operation_template) - operation.inputs = self._instantiate(operation_template.inputs) - operation.configurations = self._instantiate(operation_template.configurations) + operation.inputs = self.instantiate(operation_template.inputs) + operation.configurations = self.instantiate(operation_template.configurations) return operation + + +initiator = _Instantiation() http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/d38e6f8a/tests/storage/__init__.py ---------------------------------------------------------------------- diff --git a/tests/storage/__init__.py b/tests/storage/__init__.py index 8ca1480..8a4d613 100644 --- a/tests/storage/__init__.py +++ b/tests/storage/__init__.py @@ -23,8 +23,6 @@ from sqlalchemy import ( MetaData ) -from aria.modeling import models - class TestFileSystem(object):
