You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ariatosca.apache.org by em...@apache.org on 2017/03/05 03:32:10 UTC
[2/2] incubator-ariatosca git commit: Add rich docs, fix many tests
Add rich docs, fix many tests
Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/24ad8ba1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/24ad8ba1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/24ad8ba1
Branch: refs/heads/ARIA-105-integrate-modeling
Commit: 24ad8ba1e1a013a2348880459e81830fc270b16f
Parents: 36eb2d2
Author: Tal Liron <ta...@gmail.com>
Authored: Sat Mar 4 21:31:42 2017 -0600
Committer: Tal Liron <ta...@gmail.com>
Committed: Sat Mar 4 21:31:42 2017 -0600
----------------------------------------------------------------------
aria/modeling/orchestration.py | 18 +-
aria/modeling/service.py | 369 +++++++++++------
aria/modeling/service_template.py | 402 ++++++++++++-------
aria/modeling/utils.py | 36 ++
.../simple_v1_0/modeling/__init__.py | 16 +-
tests/mock/context.py | 4 +-
tests/mock/models.py | 217 +++++-----
tests/mock/topology.py | 90 ++---
tests/orchestrator/context/test_operation.py | 56 +--
tests/orchestrator/test_runner.py | 5 +-
tests/storage/test_instrumentation.py | 10 +-
tests/storage/test_model_storage.py | 38 +-
tests/storage/test_models.py | 337 ++++++++--------
tests/storage/test_structures.py | 52 ++-
14 files changed, 971 insertions(+), 679 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/24ad8ba1/aria/modeling/orchestration.py
----------------------------------------------------------------------
diff --git a/aria/modeling/orchestration.py b/aria/modeling/orchestration.py
index 9cbb3cf..30879e9 100644
--- a/aria/modeling/orchestration.py
+++ b/aria/modeling/orchestration.py
@@ -154,13 +154,13 @@ class ServiceUpdateBase(ModelMixin):
__tablename__ = 'service_update'
- _private_fields = ['execution_fk', 'deployment_fk']
+ _private_fields = ['execution_fk', 'service_fk']
created_at = Column(DateTime, nullable=False, index=True)
service_plan = Column(Dict, nullable=False)
- service_update_node_instances = Column(Dict)
- service_update_service_instance = Column(Dict)
- service_update_nodes = Column(List)
+ service_update_nodes = Column(Dict)
+ service_update_service = Column(Dict)
+ service_update_node_templates = Column(List)
modified_entity_ids = Column(Dict)
state = Column(Text)
@@ -239,8 +239,8 @@ class ServiceUpdateStepBase(ModelMixin):
backreference='steps')
@declared_attr
- def deployment_update_name(cls):
- return association_proxy('deployment_update', cls.name_column_name())
+ def service_update_name(cls):
+ return association_proxy('service_update', cls.name_column_name())
# region foreign keys
@@ -297,9 +297,9 @@ class ServiceModificationBase(ModelMixin):
context = Column(Dict)
created_at = Column(DateTime, nullable=False, index=True)
ended_at = Column(DateTime, index=True)
- modified_nodes = Column(Dict)
- node_instances = Column(Dict)
- status = Column(Enum(*STATES, name='deployment_modification_status'))
+ modified_node_templates = Column(Dict)
+ nodes = Column(Dict)
+ status = Column(Enum(*STATES, name='service_modification_status'))
@declared_attr
def service(cls):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/24ad8ba1/aria/modeling/service.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service.py b/aria/modeling/service.py
index e555b70..842d0fc 100644
--- a/aria/modeling/service.py
+++ b/aria/modeling/service.py
@@ -36,23 +36,47 @@ from . import (
class ServiceBase(InstanceModelMixin): # pylint: disable=too-many-public-methods
"""
- A service instance is usually an instance of a :class:`ServiceTemplate`.
+ A service is usually an instance of a :class:`ServiceTemplate`.
- You will usually not create it programmatically, but instead instantiate it from the template.
+ You will usually not create it programmatically, but instead instantiate it from a service
+ template.
+ :ivar name: Name (unique for this ARIA installation)
+ :vartype name: basestring
+ :ivar service_template: Template from which this service was instantiated (optional)
+ :vartype service_template: :class:`ServiceTemplate`
:ivar description: Human-readable description
- :ivar meta_data: Dict of :class:`Metadata`
- :ivar nodes: Dict of :class:`Node`
- :ivar groups: Dict of :class:`Group`
- :ivar policies: Dict of :class:`Policy`
- :ivar substitution: :class:`Substitution`
- :ivar inputs: Dict of :class:`Parameter`
- :ivar outputs: Dict of :class:`Parameter`
- :ivar operations: Dict of :class:`Operation`
+ :vartype description: string
+ :ivar meta_data: Custom annotations
+ :vartype meta_data: {basestring: :class:`Metadata`}
+ :ivar node: Nodes
+ :vartype node: [:class:`Node`]
+ :ivar groups: Groups of nodes
+ :vartype groups: [:class:`Group`]
+ :ivar policies: Policies
+ :vartype policies: [:class:`Policy`]
+ :ivar substitution: The entire service can appear as a node
+ :vartype substitution: :class:`Substitution`
+ :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`}
+ :ivar operations: Custom operations that can be performed on the service
+ :vartype operations: {basestring: :class:`Operation`}
+ :ivar plugins: Plugins required to be installed
+ :vartype plugins: {basestring: :class:`Plugin`}
+ :ivar created_at: Creation timestamp
+ :vartype created_at: :class:`datetime.datetime`
+ :ivar updated_at: Update timestamp
+ :vartype updated_at: :class:`datetime.datetime`
"""
__tablename__ = 'service'
+ @declared_attr
+ def service_template(cls):
+ return cls.many_to_one_relationship('service_template')
+
description = Column(Text)
@declared_attr
@@ -91,20 +115,16 @@ class ServiceBase(InstanceModelMixin): # pylint: disable=too-many-public-methods
return cls.one_to_many_relationship('operation', dict_key='name')
@declared_attr
- def service_template(cls):
- return cls.many_to_one_relationship('service_template')
-
- # region orchestration
+ def plugins(cls):
+ return cls.many_to_many_relationship('plugin')
created_at = Column(DateTime, nullable=False, index=True)
updated_at = Column(DateTime)
+
+ # region orchestration
+
permalink = Column(Text)
scaling_groups = Column(modeling_types.Dict)
- workflows = Column(modeling_types.Dict)
-
- @declared_attr
- def service_template_name(cls):
- return association_proxy('service_template', 'name')
# endregion
@@ -260,20 +280,44 @@ class NodeBase(InstanceModelMixin):
Nodes may have zero or more :class:`Relationship` instances to other nodes.
- :ivar name: Unique ID (often prefixed with the template name)
- :ivar properties: Dict of :class:`Parameter`
- :ivar interfaces: Dict of :class:`Interface`
- :ivar artifacts: Dict of :class:`Artifact`
- :ivar capabilities: Dict of :class:`CapabilityTemplate`
- :ivar relationships: List of :class:`Relationship`
+ :ivar name: Name (unique for this service)
+ :vartype name: basestring
+ :ivar node_template: Template from which this node was instantiated (optional)
+ :vartype node_template: :class:`NodeTemplate`
+ :ivar type: Node type
+ :vartype type: :class:`Type`
+ :ivar description: Human-readable description
+ :vartype description: string
+ :ivar properties: Associated parameters
+ :vartype properties: {basestring: :class:`Parameter`}
+ :ivar interfaces: Bundles of operations
+ :vartype interfaces: {basestring: :class:`Interface`}
+ :ivar artifacts: Associated files
+ :vartype artifacts: {basestring: :class:`Artifact`}
+ :ivar capabilities: Exposed capabilities
+ :vartype capabilities: {basestring: :class:`Capability`}
+ :ivar outbound_relationships: Relationships to other nodes
+ :vartype outbound_relationships: [:class:`Relationship`]
+ :ivar inbound_relationships: Relationships from other nodes
+ :vartype inbound_relationships: [:class:`Relationship`]
+ :ivar plugins: Plugins required to be installed on the node's host
+ :vartype plugins: {basestring: :class:`Plugin`}
+ :ivar host: Host node (can be self)
+ :vartype host: :class:`Node`
"""
__tablename__ = 'node'
@declared_attr
+ def node_template(cls):
+ return cls.many_to_one_relationship('node_template')
+
+ @declared_attr
def type(cls):
return cls.many_to_one_relationship('type')
+ description = Column(Text)
+
@declared_attr
def properties(cls):
return cls.many_to_many_relationship('parameter', table_prefix='properties',
@@ -304,12 +348,12 @@ class NodeBase(InstanceModelMixin):
backreference='target_node')
@declared_attr
- def host(cls):
- return cls.relationship_to_self('host_fk')
+ def plugins(cls):
+ return cls.many_to_many_relationship('plugin')
@declared_attr
- def node_template(cls):
- return cls.many_to_one_relationship('node_template')
+ def host(cls):
+ return cls.relationship_to_self('host_fk')
# region orchestration
@@ -319,10 +363,6 @@ class NodeBase(InstanceModelMixin):
version = Column(Integer, default=1)
@declared_attr
- def plugins(cls):
- return association_proxy('node_template', 'plugins')
-
- @declared_attr
def service_name(cls):
return association_proxy('service', 'name')
@@ -335,9 +375,9 @@ class NodeBase(InstanceModelMixin):
if 'ip' in host_node.runtime_properties: # pylint: disable=no-member
return host_node.runtime_properties['ip'] # pylint: disable=no-member
host_node = host_node.node_template # pylint: disable=no-member
- host_ip_property = [prop for prop in host_node.properties if prop.name == 'ip']
+ host_ip_property = host_node.properties.get('ip')
if host_ip_property:
- return host_ip_property[0].value
+ return host_ip_property.value
return None
# endregion
@@ -415,7 +455,7 @@ class NodeBase(InstanceModelMixin):
relationship = \
requirement_template.relationship_template.instantiate(context, self)
else:
- relationship = models.Relationship(capability=target_capability)
+ relationship = models.Relationship(target_capability=target_capability)
relationship.name = requirement_template.name
relationship.requirement_template = requirement_template
relationship.target_node = target_node
@@ -504,17 +544,38 @@ class GroupBase(InstanceModelMixin):
"""
Usually an instance of a :class:`GroupTemplate`.
- :ivar name: Unique ID (often equal to the template name)
- :ivar properties: Dict of :class:`Parameter`
- :ivar interfaces: Dict of :class:`Interface`
+ :ivar name: Name (unique for this service)
+ :vartype name: basestring
+ :ivar group_template: Template from which this group was instantiated (optional)
+ :vartype group_template: :class:`GroupTemplate`
+ :ivar type: Group type
+ :vartype type: :class:`Type`
+ :ivar description: Human-readable description
+ :vartype description: string
+ :ivar nodes: Members of this group
+ :vartype nodes: [:class:`Node`]
+ :ivar properties: Associated parameters
+ :vartype properties: {basestring: :class:`Parameter`}
+ :ivar interfaces: Bundles of operations
+ :vartype interfaces: {basestring: :class:`Interface`}
"""
__tablename__ = 'group'
@declared_attr
+ def group_template(cls):
+ return cls.many_to_one_relationship('group_template')
+
+ @declared_attr
def type(cls):
return cls.many_to_one_relationship('type')
+ description = Column(Text)
+
+ @declared_attr
+ def nodes(cls):
+ return cls.many_to_many_relationship('node')
+
@declared_attr
def properties(cls):
return cls.many_to_many_relationship('parameter', table_prefix='properties',
@@ -524,14 +585,6 @@ class GroupBase(InstanceModelMixin):
def interfaces(cls):
return cls.one_to_many_relationship('interface', dict_key='name')
- @declared_attr
- def nodes(cls):
- return cls.many_to_many_relationship('node')
-
- @declared_attr
- def group_template(cls):
- return cls.many_to_one_relationship('group_template')
-
# region foreign_keys
__private_fields__ = ['type_fk',
@@ -587,16 +640,34 @@ class PolicyBase(InstanceModelMixin):
"""
Usually an instance of a :class:`PolicyTemplate`.
- :ivar name: Name
- :ivar properties: Dict of :class:`Parameter`
+ :ivar name: Name (unique for this service)
+ :vartype name: basestring
+ :ivar policy_template: Template from which this policy was instantiated (optional)
+ :vartype policy_template: :class:`PolicyTemplate`
+ :ivar type: Policy type
+ :vartype type: :class:`Type`
+ :ivar description: Human-readable description
+ :vartype description: string
+ :ivar nodes: Policy will be enacted on all these nodes
+ :vartype nodes: [:class:`Node`]
+ :ivar groups: Policy will be enacted on all nodes in these groups
+ :vartype groups: [:class:`Group`]
+ :ivar properties: Associated parameters
+ :vartype properties: {basestring: :class:`Parameter`}
"""
__tablename__ = 'policy'
@declared_attr
+ def policy_template(cls):
+ return cls.many_to_one_relationship('policy_template')
+
+ @declared_attr
def type(cls):
return cls.many_to_one_relationship('type')
+ description = Column(Text)
+
@declared_attr
def properties(cls):
return cls.many_to_many_relationship('parameter', table_prefix='properties',
@@ -610,10 +681,6 @@ class PolicyBase(InstanceModelMixin):
def groups(cls):
return cls.many_to_many_relationship('group')
- @declared_attr
- def policy_template(cls):
- return cls.many_to_one_relationship('policy_template')
-
# region foreign_keys
__private_fields__ = ['type_fk',
@@ -669,14 +736,25 @@ class PolicyBase(InstanceModelMixin):
class SubstitutionBase(InstanceModelMixin):
"""
+ Used to substitute a single node for the entire deployment.
+
Usually an instance of a :class:`SubstitutionTemplate`.
- :ivar mappings: Dict of :class:` SubstitutionMapping`
+ :ivar substitution_template: Template from which this substitution was instantiated (optional)
+ :vartype substitution_template: :class:`SubstitutionTemplate`
+ :ivar node_type: Exposed node type
+ :vartype node_type: :class:`Type`
+ :ivar mappings: Requirement and capability mappings
+ :vartype mappings: {basestring: :class:`SubstitutionTemplate`}
"""
__tablename__ = 'substitution'
@declared_attr
+ def substitution_template(cls):
+ return cls.many_to_one_relationship('substitution_template')
+
+ @declared_attr
def node_type(cls):
return cls.many_to_one_relationship('type')
@@ -684,10 +762,6 @@ class SubstitutionBase(InstanceModelMixin):
def mappings(cls):
return cls.one_to_many_relationship('substitution_mapping', dict_key='name')
- @declared_attr
- def substitution_template(cls):
- return cls.many_to_one_relationship('substitution_template')
-
# region foreign_keys
__private_fields__ = ['node_type_fk',
@@ -726,9 +800,20 @@ class SubstitutionBase(InstanceModelMixin):
class SubstitutionMappingBase(InstanceModelMixin):
"""
- An instance of a :class:`SubstitutionMappingTemplate`.
+ Used by :class:`Substitution` to map a capability or a requirement to a node.
+
+ Only one of `capability_template` and `requirement_template` can be set.
+
+ Usually an instance of a :class:`SubstitutionTemplate`.
:ivar name: Exposed capability or requirement name
+ :vartype name: basestring
+ :ivar node: Node
+ :vartype node: :class:`Node`
+ :ivar capability: Capability in the node
+ :vartype capability: :class:`Capability`
+ :ivar requirement_template: Requirement template in the node template
+ :vartype requirement_template: :class:`RequirementTemplate`
"""
__tablename__ = 'substitution_mapping'
@@ -798,22 +883,43 @@ class SubstitutionMappingBase(InstanceModelMixin):
class RelationshipBase(InstanceModelMixin):
"""
- Connects :class:`Node` to another node.
+ Connects :class:`Node` to a capability in another node.
Might be an instance of a :class:`RelationshipTemplate`.
:ivar name: Name (usually the name of the requirement at the source node template)
- :ivar properties: Dict of :class:`Parameter`
- :ivar interfaces: Dict of :class:`Interface`
+ :vartype name: basestring
+ :ivar relationship_template: Template from which this relationship was instantiated (optional)
+ :vartype relationship_template: :class:`RelationshipTemplate`
+ :ivar type: Relationship type
+ :vartype type: :class:`Type`
+ :ivar source_node: Source node
+ :vartype source_node: :class:`Node`
+ :ivar target_node: Target node
+ :vartype target_node: :class:`Node`
+ :ivar target_capability: Capability at the target node (optional)
+ :vartype target_capability: :class:`Capability`
+ :ivar properties: Associated parameters
+ :vartype properties: {basestring: :class:`Parameter`}
+ :ivar interface_templates: Bundles of operations
+ :vartype interface_templates: {basestring: :class:`InterfaceTemplate`}
"""
__tablename__ = 'relationship'
@declared_attr
+ def relationship_template(cls):
+ return cls.many_to_one_relationship('relationship_template')
+
+ @declared_attr
def type(cls):
return cls.many_to_one_relationship('type')
@declared_attr
+ def target_capability(cls):
+ return cls.one_to_one_relationship('capability')
+
+ @declared_attr
def properties(cls):
return cls.many_to_many_relationship('parameter', table_prefix='properties',
dict_key='name')
@@ -823,17 +929,9 @@ class RelationshipBase(InstanceModelMixin):
return cls.one_to_many_relationship('interface', dict_key='name')
@declared_attr
- def capability(cls):
- return cls.one_to_one_relationship('capability')
-
- @declared_attr
def requirement_template(cls):
return cls.many_to_one_relationship('requirement_template')
- @declared_attr
- def relationship_template(cls):
- return cls.many_to_one_relationship('relationship_template')
-
# region orchestration
source_position = Column(Integer) # ???
@@ -907,8 +1005,9 @@ class RelationshipBase(InstanceModelMixin):
console.puts('->')
with context.style.indent:
console.puts('Node: {0}'.format(context.style.node(self.target_node.name)))
- if self.capability:
- console.puts('Capability: {0}'.format(context.style.node(self.capability.name)))
+ if self.target_capability:
+ console.puts('Capability: {0}'.format(context.style.node(
+ self.target_capability.name)))
if self.type is not None:
console.puts('Relationship type: {0}'.format(context.style.type(self.type.name)))
if (self.relationship_template is not None) and self.relationship_template.name:
@@ -924,20 +1023,34 @@ class CapabilityBase(InstanceModelMixin):
Usually an instance of a :class:`CapabilityTemplate`.
- :ivar name: Name
+ :ivar name: Name (unique for the node)
+ :vartype name: basestring
+ :ivar capability_template: Template from which this capability was instantiated (optional)
+ :vartype capability_template: :class:`capabilityTemplate`
+ :ivar type: Capability type
+ :vartype type: :class:`Type`
:ivar min_occurrences: Minimum number of requirement matches required
+ :vartype min_occurrences: int
:ivar max_occurrences: Maximum number of requirement matches allowed
- :ivar properties: Dict of :class:`Parameter`
+ :vartype min_occurrences: int
+ :ivar occurrences: Actual number of requirement matches
+ :vartype occurrences: int
+ :ivar properties: Associated parameters
+ :vartype properties: {basestring: :class:`Parameter`}
"""
__tablename__ = 'capability'
@declared_attr
+ def capability_template(cls):
+ return cls.many_to_one_relationship('capability_template')
+
+ @declared_attr
def type(cls):
return cls.many_to_one_relationship('type')
- min_occurrences = Column(Integer, default=None) # optional
- max_occurrences = Column(Integer, default=None) # optional
+ min_occurrences = Column(Integer, default=None)
+ max_occurrences = Column(Integer, default=None)
occurrences = Column(Integer, default=0)
@declared_attr
@@ -945,10 +1058,6 @@ class CapabilityBase(InstanceModelMixin):
return cls.many_to_many_relationship('parameter', table_prefix='properties',
dict_key='name')
- @declared_attr
- def capability_template(cls):
- return cls.many_to_one_relationship('capability_template')
-
# region foreign_keys
__private_fields__ = ['capability_fk',
@@ -1017,15 +1126,27 @@ class InterfaceBase(InstanceModelMixin):
Usually an instance of :class:`InterfaceTemplate`.
- :ivar name: Name
- :ivar description: Description
- :ivar inputs: Dict of :class:`Parameter`
- :ivar operations: Dict of :class:`Operation`
+ :ivar name: Name (unique for the node, group, or relationship)
+ :vartype name: basestring
+ :ivar interface_template: Template from which this interface was instantiated (optional)
+ :vartype interface_template: :class:`InterfaceTemplate`
+ :ivar type: Interface type
+ :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 operations: Operations
+ :vartype operations: {basestring: :class:`Operation`}
"""
__tablename__ = 'interface'
@declared_attr
+ def interface_template(cls):
+ return cls.many_to_one_relationship('interface_template')
+
+ @declared_attr
def type(cls):
return cls.many_to_one_relationship('type')
@@ -1040,10 +1161,6 @@ class InterfaceBase(InstanceModelMixin):
def operations(cls):
return cls.one_to_many_relationship('operation', dict_key='name')
- @declared_attr
- def interface_template(cls):
- return cls.many_to_one_relationship('interface_template')
-
# region foreign_keys
__private_fields__ = ['type_fk',
@@ -1112,37 +1229,51 @@ class OperationBase(InstanceModelMixin):
Might be an instance of :class:`OperationTemplate`.
- :ivar name: Name
- :ivar description: Description
- :ivar implementation: Implementation string (interpreted by the orchestrator)
- :ivar dependencies: List of strings (interpreted by the orchestrator)
- :ivar executor: Executor string (interpreted by the orchestrator)
+ :ivar name: Name (unique for the interface or service)
+ :vartype name: basestring
+ :ivar operation_template: Template from which this operation was instantiated (optional)
+ :vartype operation_template: :class:`OperationTemplate`
+ :ivar description: Human-readable description
+ :vartype description: string
+ :ivar plugin: Associated plugin
+ :vartype plugin: :class:`Plugin`
+ :ivar implementation: Implementation string (interpreted by the plugin)
+ :vartype implementation: basestring
+ :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 executor: Executor name
+ :vartype executor: basestring
:ivar max_retries: Maximum number of retries allowed in case of failure
- :ivar retry_interval: Interval between retries
- :ivar inputs: Dict of :class:`Parameter`
+ :vartype max_retries: int
+ :ivar retry_interval: Interval between retries (in seconds)
+ :vartype retry_interval: int
"""
__tablename__ = 'operation'
+ @declared_attr
+ def operation_template(cls):
+ return cls.many_to_one_relationship('operation_template')
+
description = Column(Text)
+
+ @declared_attr
+ def plugin(cls):
+ return cls.one_to_one_relationship('plugin')
+
implementation = Column(Text)
dependencies = Column(modeling_types.StrictList(item_cls=basestring))
- executor = Column(Text)
- max_retries = Column(Integer)
- retry_interval = Column(Integer)
@declared_attr
def inputs(cls):
return cls.many_to_many_relationship('parameter', table_prefix='inputs',
dict_key='name')
- @declared_attr
- def plugin(cls):
- return cls.one_to_one_relationship('plugin')
-
- @declared_attr
- def operation_template(cls):
- return cls.many_to_one_relationship('operation_template')
+ executor = Column(Text)
+ max_retries = Column(Integer)
+ retry_interval = Column(Integer)
# region foreign_keys
@@ -1220,23 +1351,37 @@ class ArtifactBase(InstanceModelMixin):
Usually an instance of :class:`ArtifactTemplate`.
- :ivar name: Name
- :ivar description: Description
+ :ivar name: Name (unique for the node)
+ :vartype name: basestring
+ :ivar artifact_template: Template from which this artifact was instantiated (optional)
+ :vartype artifact_template: :class:`ArtifactTemplate`
+ :ivar type: Artifact type
+ :vartype type: :class:`Type`
+ :ivar description: Human-readable description
+ :vartype description: string
:ivar source_path: Source path (CSAR or repository)
+ :vartype source_path: basestring
:ivar target_path: Path at destination machine
+ :vartype target_path: basestring
:ivar repository_url: Repository URL
- :ivar repository_credential: Dict of string
- :ivar properties: Dict of :class:`Parameter`
+ :vartype repository_path: basestring
+ :ivar repository_credential: Credentials for accessing the repository
+ :vartype repository_credential: {basestring: basestring}
+ :ivar properties: Associated parameters
+ :vartype properties: {basestring: :class:`Parameter`}
"""
__tablename__ = 'artifact'
@declared_attr
+ def artifact_template(cls):
+ return cls.many_to_one_relationship('artifact_template')
+
+ @declared_attr
def type(cls):
return cls.many_to_one_relationship('type')
description = Column(Text)
- type_name = Column(Text)
source_path = Column(Text)
target_path = Column(Text)
repository_url = Column(Text)
@@ -1247,10 +1392,6 @@ class ArtifactBase(InstanceModelMixin):
return cls.many_to_many_relationship('parameter', table_prefix='properties',
dict_key='name')
- @declared_attr
- def artifact_template(cls):
- return cls.many_to_one_relationship('artifact_template')
-
# region foreign_keys
__private_fields__ = ['type_fk',
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/24ad8ba1/aria/modeling/service_template.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_template.py b/aria/modeling/service_template.py
index 1f2d1f3..aec7aa0 100644
--- a/aria/modeling/service_template.py
+++ b/aria/modeling/service_template.py
@@ -17,7 +17,6 @@
from __future__ import absolute_import # so we can import standard 'types'
-from copy import deepcopy
from types import FunctionType
from datetime import datetime
@@ -40,27 +39,61 @@ from . import (
class ServiceTemplateBase(TemplateModelMixin):
"""
- A service template is a normalized blueprint from which :class:`ServiceInstance` instances can
- be created.
+ A service template is a source for creating :class:`Service` instances.
It is usually created by various DSL parsers, such as ARIA's TOSCA extension. However, it can
also be created programmatically.
+ :ivar name: Name (unique for this ARIA installation)
+ :vartype name: basestring
:ivar description: Human-readable description
- :vartype description: string
- :ivar meta_data: Dict of :class:`Metadata`
- :ivar node_templates: List of :class:`NodeTemplate`
- :ivar group_templates: List of :class:`GroupTemplate`
- :ivar policy_templates: List of :class:`PolicyTemplate`
- :ivar substitution_template: :class:`SubstitutionTemplate`
- :ivar inputs: Dict of :class:`Parameter`
- :ivar outputs: Dict of :class:`Parameter`
- :ivar operation_templates: Dict of :class:`OperationTemplate`
+ :vartype description: basestring
+ :ivar main_file_name: Filename of CSAR or YAML file from which this service template was parsed
+ :vartype main_file_name: basestring
+ :ivar meta_data: Custom annotations
+ :vartype meta_data: {basestring: :class:`Metadata`}
+ :ivar node_templates: Templates for creating nodes
+ :vartype node_templates: [:class:`NodeTemplate`]
+ :ivar group_templates: Templates for creating groups
+ :vartype group_templates: [:class:`GroupTemplate`]
+ :ivar policy_templates: Templates for creating policies
+ :vartype policy_templates: [:class:`PolicyTemplate`]
+ :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`}
+ :ivar outputs: These parameters are filled in after service installation
+ :vartype outputs: {basestring: :class:`Parameter`}
+ :ivar operation_templates: Custom operations that can be performed on the service
+ :vartype operation_templates: {basestring: :class:`OperationTemplate`}
+ :ivar plugins: Plugins required by services
+ :vartype plugins: {basestring: :class:`Plugin`}
+ :ivar node_types: Base for the node type hierarchy
+ :vartype node_types: :class:`Type`
+ :ivar group_types: Base for the group type hierarchy
+ :vartype group_types: :class:`Type`
+ :ivar policy_types: Base for the policy type hierarchy
+ :vartype policy_types: :class:`Type`
+ :ivar relationship_types: Base for the relationship type hierarchy
+ :vartype relationship_types: :class:`Type`
+ :ivar capability_types: Base for the capability type hierarchy
+ :vartype capability_types: :class:`Type`
+ :ivar interface_types: Base for the interface type hierarchy
+ :vartype interface_types: :class:`Type`
+ :ivar artifact_types: Base for the artifact type hierarchy
+ :vartype artifact_types: :class:`Type`
+ :ivar plugins: Plugins required to be installed
+ :vartype plugins: {basestring: :class:`Plugin`}
+ :ivar created_at: Creation timestamp
+ :vartype created_at: :class:`datetime.datetime`
+ :ivar updated_at: Update timestamp
+ :vartype updated_at: :class:`datetime.datetime`
"""
__tablename__ = 'service_template'
description = Column(Text)
+ main_file_name = Column(Text)
@declared_attr
def meta_data(cls):
@@ -98,6 +131,10 @@ class ServiceTemplateBase(TemplateModelMixin):
return cls.one_to_many_relationship('operation_template', dict_key='name')
@declared_attr
+ def plugins(cls):
+ return cls.one_to_many_relationship('plugin')
+
+ @declared_attr
def node_types(cls):
return cls.one_to_one_relationship('type', key='node_type_fk', backreference='')
@@ -106,40 +143,42 @@ class ServiceTemplateBase(TemplateModelMixin):
return cls.one_to_one_relationship('type', key='group_type_fk', backreference='')
@declared_attr
- def capability_types(cls):
- return cls.one_to_one_relationship('type', key='capability_type_fk', backreference='')
+ def policy_types(cls):
+ return cls.one_to_one_relationship('type', key='policy_type_fk', backreference='')
@declared_attr
def relationship_types(cls):
return cls.one_to_one_relationship('type', key='relationship_type_fk', backreference='')
@declared_attr
- def policy_types(cls):
- return cls.one_to_one_relationship('type', key='policy_type_fk', backreference='')
-
- @declared_attr
- def artifact_types(cls):
- return cls.one_to_one_relationship('type', key='artifact_type_fk', backreference='')
+ def capability_types(cls):
+ return cls.one_to_one_relationship('type', key='capability_type_fk', backreference='')
@declared_attr
def interface_types(cls):
return cls.one_to_one_relationship('type', key='interface_type_fk', backreference='')
+ @declared_attr
+ def artifact_types(cls):
+ return cls.one_to_one_relationship('type', key='artifact_type_fk', backreference='')
+
# region orchestration
created_at = Column(DateTime, nullable=False, index=True)
updated_at = Column(DateTime)
- main_file_name = Column(Text)
-
- @declared_attr
- def plugins(cls):
- return cls.one_to_many_relationship('plugin', dict_key='name')
# endregion
# region foreign keys
- __private_fields__ = ['substitution_template_fk']
+ __private_fields__ = ['substitution_template_fk',
+ 'node_type_fk',
+ 'group_type_fk',
+ 'policy_type_fk',
+ 'relationship_type_fk',
+ 'capability_type_fk',
+ 'interface_type_fk',
+ 'artifact_type_fk']
# ServiceTemplate one-to-one to SubstitutionTemplate
@declared_attr
@@ -158,7 +197,7 @@ class ServiceTemplateBase(TemplateModelMixin):
# ServiceTemplate one-to-one to Type
@declared_attr
- def capability_type_fk(cls):
+ def policy_type_fk(cls):
return cls.foreign_key('type', nullable=True)
# ServiceTemplate one-to-one to Type
@@ -168,17 +207,17 @@ class ServiceTemplateBase(TemplateModelMixin):
# ServiceTemplate one-to-one to Type
@declared_attr
- def policy_type_fk(cls):
+ def capability_type_fk(cls):
return cls.foreign_key('type', nullable=True)
# ServiceTemplate one-to-one to Type
@declared_attr
- def artifact_type_fk(cls):
+ def interface_type_fk(cls):
return cls.foreign_key('type', nullable=True)
# ServiceTemplate one-to-one to Type
@declared_attr
- def interface_type_fk(cls):
+ def artifact_type_fk(cls):
return cls.foreign_key('type', nullable=True)
# endregion
@@ -215,18 +254,18 @@ class ServiceTemplateBase(TemplateModelMixin):
return collections.OrderedDict((
('node_types', formatting.as_raw(self.node_types)),
('group_types', formatting.as_raw(self.group_types)),
- ('capability_types', formatting.as_raw(self.capability_types)),
- ('relationship_types', formatting.as_raw(self.relationship_types)),
('policy_types', formatting.as_raw(self.policy_types)),
- ('artifact_types', formatting.as_raw(self.artifact_types)),
- ('interface_types', formatting.as_raw(self.interface_types))))
+ ('relationship_types', formatting.as_raw(self.relationship_types)),
+ ('capability_types', formatting.as_raw(self.capability_types)),
+ ('interface_types', formatting.as_raw(self.interface_types)),
+ ('artifact_types', formatting.as_raw(self.artifact_types))))
def instantiate(self, context, container):
from . import models
now = datetime.now()
service = models.Service(created_at=now,
updated_at=now,
- description=deepcopy_with_locators(self.description),
+ description=utils.deepcopy_with_locators(self.description),
service_template=self)
#service.name = '{0}_{1}'.format(self.name, service.id)
@@ -267,6 +306,20 @@ class ServiceTemplateBase(TemplateModelMixin):
utils.validate_dict_values(context, self.inputs)
utils.validate_dict_values(context, self.outputs)
utils.validate_dict_values(context, self.operation_templates)
+ if self.node_types is not None:
+ self.node_types.validate(context)
+ if self.group_types is not None:
+ self.group_types.validate(context)
+ if self.policy_types is not None:
+ self.policy_types.validate(context)
+ if self.relationship_types is not None:
+ self.relationship_types.validate(context)
+ if self.capability_types is not None:
+ self.capability_types.validate(context)
+ if self.interface_types is not None:
+ self.interface_types.validate(context)
+ if self.artifact_types is not None:
+ self.artifact_types.validate(context)
def coerce_values(self, context, container, report_issues):
utils.coerce_dict_values(context, container, self.meta_data, report_issues)
@@ -283,7 +336,6 @@ class ServiceTemplateBase(TemplateModelMixin):
if self.description is not None:
console.puts(context.style.meta(self.description))
utils.dump_dict_values(context, self.meta_data, 'Metadata')
-
for node_template in self.node_templates:
node_template.dump(context)
for group_template in self.group_templates:
@@ -327,17 +379,33 @@ class NodeTemplateBase(TemplateModelMixin):
"""
A template for creating zero or more :class:`Node` instances.
- :ivar name: Name (will be used as a prefix for node IDs)
- :ivar description: Description
- :ivar default_instances: Default number nodes that will appear in the deployment plan
- :ivar min_instances: Minimum number nodes that will appear in the deployment plan
- :ivar max_instances: Maximum number nodes that will appear in the deployment plan
- :ivar properties: Dict of :class:`Parameter`
- :ivar interface_templates: Dict of :class:`InterfaceTemplate`
- :ivar artifact_templates: Dict of :class:`ArtifactTemplate`
- :ivar capability_templates: Dict of :class:`CapabilityTemplate`
- :ivar requirement_templates: List of :class:`RequirementTemplate`
- :ivar target_node_template_constraints: List of :class:`FunctionType`
+ :ivar name: Name (unique for this service template; will usually be used as a prefix for node
+ names)
+ :vartype name: basestring
+ :ivar type: Node type
+ :vartype type: :class:`Type`
+ :ivar description: Human-readable description
+ :vartype description: basestring
+ :ivar default_instances: Default number nodes that will appear in the service
+ :vartype default_instances: int
+ :ivar min_instances: Minimum number nodes that will appear in the service
+ :vartype min_instances: int
+ :ivar max_instances: Maximum number nodes that will appear in the service
+ :vartype max_instances: int
+ :ivar properties: Associated parameters
+ :vartype properties: {basestring: :class:`Parameter`}
+ :ivar interface_templates: Bundles of operations
+ :vartype interface_templates: {basestring: :class:`InterfaceTemplate`}
+ :ivar artifact_templates: Associated files
+ :vartype artifact_templates: {basestring: :class:`ArtifactTemplate`}
+ :ivar capability_templates: Exposed capabilities
+ :vartype capability_templates: {basestring: :class:`CapabilityTemplate`}
+ :ivar requirement_templates: Potential relationships with other nodes
+ :vartype requirement_templates: [:class:`RequirementTemplate`]
+ :ivar target_node_template_constraints: Constraints for filtering relationship targets
+ :vartype target_node_template_constraints: [:class:`FunctionType`]
+ :ivar plugins: Plugins required to be installed on the node's host
+ :vartype plugins: {basestring: :class:`Plugin`}
"""
__tablename__ = 'node_template'
@@ -350,7 +418,6 @@ class NodeTemplateBase(TemplateModelMixin):
default_instances = Column(Integer, default=1)
min_instances = Column(Integer, default=0)
max_instances = Column(Integer, default=None)
- target_node_template_constraints = Column(modeling_types.StrictList(FunctionType))
@declared_attr
def properties(cls):
@@ -372,15 +439,14 @@ class NodeTemplateBase(TemplateModelMixin):
@declared_attr
def requirement_templates(cls):
return cls.one_to_many_relationship('requirement_template',
- foreign_key='node_template_fk')
+ foreign_key='node_template_fk',
+ backreference='node_template')
- # region orchestration
+ target_node_template_constraints = Column(modeling_types.StrictList(FunctionType))
@declared_attr
def plugins(cls):
- return cls.many_to_many_relationship('plugin', dict_key='name')
-
- # endregion
+ return cls.many_to_many_relationship('plugin')
# region foreign_keys
@@ -426,6 +492,7 @@ class NodeTemplateBase(TemplateModelMixin):
name = context.modeling.generate_node_id(self.name)
node = models.Node(name=name,
type=self.type,
+ description=utils.deepcopy_with_locators(self.description),
state='',
node_template=self)
utils.instantiate_dict(context, node, node.properties, self.properties)
@@ -469,15 +536,22 @@ class NodeTemplateBase(TemplateModelMixin):
class GroupTemplateBase(TemplateModelMixin):
"""
- A template for creating zero or more :class:`Group` instances.
+ A template for creating a :class:`Group` instance.
- Groups are logical containers for zero or more nodes that allow applying zero or more
- :class:`GroupPolicy` instances to the nodes together.
+ Groups are logical containers for zero or more nodes.
- :ivar name: Name (will be used as a prefix for group IDs)
- :ivar description: Description
- :ivar properties: Dict of :class:`Parameter`
- :ivar interface_templates: Dict of :class:`InterfaceTemplate`
+ :ivar name: Name (unique for this service template)
+ :vartype name: basestring
+ :ivar type: Group type
+ :vartype type: :class:`Type`
+ :ivar description: Human-readable description
+ :vartype description: basestring
+ :ivar node_templates: All nodes instantiated by these templates will be members of the group
+ :vartype node_templates: [:class:`NodeTemplate`]
+ :ivar properties: Associated parameters
+ :vartype properties: {basestring: :class:`Parameter`}
+ :ivar interface_templates: Bundles of operations
+ :vartype interface_templates: {basestring: :class:`InterfaceTemplate`}
"""
__tablename__ = 'group_template'
@@ -489,6 +563,10 @@ class GroupTemplateBase(TemplateModelMixin):
description = Column(Text)
@declared_attr
+ def node_templates(cls):
+ return cls.many_to_many_relationship('node_template')
+
+ @declared_attr
def properties(cls):
return cls.many_to_many_relationship('parameter', table_prefix='properties',
dict_key='name')
@@ -497,10 +575,6 @@ class GroupTemplateBase(TemplateModelMixin):
def interface_templates(cls):
return cls.one_to_many_relationship('interface_template', dict_key='name')
- @declared_attr
- def node_templates(cls):
- return cls.many_to_many_relationship('node_template')
-
# region foreign keys
__private_fields__ = ['type_fk',
@@ -531,6 +605,7 @@ class GroupTemplateBase(TemplateModelMixin):
from . import models
group = models.Group(name=self.name,
type=self.type,
+ description=utils.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)
@@ -565,9 +640,18 @@ class PolicyTemplateBase(TemplateModelMixin):
Policies can be applied to zero or more :class:`NodeTemplate` or :class:`GroupTemplate`
instances.
- :ivar name: Name
- :ivar description: Description
- :ivar properties: Dict of :class:`Parameter`
+ :ivar name: Name (unique for this service template)
+ :vartype name: basestring
+ :ivar type: Policy type
+ :vartype type: :class:`Type`
+ :ivar description: Human-readable description
+ :vartype description: basestring
+ :ivar node_templates: Policy will be enacted on all nodes instantiated by these templates
+ :vartype node_templates: [:class:`NodeTemplate`]
+ :ivar group_templates: Policy will be enacted on all nodes in these groups
+ :vartype group_templates: [:class:`GroupTemplate`]
+ :ivar properties: Associated parameters
+ :vartype properties: {basestring: :class:`Parameter`}
"""
__tablename__ = 'policy_template'
@@ -579,11 +663,6 @@ class PolicyTemplateBase(TemplateModelMixin):
description = Column(Text)
@declared_attr
- def properties(cls):
- return cls.many_to_many_relationship('parameter', table_prefix='properties',
- dict_key='name')
-
- @declared_attr
def node_templates(cls):
return cls.many_to_many_relationship('node_template')
@@ -591,6 +670,11 @@ class PolicyTemplateBase(TemplateModelMixin):
def group_templates(cls):
return cls.many_to_many_relationship('group_template')
+ @declared_attr
+ def properties(cls):
+ return cls.many_to_many_relationship('parameter', table_prefix='properties',
+ dict_key='name')
+
# region foreign keys
__private_fields__ = ['type_fk',
@@ -620,6 +704,7 @@ class PolicyTemplateBase(TemplateModelMixin):
from . import models
policy = models.Policy(name=self.name,
type=self.type,
+ description=utils.deepcopy_with_locators(self.description),
policy_template=self)
utils.instantiate_dict(context, self, policy.properties, self.properties)
if self.node_templates:
@@ -655,7 +740,10 @@ class SubstitutionTemplateBase(TemplateModelMixin):
"""
Used to substitute a single node for the entire deployment.
- :ivar mappings: Dict of :class:` SubstitutionTemplateMapping`
+ :ivar node_type: Exposed node type
+ :vartype node_type: :class:`Type`
+ :ivar mappings: Requirement and capability mappings
+ :vartype mappings: {basestring: :class:`SubstitutionTemplateMapping`}
"""
__tablename__ = 'substitution_template'
@@ -708,8 +796,17 @@ class SubstitutionTemplateBase(TemplateModelMixin):
class SubstitutionTemplateMappingBase(TemplateModelMixin):
"""
Used by :class:`SubstitutionTemplate` to map a capability or a requirement to a node.
+
+ Only one of `capability_template` and `requirement_template` can be set.
:ivar name: Exposed capability or requirement name
+ :vartype name: basestring
+ :ivar node_template: Node template
+ :vartype node_template: :class:`NodeTemplate`
+ :ivar capability_template: Capability template in the node template
+ :vartype capability_template: :class:`CapabilityTemplate`
+ :ivar requirement_template: Requirement template in the node template
+ :vartype requirement_template: :class:`RequirementTemplate`
"""
__tablename__ = 'substitution_template_mapping'
@@ -807,10 +904,20 @@ class RequirementTemplateBase(TemplateModelMixin):
Requirements may optionally contain a :class:`RelationshipTemplate` that will be created between
the nodes.
- :ivar name: Name
- :ivar target_node_template_constraints: List of :class:`FunctionType`
- :ivar target_capability_name: Name of capability in target node
- :ivar relationship_template: :class:`RelationshipTemplate`
+ :ivar name: Name (a node template can have multiple requirements with the same name)
+ :vartype name: basestring
+ :ivar target_node_type: Required node type (optional)
+ :vartype target_node_type: :class:`Type`
+ :ivar target_node_template: Required node template (optional)
+ :vartype target_node_template: :class:`NodeTemplate`
+ :ivar target_capability_type: Required capability type (optional)
+ :vartype target_capability_type: :class:`Type`
+ :ivar target_capability_name: Name of capability in target node (optional)
+ :vartype target_capability_name: basestring
+ :ivar target_node_template_constraints: Constraints for filtering relationship targets
+ :vartype target_node_template_constraints: [:class:`FunctionType`]
+ :ivar relationship_template: Template for relationships (optional)
+ :vartype relationship_template: :class:`RelationshipTemplate`
"""
__tablename__ = 'requirement_template'
@@ -829,8 +936,8 @@ class RequirementTemplateBase(TemplateModelMixin):
return cls.one_to_one_relationship('type', key='target_capability_type_fk',
backreference='')
- target_node_template_constraints = Column(modeling_types.StrictList(FunctionType))
target_capability_name = Column(Text)
+ target_node_template_constraints = Column(modeling_types.StrictList(FunctionType))
@declared_attr
def relationship_template(cls):
@@ -972,10 +1079,21 @@ class RelationshipTemplateBase(TemplateModelMixin):
"""
Optional addition to a :class:`RequirementTemplate` in :class:`NodeTemplate` that can be applied
when the requirement is matched with a capability.
-
- :ivar description: Description
- :ivar properties: Dict of :class:`Parameter`
- :ivar interface_templates: Dict of :class:`InterfaceTemplate`
+
+ Note that a relationship template here is not equivalent to a relationship template entity in
+ TOSCA. For example, a TOSCA requirement specifying a relationship type instead of a template
+ would still be represented here as a relationship template.
+
+ :ivar name: Name (optional; if present is unique for this service template)
+ :vartype name: basestring
+ :ivar type: Relationship type
+ :vartype type: :class:`Type`
+ :ivar description: Human-readable description
+ :vartype description: basestring
+ :ivar properties: Associated parameters
+ :vartype properties: {basestring: :class:`Parameter`}
+ :ivar interface_templates: Bundles of operations
+ :vartype interface_templates: {basestring: :class:`InterfaceTemplate`}
"""
__tablename__ = 'relationship_template'
@@ -1052,11 +1170,18 @@ class CapabilityTemplateBase(TemplateModelMixin):
A capability of a :class:`NodeTemplate`. Nodes expose zero or more capabilities that can be
matched with :class:`Requirement` instances of other nodes.
- :ivar name: Name
- :ivar description: Description
+ :ivar name: Name (unique for the node template)
+ :vartype name: basestring
+ :ivar type: Capability type
+ :vartype type: :class:`Type`
+ :ivar description: Human-readable description
+ :vartype description: basestring
:ivar min_occurrences: Minimum number of requirement matches required
+ :vartype min_occurrences: int
:ivar max_occurrences: Maximum number of requirement matches allowed
- :ivar properties: Dict of :class:`Parameter`
+ :vartype min_occurrences: int
+ :ivar properties: Associated parameters
+ :vartype properties: {basestring: :class:`Parameter`}
"""
__tablename__ = 'capability_template'
@@ -1170,10 +1295,16 @@ class InterfaceTemplateBase(TemplateModelMixin):
"""
A typed set of :class:`OperationTemplate`.
- :ivar name: Name
- :ivar description: Description
- :ivar inputs: Dict of :class:`Parameter`
- :ivar operation_templates: Dict of :class:`OperationTemplate`
+ :ivar name: Name (unique for the node, group, or relationship template)
+ :vartype name: basestring
+ :ivar type: Interface type
+ :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 operation_templates: Operations
+ :vartype operation_templates: {basestring: :class:`OperationTemplate`}
"""
__tablename__ = 'interface_template'
@@ -1234,8 +1365,8 @@ class InterfaceTemplateBase(TemplateModelMixin):
def instantiate(self, context, container):
from . import models
interface = models.Interface(name=self.name,
- description=deepcopy_with_locators(self.description),
type=self.type,
+ description=utils.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)
@@ -1263,34 +1394,44 @@ class OperationTemplateBase(TemplateModelMixin):
"""
An operation in a :class:`InterfaceTemplate`.
- :ivar name: Name
- :ivar description: Description
- :ivar implementation: Implementation string (interpreted by the orchestrator)
- :ivar dependencies: List of strings (interpreted by the orchestrator)
- :ivar executor: Executor string (interpreted by the orchestrator)
+ Operations are executed by an associated :class:`Plugin` via an executor.
+
+ :ivar name: Name (unique for the interface or service template)
+ :vartype name: basestring
+ :ivar description: Human-readable description
+ :vartype description: basestring
+ :ivar plugin: Associated plugin
+ :vartype plugin: :class:`Plugin`
+ :ivar implementation: Implementation string (interpreted by the plugin)
+ :vartype implementation: basestring
+ :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 executor: Executor name
+ :vartype executor: basestring
:ivar max_retries: Maximum number of retries allowed in case of failure
- :ivar retry_interval: Interval between retries
- :ivar inputs: Dict of :class:`Parameter`
+ :vartype max_retries: int
+ :ivar retry_interval: Interval between retries (in seconds)
+ :vartype retry_interval: int
"""
__tablename__ = 'operation_template'
description = Column(Text)
+
+ @declared_attr
+ def plugin(cls):
+ return cls.one_to_one_relationship('plugin')
+
implementation = Column(Text)
dependencies = Column(modeling_types.StrictList(item_cls=basestring))
- executor = Column(Text)
- max_retries = Column(Integer)
- retry_interval = Column(Integer)
@declared_attr
def inputs(cls):
return cls.many_to_many_relationship('parameter', table_prefix='inputs',
dict_key='name')
- @declared_attr
- def plugin(cls):
- return cls.one_to_one_relationship('plugin')
-
executor = Column(Text)
max_retries = Column(Integer)
retry_interval = Column(Integer)
@@ -1333,7 +1474,7 @@ class OperationTemplateBase(TemplateModelMixin):
def instantiate(self, context, container):
from . import models
operation = models.Operation(name=self.name,
- description=deepcopy_with_locators(self.description),
+ description=utils.deepcopy_with_locators(self.description),
implementation=self.implementation,
dependencies=self.dependencies,
plugin=self.plugin,
@@ -1375,13 +1516,22 @@ class ArtifactTemplateBase(TemplateModelMixin):
"""
A file associated with a :class:`NodeTemplate`.
- :ivar name: Name
- :ivar description: Description
+ :ivar name: Name (unique for the node template)
+ :vartype name: basestring
+ :ivar type: Artifact type
+ :vartype type: :class:`Type`
+ :ivar description: Human-readable description
+ :vartype description: basestring
:ivar source_path: Source path (CSAR or repository)
+ :vartype source_path: basestring
:ivar target_path: Path at destination machine
+ :vartype target_path: basestring
:ivar repository_url: Repository URL
- :ivar repository_credential: Dict of string
- :ivar properties: Dict of :class:`Parameter`
+ :vartype repository_path: basestring
+ :ivar repository_credential: Credentials for accessing the repository
+ :vartype repository_credential: {basestring: basestring}
+ :ivar properties: Associated parameters
+ :vartype properties: {basestring: :class:`Parameter`}
"""
__tablename__ = 'artifact_template'
@@ -1434,8 +1584,8 @@ class ArtifactTemplateBase(TemplateModelMixin):
from . import models
artifact = models.Artifact(name=self.name,
type=self.type,
+ description=utils.deepcopy_with_locators(self.description),
source_path=self.source_path,
- description=deepcopy_with_locators(self.description),
target_path=self.target_path,
repository_url=self.repository_url,
repository_credential=self.repository_credential,
@@ -1465,35 +1615,3 @@ class ArtifactTemplateBase(TemplateModelMixin):
console.puts('Repository credential: {0}'.format(
context.style.literal(self.repository_credential)))
utils.dump_dict_values(context, self.properties, 'Properties')
-
-
-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])
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/24ad8ba1/aria/modeling/utils.py
----------------------------------------------------------------------
diff --git a/aria/modeling/utils.py b/aria/modeling/utils.py
index a2f0bfc..a071d69 100644
--- a/aria/modeling/utils.py
+++ b/aria/modeling/utils.py
@@ -13,6 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from copy import deepcopy
+
from ..parser.exceptions import InvalidValueError
from ..parser.presentation import Value
from ..utils.collections import OrderedDict
@@ -109,6 +111,40 @@ def dump_interfaces(context, interfaces, name='Interfaces'):
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])
+
+
class classproperty(object): # pylint: disable=invalid-name
def __init__(self, f):
self._func = f
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/24ad8ba1/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 959f3c4..0206e03 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
@@ -64,14 +64,14 @@ def create_service_template_model(context): # pylint: disable=too-many-locals,to
create_types(context,
model.capability_types,
context.presentation.get('service_template', 'capability_types'))
- model.artifact_types = Type(variant='artifact')
- create_types(context,
- model.artifact_types,
- context.presentation.get('service_template', 'artifact_types'))
model.interface_types = Type(variant='interface')
create_types(context,
model.interface_types,
context.presentation.get('service_template', 'interface_types'))
+ model.artifact_types = Type(variant='artifact')
+ create_types(context,
+ model.artifact_types,
+ context.presentation.get('service_template', 'artifact_types'))
# Topology template
topology_template = context.presentation.get('service_template', 'topology_template')
@@ -86,7 +86,7 @@ def create_service_template_model(context): # pylint: disable=too-many-locals,to
if policies:
for policy in policies.itervalues():
if model.policy_types.get_descendant(policy.type).role == 'plugin':
- model.plugins[policy._name] = create_plugin_model(context, policy)
+ model.plugins.append(create_plugin_model(context, policy))
# Node templates
node_templates = context.presentation.get('service_template', 'topology_template',
@@ -667,7 +667,11 @@ def parse_implementation_string(context, service_template, implementation):
if plugin_name == 'execution':
plugin = None
else:
- plugin = service_template.plugins.get(plugin_name)
+ plugin = None
+ for the_plugin in service_template.plugins:
+ if the_plugin.name == plugin_name:
+ plugin = the_plugin
+ break
if plugin is None:
raise ValueError('unknown plugin: "{0}"'.format(plugin_name))
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/24ad8ba1/tests/mock/context.py
----------------------------------------------------------------------
diff --git a/tests/mock/context.py b/tests/mock/context.py
index cf1a32d..3de3133 100644
--- a/tests/mock/context.py
+++ b/tests/mock/context.py
@@ -38,13 +38,13 @@ def simple(tmpdir, inmemory=False, context_kwargs=None):
api_kwargs=dict(directory=os.path.join(tmpdir, 'resources'))
)
- service_instance_id = create_simple_topology_two_nodes(model_storage)
+ service_id = create_simple_topology_two_nodes(model_storage)
final_kwargs = dict(
name='simple_context',
model_storage=model_storage,
resource_storage=resource_storage,
- service_instance_id=service_instance_id,
+ service_id=service_id,
workflow_name=models.WORKFLOW_NAME,
task_max_attempts=models.TASK_MAX_ATTEMPTS,
task_retry_interval=models.TASK_RETRY_INTERVAL
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/24ad8ba1/tests/mock/models.py
----------------------------------------------------------------------
diff --git a/tests/mock/models.py b/tests/mock/models.py
index 522cc78..3ccd97e 100644
--- a/tests/mock/models.py
+++ b/tests/mock/models.py
@@ -18,107 +18,161 @@ from datetime import datetime
from aria.modeling import models
from . import operations
-SERVICE_NAME = 'test_service_id'
-SERVICE_TEMPLATE_NAME = 'test_service_template_id'
-WORKFLOW_NAME = 'test_workflow_id'
-EXECUTION_NAME = 'test_execution_id'
+SERVICE_NAME = 'test_service_name'
+SERVICE_TEMPLATE_NAME = 'test_service_template_name'
+WORKFLOW_NAME = 'test_workflow_name'
+EXECUTION_NAME = 'test_execution_name'
TASK_RETRY_INTERVAL = 1
TASK_MAX_ATTEMPTS = 1
-DEPENDENCY_NODE_NAME = 'dependency_node_template'
-DEPENDENCY_NODE_INSTANCE_NAME = 'dependency_node'
-DEPENDENT_NODE_NAME = 'dependent_node_template'
-DEPENDENT_NODE_INSTANCE_NAME = 'dependent_node'
+DEPENDENCY_NODE_TEMPLATE_NAME = 'dependency_node_template'
+DEPENDENCY_NODE_NAME = 'dependency_node'
+DEPENDENT_NODE_TEMPLATE_NAME = 'dependent_node_template'
+DEPENDENT_NODE_NAME = 'dependent_node'
-def create_dependency_node_template(service):
- return models.NodeTemplate(
- name=DEPENDENCY_NODE_NAME,
- type=service.service_template.node_types.get_descendant('test_node_type'),
- default_instances=1,
- min_instances=1,
- max_instances=1,
- service_template_fk=service.service_template.id,
+def create_service_template():
+ now = datetime.now()
+ return models.ServiceTemplate(
+ name=SERVICE_TEMPLATE_NAME,
+ description=None,
+ created_at=now,
+ updated_at=now,
+ main_file_name='main_file_name',
+ node_types=models.Type(variant='node', name='test_node_type'),
+ group_types=models.Type(variant='group', name='test_group_type'),
+ policy_types=models.Type(variant='policy', name='test_policy_type'),
+ relationship_types=models.Type(variant='relationship', name='test_relationship_type'),
+ capability_types=models.Type(variant='capability', name='test_capability_type'),
+ artifact_types=models.Type(variant='artifact', name='test_artifact_type'),
+ interface_types=models.Type(variant='interface', name='test_interface_type')
)
-def create_dependency_node(dependency_node_template, service):
- return models.Node(
- name=DEPENDENCY_NODE_INSTANCE_NAME,
- type=dependency_node_template.type,
- service=service,
- runtime_properties={'ip': '1.1.1.1'},
- version=None,
- node_template=dependency_node_template,
- state='',
- scaling_groups=[]
+def create_service(service_template):
+ now = datetime.utcnow()
+ return models.Service(
+ name=SERVICE_NAME,
+ service_template=service_template,
+ description='',
+ created_at=now,
+ updated_at=now,
+ permalink='',
+ scaling_groups={},
)
-def create_requirement(source):
- requirement_template = models.RequirementTemplate(node_template=source)
+def create_dependency_node_template(service_template):
+ the_type = service_template.node_types.get_descendant('test_node_type')
+
capability_template = models.CapabilityTemplate(
- node_template=source,
- type=source.service_template.capability_types.get_descendant('test_capability_type'))
- return requirement_template, capability_template
-
-
-def create_relationship(source_instance, target_instance):
- return models.Relationship(
- target_node=target_instance,
- source_node=source_instance,
+ name='capability',
+ type=service_template.capability_types.get_descendant('test_capability_type')
)
+
+ node_template = models.NodeTemplate(
+ name=DEPENDENCY_NODE_TEMPLATE_NAME,
+ type=the_type,
+ capability_templates=_dictify(capability_template),
+ default_instances=1,
+ min_instances=1,
+ max_instances=1,
+ service_template=service_template
+ )
+ service_template.node_templates.append(node_template)
+ return node_template
+
+def create_dependent_node_template(service_template, dependency_node_template):
+ the_type = service_template.node_types.get_descendant('test_node_type')
-def create_dependent_node_template(service, requirement_template, capability_template):
operation_templates = dict((op, models.OperationTemplate(
name=op,
implementation='test'))
for op in operations.NODE_OPERATIONS)
interface_template = models.InterfaceTemplate(
- type=service.service_template.interface_types.get_descendant('test_interface_type'),
+ type=service_template.interface_types.get_descendant('test_interface_type'),
operation_templates=operation_templates)
- return models.NodeTemplate(
- name=DEPENDENT_NODE_NAME,
- type=service.service_template.node_types.get_descendant('test_node_type'),
+ requirement_template = models.RequirementTemplate(
+ name='requirement',
+ target_node_template=dependency_node_template
+ )
+
+ node_template = models.NodeTemplate(
+ name=DEPENDENT_NODE_TEMPLATE_NAME,
+ type=the_type,
default_instances=1,
min_instances=1,
max_instances=1,
- service_template=service.service_template,
interface_templates=_dictify(interface_template),
requirement_templates=[requirement_template],
- capability_templates=_dictify(capability_template),
+ service_template=service_template
+ )
+ service_template.node_templates.append(node_template)
+ return node_template
+
+
+def create_dependency_node(dependency_node_template, service):
+ node = models.Node(
+ name=DEPENDENCY_NODE_NAME,
+ type=dependency_node_template.type,
+ runtime_properties={'ip': '1.1.1.1'},
+ version=None,
+ node_template=dependency_node_template,
+ state='',
+ scaling_groups=[]
)
+ service.nodes.append(node)
+ return node
def create_dependent_node(dependent_node_template, service):
- return models.Node(
- name=DEPENDENT_NODE_INSTANCE_NAME,
- service=service,
+ node = models.Node(
+ name=DEPENDENT_NODE_NAME,
+ type=dependent_node_template.type,
runtime_properties={},
version=None,
node_template=dependent_node_template,
state='',
scaling_groups=[],
)
+ service.nodes.append(node)
+ return node
-def create_service_template():
- now = datetime.now()
- return models.ServiceTemplate(
- name=SERVICE_TEMPLATE_NAME,
- description=None,
- created_at=now,
- updated_at=now,
- main_file_name='main_file_name',
- node_types=models.Type(variant='node', name='test_node_type'),
- group_types=models.Type(variant='group', name='test_group_type'),
- policy_types=models.Type(variant='policy', name='test_policy_type'),
- relationship_types=models.Type(variant='relationship', name='test_relationship_type'),
- capability_types=models.Type(variant='capability', name='test_capability_type'),
- artifact_types=models.Type(variant='artifact', name='test_artifact_type'),
- interface_types=models.Type(variant='interface', name='test_interface_type')
+def create_relationship(source, target):
+ return models.Relationship(
+ source_node=source,
+ target_node=target
+ )
+
+
+def create_interface_template(service_template, operation_name, operation_kwargs=None,
+ interface_kwargs=None):
+ the_type = service_template.interface_types.get_descendant('test_interface_type')
+ interface_name, operation_name = operation_name.rsplit('.', 1)
+ operation_template = models.OperationTemplate(
+ name=operation_name,
+ **(operation_kwargs or {})
+ )
+ return models.InterfaceTemplate(
+ type=the_type,
+ operation_templates=_dictify(operation_template),
+ name=interface_name,
+ **(interface_kwargs or {})
+ )
+
+
+def create_interface(service, operation_name, operation_kwargs=None, interface_kwargs=None):
+ the_type = service.service_template.interface_types.get_descendant('test_interface_type')
+ interface_name, operation_name = operation_name.rsplit('.', 1)
+ operation = models.Operation(name=operation_name, **(operation_kwargs or {}))
+ return models.Interface(
+ type=the_type,
+ operations=_dictify(operation),
+ name=interface_name,
+ **(interface_kwargs or {})
)
@@ -132,20 +186,6 @@ def create_execution(service):
)
-def create_service(service_template):
- now = datetime.utcnow()
- return models.Service(
- name=SERVICE_NAME,
- service_template=service_template,
- description='',
- created_at=now,
- updated_at=now,
- workflows={},
- permalink='',
- scaling_groups={},
- )
-
-
def create_plugin(package_name='package', package_version='0.1'):
return models.Plugin(
archive_name='archive_name',
@@ -162,30 +202,5 @@ def create_plugin(package_name='package', package_version='0.1'):
)
-def create_interface_template(operation_name, operation_kwargs=None, interface_kwargs=None):
- operation_template = models.OperationTemplate(
- name=operation_name,
- **(operation_kwargs or {})
-
- )
- return models.InterfaceTemplate(
- operation_templates=_dictify(operation_template),
- name=operation_name.rsplit('.', 1)[0],
- **(interface_kwargs or {})
- )
-
-
-def create_interface(operation_name,
- operation_kwargs=None,
- interface_kwargs=None,
- edge=None):
- operation = models.Operation(name=operation_name, **(operation_kwargs or {}))
- interface_name = operation_name.rsplit('.', 1)[0]
- return models.Interface(operations=_dictify(operation),
- name=interface_name,
- edge=edge,
- **(interface_kwargs or {}))
-
-
def _dictify(item):
return dict(((item.name, item),))
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/24ad8ba1/tests/mock/topology.py
----------------------------------------------------------------------
diff --git a/tests/mock/topology.py b/tests/mock/topology.py
index b511ee3..b702783 100644
--- a/tests/mock/topology.py
+++ b/tests/mock/topology.py
@@ -20,67 +20,55 @@ from . import models
def create_simple_topology_single_node(model_storage, create_operation):
service_template = models.create_service_template()
- model_storage.service_template.put(service_template)
service = models.create_service(service_template)
- model_storage.service.put(service)
- node_template = models.create_dependency_node_template(service)
- node_template.interface_templates = [models.create_interface_template(
- 'tosca.interfaces.node.lifecycle.Standard.create',
+ node_template = models.create_dependency_node_template(service_template)
+ interface_template = models.create_interface_template(
+ service_template,
+ 'Standard.create',
operation_kwargs=dict(
implementation=create_operation,
- inputs=[aria_models.Parameter(name='key', value='create', type_name='string'),
- aria_models.Parameter(name='value', value=True, type_name='boolean')]
- )
- )]
- model_storage.node_template.put(node_template)
+ inputs={'key': aria_models.Parameter(name='key', value='create', type_name='string'),
+ 'value': aria_models.Parameter(name='value', value=True, type_name='boolean')})
+ )
+ node_template.interface_templates[interface_template.name] = interface_template
node = models.create_dependency_node(node_template, service)
- node.interfaces = [models.create_interface(
- 'tosca.interfaces.node.lifecycle.Standard.create',
+ interface = models.create_interface(
+ service,
+ 'Standard.create',
operation_kwargs=dict(
implementation=create_operation,
- inputs=[aria_models.Parameter(name='key', value='create', type_name='string'),
- aria_models.Parameter(name='value', value=True, type_name='boolean')])
- )]
- model_storage.node.put(node)
+ inputs={'key': aria_models.Parameter(name='key', value='create', type_name='string'),
+ 'value': aria_models.Parameter(name='value', value=True, type_name='boolean')})
+ )
+ node.interfaces[interface.name] = interface
+
+ model_storage.service_template.put(service_template)
+ model_storage.service.put(service)
def create_simple_topology_two_nodes(model_storage):
- blueprint = models.create_service_template()
- model_storage.service_template.put(blueprint)
- deployment = models.create_service(blueprint)
- model_storage.service.put(deployment)
-
- #################################################################################
- # Creating a simple deployment with node -> node as a graph
-
- dependency_node = models.create_dependency_node_template(deployment)
- model_storage.node_template.put(dependency_node)
- storage_dependency_node = model_storage.node_template.get(dependency_node.id)
-
- dependency_node_instance = models.create_dependency_node(storage_dependency_node,
- deployment)
- model_storage.node.put(dependency_node_instance)
- storage_dependency_node_instance = model_storage.node.get(dependency_node_instance.id)
-
- req_template, cap_template = models.create_requirement(storage_dependency_node)
- model_storage.requirement_template.put(req_template)
- model_storage.capability_template.put(cap_template)
-
- dependent_node = models.create_dependent_node_template(deployment, req_template, cap_template)
- model_storage.node_template.put(dependent_node)
- storage_dependent_node = model_storage.node_template.get(dependent_node.id)
-
- dependent_node_instance = models.create_dependent_node(storage_dependent_node, deployment)
- model_storage.node.put(dependent_node_instance)
- storage_dependent_node_instance = model_storage.node.get(dependent_node_instance.id)
-
- relationship_instance = models.create_relationship(
- target_instance=storage_dependency_node_instance,
- source_instance=storage_dependent_node_instance
- )
- model_storage.relationship.put(relationship_instance)
+ service_template = models.create_service_template()
+
+ service = models.create_service(service_template)
+
+ # Creating a simple service with node -> node as a graph
+
+ dependency_node_template = models.create_dependency_node_template(service_template)
+ dependent_node_template = models.create_dependent_node_template(service_template,
+ dependency_node_template)
+
+ dependency_node = models.create_dependency_node(dependency_node_template, service)
+ dependent_node = models.create_dependent_node(dependent_node_template, service)
+
+ dependent_node.outbound_relationships.append(models.create_relationship(
+ source=dependent_node,
+ target=dependency_node
+ ))
+
+ model_storage.service_template.put(service_template)
+ model_storage.service.put(service)
- return deployment.id
+ return service.id
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/24ad8ba1/tests/orchestrator/context/test_operation.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/context/test_operation.py b/tests/orchestrator/context/test_operation.py
index 3f39979..b460b9f 100644
--- a/tests/orchestrator/context/test_operation.py
+++ b/tests/orchestrator/context/test_operation.py
@@ -58,21 +58,23 @@ def executor():
def test_node_operation_task_execution(ctx, executor):
operation_name = 'aria.interfaces.lifecycle.create'
- node = ctx.model.node.get_by_name(mock.models.DEPENDENCY_NODE_INSTANCE_NAME)
- interface = mock.models.get_interface(
+ node = ctx.model.node.get_by_name(mock.models.DEPENDENCY_NODE_NAME)
+ interface = mock.models.create_interface(
+ node.service,
operation_name,
operation_kwargs=dict(implementation=op_path(my_operation, module_path=__name__))
)
- node.interfaces = [interface]
+ node.interfaces[interface.name] = interface
ctx.model.node.update(node)
inputs = {'putput': True}
@workflow
def basic_workflow(graph, **_):
graph.add_tasks(
- api.task.OperationTask.node(
- name=operation_name,
- instance=node,
+ api.task.OperationTask.for_node(
+ interface_name='aria.interfaces.lifecycle',
+ operation_name='create',
+ node=node,
inputs=inputs
)
)
@@ -100,24 +102,24 @@ def test_relationship_operation_task_execution(ctx, executor):
operation_name = 'aria.interfaces.relationship_lifecycle.post_configure'
relationship = ctx.model.relationship.list()[0]
- interface = mock.models.get_interface(
+ interface = mock.models.create_interface(
+ relationship.source_node.service,
operation_name=operation_name,
operation_kwargs=dict(implementation=op_path(my_operation, module_path=__name__)),
- edge='source'
)
- relationship.interfaces = [interface]
+ relationship.interfaces[interface.name] = interface
ctx.model.relationship.update(relationship)
inputs = {'putput': True}
@workflow
def basic_workflow(graph, **_):
graph.add_tasks(
- api.task.OperationTask.relationship(
- instance=relationship,
- name=operation_name,
- inputs=inputs,
- edge='source'
+ api.task.OperationTask.for_relationship(
+ relationship=relationship,
+ interface_name='aria.interfaces.relationship_lifecycle',
+ operation_name='post_configure',
+ inputs=inputs
)
)
@@ -137,9 +139,9 @@ def test_relationship_operation_task_execution(ctx, executor):
# Context based attributes (sugaring)
dependency_node_template = ctx.model.node_template.get_by_name(mock.models.DEPENDENCY_NODE_NAME)
- dependency_node = ctx.model.node.get_by_name(mock.models.DEPENDENCY_NODE_INSTANCE_NAME)
+ dependency_node = ctx.model.node.get_by_name(mock.models.DEPENDENCY_NODE_NAME)
dependent_node_template = ctx.model.node_template.get_by_name(mock.models.DEPENDENT_NODE_NAME)
- dependent_node = ctx.model.node.get_by_name(mock.models.DEPENDENT_NODE_INSTANCE_NAME)
+ dependent_node = ctx.model.node.get_by_name(mock.models.DEPENDENT_NODE_NAME)
assert operation_context.target_node_template == dependency_node_template
assert operation_context.target_node == dependency_node
@@ -161,9 +163,9 @@ def test_invalid_task_operation_id(ctx, executor):
assert other_node.id == 1
assert node.id == 2
- interface = mock.models.get_interface(
+ interface = mock.models.create_interface(
operation_name=operation_name,
- operation_kwargs=dict(implementation=op_path(get_node_instance_id, module_path=__name__))
+ operation_kwargs=dict(implementation=op_path(get_node_id, module_path=__name__))
)
node.interfaces = [interface]
ctx.model.node.update(node)
@@ -171,21 +173,21 @@ def test_invalid_task_operation_id(ctx, executor):
@workflow
def basic_workflow(graph, **_):
graph.add_tasks(
- api.task.OperationTask.node(name=operation_name, instance=node)
+ api.task.OperationTask.for_node(name=operation_name, node=node)
)
execute(workflow_func=basic_workflow, workflow_context=ctx, executor=executor)
- op_node_instance_id = global_test_holder[op_name(node, operation_name)]
- assert op_node_instance_id == node.id
- assert op_node_instance_id != other_node.id
+ op_node_id = global_test_holder[op_name(node, operation_name)]
+ assert op_node_id == node.id
+ assert op_node_id != other_node.id
def test_plugin_workdir(ctx, executor, tmpdir):
op = 'test.op'
plugin_name = 'mock_plugin'
- node = ctx.model.node.get_by_name(mock.models.DEPENDENCY_NODE_INSTANCE_NAME)
- node.interfaces = [mock.models.get_interface(
+ node = ctx.model.node.get_by_name(mock.models.DEPENDENCY_NODE_NAME)
+ node.interfaces = [mock.models.create_interface(
op,
operation_kwargs=dict(
implementation='{0}.{1}'.format(__name__, _test_plugin_workdir.__name__),
@@ -200,8 +202,8 @@ def test_plugin_workdir(ctx, executor, tmpdir):
@workflow
def basic_workflow(graph, **_):
- graph.add_tasks(api.task.OperationTask.node(
- name=op, instance=node, inputs=inputs))
+ graph.add_tasks(api.task.OperationTask.for_node(
+ name=op, node=node, inputs=inputs))
execute(workflow_func=basic_workflow, workflow_context=ctx, executor=executor)
expected_file = tmpdir.join('workdir', 'plugins', str(ctx.service_instance.id),
@@ -216,7 +218,7 @@ def my_operation(ctx, **_):
@operation
-def get_node_instance_id(ctx, **_):
+def get_node_id(ctx, **_):
global_test_holder[ctx.name] = ctx.node.id
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/24ad8ba1/tests/orchestrator/test_runner.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/test_runner.py b/tests/orchestrator/test_runner.py
index 2e509b5..74e98ad 100644
--- a/tests/orchestrator/test_runner.py
+++ b/tests/orchestrator/test_runner.py
@@ -50,7 +50,8 @@ def test_runner_tasks():
for node in ctx.model.node:
graph.add_tasks(
OperationTask.for_node(node=node,
- name='tosca.interfaces.node.lifecycle.Standard.create'))
+ interface_name='Standard',
+ operation_name='create'))
_test_runner(workflow_fn)
@@ -69,5 +70,5 @@ def _test_runner(workflow_fn):
workflow_fn=workflow_fn,
inputs={},
initialize_model_storage_fn=_initialize_model_storage_fn,
- service_instance_id=1)
+ service_id_fn=lambda: 1)
runner.run()