You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ariatosca.apache.org by av...@apache.org on 2017/05/22 08:10:29 UTC
[1/2] incubator-ariatosca git commit: add output model
Repository: incubator-ariatosca
Updated Branches:
refs/heads/ARIA-180-convert-parameter-to-one-to-many [created] ee747ef4e
add output model
Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/2631de6a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/2631de6a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/2631de6a
Branch: refs/heads/ARIA-180-convert-parameter-to-one-to-many
Commit: 2631de6a21ccf5c176e9ac9620113aba032a51be
Parents: 24d693d
Author: Avia Efrat <av...@gigaspaces.com>
Authored: Sun May 21 16:28:30 2017 +0300
Committer: Avia Efrat <av...@gigaspaces.com>
Committed: Sun May 21 16:28:30 2017 +0300
----------------------------------------------------------------------
aria/modeling/models.py | 9 +
aria/modeling/relationship.py | 4 +-
aria/modeling/service_common.py | 197 +++++++++++++++++++
aria/modeling/service_instance.py | 4 +-
aria/modeling/service_template.py | 4 +-
examples/hello-world/helloworld.yaml | 5 +
.../simple_v1_0/modeling/__init__.py | 20 +-
7 files changed, 230 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2631de6a/aria/modeling/models.py
----------------------------------------------------------------------
diff --git a/aria/modeling/models.py b/aria/modeling/models.py
index 584b877..f3acca6 100644
--- a/aria/modeling/models.py
+++ b/aria/modeling/models.py
@@ -73,6 +73,7 @@ __all__ = (
# Common service models
'Parameter',
+ 'Output'
'Type',
'Metadata',
@@ -210,6 +211,13 @@ class Parameter(aria_declarative_base, service_common.ParameterBase):
pass
+class Output(aria_declarative_base, service_common.OutputBase):
+ # Temporarily, until we will separate the Parameter model into Input, Output, Property and
+ # Attribute, Parameter will represent Input, Property and Attribute, and Output will represent
+ # the outputs.
+ pass
+
+
class Type(aria_declarative_base, service_common.TypeBase):
pass
@@ -277,6 +285,7 @@ models_to_register = [
# Common service models
Parameter,
+ Output,
Type,
Metadata,
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2631de6a/aria/modeling/relationship.py
----------------------------------------------------------------------
diff --git a/aria/modeling/relationship.py b/aria/modeling/relationship.py
index 40be5b2..c4f4cf3 100644
--- a/aria/modeling/relationship.py
+++ b/aria/modeling/relationship.py
@@ -287,8 +287,8 @@ def many_to_many(model_class,
if prefix is not None:
secondary_table_name = '{0}_{1}'.format(prefix, secondary_table_name)
- if other_property is None:
- other_property = '{0}_{1}'.format(prefix, formatting.pluralize(this_table))
+ if other_property is None:
+ other_property = '{0}_{1}'.format(prefix, formatting.pluralize(this_table))
secondary_table = _get_secondary_table(
model_class.metadata,
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2631de6a/aria/modeling/service_common.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_common.py b/aria/modeling/service_common.py
index e9c96a4..05698b6 100644
--- a/aria/modeling/service_common.py
+++ b/aria/modeling/service_common.py
@@ -228,6 +228,203 @@ class ParameterBase(TemplateModelMixin, caching.HasCachedMethods):
description=description)
+# TODO dry this code. currently it is a copy of ParameterBase
+class OutputBase(TemplateModelMixin, caching.HasCachedMethods):
+ """
+ Represents a typed value. The value can contain nested intrinsic functions.
+
+ This model can be used as the ``container_holder`` argument for :func:`functions.evaluate`.
+
+ :ivar name: Name
+ :vartype name: basestring
+ :ivar type_name: Type name
+ :vartype type_name: basestring
+ :ivar value: Value
+ :ivar description: Description
+ :vartype description: basestring
+ """
+
+ __tablename__ = 'output'
+
+ name = Column(Text)
+ type_name = Column(Text)
+ description = Column(Text)
+ _value = Column(PickleType)
+
+ @property
+ def value(self):
+ value = self._value
+ if value is not None:
+ evaluation = functions.evaluate(value, self)
+ if evaluation is not None:
+ value = evaluation.value
+ return value
+
+ @value.setter
+ def value(self, value):
+ self._value = value
+
+ @property
+ @caching.cachedmethod
+ def owner(self):
+ """
+ The sole owner of this parameter, which is another model that relates to it.
+
+ *All* parameters should have an owner model. In case this property method fails to find
+ it, it will raise a ValueError, which should signify an abnormal, orphaned parameter.
+ """
+
+ # Find first non-null relationship
+ for the_relationship in self.__mapper__.relationships:
+ v = getattr(self, the_relationship.key)
+ if v:
+ return v[0] # because we are many-to-many, the back reference will be a list
+
+ raise ValueError('orphaned output: does not have an owner: {0}'.format(self.name))
+
+
+ @property
+ @caching.cachedmethod
+ def container(self): # pylint: disable=too-many-return-statements,too-many-branches
+ """
+ The logical container for this parameter, which would be another model: service, node,
+ group, or policy (or their templates).
+
+ The logical container is equivalent to the ``SELF`` keyword used by intrinsic functions in
+ TOSCA.
+
+ *All* parameters should have a container model. In case this property method fails to find
+ it, it will raise a ValueError, which should signify an abnormal, orphaned parameter.
+ """
+
+ from . import models
+
+ container = self.owner
+
+ # Extract interface from operation
+ if isinstance(container, models.Operation):
+ container = container.interface
+ elif isinstance(container, models.OperationTemplate):
+ container = container.interface_template
+
+ # Extract from other models
+ if isinstance(container, models.Interface):
+ container = container.node or container.group or container.relationship
+ elif isinstance(container, models.InterfaceTemplate):
+ container = container.node_template or container.group_template \
+ or container.relationship_template
+ elif isinstance(container, models.Capability) or isinstance(container, models.Artifact):
+ container = container.node
+ elif isinstance(container, models.CapabilityTemplate) \
+ or isinstance(container, models.ArtifactTemplate):
+ container = container.node_template
+ elif isinstance(container, models.Task):
+ container = container.actor
+
+ # Extract node from relationship
+ if isinstance(container, models.Relationship):
+ container = container.source_node
+ elif isinstance(container, models.RelationshipTemplate):
+ container = container.requirement_template.node_template
+
+ if container is not None:
+ return container
+
+ raise ValueError('orphaned output: does not have a container: {0}'.format(self.name))
+
+ @property
+ @caching.cachedmethod
+ def service(self):
+ """
+ The :class:`Service` containing this parameter, or None if not contained in a service.
+ """
+
+ from . import models
+ container = self.container
+ if isinstance(container, models.Service):
+ return container
+ elif hasattr(container, 'service'):
+ return container.service
+ return None
+
+ @property
+ @caching.cachedmethod
+ def service_template(self):
+ """
+ The :class:`ServiceTemplate` containing this parameter, or None if not contained in a
+ service template.
+ """
+
+ from . import models
+ container = self.container
+ if isinstance(container, models.ServiceTemplate):
+ return container
+ elif hasattr(container, 'service_template'):
+ return container.service_template
+ return None
+
+ @property
+ def as_raw(self):
+ return collections.OrderedDict((
+ ('name', self.name),
+ ('type_name', self.type_name),
+ ('value', self.value),
+ ('description', self.description)))
+
+ def instantiate(self, container):
+ from . import models
+ return models.Output(name=self.name, # pylint: disable=unexpected-keyword-arg
+ type_name=self.type_name,
+ _value=self._value,
+ description=self.description)
+
+ def coerce_values(self, report_issues):
+ value = self._value
+ if value is not None:
+ evaluation = functions.evaluate(value, self, report_issues)
+ if (evaluation is not None) and evaluation.final:
+ # A final evaluation can safely replace the existing value
+ self._value = evaluation.value
+
+ def dump(self):
+ context = ConsumptionContext.get_thread_local()
+ if self.type_name is not None:
+ console.puts('{0}: {1} ({2})'.format(
+ context.style.property(self.name),
+ context.style.literal(formatting.as_raw(self.value)),
+ context.style.type(self.type_name)))
+ else:
+ console.puts('{0}: {1}'.format(
+ context.style.property(self.name),
+ context.style.literal(formatting.as_raw(self.value))))
+ if self.description:
+ console.puts(context.style.meta(self.description))
+
+ def unwrap(self):
+ return self.name, self.value
+
+ @classmethod
+ def wrap(cls, name, value, description=None):
+ """
+ Wraps an arbitrary value as a parameter. The type will be guessed via introspection.
+
+ :param name: Parameter name
+ :type name: basestring
+ :param value: Parameter value
+ :param description: Description (optional)
+ :type description: basestring
+ """
+
+ from . import models
+ type_name = canonical_type_name(value)
+ if type_name is None:
+ type_name = full_type_name(value)
+ return models.Output(name=name, # pylint: disable=unexpected-keyword-arg
+ type_name=type_name,
+ value=value,
+ description=description)
+
+
class TypeBase(InstanceModelMixin):
"""
Represents a type and its children.
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2631de6a/aria/modeling/service_instance.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_instance.py b/aria/modeling/service_instance.py
index 41a388d..4236caa 100644
--- a/aria/modeling/service_instance.py
+++ b/aria/modeling/service_instance.py
@@ -65,7 +65,7 @@ class ServiceBase(InstanceModelMixin):
:ivar inputs: Externally provided parameters
:vartype inputs: {basestring: :class:`Parameter`}
:ivar outputs: These parameters are filled in after service installation
- :vartype outputs: {basestring: :class:`Parameter`}
+ :vartype outputs: {basestring: :class:`Output`}
:ivar workflows: Custom workflows that can be performed on the service
:vartype workflows: {basestring: :class:`Operation`}
:ivar plugins: Plugins used by the service
@@ -171,7 +171,7 @@ class ServiceBase(InstanceModelMixin):
@declared_attr
def outputs(cls):
- return relationship.many_to_many(cls, 'parameter', prefix='outputs', dict_key='name')
+ return relationship.many_to_many(cls, 'output', dict_key='name')
@declared_attr
def plugins(cls):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2631de6a/aria/modeling/service_template.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_template.py b/aria/modeling/service_template.py
index 1eb95a3..e253617 100644
--- a/aria/modeling/service_template.py
+++ b/aria/modeling/service_template.py
@@ -69,7 +69,7 @@ class ServiceTemplateBase(TemplateModelMixin):
:ivar inputs: Externally provided parameters
:vartype inputs: {basestring: :class:`Parameter`}
:ivar outputs: These parameters are filled in after service installation
- :vartype outputs: {basestring: :class:`Parameter`}
+ :vartype outputs: {basestring: :class:`Output`}
:ivar workflow_templates: Custom workflows that can be performed on the service
:vartype workflow_templates: {basestring: :class:`OperationTemplate`}
:ivar plugin_specifications: Plugins used by the service
@@ -253,7 +253,7 @@ class ServiceTemplateBase(TemplateModelMixin):
@declared_attr
def outputs(cls):
- return relationship.many_to_many(cls, 'parameter', prefix='outputs', dict_key='name')
+ return relationship.many_to_many(cls, 'output', dict_key='name')
# endregion
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2631de6a/examples/hello-world/helloworld.yaml
----------------------------------------------------------------------
diff --git a/examples/hello-world/helloworld.yaml b/examples/hello-world/helloworld.yaml
index 77cef30..55c5030 100644
--- a/examples/hello-world/helloworld.yaml
+++ b/examples/hello-world/helloworld.yaml
@@ -30,3 +30,8 @@ topology_template:
configure: scripts/configure.sh
start: scripts/start.sh
stop: scripts/stop.sh
+
+ outputs:
+ test_output:
+ description: description_of_test_output
+ value: value_of_test_output
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2631de6a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
index 99389e4..1769ce5 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
@@ -32,7 +32,8 @@ from aria.modeling.models import (Type, ServiceTemplate, NodeTemplate,
RequirementTemplate, RelationshipTemplate, CapabilityTemplate,
GroupTemplate, PolicyTemplate, SubstitutionTemplate,
SubstitutionTemplateMapping, InterfaceTemplate, OperationTemplate,
- ArtifactTemplate, Metadata, Parameter, PluginSpecification)
+ ArtifactTemplate, Metadata, Parameter, Output,
+ PluginSpecification)
from .constraints import (Equal, GreaterThan, GreaterOrEqual, LessThan, LessOrEqual, InRange,
ValidValues, Length, MinLength, MaxLength, Pattern)
@@ -91,7 +92,8 @@ def create_service_template_model(context): # pylint: disable=too-many-locals,to
create_parameter_models_from_values(model.inputs,
topology_template._get_input_values(context))
create_parameter_models_from_values(model.outputs,
- topology_template._get_output_values(context))
+ topology_template._get_output_values(context),
+ model_class=Output)
# Plugin specifications
policies = context.presentation.get('service_template', 'topology_template', 'policies')
@@ -537,13 +539,17 @@ def create_types(context, root, types):
container.children.append(model)
-def create_parameter_models_from_values(properties, source_properties):
+def create_parameter_models_from_values(properties, source_properties, model_class=None):
+
+ if model_class is None:
+ model_class = Parameter
+
if source_properties:
for property_name, prop in source_properties.iteritems():
- properties[property_name] = Parameter(name=property_name, # pylint: disable=unexpected-keyword-arg
- type_name=prop.type,
- value=prop.value,
- description=prop.description)
+ properties[property_name] = model_class(name=property_name, # pylint: disable=unexpected-keyword-arg
+ type_name=prop.type,
+ value=prop.value,
+ description=prop.description)
def create_parameter_models_from_assignments(properties, source_properties):
[2/2] incubator-ariatosca git commit: Add input model
Posted by av...@apache.org.
Add input model
Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/ee747ef4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/ee747ef4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/ee747ef4
Branch: refs/heads/ARIA-180-convert-parameter-to-one-to-many
Commit: ee747ef4e635a53b937682cba06dbebbf8a27bc0
Parents: 2631de6
Author: Avia Efrat <av...@gigaspaces.com>
Authored: Sun May 21 20:10:50 2017 +0300
Committer: Avia Efrat <av...@gigaspaces.com>
Committed: Sun May 21 20:10:50 2017 +0300
----------------------------------------------------------------------
aria/modeling/models.py | 11 +-
aria/modeling/orchestration.py | 8 +-
aria/modeling/relationship.py | 6 +-
aria/modeling/service_common.py | 202 ++++++++++++++++++-
aria/modeling/service_instance.py | 18 +-
aria/modeling/service_template.py | 16 +-
aria/modeling/utils.py | 8 +-
.../simple_v1_0/modeling/__init__.py | 29 +--
tests/mock/models.py | 2 +-
tests/mock/topology.py | 8 +-
tests/modeling/test_models.py | 4 +-
tests/orchestrator/test_workflow_runner.py | 8 +-
.../workflows/executor/test_executor.py | 2 +-
13 files changed, 265 insertions(+), 57 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/ee747ef4/aria/modeling/models.py
----------------------------------------------------------------------
diff --git a/aria/modeling/models.py b/aria/modeling/models.py
index f3acca6..d7b417b 100644
--- a/aria/modeling/models.py
+++ b/aria/modeling/models.py
@@ -73,6 +73,7 @@ __all__ = (
# Common service models
'Parameter',
+ 'Input'
'Output'
'Type',
'Metadata',
@@ -211,10 +212,15 @@ class Parameter(aria_declarative_base, service_common.ParameterBase):
pass
+class Input(aria_declarative_base, service_common.InputBase):
+ # Temporarily, until we will separate the Parameter model into Input, Output, Property and
+ # Attribute, Parameter will represent only Property and Attribute.
+ pass
+
+
class Output(aria_declarative_base, service_common.OutputBase):
# Temporarily, until we will separate the Parameter model into Input, Output, Property and
- # Attribute, Parameter will represent Input, Property and Attribute, and Output will represent
- # the outputs.
+ # Attribute, Parameter will represent only Property and Attribute.
pass
@@ -285,6 +291,7 @@ models_to_register = [
# Common service models
Parameter,
+ Input,
Output,
Type,
Metadata,
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/ee747ef4/aria/modeling/orchestration.py
----------------------------------------------------------------------
diff --git a/aria/modeling/orchestration.py b/aria/modeling/orchestration.py
index ab9d34d..b65ca62 100644
--- a/aria/modeling/orchestration.py
+++ b/aria/modeling/orchestration.py
@@ -115,7 +115,7 @@ class ExecutionBase(ModelMixin):
@declared_attr
def inputs(cls):
- return relationship.many_to_many(cls, 'parameter', prefix='inputs', dict_key='name')
+ return relationship.many_to_many(cls, 'input', dict_key='name')
# region foreign keys
@@ -230,8 +230,8 @@ class TaskBase(ModelMixin):
:vartype relationship: :class:`Relationship`
:ivar plugin: The implementing plugin (set to None for default execution plugin)
:vartype plugin: :class:`Plugin`
- :ivar inputs: Parameters that can be used by this task
- :vartype inputs: {basestring: :class:`Parameter`}
+ :ivar inputs: Inputs that can be used by this task
+ :vartype inputs: {basestring: :class:`Input`}
:ivar implementation: Python path to an ``@operation`` function
:vartype implementation: basestring
:ivar max_attempts: Maximum number of retries allowed in case of failure
@@ -301,7 +301,7 @@ class TaskBase(ModelMixin):
@declared_attr
def inputs(cls):
- return relationship.many_to_many(cls, 'parameter', prefix='inputs', dict_key='name')
+ return relationship.many_to_many(cls, 'input', dict_key='name')
implementation = Column(String)
max_attempts = Column(Integer, default=1)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/ee747ef4/aria/modeling/relationship.py
----------------------------------------------------------------------
diff --git a/aria/modeling/relationship.py b/aria/modeling/relationship.py
index c4f4cf3..8644d42 100644
--- a/aria/modeling/relationship.py
+++ b/aria/modeling/relationship.py
@@ -287,8 +287,10 @@ def many_to_many(model_class,
if prefix is not None:
secondary_table_name = '{0}_{1}'.format(prefix, secondary_table_name)
- if other_property is None:
- other_property = '{0}_{1}'.format(prefix, formatting.pluralize(this_table))
+ if other_property is None:
+ other_property = '{0}_{1}'.format(prefix, formatting.pluralize(this_table))
+ elif other_property is None:
+ other_property = '{0}_{1}'.format(other_table, formatting.pluralize(this_table))
secondary_table = _get_secondary_table(
model_class.metadata,
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/ee747ef4/aria/modeling/service_common.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_common.py b/aria/modeling/service_common.py
index 05698b6..0652a5a 100644
--- a/aria/modeling/service_common.py
+++ b/aria/modeling/service_common.py
@@ -408,9 +408,9 @@ class OutputBase(TemplateModelMixin, caching.HasCachedMethods):
"""
Wraps an arbitrary value as a parameter. The type will be guessed via introspection.
- :param name: Parameter name
+ :param name: Output name
:type name: basestring
- :param value: Parameter value
+ :param value: Output value
:param description: Description (optional)
:type description: basestring
"""
@@ -532,6 +532,204 @@ class TypeBase(InstanceModelMixin):
return [self] + (self.parent.hierarchy if self.parent else [])
+# TODO dry this code. currently it is a copy of ParameterBase
+class InputBase(TemplateModelMixin, caching.HasCachedMethods):
+ """
+ Represents a typed value. The value can contain nested intrinsic functions.
+
+ This model can be used as the ``container_holder`` argument for :func:`functions.evaluate`.
+
+ :ivar name: Name
+ :vartype name: basestring
+ :ivar type_name: Type name
+ :vartype type_name: basestring
+ :ivar value: Value
+ :ivar description: Description
+ :vartype description: basestring
+ """
+
+ __tablename__ = 'input'
+
+ name = Column(Text)
+ type_name = Column(Text)
+ description = Column(Text)
+ _value = Column(PickleType)
+
+ @property
+ def value(self):
+ value = self._value
+ if value is not None:
+ evaluation = functions.evaluate(value, self)
+ if evaluation is not None:
+ value = evaluation.value
+ return value
+
+ @value.setter
+ def value(self, value):
+ self._value = value
+
+ @property
+ @caching.cachedmethod
+ def owner(self):
+ """
+ The sole owner of this parameter, which is another model that relates to it.
+
+ *All* parameters should have an owner model. In case this property method fails to find
+ it, it will raise a ValueError, which should signify an abnormal, orphaned parameter.
+ """
+
+ # Find first non-null relationship
+ for the_relationship in self.__mapper__.relationships:
+ v = getattr(self, the_relationship.key)
+ if v:
+ return v[0] # because we are many-to-many, the back reference will be a list
+
+ raise ValueError('orphaned input: does not have an owner: {0}'.format(self.name))
+
+
+ @property
+ @caching.cachedmethod
+ def container(self): # pylint: disable=too-many-return-statements,too-many-branches
+ """
+ The logical container for this parameter, which would be another model: service, node,
+ group, or policy (or their templates).
+
+ The logical container is equivalent to the ``SELF`` keyword used by intrinsic functions in
+ TOSCA.
+
+ *All* parameters should have a container model. In case this property method fails to find
+ it, it will raise a ValueError, which should signify an abnormal, orphaned parameter.
+ """
+
+ from . import models
+
+ container = self.owner
+
+ # Extract interface from operation
+ if isinstance(container, models.Operation):
+ container = container.interface
+ elif isinstance(container, models.OperationTemplate):
+ container = container.interface_template
+
+ # Extract from other models
+ if isinstance(container, models.Interface):
+ container = container.node or container.group or container.relationship
+ elif isinstance(container, models.InterfaceTemplate):
+ container = container.node_template or container.group_template \
+ or container.relationship_template
+ elif isinstance(container, models.Capability) or isinstance(container, models.Artifact):
+ container = container.node
+ elif isinstance(container, models.CapabilityTemplate) \
+ or isinstance(container, models.ArtifactTemplate):
+ container = container.node_template
+ elif isinstance(container, models.Task):
+ container = container.actor
+
+ # Extract node from relationship
+ if isinstance(container, models.Relationship):
+ container = container.source_node
+ elif isinstance(container, models.RelationshipTemplate):
+ container = container.requirement_template.node_template
+
+ if container is not None:
+ return container
+
+ raise ValueError('orphaned input: does not have a container: {0}'.format(self.name))
+
+ @property
+ @caching.cachedmethod
+ def service(self):
+ """
+ The :class:`Service` containing this parameter, or None if not contained in a service.
+ """
+
+ from . import models
+ container = self.container
+ if isinstance(container, models.Service):
+ return container
+ elif hasattr(container, 'service'):
+ return container.service
+ return None
+
+ @property
+ @caching.cachedmethod
+ def service_template(self):
+ """
+ The :class:`ServiceTemplate` containing this parameter, or None if not contained in a
+ service template.
+ """
+
+ from . import models
+ container = self.container
+ if isinstance(container, models.ServiceTemplate):
+ return container
+ elif hasattr(container, 'service_template'):
+ return container.service_template
+ return None
+
+ @property
+ def as_raw(self):
+ return collections.OrderedDict((
+ ('name', self.name),
+ ('type_name', self.type_name),
+ ('value', self.value),
+ ('description', self.description)))
+
+ def instantiate(self, container):
+ from . import models
+ return models.Input(name=self.name, # pylint: disable=unexpected-keyword-arg
+ type_name=self.type_name,
+ _value=self._value,
+ description=self.description)
+
+ def coerce_values(self, report_issues):
+ value = self._value
+ if value is not None:
+ evaluation = functions.evaluate(value, self, report_issues)
+ if (evaluation is not None) and evaluation.final:
+ # A final evaluation can safely replace the existing value
+ self._value = evaluation.value
+
+ def dump(self):
+ context = ConsumptionContext.get_thread_local()
+ if self.type_name is not None:
+ console.puts('{0}: {1} ({2})'.format(
+ context.style.property(self.name),
+ context.style.literal(formatting.as_raw(self.value)),
+ context.style.type(self.type_name)))
+ else:
+ console.puts('{0}: {1}'.format(
+ context.style.property(self.name),
+ context.style.literal(formatting.as_raw(self.value))))
+ if self.description:
+ console.puts(context.style.meta(self.description))
+
+ def unwrap(self):
+ return self.name, self.value
+
+ @classmethod
+ def wrap(cls, name, value, description=None):
+ """
+ Wraps an arbitrary value as a parameter. The type will be guessed via introspection.
+
+ :param name: Input name
+ :type name: basestring
+ :param value: Input value
+ :param description: Description (optional)
+ :type description: basestring
+ """
+
+ from . import models
+ type_name = canonical_type_name(value)
+ if type_name is None:
+ type_name = full_type_name(value)
+ return models.Input(name=name, # pylint: disable=unexpected-keyword-arg
+ type_name=type_name,
+ value=value,
+ description=description)
+
+
+
class MetadataBase(TemplateModelMixin):
"""
Custom values associated with the service.
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/ee747ef4/aria/modeling/service_instance.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_instance.py b/aria/modeling/service_instance.py
index 4236caa..f3f0f99 100644
--- a/aria/modeling/service_instance.py
+++ b/aria/modeling/service_instance.py
@@ -63,7 +63,7 @@ class ServiceBase(InstanceModelMixin):
:ivar substitution: The entire service can appear as a node
:vartype substitution: :class:`Substitution`
:ivar inputs: Externally provided parameters
- :vartype inputs: {basestring: :class:`Parameter`}
+ :vartype inputs: {basestring: :class:`Input`}
:ivar outputs: These parameters are filled in after service installation
:vartype outputs: {basestring: :class:`Output`}
:ivar workflows: Custom workflows that can be performed on the service
@@ -167,7 +167,7 @@ class ServiceBase(InstanceModelMixin):
@declared_attr
def inputs(cls):
- return relationship.many_to_many(cls, 'parameter', prefix='inputs', dict_key='name')
+ return relationship.many_to_many(cls, 'input', dict_key='name')
@declared_attr
def outputs(cls):
@@ -1490,8 +1490,8 @@ class InterfaceBase(InstanceModelMixin):
:vartype type: :class:`Type`
:ivar description: Human-readable description
:vartype description: string
- :ivar inputs: Parameters that can be used by all operations in the interface
- :vartype inputs: {basestring: :class:`Parameter`}
+ :ivar inputs: Inputs that can be used by all operations in the interface
+ :vartype inputs: {basestring: :class:`Input`}
:ivar operations: Operations
:vartype operations: {basestring: :class:`Operation`}
:ivar node: Containing node
@@ -1583,7 +1583,7 @@ class InterfaceBase(InstanceModelMixin):
@declared_attr
def inputs(cls):
- return relationship.many_to_many(cls, 'parameter', prefix='inputs', dict_key='name')
+ return relationship.many_to_many(cls, 'input', dict_key='name')
# endregion
@@ -1645,8 +1645,8 @@ class OperationBase(InstanceModelMixin):
:vartype configuration: {basestring, object}
:ivar dependencies: Dependency strings (interpreted by the plugin)
:vartype dependencies: [basestring]
- :ivar inputs: Parameters that can be used by this operation
- :vartype inputs: {basestring: :class:`Parameter`}
+ :ivar inputs: Inputs that can be used by this operation
+ :vartype inputs: {basestring: :class:`Input`}
:ivar executor: Name of executor to run the operation with
:vartype executor: basestring
:ivar max_attempts: Maximum number of attempts allowed in case of failure
@@ -1726,7 +1726,7 @@ class OperationBase(InstanceModelMixin):
@declared_attr
def inputs(cls):
- return relationship.many_to_many(cls, 'parameter', prefix='inputs', dict_key='name')
+ return relationship.many_to_many(cls, 'input', dict_key='name')
# endregion
@@ -1755,7 +1755,7 @@ class OperationBase(InstanceModelMixin):
# Note: the arguments will *override* operation inputs of the same name
if arguments:
for k, v in arguments.iteritems():
- self.inputs[k] = models.Parameter.wrap(k, v)
+ self.inputs[k] = models.Input.wrap(k, v)
@property
def as_raw(self):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/ee747ef4/aria/modeling/service_template.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_template.py b/aria/modeling/service_template.py
index e253617..3341f5f 100644
--- a/aria/modeling/service_template.py
+++ b/aria/modeling/service_template.py
@@ -67,7 +67,7 @@ class ServiceTemplateBase(TemplateModelMixin):
:ivar substitution_template: The entire service can appear as a node
:vartype substitution_template: :class:`SubstitutionTemplate`
:ivar inputs: Externally provided parameters
- :vartype inputs: {basestring: :class:`Parameter`}
+ :vartype inputs: {basestring: :class:`Input`}
:ivar outputs: These parameters are filled in after service installation
:vartype outputs: {basestring: :class:`Output`}
:ivar workflow_templates: Custom workflows that can be performed on the service
@@ -249,7 +249,7 @@ class ServiceTemplateBase(TemplateModelMixin):
@declared_attr
def inputs(cls):
- return relationship.many_to_many(cls, 'parameter', prefix='inputs', dict_key='name')
+ return relationship.many_to_many(cls, 'input', dict_key='name')
@declared_attr
def outputs(cls):
@@ -1621,8 +1621,8 @@ class InterfaceTemplateBase(TemplateModelMixin):
:vartype type: :class:`Type`
:ivar description: Human-readable description
:vartype description: basestring
- :ivar inputs: Parameters that can be used by all operations in the interface
- :vartype inputs: {basestring: :class:`Parameter`}
+ :ivar inputs: Inputs that can be used by all operations in the interface
+ :vartype inputs: {basestring: :class:`Input`}
:ivar operation_templates: Operations
:vartype operation_templates: {basestring: :class:`OperationTemplate`}
:ivar node_template: Containing node template
@@ -1712,7 +1712,7 @@ class InterfaceTemplateBase(TemplateModelMixin):
@declared_attr
def inputs(cls):
- return relationship.many_to_many(cls, 'parameter', prefix='inputs', dict_key='name')
+ return relationship.many_to_many(cls, 'input', dict_key='name')
# endregion
@@ -1779,8 +1779,8 @@ class OperationTemplateBase(TemplateModelMixin):
:vartype configuration: {basestring, object}
:ivar dependencies: Dependency strings (interpreted by the plugin)
:vartype dependencies: [basestring]
- :ivar inputs: Parameters that can be used by this operation
- :vartype inputs: {basestring: :class:`Parameter`}
+ :ivar inputs: Inputs that can be used by this operation
+ :vartype inputs: {basestring: :class:`Input`}
:ivar executor: Name of executor to run the operation with
:vartype executor: basestring
:ivar max_attempts: Maximum number of attempts allowed in case of failure
@@ -1857,7 +1857,7 @@ class OperationTemplateBase(TemplateModelMixin):
@declared_attr
def inputs(cls):
- return relationship.many_to_many(cls, 'parameter', prefix='inputs', dict_key='name')
+ return relationship.many_to_many(cls, 'input', dict_key='name')
# endregion
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/ee747ef4/aria/modeling/utils.py
----------------------------------------------------------------------
diff --git a/aria/modeling/utils.py b/aria/modeling/utils.py
index 0404fe4..ae62401 100644
--- a/aria/modeling/utils.py
+++ b/aria/modeling/utils.py
@@ -54,20 +54,20 @@ class NodeTemplateContainerHolder(object):
def create_inputs(inputs, template_inputs):
"""
:param inputs: key-value dict
- :param template_inputs: parameter name to parameter object dict
- :return: dict of parameter name to Parameter models
+ :param template_inputs: input name to input object dict
+ :return: dict of input name to Input models
"""
merged_inputs = _merge_and_validate_inputs(inputs, template_inputs)
from . import models
input_models = []
for input_name, input_val in merged_inputs.iteritems():
- parameter = models.Parameter( # pylint: disable=unexpected-keyword-arg
+ input = models.Input( # pylint: disable=unexpected-keyword-arg
name=input_name,
type_name=template_inputs[input_name].type_name,
description=template_inputs[input_name].description,
value=input_val)
- input_models.append(parameter)
+ input_models.append(input)
return dict((inp.name, inp) for inp in input_models)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/ee747ef4/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
index 1769ce5..47cb521 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
@@ -32,7 +32,7 @@ from aria.modeling.models import (Type, ServiceTemplate, NodeTemplate,
RequirementTemplate, RelationshipTemplate, CapabilityTemplate,
GroupTemplate, PolicyTemplate, SubstitutionTemplate,
SubstitutionTemplateMapping, InterfaceTemplate, OperationTemplate,
- ArtifactTemplate, Metadata, Parameter, Output,
+ ArtifactTemplate, Metadata, Parameter, Input, Output,
PluginSpecification)
from .constraints import (Equal, GreaterThan, GreaterOrEqual, LessThan, LessOrEqual, InRange,
@@ -90,7 +90,8 @@ def create_service_template_model(context): # pylint: disable=too-many-locals,to
topology_template = context.presentation.get('service_template', 'topology_template')
if topology_template is not None:
create_parameter_models_from_values(model.inputs,
- topology_template._get_input_values(context))
+ topology_template._get_input_values(context),
+ model_class=Input)
create_parameter_models_from_values(model.outputs,
topology_template._get_output_values(context),
model_class=Output)
@@ -354,10 +355,10 @@ def create_interface_template_model(context, service_template, interface):
inputs = interface.inputs
if inputs:
for input_name, the_input in inputs.iteritems():
- model.inputs[input_name] = Parameter(name=input_name, # pylint: disable=unexpected-keyword-arg
- type_name=the_input.value.type,
- value=the_input.value.value,
- description=the_input.value.description)
+ model.inputs[input_name] = Input(name=input_name, # pylint: disable=unexpected-keyword-arg
+ type_name=the_input.value.type,
+ value=the_input.value.value,
+ description=the_input.value.description)
operations = interface.operations
if operations:
@@ -401,10 +402,10 @@ def create_operation_template_model(context, service_template, operation):
inputs = operation.inputs
if inputs:
for input_name, the_input in inputs.iteritems():
- model.inputs[input_name] = Parameter(name=input_name, # pylint: disable=unexpected-keyword-arg
- type_name=the_input.value.type,
- value=the_input.value.value,
- description=the_input.value.description)
+ model.inputs[input_name] = Input(name=input_name, # pylint: disable=unexpected-keyword-arg
+ type_name=the_input.value.type,
+ value=the_input.value.value,
+ description=the_input.value.description)
return model
@@ -497,10 +498,10 @@ def create_workflow_operation_template_model(context, service_template, policy):
elif prop_name == 'dependencies':
model.dependencies = prop.value
else:
- model.inputs[prop_name] = Parameter(name=prop_name, # pylint: disable=unexpected-keyword-arg
- type_name=prop.type,
- value=prop.value,
- description=prop.description)
+ model.inputs[prop_name] = Input(name=prop_name, # pylint: disable=unexpected-keyword-arg
+ type_name=prop.type,
+ value=prop.value,
+ description=prop.description)
return model
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/ee747ef4/tests/mock/models.py
----------------------------------------------------------------------
diff --git a/tests/mock/models.py b/tests/mock/models.py
index f066551..36929ad 100644
--- a/tests/mock/models.py
+++ b/tests/mock/models.py
@@ -230,7 +230,7 @@ def create_interface(service, interface_name, operation_name, operation_kwargs=N
if operation_kwargs and operation_kwargs.get('inputs'):
operation_kwargs['inputs'] = dict(
- (input_name, models.Parameter.wrap(input_name, input_value))
+ (input_name, models.Input.wrap(input_name, input_value))
for input_name, input_value in operation_kwargs['inputs'].iteritems()
if input_value is not None)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/ee747ef4/tests/mock/topology.py
----------------------------------------------------------------------
diff --git a/tests/mock/topology.py b/tests/mock/topology.py
index bfb7b4e..fd29f8d 100644
--- a/tests/mock/topology.py
+++ b/tests/mock/topology.py
@@ -28,8 +28,8 @@ def create_simple_topology_single_node(model_storage, create_operation):
'Standard', 'create',
operation_kwargs=dict(
implementation=create_operation,
- inputs={'key': aria_models.Parameter.wrap('key', 'create'),
- 'value': aria_models.Parameter.wrap('value', True)})
+ inputs={'key': aria_models.Input.wrap('key', 'create'),
+ 'value': aria_models.Input.wrap('value', True)})
)
node_template.interface_templates[interface_template.name] = interface_template # pylint: disable=unsubscriptable-object
@@ -39,8 +39,8 @@ def create_simple_topology_single_node(model_storage, create_operation):
'Standard', 'create',
operation_kwargs=dict(
implementation=create_operation,
- inputs={'key': aria_models.Parameter.wrap('key', 'create'),
- 'value': aria_models.Parameter.wrap('value', True)})
+ inputs={'key': aria_models.Input.wrap('key', 'create'),
+ 'value': aria_models.Input.wrap('value', True)})
)
node.interfaces[interface.name] = interface # pylint: disable=unsubscriptable-object
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/ee747ef4/tests/modeling/test_models.py
----------------------------------------------------------------------
diff --git a/tests/modeling/test_models.py b/tests/modeling/test_models.py
index 61034bd..17f2104 100644
--- a/tests/modeling/test_models.py
+++ b/tests/modeling/test_models.py
@@ -36,7 +36,7 @@ from aria.modeling.models import (
Relationship,
NodeTemplate,
Node,
- Parameter,
+ Input,
Type
)
@@ -625,7 +625,7 @@ class TestNodeHostAddress(object):
service_template=storage.service_template.list()[0]
)
if host_address:
- kwargs['properties'] = {'host_address': Parameter.wrap('host_address', host_address)}
+ kwargs['properties'] = {'host_address': Input.wrap('host_address', host_address)}
node = NodeTemplate(**kwargs)
storage.node_template.put(node)
return node
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/ee747ef4/tests/orchestrator/test_workflow_runner.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/test_workflow_runner.py b/tests/orchestrator/test_workflow_runner.py
index 7374e50..2a01b63 100644
--- a/tests/orchestrator/test_workflow_runner.py
+++ b/tests/orchestrator/test_workflow_runner.py
@@ -171,7 +171,7 @@ def test_execution_inputs_override_workflow_inputs(request):
wf_inputs = {'input1': 'value1', 'input2': 'value2', 'input3': 5}
mock_workflow = _setup_mock_workflow_in_service(
request,
- inputs=dict((name, models.Parameter.wrap(name, val)) for name, val
+ inputs=dict((name, models.Input.wrap(name, val)) for name, val
in wf_inputs.iteritems()))
with mock.patch('aria.orchestrator.workflow_runner.Engine'):
@@ -196,7 +196,7 @@ def test_execution_inputs_undeclared_inputs(request):
def test_execution_inputs_missing_required_inputs(request):
mock_workflow = _setup_mock_workflow_in_service(
- request, inputs={'required_input': models.Parameter.wrap('required_input', value=None)})
+ request, inputs={'required_input': models.Input.wrap('required_input', value=None)})
with pytest.raises(modeling_exceptions.MissingRequiredInputsException):
_create_workflow_runner(request, mock_workflow, inputs={})
@@ -204,7 +204,7 @@ def test_execution_inputs_missing_required_inputs(request):
def test_execution_inputs_wrong_type_inputs(request):
mock_workflow = _setup_mock_workflow_in_service(
- request, inputs={'input': models.Parameter.wrap('input', 'value')})
+ request, inputs={'input': models.Input.wrap('input', 'value')})
with pytest.raises(modeling_exceptions.InputsOfWrongTypeException):
_create_workflow_runner(request, mock_workflow, inputs={'input': 5})
@@ -225,7 +225,7 @@ def test_workflow_function_parameters(request, tmpdir):
wf_inputs = {'output_path': output_path, 'input1': 'value1', 'input2': 'value2', 'input3': 5}
mock_workflow = _setup_mock_workflow_in_service(
- request, inputs=dict((name, models.Parameter.wrap(name, val)) for name, val
+ request, inputs=dict((name, models.Input.wrap(name, val)) for name, val
in wf_inputs.iteritems()))
_create_workflow_runner(request, mock_workflow,
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/ee747ef4/tests/orchestrator/workflows/executor/test_executor.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/workflows/executor/test_executor.py b/tests/orchestrator/workflows/executor/test_executor.py
index 29cb0e8..643acae 100644
--- a/tests/orchestrator/workflows/executor/test_executor.py
+++ b/tests/orchestrator/workflows/executor/test_executor.py
@@ -47,7 +47,7 @@ def execute_and_assert(executor, storage=None):
successful_task = MockTask(_get_implementation(mock_successful_task), storage=storage)
failing_task = MockTask(_get_implementation(mock_failing_task), storage=storage)
task_with_inputs = MockTask(_get_implementation(mock_task_with_input),
- inputs={'input': models.Parameter.wrap('input', 'value')},
+ inputs={'input': models.Input.wrap('input', 'value')},
storage=storage)
for task in [successful_task, failing_task, task_with_inputs]: