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.
16 from aria.utils.collections import FrozenDict
17 from aria.utils.caching import cachedmethod
18 from aria.parser import implements_specification
19 from aria.parser.presentation import (has_fields, short_form_field, allow_unknown_fields,
20 primitive_field, primitive_list_field, object_field,
21 object_list_field, object_dict_field,
22 object_dict_unknown_fields, field_validator,
23 field_getter, type_validator, list_type_validator)
25 from .data_types import Range
26 from .misc import (Description, ConstraintClause, OperationImplementation, EntrySchema)
27 from .presentation.extensible import ExtensiblePresentation
28 from .presentation.field_getters import data_type_class_getter
29 from .presentation.field_validators import (data_type_validator, data_value_validator,
30 entry_schema_validator)
31 from .presentation.types import (convert_name_to_full_type_name, get_type_by_name)
32 from .modeling.data_types import get_data_type, get_property_constraints
33 from .modeling.interfaces import (get_and_override_input_definitions_from_type,
34 get_and_override_operation_definitions_from_type)
38 @implements_specification('3.5.8', 'tosca-simple-1.0')
39 class PropertyDefinition(ExtensiblePresentation):
41 A property definition defines a named, typed value and related data that can be associated with
42 an entity defined in this specification (e.g., Node Types, Relationship Types, Capability Types,
43 etc.). Properties are used by template authors to provide input values to TOSCA entities which
44 indicate their "desired state" when they are instantiated. The value of a property can be
45 retrieved using the ``get_property`` function within TOSCA Service Templates.
47 See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
48 /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
49 #DEFN_ELEMENT_PROPERTY_DEFN>`__
52 @field_validator(data_type_validator())
53 @primitive_field(str, required=True)
56 The required data type for the property.
58 :type: :obj:`basestring`
61 @object_field(Description)
62 def description(self):
64 The optional description for the property.
66 :type: :class:`Description`
69 @primitive_field(bool, default=True)
72 An optional key that declares a property as required (true) or not (false).
77 @field_validator(data_value_validator)
81 An optional key that may provide a value to be used as a default if not provided by another
84 :type: :obj:`basestring`
87 @primitive_field(str, default='supported', allowed=('supported', 'unsupported', 'experimental',
89 @implements_specification(section='3.5.8.3', spec='tosca-simple-1.0')
92 The optional status of the property relative to the specification or implementation.
94 :type: :obj:`basestring`
97 @object_list_field(ConstraintClause)
98 def constraints(self):
100 The optional list of sequenced constraint clauses for the property.
102 :type: list of (str, :class:`ConstraintClause`)
105 @field_validator(entry_schema_validator)
106 @object_field(EntrySchema)
107 def entry_schema(self):
109 The optional key that is used to declare the name of the Datatype definition for entries of
110 set types such as the TOSCA list or map.
112 :type: :obj:`basestring`
116 def _get_type(self, context):
117 return get_data_type(context, self, 'type')
120 def _get_constraints(self, context):
121 return get_property_constraints(context, self)
125 @implements_specification('3.5.10', 'tosca-simple-1.0')
126 class AttributeDefinition(ExtensiblePresentation):
128 An attribute definition defines a named, typed value that can be associated with an entity
129 defined in this specification (e.g., a Node, Relationship or Capability Type). Specifically, it
130 is used to expose the "actual state" of some property of a TOSCA entity after it has been
131 deployed and instantiated (as set by the TOSCA orchestrator). Attribute values can be retrieved
132 via the ``get_attribute`` function from the instance model and used as values to other
133 entities within TOSCA Service Templates.
135 See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
136 /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
137 #DEFN_ELEMENT_ATTRIBUTE_DEFN>`__
140 @field_validator(data_type_validator())
141 @primitive_field(str, required=True)
144 The required data type for the attribute.
146 :type: :obj:`basestring`
149 @object_field(Description)
150 def description(self):
152 The optional description for the attribute.
154 :type: :class:`Description`
157 @field_validator(data_value_validator)
161 An optional key that may provide a value to be used as a default if not provided by another
164 This value SHALL be type compatible with the type declared by the property definition's type
167 :type: :obj:`basestring`
170 @primitive_field(str, default='supported', allowed=('supported', 'unsupported', 'experimental',
174 The optional status of the attribute relative to the specification or implementation.
176 :type: :obj:`basestring`
179 @field_validator(entry_schema_validator)
180 @object_field(EntrySchema)
181 def entry_schema(self):
183 The optional key that is used to declare the name of the Datatype definition for entries of
184 set types such as the TOSCA list or map.
186 :type: :obj:`basestring`
190 def _get_type(self, context):
191 return get_data_type(context, self, 'type')
195 @implements_specification('3.5.12', 'tosca-simple-1.0')
196 class ParameterDefinition(PropertyDefinition):
198 A parameter definition is essentially a TOSCA property definition; however, it also allows a
199 value to be assigned to it (as for a TOSCA property assignment). In addition, in the case of
200 output parameters, it can optionally inherit the data type of the value assigned to it rather
201 than have an explicit data type defined for it.
203 See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
204 /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
205 #DEFN_ELEMENT_PARAMETER_DEF>`__
208 @field_validator(data_type_validator())
209 @primitive_field(str)
212 The required data type for the parameter.
214 Note: This keyname is required for a TOSCA Property definition, but is not for a TOSCA
215 Parameter definition.
217 :type: :obj:`basestring`
220 @field_validator(data_value_validator)
224 The type-compatible value to assign to the named parameter. Parameter values may be provided
225 as the result from the evaluation of an expression or a function.
229 @short_form_field('implementation')
231 @implements_specification('3.5.13-1', 'tosca-simple-1.0')
232 class OperationDefinition(ExtensiblePresentation):
234 An operation definition defines a named function or procedure that can be bound to an
235 implementation artifact (e.g., a script).
237 See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
238 /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
239 #DEFN_ELEMENT_OPERATION_DEF>`__
242 @object_field(Description)
243 def description(self):
245 The optional description string for the associated named operation.
247 :type: :class:`Description`
250 @object_field(OperationImplementation)
251 def implementation(self):
253 The optional implementation artifact name (e.g., a script file name within a TOSCA CSAR
256 :type: :class:`OperationImplementation`
259 @object_dict_field(PropertyDefinition)
262 The optional list of input property definitions available to all defined operations for
263 interface definitions that are within TOSCA Node or Relationship Type definitions. This
264 includes when interface definitions are included as part of a Requirement definition in a
267 :type: {:obj:`basestring`: :class:`PropertyDefinition`}
271 @allow_unknown_fields
273 @implements_specification('3.5.14-1', 'tosca-simple-1.0')
274 class InterfaceDefinition(ExtensiblePresentation):
276 An interface definition defines a named interface that can be associated with a Node or
279 See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
280 /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
281 #DEFN_ELEMENT_INTERFACE_DEF>`__
284 @field_validator(type_validator('interface type', convert_name_to_full_type_name,
286 @primitive_field(str)
289 ARIA NOTE: This field is not mentioned in the spec, but is implied.
291 :type: :obj:`basestring`
294 @object_dict_field(PropertyDefinition)
297 The optional list of input property definitions available to all defined operations for
298 interface definitions that are within TOSCA Node or Relationship Type definitions. This
299 includes when interface definitions are included as part of a Requirement definition in a
302 :type: {:obj:`basestring`: :class:`PropertyDefinition`}
305 @object_dict_unknown_fields(OperationDefinition)
306 def operations(self):
308 :type: {:obj:`basestring`: :class:`OperationDefinition`}
312 def _get_type(self, context):
313 return get_type_by_name(context, self.type, 'interface_types')
316 def _get_inputs(self, context):
317 return FrozenDict(get_and_override_input_definitions_from_type(context, self))
320 def _get_operations(self, context):
321 return FrozenDict(get_and_override_operation_definitions_from_type(context, self))
323 def _validate(self, context):
324 super(InterfaceDefinition, self)._validate(context)
326 for operation in self.operations.itervalues(): # pylint: disable=no-member
327 operation._validate(context)
330 @short_form_field('type')
332 class RelationshipDefinition(ExtensiblePresentation):
334 Relationship definition.
337 @field_validator(type_validator('relationship type', convert_name_to_full_type_name,
338 'relationship_types'))
339 @primitive_field(str, required=True)
342 The optional reserved keyname used to provide the name of the Relationship Type for the
343 requirement definition's relationship keyname.
345 :type: :obj:`basestring`
348 @object_dict_field(InterfaceDefinition)
349 def interfaces(self):
351 The optional reserved keyname used to reference declared (named) interface definitions of
352 the corresponding Relationship Type in order to declare additional Property definitions for
353 these interfaces or operations of these interfaces.
355 :type: list of :class:`InterfaceDefinition`
359 def _get_type(self, context):
360 return get_type_by_name(context, self.type, 'relationship_types')
364 @short_form_field('capability')
366 @implements_specification('3.6.2', 'tosca-simple-1.0')
367 class RequirementDefinition(ExtensiblePresentation):
369 The Requirement definition describes a named requirement (dependencies) of a TOSCA Node Type or
370 Node template which needs to be fulfilled by a matching Capability definition declared by
371 another TOSCA modelable entity. The requirement definition may itself include the specific name
372 of the fulfilling entity (explicitly) or provide an abstract type, along with additional
373 filtering characteristics, that a TOSCA orchestrator can use to fulfill the capability at
374 runtime (implicitly).
376 See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
377 /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
378 #DEFN_ELEMENT_REQUIREMENT_DEF>`__
381 @field_validator(type_validator('capability type', convert_name_to_full_type_name,
383 @primitive_field(str, required=True)
384 def capability(self):
386 The required reserved keyname used that can be used to provide the name of a valid
387 Capability Type that can fulfill the requirement.
389 :type: :obj:`basestring`
392 @field_validator(type_validator('node type', convert_name_to_full_type_name,
394 @primitive_field(str)
397 The optional reserved keyname used to provide the name of a valid Node Type that contains
398 the capability definition that can be used to fulfill the requirement.
400 :type: :obj:`basestring`
403 @object_field(RelationshipDefinition)
404 def relationship(self):
406 The optional reserved keyname used to provide the name of a valid Relationship Type to
407 construct when fulfilling the requirement.
409 :type: :class:`RelationshipDefinition`
412 @field_getter(data_type_class_getter(Range))
414 def occurrences(self):
416 The optional minimum and maximum occurrences for the requirement.
418 Note: the keyword UNBOUNDED is also supported to represent any positive integer.
420 :type: :class:`Range`
424 def _get_capability_type(self, context):
425 return get_type_by_name(context, self.capability, 'capability_types')
428 def _get_node_type(self, context):
429 return context.presentation.get_from_dict('service_template', 'node_types', self.node)
432 @short_form_field('type')
434 @implements_specification('3.6.1', 'tosca-simple-1.0')
435 class CapabilityDefinition(ExtensiblePresentation):
437 A capability definition defines a named, typed set of data that can be associated with Node Type
438 or Node Template to describe a transparent capability or feature of the software component the
441 See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
442 /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
443 #DEFN_ELEMENT_CAPABILITY_DEFN>`__
446 @field_validator(type_validator('capability type', convert_name_to_full_type_name,
448 @primitive_field(str, required=True)
451 The required name of the Capability Type the capability definition is based upon.
453 :type: :obj:`basestring`
456 @object_field(Description)
457 def description(self):
459 The optional description of the Capability definition.
461 :type: :class:`Description`
464 @object_dict_field(PropertyDefinition)
465 def properties(self):
467 An optional list of property definitions for the Capability definition.
469 :type: {:obj:`basestring`: :class:`PropertyDefinition`}
472 @object_dict_field(AttributeDefinition)
473 def attributes(self):
475 An optional list of attribute definitions for the Capability definition.
477 :type: {:obj:`basestring`: :class:`AttributeDefinition`}
480 @field_validator(list_type_validator('node type', convert_name_to_full_type_name,
482 @primitive_list_field(str)
483 def valid_source_types(self):
485 An optional list of one or more valid names of Node Types that are supported as valid
486 sources of any relationship established to the declared Capability Type.
488 :type: [:obj:`basestring`]
491 @field_getter(data_type_class_getter(Range))
493 def occurrences(self):
495 The optional minimum and maximum occurrences for the capability. By default, an exported
496 Capability should allow at least one relationship to be formed with it with a maximum of
497 ``UNBOUNDED`` relationships.
499 Note: the keyword ``UNBOUNDED`` is also supported to represent any positive integer.
501 ARIA NOTE: The spec seems wrong here: the implied default should be ``[0,UNBOUNDED]``, not
502 ``[1,UNBOUNDED]``, otherwise it would imply that at 1 least one relationship *must* be
505 :type: :class:`Range`
509 def _get_type(self, context):
510 return get_type_by_name(context, self.type, 'capability_types')
513 def _get_parent(self, context):
514 container_parent = self._container._get_parent(context)
515 container_parent_capabilities = container_parent._get_capabilities(context) \
516 if container_parent is not None else None
517 return container_parent_capabilities.get(self._name) \
518 if container_parent_capabilities is not None else None