You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ariatosca.apache.org by mx...@apache.org on 2017/01/24 17:03:22 UTC
[2/3] incubator-ariatosca git commit: strucutre major ref,
relationships still need to move from one-to-many style into
many-to-one
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9c6c378c/aria/storage/base_model.py
----------------------------------------------------------------------
diff --git a/aria/storage/base_model.py b/aria/storage/base_model.py
index 65344a6..d041a38 100644
--- a/aria/storage/base_model.py
+++ b/aria/storage/base_model.py
@@ -1,743 +1,743 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""
-Aria's storage.models module
-Path: aria.storage.models
-
-models module holds aria's models.
-
-classes:
- * Field - represents a single field.
- * IterField - represents an iterable field.
- * Model - abstract model implementation.
- * Snapshot - snapshots implementation model.
- * Deployment - deployment implementation model.
- * DeploymentUpdateStep - deployment update step implementation model.
- * DeploymentUpdate - deployment update implementation model.
- * DeploymentModification - deployment modification implementation model.
- * Execution - execution implementation model.
- * Node - node implementation model.
- * Relationship - relationship implementation model.
- * NodeInstance - node instance implementation model.
- * RelationshipInstance - relationship instance implementation model.
- * Plugin - plugin implementation model.
-"""
-from collections import namedtuple
-from datetime import datetime
-
-from sqlalchemy.ext.associationproxy import association_proxy
-from sqlalchemy.ext.declarative import declared_attr
-from sqlalchemy import (
- Column,
- Integer,
- Text,
- DateTime,
- Boolean,
- Enum,
- String,
- Float,
- orm,
-)
-from sqlalchemy.ext.orderinglist import ordering_list
-
-from ..orchestrator.exceptions import TaskAbortException, TaskRetryException
-from .structure import ModelMixin
-from .type import (
- List,
- Dict
-)
-
-__all__ = (
- 'BlueprintBase',
- 'DeploymentBase',
- 'DeploymentUpdateStepBase',
- 'DeploymentUpdateBase',
- 'DeploymentModificationBase',
- 'ExecutionBase',
- 'NodeBase',
- 'RelationshipBase',
- 'NodeInstanceBase',
- 'RelationshipInstanceBase',
- 'PluginBase',
- 'TaskBase'
-)
-
-#pylint: disable=no-self-argument, abstract-method
-
-
-class BlueprintBase(ModelMixin):
- """
- Blueprint model representation.
- """
- __tablename__ = 'blueprints'
-
- created_at = Column(DateTime, nullable=False, index=True)
- main_file_name = Column(Text, nullable=False)
- plan = Column(Dict, nullable=False)
- updated_at = Column(DateTime)
- description = Column(Text)
-
-
-class DeploymentBase(ModelMixin):
- """
- Deployment model representation.
- """
- __tablename__ = 'deployments'
-
- _private_fields = ['blueprint_fk']
-
- created_at = Column(DateTime, nullable=False, index=True)
- description = Column(Text)
- inputs = Column(Dict)
- groups = Column(Dict)
- permalink = Column(Text)
- policy_triggers = Column(Dict)
- policy_types = Column(Dict)
- outputs = Column(Dict)
- scaling_groups = Column(Dict)
- updated_at = Column(DateTime)
- workflows = Column(Dict)
-
- @declared_attr
- def blueprint_fk(cls):
- return cls.foreign_key(BlueprintBase, nullable=False)
-
- @declared_attr
- def blueprint(cls):
- return cls.many_to_one_relationship('blueprint_fk')
-
- @declared_attr
- def blueprint_name(cls):
- return association_proxy('blueprint', cls.name_column_name())
-
-
-class ExecutionBase(ModelMixin):
- """
- Execution model representation.
- """
- # Needed only for pylint. the id will be populated by sqlalcehmy and the proper column.
- __tablename__ = 'executions'
- _private_fields = ['deployment_fk']
-
- TERMINATED = 'terminated'
- FAILED = 'failed'
- CANCELLED = 'cancelled'
- PENDING = 'pending'
- STARTED = 'started'
- CANCELLING = 'cancelling'
- FORCE_CANCELLING = 'force_cancelling'
-
- STATES = [TERMINATED, FAILED, CANCELLED, PENDING, STARTED, CANCELLING, FORCE_CANCELLING]
- END_STATES = [TERMINATED, FAILED, CANCELLED]
- ACTIVE_STATES = [state for state in STATES if state not in END_STATES]
-
- VALID_TRANSITIONS = {
- PENDING: [STARTED, CANCELLED],
- STARTED: END_STATES + [CANCELLING],
- CANCELLING: END_STATES + [FORCE_CANCELLING]
- }
-
- @orm.validates('status')
- def validate_status(self, key, value):
- """Validation function that verifies execution status transitions are OK"""
- try:
- current_status = getattr(self, key)
- except AttributeError:
- return
- valid_transitions = self.VALID_TRANSITIONS.get(current_status, [])
- if all([current_status is not None,
- current_status != value,
- value not in valid_transitions]):
- raise ValueError('Cannot change execution status from {current} to {new}'.format(
- current=current_status,
- new=value))
- return value
-
- created_at = Column(DateTime, index=True)
- started_at = Column(DateTime, nullable=True, index=True)
- ended_at = Column(DateTime, nullable=True, index=True)
- error = Column(Text, nullable=True)
- is_system_workflow = Column(Boolean, nullable=False, default=False)
- parameters = Column(Dict)
- status = Column(Enum(*STATES, name='execution_status'), default=PENDING)
- workflow_name = Column(Text)
-
- @declared_attr
- def blueprint(cls):
- return association_proxy('deployment', 'blueprint')
-
- @declared_attr
- def deployment_fk(cls):
- return cls.foreign_key(DeploymentBase, nullable=True)
-
- @declared_attr
- def deployment(cls):
- return cls.many_to_one_relationship('deployment_fk')
-
- @declared_attr
- def deployment_name(cls):
- return association_proxy('deployment', cls.name_column_name())
-
- @declared_attr
- def blueprint_name(cls):
- return association_proxy('deployment', 'blueprint_name')
-
- def __str__(self):
- return '<{0} id=`{1}` (status={2})>'.format(
- self.__class__.__name__,
- getattr(self, self.name_column_name()),
- self.status
- )
-
-
-class DeploymentUpdateBase(ModelMixin):
- """
- Deployment update model representation.
- """
- # Needed only for pylint. the id will be populated by sqlalcehmy and the proper column.
- steps = None
-
- __tablename__ = 'deployment_updates'
-
- _private_fields = ['execution_fk', 'deployment_fk']
-
- created_at = Column(DateTime, nullable=False, index=True)
- deployment_plan = Column(Dict, nullable=False)
- deployment_update_node_instances = Column(Dict)
- deployment_update_deployment = Column(Dict)
- deployment_update_nodes = Column(List)
- modified_entity_ids = Column(Dict)
- state = Column(Text)
-
- @declared_attr
- def execution_fk(cls):
- return cls.foreign_key(ExecutionBase, nullable=True)
-
- @declared_attr
- def execution(cls):
- return cls.many_to_one_relationship('execution_fk')
-
- @declared_attr
- def execution_name(cls):
- return association_proxy('execution', cls.name_column_name())
-
- @declared_attr
- def deployment_fk(cls):
- return cls.foreign_key(DeploymentBase)
-
- @declared_attr
- def deployment(cls):
- return cls.many_to_one_relationship('deployment_fk')
-
- @declared_attr
- def deployment_name(cls):
- return association_proxy('deployment', cls.name_column_name())
-
- def to_dict(self, suppress_error=False, **kwargs):
- dep_update_dict = super(DeploymentUpdateBase, self).to_dict(suppress_error) #pylint: disable=no-member
- # Taking care of the fact the DeploymentSteps are _BaseModels
- dep_update_dict['steps'] = [step.to_dict() for step in self.steps]
- return dep_update_dict
-
-
-class DeploymentUpdateStepBase(ModelMixin):
- """
- Deployment update step model representation.
- """
- # Needed only for pylint. the id will be populated by sqlalcehmy and the proper column.
- __tablename__ = 'deployment_update_steps'
- _private_fields = ['deployment_update_fk']
-
- _action_types = namedtuple('ACTION_TYPES', 'ADD, REMOVE, MODIFY')
- ACTION_TYPES = _action_types(ADD='add', REMOVE='remove', MODIFY='modify')
- _entity_types = namedtuple(
- 'ENTITY_TYPES',
- 'NODE, RELATIONSHIP, PROPERTY, OPERATION, WORKFLOW, OUTPUT, DESCRIPTION, GROUP, '
- 'POLICY_TYPE, POLICY_TRIGGER, PLUGIN')
- ENTITY_TYPES = _entity_types(
- NODE='node',
- RELATIONSHIP='relationship',
- PROPERTY='property',
- OPERATION='operation',
- WORKFLOW='workflow',
- OUTPUT='output',
- DESCRIPTION='description',
- GROUP='group',
- POLICY_TYPE='policy_type',
- POLICY_TRIGGER='policy_trigger',
- PLUGIN='plugin'
- )
-
- action = Column(Enum(*ACTION_TYPES, name='action_type'), nullable=False)
- entity_id = Column(Text, nullable=False)
- entity_type = Column(Enum(*ENTITY_TYPES, name='entity_type'), nullable=False)
-
- @declared_attr
- def deployment_update_fk(cls):
- return cls.foreign_key(DeploymentUpdateBase)
-
- @declared_attr
- def deployment_update(cls):
- return cls.many_to_one_relationship('deployment_update_fk', backreference='steps')
-
- @declared_attr
- def deployment_update_name(cls):
- return association_proxy('deployment_update', cls.name_column_name())
-
- def __hash__(self):
- return hash((getattr(self, self.id_column_name()), self.entity_id))
-
- def __lt__(self, other):
- """
- the order is 'remove' < 'modify' < 'add'
- :param other:
- :return:
- """
- if not isinstance(other, self.__class__):
- return not self >= other
-
- if self.action != other.action:
- if self.action == 'remove':
- return_value = True
- elif self.action == 'add':
- return_value = False
- else:
- return_value = other.action == 'add'
- return return_value
-
- if self.action == 'add':
- return self.entity_type == 'node' and other.entity_type == 'relationship'
- if self.action == 'remove':
- return self.entity_type == 'relationship' and other.entity_type == 'node'
- return False
-
-
-class DeploymentModificationBase(ModelMixin):
- """
- Deployment modification model representation.
- """
- __tablename__ = 'deployment_modifications'
- _private_fields = ['deployment_fk']
-
- STARTED = 'started'
- FINISHED = 'finished'
- ROLLEDBACK = 'rolledback'
-
- STATES = [STARTED, FINISHED, ROLLEDBACK]
- END_STATES = [FINISHED, ROLLEDBACK]
-
- 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'))
-
- @declared_attr
- def deployment_fk(cls):
- return cls.foreign_key(DeploymentBase)
-
- @declared_attr
- def deployment(cls):
- return cls.many_to_one_relationship('deployment_fk', backreference='modifications')
-
- @declared_attr
- def deployment_name(cls):
- return association_proxy('deployment', cls.name_column_name())
-
-
-class NodeBase(ModelMixin):
- """
- Node model representation.
- """
- __tablename__ = 'nodes'
-
- # See base class for an explanation on these properties
- is_id_unique = False
-
- _private_fields = ['blueprint_fk', 'host_fk']
-
- @declared_attr
- def host_fk(cls):
- return cls.foreign_key(NodeBase, nullable=True)
-
- @declared_attr
- def host(cls):
- return cls.relationship_to_self('host_fk')
-
- @declared_attr
- def host_name(cls):
- return association_proxy('host', cls.name_column_name())
-
- @declared_attr
- def deployment_fk(cls):
- return cls.foreign_key(DeploymentBase)
-
- @declared_attr
- def deployment(cls):
- return cls.many_to_one_relationship('deployment_fk')
-
- @declared_attr
- def deployment_name(cls):
- return association_proxy('deployment', cls.name_column_name())
-
- @declared_attr
- def blueprint_name(cls):
- return association_proxy('deployment', 'blueprint_{0}'.format(cls.name_column_name()))
-
- deploy_number_of_instances = Column(Integer, nullable=False)
- max_number_of_instances = Column(Integer, nullable=False)
- min_number_of_instances = Column(Integer, nullable=False)
- number_of_instances = Column(Integer, nullable=False)
- planned_number_of_instances = Column(Integer, nullable=False)
- plugins = Column(List)
- properties = Column(Dict)
- operations = Column(Dict)
- type = Column(Text, nullable=False, index=True)
- type_hierarchy = Column(List)
-
-
-class RelationshipBase(ModelMixin):
- """
- Relationship model representation.
- """
- __tablename__ = 'relationships'
-
- _private_fields = ['source_node_fk', 'target_node_fk', 'source_position', 'target_position']
-
- source_position = Column(Integer)
- target_position = Column(Integer)
-
- @declared_attr
- def deployment_id(self):
- return association_proxy('source_node', 'deployment_id')
-
- @declared_attr
- def source_node_fk(cls):
- return cls.foreign_key(NodeBase)
-
- @declared_attr
- def source_node(cls):
- return cls.many_to_one_relationship(
- 'source_node_fk',
- backreference='outbound_relationships',
- backref_kwargs=dict(
- order_by=cls.source_position,
- collection_class=ordering_list('source_position', count_from=0)
- )
- )
-
- @declared_attr
- def source_name(cls):
- return association_proxy('source_node', cls.name_column_name())
-
- @declared_attr
- def target_node_fk(cls):
- return cls.foreign_key(NodeBase, nullable=True)
-
- @declared_attr
- def target_node(cls):
- return cls.many_to_one_relationship(
- 'target_node_fk',
- backreference='inbound_relationships',
- backref_kwargs=dict(
- order_by=cls.target_position,
- collection_class=ordering_list('target_position', count_from=0)
- )
- )
-
- @declared_attr
- def target_name(cls):
- return association_proxy('target_node', cls.name_column_name())
-
- source_interfaces = Column(Dict)
- source_operations = Column(Dict, nullable=False)
- target_interfaces = Column(Dict)
- target_operations = Column(Dict, nullable=False)
- type = Column(String, nullable=False)
- type_hierarchy = Column(List)
- properties = Column(Dict)
-
-
-class NodeInstanceBase(ModelMixin):
- """
- Node instance model representation.
- """
- __tablename__ = 'node_instances'
- _private_fields = ['node_fk', 'host_fk']
-
- runtime_properties = Column(Dict)
- scaling_groups = Column(List)
- state = Column(Text, nullable=False)
- version = Column(Integer, default=1)
-
- @declared_attr
- def host_fk(cls):
- return cls.foreign_key(NodeInstanceBase, nullable=True)
-
- @declared_attr
- def host(cls):
- return cls.relationship_to_self('host_fk')
-
- @declared_attr
- def host_name(cls):
- return association_proxy('host', cls.name_column_name())
-
- @declared_attr
- def deployment(cls):
- return association_proxy('node', 'deployment')
-
- @declared_attr
- def deployment_name(cls):
- return association_proxy('node', 'deployment_name')
-
- @declared_attr
- def node_fk(cls):
- return cls.foreign_key(NodeBase, nullable=True)
-
- @declared_attr
- def node(cls):
- return cls.many_to_one_relationship('node_fk')
-
- @declared_attr
- def node_name(cls):
- return association_proxy('node', cls.name_column_name())
-
- @property
- def ip(self):
- if not self.host_fk:
- return None
- host_node_instance = self.host
- if 'ip' in host_node_instance.runtime_properties: # pylint: disable=no-member
- return host_node_instance.runtime_properties['ip'] # pylint: disable=no-member
- host_node = host_node_instance.node # pylint: disable=no-member
- if 'ip' in host_node.properties:
- return host_node.properties['ip']
- return None
-
-
-class RelationshipInstanceBase(ModelMixin):
- """
- Relationship instance model representation.
- """
- __tablename__ = 'relationship_instances'
- _private_fields = ['relationship_storage_fk',
- 'source_node_instance_fk',
- 'target_node_instance_fk',
- 'source_position',
- 'target_position']
-
- source_position = Column(Integer)
- target_position = Column(Integer)
-
- @declared_attr
- def source_node_instance_fk(cls):
- return cls.foreign_key(NodeInstanceBase, nullable=True)
-
- @declared_attr
- def source_node_instance(cls):
- return cls.many_to_one_relationship(
- 'source_node_instance_fk',
- backreference='outbound_relationship_instances',
- backref_kwargs=dict(
- order_by=cls.source_position,
- collection_class=ordering_list('source_position', count_from=0)
- )
- )
-
- @declared_attr
- def source_node_instance_name(cls):
- return association_proxy('source_node_instance', 'node_{0}'.format(cls.name_column_name()))
-
- @declared_attr
- def source_node_name(cls):
- return association_proxy('source_node_instance', cls.name_column_name())
-
- @declared_attr
- def target_node_instance_fk(cls):
- return cls.foreign_key(NodeInstanceBase, nullable=True)
-
- @declared_attr
- def target_node_instance(cls):
- return cls.many_to_one_relationship(
- 'target_node_instance_fk',
- backreference='inbound_relationship_instances',
- backref_kwargs=dict(
- order_by=cls.target_position,
- collection_class=ordering_list('target_position', count_from=0)
- )
- )
-
- @declared_attr
- def target_node_instance_name(cls):
- return association_proxy('target_node_instance', cls.name_column_name())
-
- @declared_attr
- def target_node_name(cls):
- return association_proxy('target_node_instance', 'node_{0}'.format(cls.name_column_name()))
-
- @declared_attr
- def relationship_fk(cls):
- return cls.foreign_key(RelationshipBase)
-
- @declared_attr
- def relationship(cls):
- return cls.many_to_one_relationship('relationship_fk')
-
- @declared_attr
- def relationship_name(cls):
- return association_proxy('relationship', cls.name_column_name())
-
-
-class PluginBase(ModelMixin):
- """
- Plugin model representation.
- """
- __tablename__ = 'plugins'
-
- archive_name = Column(Text, nullable=False, index=True)
- distribution = Column(Text)
- distribution_release = Column(Text)
- distribution_version = Column(Text)
- package_name = Column(Text, nullable=False, index=True)
- package_source = Column(Text)
- package_version = Column(Text)
- supported_platform = Column(Text)
- supported_py_versions = Column(List)
- uploaded_at = Column(DateTime, nullable=False, index=True)
- wheels = Column(List, nullable=False)
-
-
-class TaskBase(ModelMixin):
- """
- A Model which represents an task
- """
- __tablename__ = 'tasks'
- _private_fields = ['node_instance_fk', 'relationship_instance_fk', 'execution_fk']
-
- @declared_attr
- def node_instance_fk(cls):
- return cls.foreign_key(NodeInstanceBase, nullable=True)
-
- @declared_attr
- def node_instance_name(cls):
- return association_proxy('node_instance', cls.name_column_name())
-
- @declared_attr
- def node_instance(cls):
- return cls.many_to_one_relationship('node_instance_fk')
-
- @declared_attr
- def relationship_instance_fk(cls):
- return cls.foreign_key(RelationshipInstanceBase, nullable=True)
-
- @declared_attr
- def relationship_instance_name(cls):
- return association_proxy('relationship_instance', cls.name_column_name())
-
- @declared_attr
- def relationship_instance(cls):
- return cls.many_to_one_relationship('relationship_instance_fk')
-
- @declared_attr
- def plugin_fk(cls):
- return cls.foreign_key(PluginBase, nullable=True)
-
- @declared_attr
- def plugin(cls):
- return cls.many_to_one_relationship('plugin_fk')
-
- @declared_attr
- def plugin_name(cls):
- return association_proxy('plugin', 'name')
-
- @declared_attr
- def execution_fk(cls):
- return cls.foreign_key(ExecutionBase, nullable=True)
-
- @declared_attr
- def execution(cls):
- return cls.many_to_one_relationship('execution_fk')
-
- @declared_attr
- def execution_name(cls):
- return association_proxy('execution', cls.name_column_name())
-
- PENDING = 'pending'
- RETRYING = 'retrying'
- SENT = 'sent'
- STARTED = 'started'
- SUCCESS = 'success'
- FAILED = 'failed'
- STATES = (
- PENDING,
- RETRYING,
- SENT,
- STARTED,
- SUCCESS,
- FAILED,
- )
-
- WAIT_STATES = [PENDING, RETRYING]
- END_STATES = [SUCCESS, FAILED]
-
- @orm.validates('max_attempts')
- def validate_max_attempts(self, _, value): # pylint: disable=no-self-use
- """Validates that max attempts is either -1 or a positive number"""
- if value < 1 and value != TaskBase.INFINITE_RETRIES:
- raise ValueError('Max attempts can be either -1 (infinite) or any positive number. '
- 'Got {value}'.format(value=value))
- return value
-
- INFINITE_RETRIES = -1
-
- status = Column(Enum(*STATES, name='status'), default=PENDING)
-
- due_at = Column(DateTime, default=datetime.utcnow)
- started_at = Column(DateTime, default=None)
- ended_at = Column(DateTime, default=None)
- max_attempts = Column(Integer, default=1)
- retry_count = Column(Integer, default=0)
- retry_interval = Column(Float, default=0)
- ignore_failure = Column(Boolean, default=False)
-
- # Operation specific fields
- operation_mapping = Column(String)
- inputs = Column(Dict)
-
- @property
- def actor(self):
- """
- Return the actor of the task
- :return:
- """
- return self.node_instance or self.relationship_instance
-
- @classmethod
- def as_node_instance(cls, instance, **kwargs):
- return cls(node_instance=instance, **kwargs)
-
- @classmethod
- def as_relationship_instance(cls, instance, **kwargs):
- return cls(relationship_instance=instance, **kwargs)
-
- @staticmethod
- def abort(message=None):
- raise TaskAbortException(message)
-
- @staticmethod
- def retry(message=None, retry_interval=None):
- raise TaskRetryException(message, retry_interval=retry_interval)
+# # Licensed to the Apache Software Foundation (ASF) under one or more
+# # contributor license agreements. See the NOTICE file distributed with
+# # this work for additional information regarding copyright ownership.
+# # The ASF licenses this file to You under the Apache License, Version 2.0
+# # (the "License"); you may not use this file except in compliance with
+# # the License. You may obtain a copy of the License at
+# #
+# # http://www.apache.org/licenses/LICENSE-2.0
+# #
+# # Unless required by applicable law or agreed to in writing, software
+# # distributed under the License is distributed on an "AS IS" BASIS,
+# # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# # See the License for the specific language governing permissions and
+# # limitations under the License.
+#
+# """
+# Aria's storage.models module
+# Path: aria.storage.models
+#
+# models module holds aria's models.
+#
+# classes:
+# * Field - represents a single field.
+# * IterField - represents an iterable field.
+# * Model - abstract model implementation.
+# * Snapshot - snapshots implementation model.
+# * Deployment - deployment implementation model.
+# * DeploymentUpdateStep - deployment update step implementation model.
+# * DeploymentUpdate - deployment update implementation model.
+# * DeploymentModification - deployment modification implementation model.
+# * Execution - execution implementation model.
+# * Node - node implementation model.
+# * Relationship - relationship implementation model.
+# * NodeInstance - node instance implementation model.
+# * RelationshipInstance - relationship instance implementation model.
+# * Plugin - plugin implementation model.
+# """
+# from collections import namedtuple
+# from datetime import datetime
+#
+# from sqlalchemy.ext.associationproxy import association_proxy
+# from sqlalchemy.ext.declarative import declared_attr
+# from sqlalchemy import (
+# Column,
+# Integer,
+# Text,
+# DateTime,
+# Boolean,
+# Enum,
+# String,
+# Float,
+# orm,
+# )
+# from sqlalchemy.ext.orderinglist import ordering_list
+#
+# from ..orchestrator.exceptions import TaskAbortException, TaskRetryException
+# from .structure import ModelMixin
+# from .type import (
+# List,
+# Dict
+# )
+#
+# __all__ = (
+# 'BlueprintBase',
+# 'DeploymentBase',
+# 'DeploymentUpdateStepBase',
+# 'DeploymentUpdateBase',
+# 'DeploymentModificationBase',
+# 'ExecutionBase',
+# 'NodeBase',
+# 'RelationshipBase',
+# 'NodeInstanceBase',
+# 'RelationshipInstanceBase',
+# 'PluginBase',
+# 'TaskBase'
+# )
+#
+# #pylint: disable=no-self-argument, abstract-method
+#
+#
+# class BlueprintBase(ModelMixin):
+# """
+# Blueprint model representation.
+# """
+# __tablename__ = 'blueprints'
+#
+# created_at = Column(DateTime, nullable=False, index=True)
+# main_file_name = Column(Text, nullable=False)
+# plan = Column(Dict, nullable=False)
+# updated_at = Column(DateTime)
+# description = Column(Text)
+#
+#
+# class DeploymentBase(ModelMixin):
+# """
+# Deployment model representation.
+# """
+# __tablename__ = 'deployments'
+#
+# _private_fields = ['blueprint_fk']
+#
+# created_at = Column(DateTime, nullable=False, index=True)
+# description = Column(Text)
+# inputs = Column(Dict)
+# groups = Column(Dict)
+# permalink = Column(Text)
+# policy_triggers = Column(Dict)
+# policy_types = Column(Dict)
+# outputs = Column(Dict)
+# scaling_groups = Column(Dict)
+# updated_at = Column(DateTime)
+# workflows = Column(Dict)
+#
+# @declared_attr
+# def blueprint_fk(cls):
+# return cls.foreign_key(BlueprintBase, nullable=False)
+#
+# @declared_attr
+# def blueprint(cls):
+# return cls.many_to_one_relationship('blueprint_fk')
+#
+# @declared_attr
+# def blueprint_name(cls):
+# return association_proxy('blueprint', cls.name_column_name())
+#
+#
+# class ExecutionBase(ModelMixin):
+# """
+# Execution model representation.
+# """
+# # Needed only for pylint. the id will be populated by sqlalcehmy and the proper column.
+# __tablename__ = 'executions'
+# _private_fields = ['deployment_fk']
+#
+# TERMINATED = 'terminated'
+# FAILED = 'failed'
+# CANCELLED = 'cancelled'
+# PENDING = 'pending'
+# STARTED = 'started'
+# CANCELLING = 'cancelling'
+# FORCE_CANCELLING = 'force_cancelling'
+#
+# STATES = [TERMINATED, FAILED, CANCELLED, PENDING, STARTED, CANCELLING, FORCE_CANCELLING]
+# END_STATES = [TERMINATED, FAILED, CANCELLED]
+# ACTIVE_STATES = [state for state in STATES if state not in END_STATES]
+#
+# VALID_TRANSITIONS = {
+# PENDING: [STARTED, CANCELLED],
+# STARTED: END_STATES + [CANCELLING],
+# CANCELLING: END_STATES + [FORCE_CANCELLING]
+# }
+#
+# @orm.validates('status')
+# def validate_status(self, key, value):
+# """Validation function that verifies execution status transitions are OK"""
+# try:
+# current_status = getattr(self, key)
+# except AttributeError:
+# return
+# valid_transitions = self.VALID_TRANSITIONS.get(current_status, [])
+# if all([current_status is not None,
+# current_status != value,
+# value not in valid_transitions]):
+# raise ValueError('Cannot change execution status from {current} to {new}'.format(
+# current=current_status,
+# new=value))
+# return value
+#
+# created_at = Column(DateTime, index=True)
+# started_at = Column(DateTime, nullable=True, index=True)
+# ended_at = Column(DateTime, nullable=True, index=True)
+# error = Column(Text, nullable=True)
+# is_system_workflow = Column(Boolean, nullable=False, default=False)
+# parameters = Column(Dict)
+# status = Column(Enum(*STATES, name='execution_status'), default=PENDING)
+# workflow_name = Column(Text)
+#
+# @declared_attr
+# def blueprint(cls):
+# return association_proxy('deployment', 'blueprint')
+#
+# @declared_attr
+# def deployment_fk(cls):
+# return cls.foreign_key(DeploymentBase, nullable=True)
+#
+# @declared_attr
+# def deployment(cls):
+# return cls.many_to_one_relationship('deployment_fk')
+#
+# @declared_attr
+# def deployment_name(cls):
+# return association_proxy('deployment', cls.name_column_name())
+#
+# @declared_attr
+# def blueprint_name(cls):
+# return association_proxy('deployment', 'blueprint_name')
+#
+# def __str__(self):
+# return '<{0} id=`{1}` (status={2})>'.format(
+# self.__class__.__name__,
+# getattr(self, self.name_column_name()),
+# self.status
+# )
+#
+#
+# class DeploymentUpdateBase(ModelMixin):
+# """
+# Deployment update model representation.
+# """
+# # Needed only for pylint. the id will be populated by sqlalcehmy and the proper column.
+# steps = None
+#
+# __tablename__ = 'deployment_updates'
+#
+# _private_fields = ['execution_fk', 'deployment_fk']
+#
+# created_at = Column(DateTime, nullable=False, index=True)
+# deployment_plan = Column(Dict, nullable=False)
+# deployment_update_node_instances = Column(Dict)
+# deployment_update_deployment = Column(Dict)
+# deployment_update_nodes = Column(List)
+# modified_entity_ids = Column(Dict)
+# state = Column(Text)
+#
+# @declared_attr
+# def execution_fk(cls):
+# return cls.foreign_key(ExecutionBase, nullable=True)
+#
+# @declared_attr
+# def execution(cls):
+# return cls.many_to_one_relationship('execution_fk')
+#
+# @declared_attr
+# def execution_name(cls):
+# return association_proxy('execution', cls.name_column_name())
+#
+# @declared_attr
+# def deployment_fk(cls):
+# return cls.foreign_key(DeploymentBase)
+#
+# @declared_attr
+# def deployment(cls):
+# return cls.many_to_one_relationship('deployment_fk')
+#
+# @declared_attr
+# def deployment_name(cls):
+# return association_proxy('deployment', cls.name_column_name())
+#
+# def to_dict(self, suppress_error=False, **kwargs):
+# dep_update_dict = super(DeploymentUpdateBase, self).to_dict(suppress_error) #pylint: disable=no-member
+# # Taking care of the fact the DeploymentSteps are _BaseModels
+# dep_update_dict['steps'] = [step.to_dict() for step in self.steps]
+# return dep_update_dict
+#
+#
+# class DeploymentUpdateStepBase(ModelMixin):
+# """
+# Deployment update step model representation.
+# """
+# # Needed only for pylint. the id will be populated by sqlalcehmy and the proper column.
+# __tablename__ = 'deployment_update_steps'
+# _private_fields = ['deployment_update_fk']
+#
+# _action_types = namedtuple('ACTION_TYPES', 'ADD, REMOVE, MODIFY')
+# ACTION_TYPES = _action_types(ADD='add', REMOVE='remove', MODIFY='modify')
+# _entity_types = namedtuple(
+# 'ENTITY_TYPES',
+# 'NODE, RELATIONSHIP, PROPERTY, OPERATION, WORKFLOW, OUTPUT, DESCRIPTION, GROUP, '
+# 'POLICY_TYPE, POLICY_TRIGGER, PLUGIN')
+# ENTITY_TYPES = _entity_types(
+# NODE='node',
+# RELATIONSHIP='relationship',
+# PROPERTY='property',
+# OPERATION='operation',
+# WORKFLOW='workflow',
+# OUTPUT='output',
+# DESCRIPTION='description',
+# GROUP='group',
+# POLICY_TYPE='policy_type',
+# POLICY_TRIGGER='policy_trigger',
+# PLUGIN='plugin'
+# )
+#
+# action = Column(Enum(*ACTION_TYPES, name='action_type'), nullable=False)
+# entity_id = Column(Text, nullable=False)
+# entity_type = Column(Enum(*ENTITY_TYPES, name='entity_type'), nullable=False)
+#
+# @declared_attr
+# def deployment_update_fk(cls):
+# return cls.foreign_key(DeploymentUpdateBase)
+#
+# @declared_attr
+# def deployment_update(cls):
+# return cls.many_to_one_relationship('deployment_update_fk', backreference='steps')
+#
+# @declared_attr
+# def deployment_update_name(cls):
+# return association_proxy('deployment_update', cls.name_column_name())
+#
+# def __hash__(self):
+# return hash((getattr(self, self.id_column_name()), self.entity_id))
+#
+# def __lt__(self, other):
+# """
+# the order is 'remove' < 'modify' < 'add'
+# :param other:
+# :return:
+# """
+# if not isinstance(other, self.__class__):
+# return not self >= other
+#
+# if self.action != other.action:
+# if self.action == 'remove':
+# return_value = True
+# elif self.action == 'add':
+# return_value = False
+# else:
+# return_value = other.action == 'add'
+# return return_value
+#
+# if self.action == 'add':
+# return self.entity_type == 'node' and other.entity_type == 'relationship'
+# if self.action == 'remove':
+# return self.entity_type == 'relationship' and other.entity_type == 'node'
+# return False
+#
+#
+# class DeploymentModificationBase(ModelMixin):
+# """
+# Deployment modification model representation.
+# """
+# __tablename__ = 'deployment_modifications'
+# _private_fields = ['deployment_fk']
+#
+# STARTED = 'started'
+# FINISHED = 'finished'
+# ROLLEDBACK = 'rolledback'
+#
+# STATES = [STARTED, FINISHED, ROLLEDBACK]
+# END_STATES = [FINISHED, ROLLEDBACK]
+#
+# 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'))
+#
+# @declared_attr
+# def deployment_fk(cls):
+# return cls.foreign_key(DeploymentBase)
+#
+# @declared_attr
+# def deployment(cls):
+# return cls.many_to_one_relationship('deployment_fk', backreference='modifications')
+#
+# @declared_attr
+# def deployment_name(cls):
+# return association_proxy('deployment', cls.name_column_name())
+#
+#
+# class NodeBase(ModelMixin):
+# """
+# Node model representation.
+# """
+# __tablename__ = 'nodes'
+#
+# # See base class for an explanation on these properties
+# is_id_unique = False
+#
+# _private_fields = ['blueprint_fk', 'host_fk']
+#
+# @declared_attr
+# def host_fk(cls):
+# return cls.foreign_key(NodeBase, nullable=True)
+#
+# @declared_attr
+# def host(cls):
+# return cls.relationship_to_self('host_fk')
+#
+# @declared_attr
+# def host_name(cls):
+# return association_proxy('host', cls.name_column_name())
+#
+# @declared_attr
+# def deployment_fk(cls):
+# return cls.foreign_key(DeploymentBase)
+#
+# @declared_attr
+# def deployment(cls):
+# return cls.many_to_one_relationship('deployment_fk')
+#
+# @declared_attr
+# def deployment_name(cls):
+# return association_proxy('deployment', cls.name_column_name())
+#
+# @declared_attr
+# def blueprint_name(cls):
+# return association_proxy('deployment', 'blueprint_{0}'.format(cls.name_column_name()))
+#
+# deploy_number_of_instances = Column(Integer, nullable=False)
+# max_number_of_instances = Column(Integer, nullable=False)
+# min_number_of_instances = Column(Integer, nullable=False)
+# number_of_instances = Column(Integer, nullable=False)
+# planned_number_of_instances = Column(Integer, nullable=False)
+# plugins = Column(List)
+# properties = Column(Dict)
+# operations = Column(Dict)
+# type = Column(Text, nullable=False, index=True)
+# type_hierarchy = Column(List)
+#
+#
+# class RelationshipBase(ModelMixin):
+# """
+# Relationship model representation.
+# """
+# __tablename__ = 'relationships'
+#
+# _private_fields = ['source_node_fk', 'target_node_fk', 'source_position', 'target_position']
+#
+# source_position = Column(Integer)
+# target_position = Column(Integer)
+#
+# @declared_attr
+# def deployment_id(self):
+# return association_proxy('source_node', 'deployment_id')
+#
+# @declared_attr
+# def source_node_fk(cls):
+# return cls.foreign_key(NodeBase)
+#
+# @declared_attr
+# def source_node(cls):
+# return cls.many_to_one_relationship(
+# 'source_node_fk',
+# backreference='outbound_relationships',
+# backref_kwargs=dict(
+# order_by=cls.source_position,
+# collection_class=ordering_list('source_position', count_from=0)
+# )
+# )
+#
+# @declared_attr
+# def source_name(cls):
+# return association_proxy('source_node', cls.name_column_name())
+#
+# @declared_attr
+# def target_node_fk(cls):
+# return cls.foreign_key(NodeBase, nullable=True)
+#
+# @declared_attr
+# def target_node(cls):
+# return cls.many_to_one_relationship(
+# 'target_node_fk',
+# backreference='inbound_relationships',
+# backref_kwargs=dict(
+# order_by=cls.target_position,
+# collection_class=ordering_list('target_position', count_from=0)
+# )
+# )
+#
+# @declared_attr
+# def target_name(cls):
+# return association_proxy('target_node', cls.name_column_name())
+#
+# source_interfaces = Column(Dict)
+# source_operations = Column(Dict, nullable=False)
+# target_interfaces = Column(Dict)
+# target_operations = Column(Dict, nullable=False)
+# type = Column(String, nullable=False)
+# type_hierarchy = Column(List)
+# properties = Column(Dict)
+#
+#
+# class NodeInstanceBase(ModelMixin):
+# """
+# Node instance model representation.
+# """
+# __tablename__ = 'node_instances'
+# _private_fields = ['node_fk', 'host_fk']
+#
+# runtime_properties = Column(Dict)
+# scaling_groups = Column(List)
+# state = Column(Text, nullable=False)
+# version = Column(Integer, default=1)
+#
+# @declared_attr
+# def host_fk(cls):
+# return cls.foreign_key(NodeInstanceBase, nullable=True)
+#
+# @declared_attr
+# def host(cls):
+# return cls.relationship_to_self('host_fk')
+#
+# @declared_attr
+# def host_name(cls):
+# return association_proxy('host', cls.name_column_name())
+#
+# @declared_attr
+# def deployment(cls):
+# return association_proxy('node', 'deployment')
+#
+# @declared_attr
+# def deployment_name(cls):
+# return association_proxy('node', 'deployment_name')
+#
+# @declared_attr
+# def node_fk(cls):
+# return cls.foreign_key(NodeBase, nullable=True)
+#
+# @declared_attr
+# def node(cls):
+# return cls.many_to_one_relationship('node_fk')
+#
+# @declared_attr
+# def node_name(cls):
+# return association_proxy('node', cls.name_column_name())
+#
+# @property
+# def ip(self):
+# if not self.host_fk:
+# return None
+# host_node_instance = self.host
+# if 'ip' in host_node_instance.runtime_properties: # pylint: disable=no-member
+# return host_node_instance.runtime_properties['ip'] # pylint: disable=no-member
+# host_node = host_node_instance.node # pylint: disable=no-member
+# if 'ip' in host_node.properties:
+# return host_node.properties['ip']
+# return None
+#
+#
+# class RelationshipInstanceBase(ModelMixin):
+# """
+# Relationship instance model representation.
+# """
+# __tablename__ = 'relationship_instances'
+# _private_fields = ['relationship_storage_fk',
+# 'source_node_instance_fk',
+# 'target_node_instance_fk',
+# 'source_position',
+# 'target_position']
+#
+# source_position = Column(Integer)
+# target_position = Column(Integer)
+#
+# @declared_attr
+# def source_node_instance_fk(cls):
+# return cls.foreign_key(NodeInstanceBase, nullable=True)
+#
+# @declared_attr
+# def source_node_instance(cls):
+# return cls.many_to_one_relationship(
+# 'source_node_instance_fk',
+# backreference='outbound_relationship_instances',
+# backref_kwargs=dict(
+# order_by=cls.source_position,
+# collection_class=ordering_list('source_position', count_from=0)
+# )
+# )
+#
+# @declared_attr
+# def source_node_instance_name(cls):
+# return association_proxy('source_node_instance', 'node_{0}'.format(cls.name_column_name()))
+#
+# @declared_attr
+# def source_node_name(cls):
+# return association_proxy('source_node_instance', cls.name_column_name())
+#
+# @declared_attr
+# def target_node_instance_fk(cls):
+# return cls.foreign_key(NodeInstanceBase, nullable=True)
+#
+# @declared_attr
+# def target_node_instance(cls):
+# return cls.many_to_one_relationship(
+# 'target_node_instance_fk',
+# backreference='inbound_relationship_instances',
+# backref_kwargs=dict(
+# order_by=cls.target_position,
+# collection_class=ordering_list('target_position', count_from=0)
+# )
+# )
+#
+# @declared_attr
+# def target_node_instance_name(cls):
+# return association_proxy('target_node_instance', cls.name_column_name())
+#
+# @declared_attr
+# def target_node_name(cls):
+# return association_proxy('target_node_instance', 'node_{0}'.format(cls.name_column_name()))
+#
+# @declared_attr
+# def relationship_fk(cls):
+# return cls.foreign_key(RelationshipBase)
+#
+# @declared_attr
+# def relationship(cls):
+# return cls.many_to_one_relationship('relationship_fk')
+#
+# @declared_attr
+# def relationship_name(cls):
+# return association_proxy('relationship', cls.name_column_name())
+#
+#
+# class PluginBase(ModelMixin):
+# """
+# Plugin model representation.
+# """
+# __tablename__ = 'plugins'
+#
+# archive_name = Column(Text, nullable=False, index=True)
+# distribution = Column(Text)
+# distribution_release = Column(Text)
+# distribution_version = Column(Text)
+# package_name = Column(Text, nullable=False, index=True)
+# package_source = Column(Text)
+# package_version = Column(Text)
+# supported_platform = Column(Text)
+# supported_py_versions = Column(List)
+# uploaded_at = Column(DateTime, nullable=False, index=True)
+# wheels = Column(List, nullable=False)
+#
+#
+# class TaskBase(ModelMixin):
+# """
+# A Model which represents an task
+# """
+# __tablename__ = 'tasks'
+# _private_fields = ['node_instance_fk', 'relationship_instance_fk', 'execution_fk']
+#
+# @declared_attr
+# def node_instance_fk(cls):
+# return cls.foreign_key(NodeInstanceBase, nullable=True)
+#
+# @declared_attr
+# def node_instance_name(cls):
+# return association_proxy('node_instance', cls.name_column_name())
+#
+# @declared_attr
+# def node_instance(cls):
+# return cls.many_to_one_relationship('node_instance_fk')
+#
+# @declared_attr
+# def relationship_instance_fk(cls):
+# return cls.foreign_key(RelationshipInstanceBase, nullable=True)
+#
+# @declared_attr
+# def relationship_instance_name(cls):
+# return association_proxy('relationship_instance', cls.name_column_name())
+#
+# @declared_attr
+# def relationship_instance(cls):
+# return cls.many_to_one_relationship('relationship_instance_fk')
+#
+# @declared_attr
+# def plugin_fk(cls):
+# return cls.foreign_key(PluginBase, nullable=True)
+#
+# @declared_attr
+# def plugin(cls):
+# return cls.many_to_one_relationship('plugin_fk')
+#
+# @declared_attr
+# def plugin_name(cls):
+# return association_proxy('plugin', 'name')
+#
+# @declared_attr
+# def execution_fk(cls):
+# return cls.foreign_key(ExecutionBase, nullable=True)
+#
+# @declared_attr
+# def execution(cls):
+# return cls.many_to_one_relationship('execution_fk')
+#
+# @declared_attr
+# def execution_name(cls):
+# return association_proxy('execution', cls.name_column_name())
+#
+# PENDING = 'pending'
+# RETRYING = 'retrying'
+# SENT = 'sent'
+# STARTED = 'started'
+# SUCCESS = 'success'
+# FAILED = 'failed'
+# STATES = (
+# PENDING,
+# RETRYING,
+# SENT,
+# STARTED,
+# SUCCESS,
+# FAILED,
+# )
+#
+# WAIT_STATES = [PENDING, RETRYING]
+# END_STATES = [SUCCESS, FAILED]
+#
+# @orm.validates('max_attempts')
+# def validate_max_attempts(self, _, value): # pylint: disable=no-self-use
+# """Validates that max attempts is either -1 or a positive number"""
+# if value < 1 and value != TaskBase.INFINITE_RETRIES:
+# raise ValueError('Max attempts can be either -1 (infinite) or any positive number. '
+# 'Got {value}'.format(value=value))
+# return value
+#
+# INFINITE_RETRIES = -1
+#
+# status = Column(Enum(*STATES, name='status'), default=PENDING)
+#
+# due_at = Column(DateTime, default=datetime.utcnow)
+# started_at = Column(DateTime, default=None)
+# ended_at = Column(DateTime, default=None)
+# max_attempts = Column(Integer, default=1)
+# retry_count = Column(Integer, default=0)
+# retry_interval = Column(Float, default=0)
+# ignore_failure = Column(Boolean, default=False)
+#
+# # Operation specific fields
+# operation_mapping = Column(String)
+# inputs = Column(Dict)
+#
+# @property
+# def actor(self):
+# """
+# Return the actor of the task
+# :return:
+# """
+# return self.node_instance or self.relationship_instance
+#
+# @classmethod
+# def as_node_instance(cls, instance, **kwargs):
+# return cls(node_instance=instance, **kwargs)
+#
+# @classmethod
+# def as_relationship_instance(cls, instance, **kwargs):
+# return cls(relationship_instance=instance, **kwargs)
+#
+# @staticmethod
+# def abort(message=None):
+# raise TaskAbortException(message)
+#
+# @staticmethod
+# def retry(message=None, retry_interval=None):
+# raise TaskRetryException(message, retry_interval=retry_interval)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9c6c378c/aria/storage/model.py
----------------------------------------------------------------------
diff --git a/aria/storage/model.py b/aria/storage/model.py
index afca3e4..6533b7f 100644
--- a/aria/storage/model.py
+++ b/aria/storage/model.py
@@ -1,110 +1,110 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""
-Aria's storage.models module
-Path: aria.storage.models
-
-models module holds aria's models.
-
-classes:
- * Field - represents a single field.
- * IterField - represents an iterable field.
- * Model - abstract model implementation.
- * Snapshot - snapshots implementation model.
- * Deployment - deployment implementation model.
- * DeploymentUpdateStep - deployment update step implementation model.
- * DeploymentUpdate - deployment update implementation model.
- * DeploymentModification - deployment modification implementation model.
- * Execution - execution implementation model.
- * Node - node implementation model.
- * Relationship - relationship implementation model.
- * NodeInstance - node instance implementation model.
- * RelationshipInstance - relationship instance implementation model.
- * ProviderContext - provider context implementation model.
- * Plugin - plugin implementation model.
-"""
-from sqlalchemy.ext.declarative import declarative_base
-
-from . import structure
-from . import base_model as base
-
-__all__ = (
- 'Blueprint',
- 'Deployment',
- 'DeploymentUpdateStep',
- 'DeploymentUpdate',
- 'DeploymentModification',
- 'Execution',
- 'Node',
- 'Relationship',
- 'NodeInstance',
- 'RelationshipInstance',
- 'Plugin',
-)
-
-
-#pylint: disable=abstract-method
-# The required abstract method implementation are implemented in the ModelIDMixin, which is used as
-# a base to the DeclerativeBase.
-DeclarativeBase = declarative_base(cls=structure.ModelIDMixin)
-
-
-class Blueprint(DeclarativeBase, base.BlueprintBase):
- pass
-
-
-class Deployment(DeclarativeBase, base.DeploymentBase):
- pass
-
-
-class Execution(DeclarativeBase, base.ExecutionBase):
- pass
-
-
-class DeploymentUpdate(DeclarativeBase, base.DeploymentUpdateBase):
- pass
-
-
-class DeploymentUpdateStep(DeclarativeBase, base.DeploymentUpdateStepBase):
- pass
-
-
-class DeploymentModification(DeclarativeBase, base.DeploymentModificationBase):
- pass
-
-
-class Node(DeclarativeBase, base.NodeBase):
- pass
-
-
-class Relationship(DeclarativeBase, base.RelationshipBase):
- pass
-
-
-class NodeInstance(DeclarativeBase, base.NodeInstanceBase):
- pass
-
-
-class RelationshipInstance(DeclarativeBase, base.RelationshipInstanceBase):
- pass
-
-
-class Plugin(DeclarativeBase, base.PluginBase):
- pass
-
-
-class Task(DeclarativeBase, base.TaskBase):
- pass
+# # Licensed to the Apache Software Foundation (ASF) under one or more
+# # contributor license agreements. See the NOTICE file distributed with
+# # this work for additional information regarding copyright ownership.
+# # The ASF licenses this file to You under the Apache License, Version 2.0
+# # (the "License"); you may not use this file except in compliance with
+# # the License. You may obtain a copy of the License at
+# #
+# # http://www.apache.org/licenses/LICENSE-2.0
+# #
+# # Unless required by applicable law or agreed to in writing, software
+# # distributed under the License is distributed on an "AS IS" BASIS,
+# # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# # See the License for the specific language governing permissions and
+# # limitations under the License.
+#
+# """
+# Aria's storage.models module
+# Path: aria.storage.models
+#
+# models module holds aria's models.
+#
+# classes:
+# * Field - represents a single field.
+# * IterField - represents an iterable field.
+# * Model - abstract model implementation.
+# * Snapshot - snapshots implementation model.
+# * Deployment - deployment implementation model.
+# * DeploymentUpdateStep - deployment update step implementation model.
+# * DeploymentUpdate - deployment update implementation model.
+# * DeploymentModification - deployment modification implementation model.
+# * Execution - execution implementation model.
+# * Node - node implementation model.
+# * Relationship - relationship implementation model.
+# * NodeInstance - node instance implementation model.
+# * RelationshipInstance - relationship instance implementation model.
+# * ProviderContext - provider context implementation model.
+# * Plugin - plugin implementation model.
+# """
+# from sqlalchemy.ext.declarative import declarative_base
+#
+# from . import structure
+# from . import base_model as base
+#
+# __all__ = (
+# 'Blueprint',
+# 'Deployment',
+# 'DeploymentUpdateStep',
+# 'DeploymentUpdate',
+# 'DeploymentModification',
+# 'Execution',
+# 'Node',
+# 'Relationship',
+# 'NodeInstance',
+# 'RelationshipInstance',
+# 'Plugin',
+# )
+#
+#
+# #pylint: disable=abstract-method
+# # The required abstract method implementation are implemented in the ModelIDMixin, which is used as
+# # a base to the DeclerativeBase.
+# DeclarativeBase = declarative_base(cls=structure.ModelIDMixin)
+#
+#
+# class Blueprint(DeclarativeBase, base.BlueprintBase):
+# pass
+#
+#
+# class Deployment(DeclarativeBase, base.DeploymentBase):
+# pass
+#
+#
+# class Execution(DeclarativeBase, base.ExecutionBase):
+# pass
+#
+#
+# class DeploymentUpdate(DeclarativeBase, base.DeploymentUpdateBase):
+# pass
+#
+#
+# class DeploymentUpdateStep(DeclarativeBase, base.DeploymentUpdateStepBase):
+# pass
+#
+#
+# class DeploymentModification(DeclarativeBase, base.DeploymentModificationBase):
+# pass
+#
+#
+# class Node(DeclarativeBase, base.NodeBase):
+# pass
+#
+#
+# class Relationship(DeclarativeBase, base.RelationshipBase):
+# pass
+#
+#
+# class NodeInstance(DeclarativeBase, base.NodeInstanceBase):
+# pass
+#
+#
+# class RelationshipInstance(DeclarativeBase, base.RelationshipInstanceBase):
+# pass
+#
+#
+# class Plugin(DeclarativeBase, base.PluginBase):
+# pass
+#
+#
+# class Task(DeclarativeBase, base.TaskBase):
+# pass
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9c6c378c/aria/storage/structure.py
----------------------------------------------------------------------
diff --git a/aria/storage/structure.py b/aria/storage/structure.py
index 472b5ba..f9cd58b 100644
--- a/aria/storage/structure.py
+++ b/aria/storage/structure.py
@@ -37,6 +37,7 @@ from sqlalchemy import (
Table
)
+from aria.storage.api import generate_lower_name
from ..parser.modeling.elements import Element
@@ -62,33 +63,29 @@ class ModelMixin(Element):
return cls
for table_cls in cls._decl_class_registry.values():
- if tablename in (getattr(table_cls, '__name__', None),
- getattr(table_cls, '__tablename__', None)):
+ if tablename == getattr(table_cls, '__tablename__', None):
return table_cls
@classmethod
- def foreign_key(cls, table, nullable=False):
+ def foreign_key(cls, table_name, nullable=False):
"""Return a ForeignKey object with the relevant
:param table: Unique id column in the parent table
:param nullable: Should the column be allowed to remain empty
"""
- table_cls = cls._get_cls_by_tablename(table.__tablename__)
- foreign_key_str = '{tablename}.{unique_id}'.format(tablename=table_cls.__tablename__,
- unique_id=table_cls.id_column_name())
- column = Column(ForeignKey(foreign_key_str, ondelete='CASCADE'),
- nullable=nullable)
- column.__remote_table_name = table_cls.__name__
- return column
+ return Column(Integer,
+ ForeignKey('{tablename}.id'.format(tablename=table_name), ondelete='CASCADE'),
+ nullable=nullable)
@classmethod
- def one_to_one_relationship(cls, table, backreference=None):
- return relationship(table.__name__,
+ def one_to_one_relationship(cls, table_name, backreference=None):
+ return relationship(lambda: cls._get_cls_by_tablename(table_name),
backref=backref(backreference or cls.__tablename__, uselist=False))
@classmethod
def many_to_one_relationship(cls,
- foreign_key_column,
+ parent_table_name,
+ foreign_key_column=None,
backreference=None,
backref_kwargs=None,
**kwargs):
@@ -100,31 +97,27 @@ class ModelMixin(Element):
:param foreign_key_column: The column of the foreign key (from the child table)
:param backreference: The name to give to the reference to the child (on the parent table)
"""
- backref_kwargs = backref_kwargs or {}
- parent_table = cls._get_cls_by_tablename(
- getattr(cls, foreign_key_column).__remote_table_name)
- primaryjoin_str = '{parent_class_name}.{parent_unique_id} == ' \
- '{child_class.__name__}.{foreign_key_column}'\
- .format(
- parent_class_name=parent_table.__name__,
- parent_unique_id=parent_table.id_column_name(),
- child_class=cls,
- foreign_key_column=foreign_key_column
- )
- return relationship(
- parent_table.__name__,
- primaryjoin=primaryjoin_str,
- foreign_keys=[getattr(cls, foreign_key_column)],
- # The following line make sure that when the *parent* is
- # deleted, all its connected children are deleted as well
- backref=backref(backreference or cls.__tablename__, cascade='all', **backref_kwargs),
- **kwargs
- )
+ relationship_kwargs_ = kwargs
+ if foreign_key_column:
+ relationship_kwargs_['foreign_keys'] = [getattr(cls, foreign_key_column)]
+
+ return relationship(lambda: cls._get_cls_by_tablename(parent_table_name),
+ backref=backref(
+ backreference or cls.__tablename__,
+ lazy='dynamic',
+ # The following line make sure that when the *parent* is
+ # deleted, all its connected children are deleted as well
+ cascade='all',
+
+ **backref_kwargs or {}),
+
+ **relationship_kwargs_)
@classmethod
- def one_to_many_relationship(cls, table, backrefernce=None):
- return relationship(table.__name__,
- backref=backrefernce or cls.__tablename__)
+ def one_to_many_relationship(cls, child_table_name, backrefernce=None):
+ return relationship(lambda: cls._get_cls_by_tablename(child_table_name),
+ backref=backrefernce or '{0}s'.format(cls.__tablename__),
+ lazy='dynamic')
@classmethod
def relationship_to_self(cls, local_column):
@@ -137,13 +130,13 @@ class ModelMixin(Element):
remote_side_str=remote_side_str,
cls=cls,
local_column=local_column)
- return relationship(cls.__name__,
+ return relationship(cls._get_cls_by_tablename(cls.__tablename__).__name__,
primaryjoin=primaryjoin_str,
remote_side=remote_side_str,
post_update=True)
@classmethod
- def many_to_many_relationship(cls, other_cls, table_prefix):
+ def many_to_many_relationship(cls, other_table_name, table_prefix):
"""Return a many-to-many SQL relationship object
Notes:
@@ -151,29 +144,18 @@ class ModelMixin(Element):
2. This method creates a new helper table in the DB
:param cls: The class of the table we're connecting from
- :param other_cls: The class of the table we're connecting to
+ :param other_table_name: The class of the table we're connecting to
:param table_prefix: Custom prefix for the helper table name and the
backreference name
"""
current_table_name = cls.__tablename__
current_column_name = '{0}_id'.format(current_table_name)
- current_foreign_key = '{0}.{1}'.format(
- current_table_name,
- cls.id_column_name()
- )
+ current_foreign_key = '{0}.id'.format(current_table_name)
- other_cls = cls._get_cls_by_tablename(other_cls.__tablename__)
- other_table_name = other_cls.__tablename__
other_column_name = '{0}_id'.format(other_table_name)
- other_foreign_key = '{0}.{1}'.format(
- other_table_name,
- other_cls.id_column_name()
- )
+ other_foreign_key = '{0}.id'.format(other_table_name)
- helper_table_name = '{0}_{1}'.format(
- current_table_name,
- other_table_name
- )
+ helper_table_name = '{0}_{1}'.format(current_table_name, other_table_name)
backref_name = current_table_name
if table_prefix:
@@ -188,8 +170,9 @@ class ModelMixin(Element):
current_foreign_key,
other_foreign_key
)
+
return relationship(
- other_cls,
+ lambda: cls._get_cls_by_tablename(other_table_name),
secondary=secondary_table,
backref=backref(backref_name)
)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9c6c378c/tests/mock/models.py
----------------------------------------------------------------------
diff --git a/tests/mock/models.py b/tests/mock/models.py
index 87fa352..e5f29ff 100644
--- a/tests/mock/models.py
+++ b/tests/mock/models.py
@@ -35,11 +35,6 @@ RELATIONSHIP_INSTANCE_NAME = 'relationship_instance'
def get_dependency_node(deployment):
- operation_templates = [models.OperationTemplate(implementation=op,
- service_template=deployment.service_template)
- for op in operations.NODE_OPERATIONS]
- interface_template = models.InterfaceTemplate(operation_templates=operation_templates)
-
return models.NodeTemplate(
name=DEPENDENCY_NODE_NAME,
type_name='test_node_type',
@@ -48,7 +43,7 @@ def get_dependency_node(deployment):
min_instances=1,
max_instances=1,
service_template=deployment.service_template,
- interface_templates=[interface_template],
+ # interface_templates=[get_interface_template(op) for op in operations.NODE_OPERATIONS],
)
@@ -162,3 +157,29 @@ def get_plugin(package_name='package', package_version='0.1'):
uploaded_at=datetime.now(),
wheels=[],
)
+
+
+def get_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=[operation_template],
+ name=operation_name.rsplit('.', 1)[0],
+ **(interface_kwargs or {})
+ )
+
+
+def get_interface(operation_name, operation_kwargs=None, interface_kwargs=None):
+ operation = models.Operation(
+ name=operation_name,
+ **(operation_kwargs or {})
+ )
+
+ return models.Interface(
+ operations=[operation],
+ name=operation_name.rsplit('.', 1)[0],
+ **(interface_kwargs or {})
+ )
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9c6c378c/tests/orchestrator/workflows/api/test_task.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/workflows/api/test_task.py b/tests/orchestrator/workflows/api/test_task.py
index 198e461..2393af4 100644
--- a/tests/orchestrator/workflows/api/test_task.py
+++ b/tests/orchestrator/workflows/api/test_task.py
@@ -18,6 +18,7 @@ import pytest
from aria.orchestrator import context
from aria.orchestrator.workflows import api
+from aria.modeling import models
from tests import mock, storage
@@ -39,16 +40,19 @@ class TestOperationTask(object):
def test_node_operation_task_creation(self, ctx):
operation_name = 'aria.interfaces.lifecycle.create'
- op_details = {'operation': True, 'plugin': 'plugin'}
+ interface_template = mock.models.get_interface_template(
+ operation_name,
+ operation_kwargs=dict(plugin='plugin', operation=True))
+
node = ctx.model.node_template.get_by_name(mock.models.DEPENDENT_NODE_NAME)
- node.operations[operation_name] = op_details
+ node.interface_templates = [interface_template]
node.plugins = [{'name': 'plugin',
'package_name': 'package',
'package_version': '0.1'}]
ctx.model.node_template.update(node)
node_instance = \
ctx.model.node.get_by_name(mock.models.DEPENDENT_NODE_INSTANCE_NAME)
- inputs = {'inputs': True}
+ inputs = [models.Parameter(type_name='Boolean', value=True)]
max_attempts = 10
retry_interval = 10
ignore_failure = True
@@ -75,14 +79,18 @@ class TestOperationTask(object):
def test_source_relationship_operation_task_creation(self, ctx):
operation_name = 'aria.interfaces.relationship_lifecycle.preconfigure'
- op_details = {'operation': True, 'plugin': 'plugin'}
+
+ interface = mock.models.get_interface(
+ operation_name,
+ operation_kwargs=dict(operation=True, plugin='plugin'))
+
relationship = ctx.model.relationship.list()[0]
- relationship.source_operations[operation_name] = op_details
+ relationship.source_interfaces = [interface]
relationship.source_node.plugins = [{'name': 'plugin',
'package_name': 'package',
'package_version': '0.1'}]
relationship_instance = ctx.model.relationship_instance.list()[0]
- inputs = {'inputs': True}
+ input = models.Parameter(type_name='Boolean', value=True)
max_attempts = 10
retry_interval = 10
@@ -91,7 +99,7 @@ class TestOperationTask(object):
name=operation_name,
instance=relationship_instance,
operation_end=api.task.OperationTask.SOURCE_OPERATION,
- inputs=inputs,
+ inputs=[input],
max_attempts=max_attempts,
retry_interval=retry_interval)
@@ -138,7 +146,7 @@ class TestOperationTask(object):
'package_version': '0.1'}
def test_operation_task_default_values(self, ctx):
- dependency_node_instance = ctx.model.node_instance.get_by_name(
+ dependency_node_instance = ctx.model.node.get_by_name(
mock.models.DEPENDENCY_NODE_INSTANCE_NAME)
with context.workflow.current.push(ctx):
task = api.task.OperationTask(
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9c6c378c/tests/storage/__init__.py
----------------------------------------------------------------------
diff --git a/tests/storage/__init__.py b/tests/storage/__init__.py
index 1c8b41b..acdfc8a 100644
--- a/tests/storage/__init__.py
+++ b/tests/storage/__init__.py
@@ -17,7 +17,7 @@ import platform
from tempfile import mkdtemp
from shutil import rmtree
-from aria.storage import model
+from aria.modeling import models
from sqlalchemy import (
create_engine,
orm)
@@ -34,9 +34,9 @@ class TestFileSystem(object):
rmtree(self.path, ignore_errors=True)
-def get_sqlite_api_kwargs(base_dir=None,
- filename='db.sqlite',
- declarative_base=model.DeclarativeBase):
+def get_sqlite_api_kwargs(declarative_base=models.DB,
+ base_dir=None,
+ filename='db.sqlite'):
"""
Create sql params. works in in-memory and in filesystem mode.
If base_dir is passed, the mode will be filesystem mode. while the default mode is in-memory.
@@ -61,7 +61,8 @@ def get_sqlite_api_kwargs(base_dir=None,
session_factory = orm.sessionmaker(bind=engine)
session = scoped_session(session_factory=session_factory) if base_dir else session_factory()
- declarative_base.metadata.create_all(bind=engine)
+ if declarative_base:
+ declarative_base.metadata.create_all(bind=engine)
return dict(engine=engine, session=session)
@@ -78,4 +79,4 @@ def release_sqlite_storage(storage):
session.rollback()
session.close()
for engine in set(mapi._engine for mapi in mapis):
- model.DeclarativeBase.metadata.drop_all(engine)
+ models.DB.metadata.drop_all(engine)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9c6c378c/tests/storage/test_model_storage.py
----------------------------------------------------------------------
diff --git a/tests/storage/test_model_storage.py b/tests/storage/test_model_storage.py
index d9b7329..b96c2b2 100644
--- a/tests/storage/test_model_storage.py
+++ b/tests/storage/test_model_storage.py
@@ -25,6 +25,7 @@ from aria.storage import (
structure,
type as aria_type,
)
+from aria import modeling
from aria import application_model_storage
from ..storage import get_sqlite_api_kwargs, release_sqlite_storage
from ..mock import (
@@ -34,7 +35,7 @@ from ..mock import (
)
-class MockModel(model.DeclarativeBase, structure.ModelMixin): #pylint: disable=abstract-method
+class MockModel(modeling.models.DB, structure.ModelMixin): #pylint: disable=abstract-method
__tablename__ = 'mock_models'
model_dict = Column(aria_type.Dict)
model_list = Column(aria_type.List)
@@ -57,7 +58,7 @@ def context():
@pytest.fixture(scope='module', autouse=True)
def module_cleanup():
- model.DeclarativeBase.metadata.remove(MockModel.__table__) #pylint: disable=no-member
+ modeling.models.DB.metadata.remove(MockModel.__table__) #pylint: disable=no-member
def test_storage_base(storage):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9c6c378c/tests/storage/test_new_modelling.py
----------------------------------------------------------------------
diff --git a/tests/storage/test_new_modelling.py b/tests/storage/test_new_modelling.py
index ff96d3d..477144b 100644
--- a/tests/storage/test_new_modelling.py
+++ b/tests/storage/test_new_modelling.py
@@ -14,8 +14,6 @@ from ..storage import (
release_sqlite_storage
)
-DB = declarative_base(cls=structure.ModelIDMixin)
-
tosca_classes = [
models.Parameter,
@@ -59,7 +57,7 @@ tosca_classes = [
@pytest.fixture
def storage():
base_storage = ModelStorage(sql_mapi.SQLAlchemyModelAPI,
- api_kwargs=get_sqlite_api_kwargs(declarative_base=DB),
+ api_kwargs=get_sqlite_api_kwargs(),
items=tosca_classes)
yield base_storage
release_sqlite_storage(base_storage)
@@ -71,5 +69,5 @@ def test_models_creation(storage):
:param storage:
:return:
"""
- for cls in tosca_classes:
- assert len(getattr(storage, api.generate_lower_name(cls)).list()) == 0
+ for cls in storage.registered.values():
+ assert len(cls.list()) == 0