1 # Licensed to the Apache Software Foundation (ASF) under one or more
2 # contributor license agreements. See the NOTICE file distributed with
3 # this work for additional information regarding copyright ownership.
4 # The ASF licenses this file to You under the Apache License, Version 2.0
5 # (the "License"); you may not use this file except in compliance with
6 # the License. You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
17 ARIA modeling service changes module
20 # pylint: disable=no-self-argument, no-member, abstract-method
22 from collections import namedtuple
24 from sqlalchemy import (
30 from sqlalchemy.ext.declarative import declared_attr
32 from .types import (List, Dict)
33 from .mixins import ModelMixin
34 from . import relationship
37 class ServiceUpdateBase(ModelMixin):
39 Deployment update model representation.
41 __tablename__ = 'service_update'
43 __private_fields__ = ('service_fk',
46 created_at = Column(DateTime, nullable=False, index=True)
47 service_plan = Column(Dict, nullable=False)
48 service_update_nodes = Column(Dict)
49 service_update_service = Column(Dict)
50 service_update_node_templates = Column(List)
51 modified_entity_ids = Column(Dict)
54 # region association proxies
57 def execution_name(cls):
58 return relationship.association_proxy('execution', cls.name_column_name())
61 def service_name(cls):
62 return relationship.association_proxy('service', cls.name_column_name())
66 # region one_to_one relationships
70 # region one_to_many relationships
74 return relationship.one_to_many(cls, 'service_update_step')
78 # region many_to_one relationships
82 return relationship.one_to_one(cls, 'execution', back_populates=relationship.NO_BACK_POP)
86 return relationship.many_to_one(cls, 'service', back_populates='updates')
93 def execution_fk(cls):
94 return relationship.foreign_key('execution', nullable=True)
98 return relationship.foreign_key('service')
102 def to_dict(self, suppress_error=False, **kwargs):
103 dep_update_dict = super(ServiceUpdateBase, self).to_dict(suppress_error) #pylint: disable=no-member
104 # Taking care of the fact the DeploymentSteps are _BaseModels
105 dep_update_dict['steps'] = [step.to_dict() for step in self.steps]
106 return dep_update_dict
109 class ServiceUpdateStepBase(ModelMixin):
111 Deployment update step model representation.
114 __tablename__ = 'service_update_step'
116 __private_fields__ = ('service_update_fk',)
118 _action_types = namedtuple('ACTION_TYPES', 'ADD, REMOVE, MODIFY')
119 ACTION_TYPES = _action_types(ADD='add', REMOVE='remove', MODIFY='modify')
121 _entity_types = namedtuple(
123 'NODE, RELATIONSHIP, PROPERTY, OPERATION, WORKFLOW, OUTPUT, DESCRIPTION, GROUP, PLUGIN')
124 ENTITY_TYPES = _entity_types(
126 RELATIONSHIP='relationship',
128 OPERATION='operation',
131 DESCRIPTION='description',
136 action = Column(Enum(*ACTION_TYPES, name='action_type'), nullable=False)
137 entity_id = Column(Text, nullable=False)
138 entity_type = Column(Enum(*ENTITY_TYPES, name='entity_type'), nullable=False)
140 # region association proxies
143 def service_update_name(cls):
144 return relationship.association_proxy('service_update', cls.name_column_name())
148 # region one_to_one relationships
152 # region one_to_many relationships
156 # region many_to_one relationships
159 def service_update(cls):
160 return relationship.many_to_one(cls, 'service_update', back_populates='steps')
164 # region foreign keys
167 def service_update_fk(cls):
168 return relationship.foreign_key('service_update')
173 return hash((getattr(self, self.id_column_name()), self.entity_id))
175 def __lt__(self, other):
177 the order is 'remove' < 'modify' < 'add'
181 if not isinstance(other, self.__class__):
182 return not self >= other
184 if self.action != other.action:
185 if self.action == 'remove':
187 elif self.action == 'add':
190 return_value = other.action == 'add'
193 if self.action == 'add':
194 return self.entity_type == 'node' and other.entity_type == 'relationship'
195 if self.action == 'remove':
196 return self.entity_type == 'relationship' and other.entity_type == 'node'
200 class ServiceModificationBase(ModelMixin):
202 Deployment modification model representation.
205 __tablename__ = 'service_modification'
207 __private_fields__ = ('service_fk',)
210 FINISHED = 'finished'
211 ROLLEDBACK = 'rolledback'
213 STATES = [STARTED, FINISHED, ROLLEDBACK]
214 END_STATES = [FINISHED, ROLLEDBACK]
216 context = Column(Dict)
217 created_at = Column(DateTime, nullable=False, index=True)
218 ended_at = Column(DateTime, index=True)
219 modified_node_templates = Column(Dict)
221 status = Column(Enum(*STATES, name='service_modification_status'))
223 # region association proxies
226 def service_name(cls):
227 return relationship.association_proxy('service', cls.name_column_name())
231 # region one_to_one relationships
235 # region one_to_many relationships
239 # region many_to_one relationships
243 return relationship.many_to_one(cls, 'service', back_populates='modifications')
247 # region foreign keys
251 return relationship.foreign_key('service')