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:09 UTC
[1/2] incubator-ariatosca git commit: Add rich docs, fix many tests
Repository: incubator-ariatosca
Updated Branches:
refs/heads/ARIA-105-integrate-modeling 36eb2d24c -> 24ad8ba1e
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/24ad8ba1/tests/storage/test_instrumentation.py
----------------------------------------------------------------------
diff --git a/tests/storage/test_instrumentation.py b/tests/storage/test_instrumentation.py
index 413b888..3ef74e4 100644
--- a/tests/storage/test_instrumentation.py
+++ b/tests/storage/test_instrumentation.py
@@ -18,11 +18,11 @@ from sqlalchemy import Column, Text, Integer, event
from aria.modeling import (
bases,
- exceptions,
types as modeling_types,
models
)
from aria.storage import (
+ exceptions,
ModelStorage,
sql_mapi,
instrumentation
@@ -281,8 +281,8 @@ class TestInstrumentation(object):
def test_track_changes_to_strict_dict(self, storage):
model_kwargs = dict(strict_dict={'key': 'value'},
strict_list=['item'])
- mode_instance = StrictMockModel(**model_kwargs)
- storage.strict_mock_model.put(mode_instance)
+ model_instance = StrictMockModel(**model_kwargs)
+ storage.strict_mock_model.put(model_instance)
instrument = self._track_changes({
StrictMockModel.strict_dict: dict,
@@ -291,7 +291,7 @@ class TestInstrumentation(object):
assert not instrument.tracked_changes
- storage_model_instance = storage.strict_mock_model.get(mode_instance.id)
+ storage_model_instance = storage.strict_mock_model.get(model_instance.id)
with pytest.raises(exceptions.StorageError):
storage_model_instance.strict_dict = {1: 1}
@@ -312,7 +312,7 @@ class TestInstrumentation(object):
assert instrument.tracked_changes == {
'strict_mock_model': {
- mode_instance.id: {
+ model_instance.id: {
'strict_dict': Value(STUB, {'hello': 'world'}),
'strict_list': Value(STUB, ['hello']),
}
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/24ad8ba1/tests/storage/test_model_storage.py
----------------------------------------------------------------------
diff --git a/tests/storage/test_model_storage.py b/tests/storage/test_model_storage.py
index 416a0a8..bb778d4 100644
--- a/tests/storage/test_model_storage.py
+++ b/tests/storage/test_model_storage.py
@@ -63,40 +63,40 @@ def test_application_storage_factory():
storage = application_model_storage(sql_mapi.SQLAlchemyModelAPI,
initiator=init_inmemory_model_storage)
- assert storage.parameter
- assert storage.mapping_template
- assert storage.substitution_template
assert storage.service_template
assert storage.node_template
assert storage.group_template
- assert storage.interface_template
- assert storage.operation_template
- assert storage.artifact_template
assert storage.policy_template
- assert storage.group_policy_template
- assert storage.group_policy_trigger_template
+ assert storage.substitution_template
+ assert storage.substitution_template_mapping
assert storage.requirement_template
+ assert storage.relationship_template
assert storage.capability_template
+ assert storage.interface_template
+ assert storage.operation_template
+ assert storage.artifact_template
- assert storage.mapping
- assert storage.substitution
- assert storage.service_instance
+ assert storage.service
assert storage.node
assert storage.group
+ assert storage.policy
+ assert storage.substitution
+ assert storage.substitution_mapping
+ assert storage.relationship
+ assert storage.capability
assert storage.interface
assert storage.operation
- assert storage.capability
assert storage.artifact
- assert storage.policy
- assert storage.group_policy
- assert storage.group_policy_trigger
- assert storage.relationship
assert storage.execution
- assert storage.service_instance_update
- assert storage.service_instance_update_step
- assert storage.service_instance_modification
+ assert storage.service_update
+ assert storage.service_update_step
+ assert storage.service_modification
assert storage.plugin
assert storage.task
+ assert storage.parameter
+ assert storage.type
+ assert storage.metadata
+
release_sqlite_storage(storage)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/24ad8ba1/tests/storage/test_models.py
----------------------------------------------------------------------
diff --git a/tests/storage/test_models.py b/tests/storage/test_models.py
index 45324dc..0088314 100644
--- a/tests/storage/test_models.py
+++ b/tests/storage/test_models.py
@@ -12,6 +12,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+
from datetime import datetime
from contextlib import contextmanager
@@ -34,7 +35,8 @@ from aria.modeling.models import (
Relationship,
NodeTemplate,
Node,
- Parameter
+ Parameter,
+ Type
)
from tests import mock
@@ -59,55 +61,55 @@ def _empty_storage():
def _service_template_storage():
storage = _empty_storage()
- service_template = mock.models.get_service_template()
+ service_template = mock.models.create_service_template()
storage.service_template.put(service_template)
+ storage.type.put(Type(variant='node'))
return storage
-def _service_instance_storage():
+def _service_storage():
storage = _service_template_storage()
- service_instance = mock.models.get_service(
+ service = mock.models.create_service(
storage.service_template.get_by_name(mock.models.SERVICE_TEMPLATE_NAME))
- storage.service_instance.put(service_instance)
+ storage.service.put(service)
return storage
-def _service_instance_update_storage():
- storage = _service_instance_storage()
- service_instance_update = ServiceUpdate(
- service_instance=storage.service_instance.list()[0],
+def _service_update_storage():
+ storage = _service_storage()
+ service_update = ServiceUpdate(
+ service=storage.service.list()[0],
created_at=now,
- service_instance_plan={},
+ service_plan={},
)
- storage.service_instance_update.put(service_instance_update)
+ storage.service_update.put(service_update)
return storage
def _node_template_storage():
- storage = _service_instance_storage()
- node_template = mock.models.get_dependency_node_template(storage.service_instance.list()[0])
+ storage = _service_storage()
+ service_template = storage.service_template.list()[0]
+ node_template = mock.models.create_dependency_node_template(service_template)
storage.node_template.put(node_template)
return storage
def _nodes_storage():
- storage = _nodes_storage()
- service_instance = storage.service_instance.get_by_name(mock.models.SERVICE_NAME)
+ storage = _nodes_storage() # ???
+ service = storage.service.get_by_name(mock.models.SERVICE_NAME)
dependent_node_template = storage.node_template.get_by_name(mock.models.DEPENDENT_NODE_NAME)
dependency_node_template = storage.node_template.get_by_name(mock.models.DEPENDENCY_NODE_NAME)
- dependency_node = mock.models.get_dependency_node(dependency_node_template,
- service_instance)
- dependent_node = mock.models.get_dependent_node(dependent_node_template,
- service_instance)
+ dependency_node = mock.models.create_dependency_node(dependency_node_template, service)
+ dependent_node = mock.models.create_dependent_node(dependent_node_template, service)
storage.node.put(dependency_node)
storage.node.put(dependent_node)
return storage
def _execution_storage():
- storage = _service_instance_storage()
- execution = mock.models.get_execution(storage.service_instance.list()[0])
- plugin = mock.models.get_plugin()
+ storage = _service_storage()
+ execution = mock.models.create_execution(storage.service.list()[0])
+ plugin = mock.models.create_plugin()
storage.execution.put(execution)
storage.plugin.put(plugin)
return storage
@@ -126,14 +128,14 @@ def service_template_storage():
@pytest.fixture
-def service_instance_storage():
- with sql_storage(_service_instance_storage) as storage:
+def service_storage():
+ with sql_storage(_service_storage) as storage:
yield storage
@pytest.fixture
-def service_instance_update_storage():
- with sql_storage(_service_instance_update_storage) as storage:
+def service_update_storage():
+ with sql_storage(_service_update_storage) as storage:
yield storage
@@ -174,7 +176,7 @@ class TestServiceTemplate(object):
@pytest.mark.parametrize(
'is_valid, description, created_at, updated_at, main_file_name',
[
- (False, 'description', now, now, '/path'),
+ (True, 'description', now, now, '/path'),
(False, {}, now, now, '/path'),
(False, 'description', 'error', now, '/path'),
(False, 'description', now, 'error', '/path'),
@@ -183,8 +185,8 @@ class TestServiceTemplate(object):
]
)
- def test_blueprint_model_creation(self, empty_storage, is_valid, description, created_at,
- updated_at, main_file_name):
+ def test_service_template_model_creation(self, empty_storage, is_valid, description, created_at,
+ updated_at, main_file_name):
_test_model(is_valid=is_valid,
storage=empty_storage,
model_cls=ServiceTemplate,
@@ -199,58 +201,49 @@ class TestServiceTemplate(object):
class TestService(object):
@pytest.mark.parametrize(
- 'is_valid, name, created_at, description, inputs, permalink, policy_triggers, '
- 'policy_types, outputs, scaling_groups, updated_at, workflows',
+ 'is_valid, name, created_at, description, inputs, permalink, '
+ 'outputs, scaling_groups, updated_at',
[
- (False, m_cls, now, 'desc', [], 'perlnk', {}, {}, [], {}, now, {}),
- (False, 'name', m_cls, 'desc', [], 'perlnk', {}, {}, [], {}, now, {}),
- (False, 'name', now, m_cls, [], 'perlnk', {}, {}, [], {}, now, {}),
- (False, 'name', now, 'desc', [], m_cls, {}, {}, [], {}, now, {}),
- (False, 'name', now, 'desc', [], 'perlnk', m_cls, {}, [], {}, now, {}),
- (False, 'name', now, 'desc', [], 'perlnk', {}, m_cls, [], {}, now, {}),
- (False, 'name', now, 'desc', [], 'perlnk', {}, {}, m_cls, {}, now, {}),
- (False, 'name', now, 'desc', [], 'perlnk', {}, {}, [], m_cls, now, {}),
- (False, 'name', now, 'desc', [], 'perlnk', {}, {}, [], {}, m_cls, {}),
- (False, 'name', now, 'desc', [], 'perlnk', {}, {}, [], {}, now, m_cls),
-
- (True, 'name', now, 'desc', [], 'perlnk', {}, {}, [], {}, now, {}),
- (True, None, now, 'desc', [], 'perlnk', {}, {}, [], {}, now, {}),
- (True, 'name', now, 'desc', [], 'perlnk', {}, {}, [], {}, now, {}),
- (True, 'name', now, None, [], 'perlnk', {}, {}, [], {}, now, {}),
- (True, 'name', now, 'desc', [], 'perlnk', {}, {}, [], {}, now, {}),
- (True, 'name', now, 'desc', [], None, {}, {}, [], {}, now, {}),
- (True, 'name', now, 'desc', [], 'perlnk', None, {}, [], {}, now, {}),
- (True, 'name', now, 'desc', [], 'perlnk', {}, None, [], {}, now, {}),
- (True, 'name', now, 'desc', [], 'perlnk', {}, {}, [], None, now, {}),
- (True, 'name', now, 'desc', [], 'perlnk', {}, {}, [], {}, None, {}),
- (True, 'name', now, 'desc', [], 'perlnk', {}, {}, [], {}, now, None),
+ (False, m_cls, now, 'desc', {}, 'perlnk', {}, {}, now),
+ (False, 'name', m_cls, 'desc', {}, 'perlnk', {}, {}, now),
+ (False, 'name', now, m_cls, {}, 'perlnk', {}, {}, now),
+ (False, 'name', now, 'desc', {}, m_cls, {}, {}, now),
+ (False, 'name', now, 'desc', {}, 'perlnk', m_cls, {}, now),
+ (False, 'name', now, 'desc', {}, 'perlnk', {}, m_cls, now),
+ (False, 'name', now, 'desc', {}, 'perlnk', {}, {}, m_cls),
+
+ (True, 'name', now, 'desc', {}, 'perlnk', {}, {}, now),
+ (True, None, now, 'desc', {}, 'perlnk', {}, {}, now),
+ (True, 'name', now, 'desc', {}, 'perlnk', {}, {}, now),
+ (True, 'name', now, None, {}, 'perlnk', {}, {}, now),
+ (True, 'name', now, 'desc', {}, 'perlnk', {}, {}, now),
+ (True, 'name', now, 'desc', {}, None, {}, {}, now),
+ (True, 'name', now, 'desc', {}, 'perlnk', {}, {}, now),
+ (True, 'name', now, 'desc', {}, 'perlnk', {}, None, now),
+ (True, 'name', now, 'desc', {}, 'perlnk', {}, {}, None),
+ (True, 'name', now, 'desc', {}, 'perlnk', {}, {}, now),
]
)
- def test_deployment_model_creation(self, service_instance_storage, is_valid, name, created_at,
- description, inputs, permalink, policy_triggers,
- policy_types, outputs, scaling_groups, updated_at,
- workflows):
- service_instance = _test_model(
+ def test_service_model_creation(self, service_storage, is_valid, name, created_at, description,
+ inputs, permalink, outputs, scaling_groups, updated_at):
+ service = _test_model(
is_valid=is_valid,
- storage=service_instance_storage,
+ storage=service_storage,
model_cls=Service,
model_kwargs=dict(
name=name,
- service_template=service_instance_storage.service_template.list()[0],
+ service_template=service_storage.service_template.list()[0],
created_at=created_at,
description=description,
inputs=inputs,
permalink=permalink,
- policy_triggers=policy_triggers,
- policy_types=policy_types,
outputs=outputs,
scaling_groups=scaling_groups,
- updated_at=updated_at,
- workflows=workflows
+ updated_at=updated_at
))
if is_valid:
- assert service_instance.service_template == \
- service_instance_storage.service_template.list()[0]
+ assert service.service_template == \
+ service_storage.service_template.list()[0]
class TestExecution(object):
@@ -274,15 +267,15 @@ class TestExecution(object):
(True, now, now, now, 'error', False, None, Execution.STARTED, 'wf_name'),
]
)
- def test_execution_model_creation(self, service_instance_storage, is_valid, created_at,
- started_at, ended_at, error, is_system_workflow, parameters,
- status, workflow_name):
+ def test_execution_model_creation(self, service_storage, is_valid, created_at, started_at,
+ ended_at, error, is_system_workflow, parameters, status,
+ workflow_name):
execution = _test_model(
is_valid=is_valid,
- storage=service_instance_storage,
+ storage=service_storage,
model_cls=Execution,
model_kwargs=dict(
- service_instance=service_instance_storage.service_instance.list()[0],
+ service=service_storage.service.list()[0],
created_at=created_at,
started_at=started_at,
ended_at=ended_at,
@@ -293,8 +286,8 @@ class TestExecution(object):
workflow_name=workflow_name,
))
if is_valid:
- assert execution.service_instance == service_instance_storage.service_instance.list()[0]
- assert execution.service_template == service_instance_storage.service_template.list()[0]
+ assert execution.service == service_storage.service.list()[0]
+ assert execution.service_template == service_storage.service_template.list()[0]
def test_execution_status_transition(self):
def create_execution(status):
@@ -363,8 +356,8 @@ class TestExecution(object):
class TestServiceUpdate(object):
@pytest.mark.parametrize(
- 'is_valid, created_at, deployment_plan, service_instance_update_node_instances, '
- 'service_instance_update_service_instance, service_instance_update_nodes, '
+ 'is_valid, created_at, service_plan, service_update_nodes, '
+ 'service_update_service, service_update_node_templates, '
'modified_entity_ids, state',
[
(False, m_cls, {}, {}, {}, [], {}, 'state'),
@@ -383,27 +376,27 @@ class TestServiceUpdate(object):
(True, now, {}, {}, {}, [], {}, None),
]
)
- def test_service_instance_update_model_creation(
- self, service_instance_storage, is_valid, created_at, deployment_plan,
- service_instance_update_node_instances, service_instance_update_service_instance,
- service_instance_update_nodes, modified_entity_ids, state):
- service_instance_update = _test_model(
+ def test_service_update_model_creation(self, service_storage, is_valid, created_at,
+ service_plan, service_update_nodes,
+ service_update_service, service_update_node_templates,
+ modified_entity_ids, state):
+ service_update = _test_model(
is_valid=is_valid,
- storage=service_instance_storage,
+ storage=service_storage,
model_cls=ServiceUpdate,
model_kwargs=dict(
- service_instance=service_instance_storage.service_instance.list()[0],
+ service=service_storage.service.list()[0],
created_at=created_at,
- service_instance_plan=deployment_plan,
- service_instance_update_node_instances=service_instance_update_node_instances,
- service_instance_update_service_instance=service_instance_update_service_instance,
- service_instance_update_nodes=service_instance_update_nodes,
+ service_plan=service_plan,
+ service_update_nodes=service_update_nodes,
+ service_update_service=service_update_service,
+ service_update_node_templates=service_update_node_templates,
modified_entity_ids=modified_entity_ids,
- state=state,
+ state=state
))
if is_valid:
- assert service_instance_update.service_instance == \
- service_instance_storage.service_instance.list()[0]
+ assert service_update.service == \
+ service_storage.service.list()[0]
class TestServiceUpdateStep(object):
@@ -420,24 +413,24 @@ class TestServiceUpdateStep(object):
ServiceUpdateStep.ENTITY_TYPES.NODE)
]
)
- def test_deployment_update_step_model_creation(self, service_instance_update_storage, is_valid,
- action, entity_id, entity_type):
- service_instance_update_step = _test_model(
+ def test_service_update_step_model_creation(self, service_update_storage, is_valid, action,
+ entity_id, entity_type):
+ service_update_step = _test_model(
is_valid=is_valid,
- storage=service_instance_update_storage,
+ storage=service_update_storage,
model_cls=ServiceUpdateStep,
model_kwargs=dict(
- service_instance_update=
- service_instance_update_storage.service_instance_update.list()[0],
+ service_update=
+ service_update_storage.service_update.list()[0],
action=action,
entity_id=entity_id,
entity_type=entity_type
))
if is_valid:
- assert service_instance_update_step.service_instance_update == \
- service_instance_update_storage.service_instance_update.list()[0]
+ assert service_update_step.service_update == \
+ service_update_storage.service_update.list()[0]
- def test_deployment_update_step_order(self):
+ def test_service_update_step_order(self):
add_node = ServiceUpdateStep(
id='add_step',
action='add',
@@ -478,7 +471,7 @@ class TestServiceUpdateStep(object):
assert not add_node < None
-class TestDeploymentModification(object):
+class TestServiceModification(object):
@pytest.mark.parametrize(
'is_valid, context, created_at, ended_at, modified_node_templates, nodes, status',
[
@@ -495,66 +488,60 @@ class TestDeploymentModification(object):
(True, {}, now, now, {}, None, ServiceModification.STARTED),
]
)
- def test_deployment_modification_model_creation(
- self, service_instance_storage, is_valid, context, created_at, ended_at,
- modified_node_templates, nodes, status):
- deployment_modification = _test_model(
+ def test_service_modification_model_creation(self, service_storage, is_valid, context,
+ created_at, ended_at, modified_node_templates,
+ nodes, status):
+ service_modification = _test_model(
is_valid=is_valid,
- storage=service_instance_storage,
+ storage=service_storage,
model_cls=ServiceModification,
model_kwargs=dict(
- service_instance=service_instance_storage.service_instance.list()[0],
+ service=service_storage.service.list()[0],
context=context,
created_at=created_at,
ended_at=ended_at,
- modified_nodes=modified_node_templates,
- node_instances=nodes,
+ modified_node_templates=modified_node_templates,
+ nodes=nodes,
status=status,
))
if is_valid:
- assert deployment_modification.service_instance == \
- service_instance_storage.service_instance.list()[0]
+ assert service_modification.service == \
+ service_storage.service.list()[0]
class TestNodeTemplate(object):
@pytest.mark.parametrize(
- 'is_valid, name, default_instances, max_instances, min_instances, plugins, properties, '
- 'type_name, type_hierarchy',
+ 'is_valid, name, default_instances, max_instances, min_instances, plugins, properties',
[
- (False, m_cls, 1, 1, 1, [], [], 'type', []),
- (False, 'name', m_cls, 1, 1, [], [], 'type', []),
- (False, 'name', 1, m_cls, 1, [], [], 'type', []),
- (False, 'name', 1, 1, m_cls, [], [], 'type', []),
- (False, 'name', 1, 1, 1, m_cls, [], 'type', []),
- (False, 'name', 1, 1, 1, [], [], m_cls, []),
- (False, 'name', 1, 1, 1, [], [], 'type', m_cls),
- #
- (True, 'name', 1, 1, 1, [], [], 'type', []),
- (True, 'name', 1, 1, 1, None, [], 'type', []),
- (True, 'name', 1, 1, 1, [], [], 'type', None),
+ (False, m_cls, 1, 1, 1, [], {}),
+ (False, 'name', m_cls, 1, 1, [], {}),
+ (False, 'name', 1, m_cls, 1, [], {}),
+ (False, 'name', 1, 1, m_cls, [], {}),
+ (False, 'name', 1, 1, 1, m_cls, {}),
+ (False, 'name', 1, 1, 1, None, {}),
+
+ (True, 'name', 1, 1, 1, [], {}),
]
)
- def test_node_model_creation(self, service_instance_storage, is_valid, name,
- default_instances, max_instances, min_instances, plugins,
- properties, type_name, type_hierarchy):
+ def test_node_template_model_creation(self, service_storage, is_valid, name, default_instances,
+ max_instances, min_instances, plugins, properties):
node_template = _test_model(
is_valid=is_valid,
- storage=service_instance_storage,
+ storage=service_storage,
model_cls=NodeTemplate,
model_kwargs=dict(
name=name,
+ type=service_storage.type.list()[0],
default_instances=default_instances,
max_instances=max_instances,
min_instances=min_instances,
plugins=plugins,
properties=properties,
- type_name=type_name,
- type_hierarchy=type_hierarchy,
- service_template=service_instance_storage.service_template.list()[0]
+ service_template=service_storage.service_template.list()[0]
))
if is_valid:
assert node_template.service_template == \
- service_instance_storage.service_template.list()[0]
+ service_storage.service_template.list()[0]
class TestNode(object):
@@ -574,62 +561,63 @@ class TestNode(object):
(True, 'name', {}, [], 'state', None),
]
)
- def test_node_instance_model_creation(self, node_template_storage, is_valid, name,
- runtime_properties, scaling_groups, state, version):
- node_instance = _test_model(
+ def test_node_model_creation(self, node_template_storage, is_valid, name, runtime_properties,
+ scaling_groups, state, version):
+ node = _test_model(
is_valid=is_valid,
storage=node_template_storage,
model_cls=Node,
model_kwargs=dict(
node_template=node_template_storage.node_template.list()[0],
+ type=node_template_storage.type.list()[0],
name=name,
runtime_properties=runtime_properties,
scaling_groups=scaling_groups,
state=state,
version=version,
- service_instance=node_template_storage.service_instance.list()[0]
+ service=node_template_storage.service.list()[0]
))
if is_valid:
- assert node_instance.node_template == node_template_storage.node_template.list()[0]
- assert node_instance.service_instance == \
- node_template_storage.service_instance.list()[0]
+ assert node.node_template == node_template_storage.node_template.list()[0]
+ assert node.service == \
+ node_template_storage.service.list()[0]
class TestNodeInstanceIP(object):
ip = '1.1.1.1'
- def test_ip_on_none_hosted_node_instance(self, service_instance_storage):
- node_template = self._node_template(service_instance_storage, ip='not considered')
- node = self._node(service_instance_storage,
+ def test_ip_on_none_hosted_node(self, service_storage):
+ node_template = self._node_template(service_storage, ip='not considered')
+ node = self._node(service_storage,
node_template,
is_host=False,
ip='not considered')
assert node.ip is None
- def test_property_ip_on_host_node_instance(self, service_instance_storage):
- node_template = self._node_template(service_instance_storage, ip=self.ip)
- node = self._node(service_instance_storage, node_template, is_host=True, ip=None)
+ def test_property_ip_on_host_node(self, service_storage):
+ node_template = self._node_template(service_storage, ip=self.ip)
+ node = self._node(service_storage, node_template, is_host=True, ip=None)
assert node.ip == self.ip
- def test_runtime_property_ip_on_host_node_instance(self, service_instance_storage):
- node_template = self._node_template(service_instance_storage, ip='not considered')
- node = self._node(service_instance_storage, node_template, is_host=True, ip=self.ip)
+ def test_runtime_property_ip_on_host_node(self, service_storage):
+ node_template = self._node_template(service_storage, ip='not considered')
+ node = self._node(service_storage, node_template, is_host=True, ip=self.ip)
assert node.ip == self.ip
- def test_no_ip_configured_on_host_node_instance(self, service_instance_storage):
- node_template = self._node_template(service_instance_storage, ip=None)
- node = self._node(service_instance_storage, node_template, is_host=True, ip=None)
+ def test_no_ip_configured_on_host_node(self, service_storage):
+ node_template = self._node_template(service_storage, ip=None)
+ node = self._node(service_storage, node_template, is_host=True, ip=None)
assert node.ip is None
- def test_runtime_property_on_hosted_node_instance(self, service_instance_storage):
- host_node_template = self._node_template(service_instance_storage, ip=None)
- host_node = self._node(service_instance_storage,
+ def test_runtime_property_on_hosted_node(self, service_storage):
+ host_node_template = self._node_template(service_storage, ip=None)
+ host_node = self._node(service_storage,
host_node_template,
is_host=True,
ip=self.ip)
- node_template = self._node_template(service_instance_storage, ip=None)
- node = self._node(service_instance_storage,
+ node_template = self._node_template(service_storage, ip=None)
+ node = self._node(service_storage,
node_template,
is_host=False,
ip=None,
@@ -639,14 +627,14 @@ class TestNodeInstanceIP(object):
def _node_template(self, storage, ip):
kwargs = dict(
name='node_template',
+ type=storage.type.list()[0],
default_instances=1,
max_instances=1,
min_instances=1,
- type_name='',
service_template=storage.service_template.list()[0]
)
if ip:
- kwargs['properties'] = [Parameter(name='ip', type='str', str_value=str(ip))]
+ kwargs['properties'] = {'ip': Parameter(name='ip', type_name='string', value=ip)}
node = NodeTemplate(**kwargs)
storage.node_template.put(node)
return node
@@ -655,9 +643,10 @@ class TestNodeInstanceIP(object):
kwargs = dict(
name='node',
node_template=node,
+ type=storage.type.list()[0],
runtime_properties={},
state='',
- service_instance=storage.service_instance.list()[0]
+ service=storage.service.list()[0]
)
if ip:
kwargs['runtime_properties']['ip'] = ip
@@ -665,21 +654,21 @@ class TestNodeInstanceIP(object):
kwargs['host_fk'] = 1
elif host_fk:
kwargs['host_fk'] = host_fk
- node_instance = Node(**kwargs)
- storage.node.put(node_instance)
- return node_instance
+ node = Node(**kwargs)
+ storage.node.put(node)
+ return node
@pytest.mark.skip('Should be reworked into relationship')
-class TestRelationshipInstance(object):
- def test_relatiship_instance_model_creation(self, nodes_storage):
- relationship = mock.models.get_relationship(
+class TestRelationship(object):
+ def test_relationship_model_creation(self, nodes_storage):
+ relationship = mock.models.create_relationship(
target=nodes_storage.node.get_by_name(mock.models.DEPENDENCY_NODE_NAME)
)
nodes_storage.relationship.put(relationship)
- node_instances = nodes_storage.node
- source_node_instance = node_instances.get_by_name(mock.models.DEPENDENT_NODE_INSTANCE_NAME)
- target_node_instance = node_instances.get_by_name(mock.models.DEPENDENCY_NODE_INSTANCE_NAME)
+ nodes = nodes_storage.node
+ source_node = nodes.get_by_name(mock.models.DEPENDENT_NODE_NAME)
+ target_node = nodes.get_by_name(mock.models.DEPENDENCY_NODE_NAME)
relationship_instance = _test_model(
is_valid=True,
@@ -687,12 +676,12 @@ class TestRelationshipInstance(object):
model_cls=Relationship,
model_kwargs=dict(
relationship=relationship,
- source_node_instance=source_node_instance,
- target_node_instance=target_node_instance
+ source_node=source_node,
+ target_node=target_node
))
assert relationship_instance.relationship == relationship
- assert relationship_instance.source_node_instance == source_node_instance
- assert relationship_instance.target_node_instance == target_node_instance
+ assert relationship_instance.source_node == source_node
+ assert relationship_instance.target_node == target_node
class TestPlugin(object):
@@ -747,9 +736,9 @@ class TestPlugin(object):
]
)
def test_plugin_model_creation(self, empty_storage, is_valid, archive_name, distribution,
- distribution_release, distribution_version,
- package_name, package_source, package_version,
- supported_platform, supported_py_versions, uploaded_at, wheels):
+ distribution_release, distribution_version, package_name,
+ package_source, package_version, supported_platform,
+ supported_py_versions, uploaded_at, wheels):
_test_model(is_valid=is_valid,
storage=empty_storage,
model_cls=Plugin,
@@ -785,6 +774,7 @@ class TestTask(object):
(False, Task.STARTED, now, now, now, 1, 1, 1, True, 'name', m_cls, {}, '1'),
(False, Task.STARTED, now, now, now, 1, 1, 1, True, 'name', 'map', m_cls, '1'),
(False, Task.STARTED, now, now, now, 1, 1, 1, True, 'name', 'map', {}, m_cls),
+ (False, Task.STARTED, now, now, now, 1, 1, 1, True, 'name', 'map', None, '1'),
(True, Task.STARTED, now, now, now, 1, 1, 1, True, 'name', 'map', {}, '1'),
(True, Task.STARTED, None, now, now, 1, 1, 1, True, 'name', 'map', {}, '1'),
@@ -795,7 +785,6 @@ class TestTask(object):
(True, Task.STARTED, now, now, now, 1, 1, 1, None, 'name', 'map', {}, '1'),
(True, Task.STARTED, now, now, now, 1, 1, 1, True, None, 'map', {}, '1'),
(True, Task.STARTED, now, now, now, 1, 1, 1, True, 'name', None, {}, '1'),
- (True, Task.STARTED, now, now, now, 1, 1, 1, True, 'name', 'map', None, '1'),
(True, Task.STARTED, now, now, now, 1, 1, 1, True, 'name', 'map', {}, None),
]
)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/24ad8ba1/tests/storage/test_structures.py
----------------------------------------------------------------------
diff --git a/tests/storage/test_structures.py b/tests/storage/test_structures.py
index 67510ad..ceaea11 100644
--- a/tests/storage/test_structures.py
+++ b/tests/storage/test_structures.py
@@ -92,73 +92,71 @@ def test_inner_list_update(storage):
def test_model_to_dict(context):
- service_instance = context.service_instance
- service_instance = service_instance.to_dict()
+ service = context.service
+ service = service.to_dict()
expected_keys = [
'description',
- '_metadata',
'created_at',
'permalink',
- 'policy_triggers',
- 'policy_types',
'scaling_groups',
- 'updated_at',
- 'workflows',
+ 'updated_at'
]
for expected_key in expected_keys:
- assert expected_key in service_instance
+ assert expected_key in service
def test_relationship_model_ordering(context):
- service_instance = context.model.service_instance.get_by_name(models.SERVICE_NAME)
- source_node = context.model.node.get_by_name(models.DEPENDENT_NODE_INSTANCE_NAME)
- target_node = context.model.node.get_by_name(models.DEPENDENCY_NODE_INSTANCE_NAME)
+ service = context.model.service.get_by_name(models.SERVICE_NAME)
+ source_node = context.model.node.get_by_name(models.DEPENDENT_NODE_NAME)
+ target_node = context.model.node.get_by_name(models.DEPENDENCY_NODE_NAME)
+
new_node_template = modeling.models.NodeTemplate(
- name='new_node',
- type_name='test_node_type',
- type_hierarchy=[],
+ name='new_node_template',
+ type=source_node.type,
default_instances=1,
min_instances=1,
max_instances=1,
- service_template=service_instance.service_template
+ service_template=service.service_template
)
+
new_node = modeling.models.Node(
- name='new_node_instance',
+ name='new_node',
+ type=source_node.type,
runtime_properties={},
- service_instance=service_instance,
+ service=service,
version=None,
node_template=new_node_template,
state='',
scaling_groups=[]
)
- source_to_new_relationship = modeling.models.Relationship(
- target_node=new_node,
+ source_node.outbound_relationships.append(modeling.models.Relationship(
source_node=source_node,
- )
+ target_node=new_node,
+ ))
- new_to_target_relationship = modeling.models.Relationship(
+ new_node.outbound_relationships.append(modeling.models.Relationship(
source_node=new_node,
target_node=target_node,
- )
+ ))
context.model.node_template.put(new_node_template)
context.model.node.put(new_node)
- context.model.relationship.put(source_to_new_relationship)
- context.model.relationship.put(new_to_target_relationship)
+ context.model.node.refresh(source_node)
+ context.model.node.refresh(target_node)
def flip_and_assert(node, direction):
"""
Reversed the order of relationships and assert effects took place.
- :param node: the node instance to operatate on
- :param direction: the type of relationships to flip (inbound/outbount)
+ :param node: the node instance to operate on
+ :param direction: the type of relationships to flip (inbound/outbound)
:return:
"""
assert direction in ('inbound', 'outbound')
- relationships = getattr(node, direction + '_relationships').all()
+ relationships = getattr(node, direction + '_relationships')
assert len(relationships) == 2
reversed_relationship_instances = list(reversed(relationships))
[2/2] incubator-ariatosca git commit: Add rich docs, fix many tests
Posted by em...@apache.org.
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()