blob: b533a8822859c66c2a32917ff96e4ef1f8b0a05d [file] [log] [blame]
# 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 modeling service common module
"""
# pylint: disable=no-self-argument, no-member, abstract-method
from sqlalchemy import (
Column,
Text,
)
from sqlalchemy.ext.declarative import declared_attr
from ..parser.consumption import ConsumptionContext
from ..utils import (
collections,
formatting,
console,
)
from .mixins import InstanceModelMixin, TemplateModelMixin, ParameterMixin
from . import relationship
class OutputBase(ParameterMixin):
"""
Output parameter or declaration for an output parameter.
"""
__tablename__ = 'output'
# region many_to_one relationships
@declared_attr
def service_template(cls):
"""
Containing service template (can be ``None``).
:type: :class:`ServiceTemplate`
"""
return relationship.many_to_one(cls, 'service_template')
@declared_attr
def service(cls):
"""
Containing service (can be ``None``).
:type: :class:`ServiceTemplate`
"""
return relationship.many_to_one(cls, 'service')
# endregion
# region foreign keys
@declared_attr
def service_template_fk(cls):
return relationship.foreign_key('service_template', nullable=True)
@declared_attr
def service_fk(cls):
return relationship.foreign_key('service', nullable=True)
# endregion
class InputBase(ParameterMixin):
"""
Input parameter or declaration for an input parameter.
"""
__tablename__ = 'input'
# region many_to_one relationships
@declared_attr
def service_template(cls):
"""
Containing service template (can be ``None``).
:type: :class:`ServiceTemplate`
"""
return relationship.many_to_one(cls, 'service_template')
@declared_attr
def service(cls):
"""
Containing service (can be ``None``).
:type: :class:`Service`
"""
return relationship.many_to_one(cls, 'service')
@declared_attr
def interface(cls):
"""
Containing interface (can be ``None``).
:type: :class:`Interface`
"""
return relationship.many_to_one(cls, 'interface')
@declared_attr
def operation(cls):
"""
Containing operation (can be ``None``).
:type: :class:`Operation`
"""
return relationship.many_to_one(cls, 'operation')
@declared_attr
def interface_template(cls):
"""
Containing interface template (can be ``None``).
:type: :class:`InterfaceTemplate`
"""
return relationship.many_to_one(cls, 'interface_template')
@declared_attr
def operation_template(cls):
"""
Containing operation template (can be ``None``).
:type: :class:`OperationTemplate`
"""
return relationship.many_to_one(cls, 'operation_template')
@declared_attr
def execution(cls):
"""
Containing execution (can be ``None``).
:type: :class:`Execution`
"""
return relationship.many_to_one(cls, 'execution')
# endregion
# region foreign keys
@declared_attr
def service_template_fk(cls):
return relationship.foreign_key('service_template', nullable=True)
@declared_attr
def service_fk(cls):
return relationship.foreign_key('service', nullable=True)
@declared_attr
def interface_fk(cls):
return relationship.foreign_key('interface', nullable=True)
@declared_attr
def operation_fk(cls):
return relationship.foreign_key('operation', nullable=True)
@declared_attr
def interface_template_fk(cls):
return relationship.foreign_key('interface_template', nullable=True)
@declared_attr
def operation_template_fk(cls):
return relationship.foreign_key('operation_template', nullable=True)
@declared_attr
def execution_fk(cls):
return relationship.foreign_key('execution', nullable=True)
@declared_attr
def task_fk(cls):
return relationship.foreign_key('task', nullable=True)
# endregion
class ConfigurationBase(ParameterMixin):
"""
Configuration parameter.
"""
__tablename__ = 'configuration'
# region many_to_one relationships
@declared_attr
def operation_template(cls):
"""
Containing operation template (can be ``None``).
:type: :class:`OperationTemplate`
"""
return relationship.many_to_one(cls, 'operation_template')
@declared_attr
def operation(cls):
"""
Containing operation (can be ``None``).
:type: :class:`Operation`
"""
return relationship.many_to_one(cls, 'operation')
# endregion
# region foreign keys
@declared_attr
def operation_template_fk(cls):
return relationship.foreign_key('operation_template', nullable=True)
@declared_attr
def operation_fk(cls):
return relationship.foreign_key('operation', nullable=True)
# endregion
class PropertyBase(ParameterMixin):
"""
Property parameter or declaration for a property parameter.
"""
__tablename__ = 'property'
# region many_to_one relationships
@declared_attr
def node_template(cls):
"""
Containing node template (can be ``None``).
:type: :class:`NodeTemplate`
"""
return relationship.many_to_one(cls, 'node_template')
@declared_attr
def group_template(cls):
"""
Containing group template (can be ``None``).
:type: :class:`GroupTemplate`
"""
return relationship.many_to_one(cls, 'group_template')
@declared_attr
def policy_template(cls):
"""
Containing policy template (can be ``None``).
:type: :class:`PolicyTemplate`
"""
return relationship.many_to_one(cls, 'policy_template')
@declared_attr
def relationship_template(cls):
"""
Containing relationship template (can be ``None``).
:type: :class:`RelationshipTemplate`
"""
return relationship.many_to_one(cls, 'relationship_template')
@declared_attr
def capability_template(cls):
"""
Containing capability template (can be ``None``).
:type: :class:`CapabilityTemplate`
"""
return relationship.many_to_one(cls, 'capability_template')
@declared_attr
def artifact_template(cls):
"""
Containing artifact template (can be ``None``).
:type: :class:`ArtifactTemplate`
"""
return relationship.many_to_one(cls, 'artifact_template')
@declared_attr
def node(cls):
"""
Containing node (can be ``None``).
:type: :class:`Node`
"""
return relationship.many_to_one(cls, 'node')
@declared_attr
def group(cls):
"""
Containing group (can be ``None``).
:type: :class:`Group`
"""
return relationship.many_to_one(cls, 'group')
@declared_attr
def policy(cls):
"""
Containing policy (can be ``None``).
:type: :class:`Policy`
"""
return relationship.many_to_one(cls, 'policy')
@declared_attr
def relationship(cls):
"""
Containing relationship (can be ``None``).
:type: :class:`Relationship`
"""
return relationship.many_to_one(cls, 'relationship')
@declared_attr
def capability(cls):
"""
Containing capability (can be ``None``).
:type: :class:`Capability`
"""
return relationship.many_to_one(cls, 'capability')
@declared_attr
def artifact(cls):
"""
Containing artifact (can be ``None``).
:type: :class:`Artifact`
"""
return relationship.many_to_one(cls, 'artifact')
# endregion
# region foreign keys
@declared_attr
def node_template_fk(cls):
return relationship.foreign_key('node_template', nullable=True)
@declared_attr
def group_template_fk(cls):
return relationship.foreign_key('group_template', nullable=True)
@declared_attr
def policy_template_fk(cls):
return relationship.foreign_key('policy_template', nullable=True)
@declared_attr
def relationship_template_fk(cls):
return relationship.foreign_key('relationship_template', nullable=True)
@declared_attr
def capability_template_fk(cls):
return relationship.foreign_key('capability_template', nullable=True)
@declared_attr
def artifact_template_fk(cls):
return relationship.foreign_key('artifact_template', nullable=True)
@declared_attr
def node_fk(cls):
return relationship.foreign_key('node', nullable=True)
@declared_attr
def group_fk(cls):
return relationship.foreign_key('group', nullable=True)
@declared_attr
def policy_fk(cls):
return relationship.foreign_key('policy', nullable=True)
@declared_attr
def relationship_fk(cls):
return relationship.foreign_key('relationship', nullable=True)
@declared_attr
def capability_fk(cls):
return relationship.foreign_key('capability', nullable=True)
@declared_attr
def artifact_fk(cls):
return relationship.foreign_key('artifact', nullable=True)
# endregion
class AttributeBase(ParameterMixin):
"""
Attribute parameter or declaration for an attribute parameter.
"""
__tablename__ = 'attribute'
# region many_to_one relationships
@declared_attr
def node_template(cls):
"""
Containing node template (can be ``None``).
:type: :class:`NodeTemplate`
"""
return relationship.many_to_one(cls, 'node_template')
@declared_attr
def node(cls):
"""
Containing node (can be ``None``).
:type: :class:`Node`
"""
return relationship.many_to_one(cls, 'node')
# endregion
# region foreign keys
@declared_attr
def node_template_fk(cls):
"""For Attribute many-to-one to NodeTemplate"""
return relationship.foreign_key('node_template', nullable=True)
@declared_attr
def node_fk(cls):
"""For Attribute many-to-one to Node"""
return relationship.foreign_key('node', nullable=True)
# endregion
class TypeBase(InstanceModelMixin):
"""
Type and its children. Can serve as the root for a type hierarchy.
"""
__tablename__ = 'type'
__private_fields__ = ('parent_type_fk',)
variant = Column(Text, nullable=False)
description = Column(Text, doc="""
Human-readable description.
:type: :obj:`basestring`
""")
_role = Column(Text, name='role')
# region one_to_one relationships
@declared_attr
def parent(cls):
"""
Parent type (will be ``None`` for the root of a type hierarchy).
:type: :class:`Type`
"""
return relationship.one_to_one_self(cls, 'parent_type_fk')
# endregion
# region one_to_many relationships
@declared_attr
def children(cls):
"""
Children.
:type: [:class:`Type`]
"""
return relationship.one_to_many(cls, other_fk='parent_type_fk', self=True)
# endregion
# region foreign keys
@declared_attr
def parent_type_fk(cls):
"""For Type one-to-many to Type"""
return relationship.foreign_key('type', nullable=True)
# endregion
@property
def role(self):
def get_role(the_type):
if the_type is None:
return None
elif the_type._role is None:
return get_role(the_type.parent)
return the_type._role
return get_role(self)
@role.setter
def role(self, value):
self._role = value
def is_descendant(self, base_name, name):
base = self.get_descendant(base_name)
if base is not None:
if base.get_descendant(name) is not None:
return True
return False
def get_descendant(self, name):
if self.name == name:
return self
for child in self.children:
found = child.get_descendant(name)
if found is not None:
return found
return None
def iter_descendants(self):
for child in self.children:
yield child
for descendant in child.iter_descendants():
yield descendant
@property
def as_raw(self):
return collections.OrderedDict((
('name', self.name),
('description', self.description),
('role', self.role)))
@property
def as_raw_all(self):
types = []
self._append_raw_children(types)
return types
def coerce_values(self, report_issues):
pass
def dump(self):
context = ConsumptionContext.get_thread_local()
if self.name:
console.puts(context.style.type(self.name))
with context.style.indent:
for child in self.children:
child.dump()
def _append_raw_children(self, types):
for child in self.children:
raw_child = formatting.as_raw(child)
raw_child['parent'] = self.name
types.append(raw_child)
child._append_raw_children(types)
@property
def hierarchy(self):
"""
Type hierarchy as a list beginning with this type and ending in the root.
:type: [:class:`Type`]
"""
return [self] + (self.parent.hierarchy if self.parent else [])
class MetadataBase(TemplateModelMixin):
"""
Custom values associated with the service.
This model is used by both service template and service instance elements.
:ivar name: name
:vartype name: basestring
:ivar value: value
:vartype value: basestring
"""
__tablename__ = 'metadata'
value = Column(Text)
@property
def as_raw(self):
return collections.OrderedDict((
('name', self.name),
('value', self.value)))
def coerce_values(self, report_issues):
pass
def instantiate(self, container):
from . import models
return models.Metadata(name=self.name,
value=self.value)
def dump(self):
context = ConsumptionContext.get_thread_local()
console.puts('{0}: {1}'.format(
context.style.property(self.name),
context.style.literal(self.value)))