Пример #1
0
class NodeType(Presentation):
    """
    :code:`node_types` are used for defining common properties and behaviors for :code:`node_templates`. :code:`node_templates` can then be created based on these types, inheriting their definitions.

    See the `Cloudify DSL v1.3 specification <http://docs.getcloudify.org/3.4.0/blueprints/spec-node-types/>`__
    """
    @primitive_field(str)
    def description(self):
        """
        ARIA NOTE: Not mentioned in the spec.
        
        :rtype: str
        """

    @field_validator(derived_from_validator('node_types'))
    @primitive_field(str)
    def derived_from(self):
        """
        A string referencing a parent type.
        
        :rtype: str
        """

    @object_dict_field(InterfaceDefinition)
    def interfaces(self):
        """
        A dictionary of node interfaces.
        
        :rtype: dict of str, :class:`InterfaceDefinition`
        """

    @object_dict_field(PropertyDefinition)
    def properties(self):
        """
        A dictionary of node interfaces.
        
        :rtype: dict of str, :class:`PropertyDefinition`
        """

    @cachedmethod
    def _get_parent(self, context):
        return get_parent_presentation(context, self, 'node_types')

    @cachedmethod
    def _get_properties(self, context):
        return FrozenDict(
            get_inherited_property_definitions(context, self, 'properties'))

    @cachedmethod
    def _get_interfaces(self, context):
        return FrozenDict(
            get_inherited_interface_definitions(context, self, 'node type',
                                                'interfaces'))

    def _validate(self, context):
        super(NodeType, self)._validate(context)
        self._get_properties(context)
        self._get_interfaces(context)
Пример #2
0
class DataType(Presentation):
    """
    :code:`data_types` are useful for grouping together and re-using a common set of properties, along with their types and default values.
    
    See the `Cloudify DSL v1.3 specification <http://docs.getcloudify.org/3.4.0/blueprints/spec-data-types/>`__.
    """
    @primitive_field(str)
    def description(self):
        """
        Description for the data type.
        
        :rtype: str
        """

    @object_dict_field(PropertyDefinition)
    def properties(self):
        """
        Dictionary of the data type properties.
        
        :rtype: dict of str, :class:`PropertyDefinition`
        """

    @field_validator(derived_from_validator('data_types'))
    @primitive_field(str)
    def derived_from(self):
        """
        Parent data type.
        
        :rtype: str
        """

    @cachedmethod
    def _get_parent(self, context):
        return get_parent_presentation(context, self, 'data_types')

    @cachedmethod
    def _get_properties(self, context):
        return FrozenDict(
            get_inherited_property_definitions(context, self, 'properties'))

    def _validate(self, context):
        super(DataType, self)._validate(context)
        validate_data_type_name(context, self)
        self._get_properties(context)

    def _coerce_value(self, context, presentation, value, aspect):
        return coerce_data_type_value(context, presentation, self, value,
                                      aspect)
Пример #3
0
    if value is not None:
        the_type = presentation._get_type(context)
        entry_schema = presentation.entry_schema
        constraints = presentation._get_constraints(context) if hasattr(
            presentation, '_get_constraints'
        ) else None  # AttributeDefinition does not have this
        coerce_value(context, presentation, the_type, entry_schema,
                     constraints, value, field.name)


#
# DataType
#

_data_type_validator = data_type_validator()
_data_type_derived_from_validator = derived_from_validator(
    convert_shorthand_to_full_type_name, 'data_types')


def data_type_derived_from_validator(field, presentation, context):
    """
    Makes sure that the field refers to a valid parent data type (complex or primitive).
    
    Used with the :func:`field_validator` decorator for the :code:`derived_from` field in :class:`DataType`.
    """

    if _data_type_validator(field, presentation, context):
        # Validate derivation only if a complex data type (primitive types have no derivation hierarchy)
        _data_type_derived_from_validator(field, presentation, context)


def data_type_constraints_validator(field, presentation, context):
Пример #4
0
class PolicyType(ExtensiblePresentation):
    """
    A Policy Type defines a type of requirement that affects or governs an application or service's topology at some stage of its lifecycle, but is not explicitly part of the topology itself (i.e., it does not prevent the application or service from being deployed or run if it did not exist).
    
    See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_ENTITY_POLICY_TYPE>`__
    """
    @field_validator(
        derived_from_validator(convert_shorthand_to_full_type_name,
                               'policy_types'))
    @primitive_field(str)
    def derived_from(self):
        """
        An optional parent Policy Type name the Policy Type derives from.
        
        :rtype: str
        """

    @object_field(Version)
    def version(self):
        """
        An optional version for the Policy Type definition.
        
        :rtype: :class:`Version`
        """

    @object_field(Description)
    def description(self):
        """
        The optional description for the Policy Type.
        
        :rtype: :class:`Description`
        """

    @object_dict_field(PropertyDefinition)
    def properties(self):
        """
        An optional list of property definitions for the Policy Type.
        
        :rtype: :class:`PropertyDefinition`
        """

    @field_validator(list_node_type_or_group_type_validator)
    @primitive_list_field(str)
    def targets(self):
        """
        An optional list of valid Node Types or Group Types the Policy Type can be applied to.

        Note: This can be viewed by TOSCA Orchestrators as an implied relationship to the target nodes, but one that does not have operational lifecycle considerations. For example, if we were to name this as an explicit Relationship Type we might call this "AppliesTo" (node or group).
        
        :rtype: list of str
        """

    @cachedmethod
    def _get_parent(self, context):
        return get_parent_presentation(context, self,
                                       convert_shorthand_to_full_type_name,
                                       'policy_types')

    @cachedmethod
    def _get_properties(self, context):
        return FrozenDict(
            get_inherited_property_definitions(context, self, 'properties'))

    @cachedmethod
    def _get_targets(self, context):
        node_types, group_types = get_inherited_targets(context, self)
        return FrozenList(node_types), FrozenList(group_types)

    def _validate(self, context):
        super(PolicyType, self)._validate(context)
        self._get_properties(context)

    def _dump(self, context):
        self._dump_content(context, ('description', 'version', 'derived_from',
                                     'targets', 'properties'))
Пример #5
0
class GroupType(ExtensiblePresentation):
    """
    A Group Type defines logical grouping types for nodes, typically for different management purposes. Groups can effectively be viewed as logical nodes that are not part of the physical deployment topology of an application, yet can have capabilities and the ability to attach policies and interfaces that can be applied (depending on the group type) to its member nodes.

    Conceptually, group definitions allow the creation of logical "membership" relationships to nodes in a service template that are not a part of the application's explicit requirement dependencies in the topology template (i.e. those required to actually get the application deployed and running). Instead, such logical membership allows for the introduction of things such as group management and uniform application of policies (i.e., requirements that are also not bound to the application itself) to the group's members.
    
    See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_ENTITY_GROUP_TYPE>`__
    """
    @field_validator(
        derived_from_validator(convert_shorthand_to_full_type_name,
                               'group_types'))
    @primitive_field(str)
    def derived_from(self):
        """
        An optional parent Group Type name the Group Type derives from.
        
        :rtype: str
        """

    @object_field(Version)
    def version(self):
        """
        An optional version for the Group Type definition.
        
        :rtype: :class:`Version`
        """

    @object_field(Description)
    def description(self):
        """
        The optional description for the Group Type.
        
        :rtype: :class:`Description`
        """

    @object_dict_field(PropertyDefinition)
    def properties(self):
        """
        An optional list of property definitions for the Group Type.
        
        :rtype: dict of str, :class:`PropertyDefinition`
        """

    @field_validator(
        list_type_validator('node type', convert_shorthand_to_full_type_name,
                            'node_types'))
    @primitive_list_field(str)
    def members(self):
        """
        An optional list of one or more names of Node Types that are valid (allowed) as members of the Group Type. 

        Note: This can be viewed by TOSCA Orchestrators as an implied relationship from the listed members nodes to the group, but one that does not have operational lifecycle considerations. For example, if we were to name this as an explicit Relationship Type we might call this "MemberOf" (group).
        
        :rtype: list of str
        """

    @object_dict_field(InterfaceDefinition)
    def interfaces(self):
        """
        An optional list of interface definitions supported by the Group Type.
        
        :rtype: dict of str, :class:`InterfaceDefinition`
        """

    @cachedmethod
    def _get_parent(self, context):
        return get_parent_presentation(context, self,
                                       convert_shorthand_to_full_type_name,
                                       'group_types')

    @cachedmethod
    def _is_descendant(self, context, the_type):
        if the_type is None:
            return False
        elif the_type._name == self._name:
            return True
        return self._is_descendant(context, the_type._get_parent(context))

    @cachedmethod
    def _get_properties(self, context):
        return FrozenDict(
            get_inherited_property_definitions(context, self, 'properties'))

    @cachedmethod
    def _get_interfaces(self, context):
        return FrozenDict(
            get_inherited_interface_definitions(context, self, 'group type'))

    def _validate(self, context):
        super(GroupType, self)._validate(context)
        self._get_properties(context)
        self._get_interfaces(context)

    def _dump(self, context):
        self._dump_content(context, ('description', 'version', 'derived_from',
                                     'members', 'properties', 'interfaces'))
Пример #6
0
class NodeType(ExtensiblePresentation):
    """
    A Node Type is a reusable entity that defines the type of one or more Node Templates. As such, a Node Type defines the structure of observable properties via a Properties Definition, the Requirements and Capabilities of the node as well as its supported interfaces.
    
    See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_ENTITY_NODE_TYPE>`__
    """
    @field_validator(
        derived_from_validator(convert_shorthand_to_full_type_name,
                               'node_types'))
    @primitive_field(str)
    def derived_from(self):
        """
        An optional parent Node Type name this new Node Type derives from.
        
        :rtype: str
        """

    @object_field(Version)
    def version(self):
        """
        An optional version for the Node Type definition.
        
        :rtype: :class:`Version`
        """

    @object_field(Description)
    def description(self):
        """
        An optional description for the Node Type.
        
        :rtype: :class:`Description`
        """

    @object_dict_field(PropertyDefinition)
    def properties(self):
        """
        An optional list of property definitions for the Node Type.
        
        :rtype: dict of str, :class:`PropertyDefinition`
        """

    @object_dict_field(AttributeDefinition)
    def attributes(self):
        """
        An optional list of attribute definitions for the Node Type.
        
        :rtype: dict of str, :class:`AttributeDefinition`
        """

    @object_sequenced_list_field(RequirementDefinition)
    def requirements(self):
        """
        An optional sequenced list of requirement definitions for the Node Type.
        
        ARIA NOTE: The spec seems wrong to make this a sequenced list. It seems that when you have more than one requirement of the same
        name, behavior is undefined. The idea is to use the "occurrences" field if you need to limit the number of requirement assignments.
        
        :rtype: list of (str, :class:`RequirementDefinition`)
        """

    @object_dict_field(CapabilityDefinition)
    def capabilities(self):
        """
        An optional list of capability definitions for the Node Type.
        
        :rtype: list of :class:`CapabilityDefinition`
        """

    @object_dict_field(InterfaceDefinition)
    def interfaces(self):
        """
        An optional list of interface definitions supported by the Node Type.
        
        :rtype: dict of str, :class:`InterfaceDefinition`
        """

    @object_dict_field(ArtifactAssignment)
    def artifacts(self):
        """
        An optional list of named artifact definitions for the Node Type.
        
        :rtype: dict of str, :class:`ArtifactAssignment`
        """

    @cachedmethod
    def _get_parent(self, context):
        return get_parent_presentation(context, self,
                                       convert_shorthand_to_full_type_name,
                                       'node_types')

    @cachedmethod
    def _is_descendant(self, context, the_type):
        if the_type is None:
            return False
        elif the_type._name == self._name:
            return True
        return self._is_descendant(context, the_type._get_parent(context))

    @cachedmethod
    def _get_properties(self, context):
        return FrozenDict(
            get_inherited_property_definitions(context, self, 'properties'))

    @cachedmethod
    def _get_attributes(self, context):
        return FrozenDict(
            get_inherited_property_definitions(context, self, 'attributes'))

    @cachedmethod
    def _get_requirements(self, context):
        return FrozenList(get_inherited_requirement_definitions(context, self))

    @cachedmethod
    def _get_capabilities(self, context):
        return FrozenDict(get_inherited_capability_definitions(context, self))

    @cachedmethod
    def _get_interfaces(self, context):
        return FrozenDict(
            get_inherited_interface_definitions(context, self, 'node type'))

    @cachedmethod
    def _get_artifacts(self, context):
        return FrozenDict(get_inherited_artifact_definitions(context, self))

    def _validate(self, context):
        super(NodeType, self)._validate(context)
        self._get_properties(context)
        self._get_attributes(context)
        self._get_requirements(context)
        self._get_capabilities(context)
        self._get_interfaces(context)
        self._get_artifacts(context)

    def _dump(self, context):
        self._dump_content(context,
                           ('description', 'version', 'derived_from',
                            'properties', 'attributes', 'interfaces',
                            'artifacts', 'requirements', 'capabilities'))
Пример #7
0
class RelationshipType(ExtensiblePresentation):
    """
    A Relationship Type is a reusable entity that defines the type of one or more relationships between Node Types or Node Templates.
    
    See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_ENTITY_RELATIONSHIP_TYPE>`__
    """
    @field_validator(
        derived_from_validator(convert_shorthand_to_full_type_name,
                               'relationship_types'))
    @primitive_field(str)
    def derived_from(self):
        """
        An optional parent Relationship Type name the Relationship Type derives from.
        
        :rtype: str
        """

    @object_field(Version)
    def version(self):
        """
        An optional version for the Relationship Type definition.
        
        :rtype: :class:`Version`
        """

    @object_field(Description)
    def description(self):
        """
        An optional description for the Relationship Type.
        
        :rtype: :class:`Description`
        """

    @object_dict_field(PropertyDefinition)
    def properties(self):
        """
        An optional list of property definitions for the Relationship Type.
        
        :rtype: dict of str, :class:`PropertyDefinition`
        """

    @object_dict_field(AttributeDefinition)
    def attributes(self):
        """
        An optional list of attribute definitions for the Relationship Type.
        
        :rtype: dict of str, :class:`AttributeDefinition`
        """

    @object_dict_field(InterfaceDefinition)
    def interfaces(self):
        """
        An optional list of interface definitions interfaces supported by the Relationship Type.
        
        :rtype: dict of str, :class:`InterfaceDefinition`
        """

    @field_validator(
        list_type_validator('capability type',
                            convert_shorthand_to_full_type_name,
                            'capability_types'))
    @primitive_list_field(str)
    def valid_target_types(self):
        """
        An optional list of one or more names of Capability Types that are valid targets for this relationship.
        
        :rtype: list of str
        """

    @cachedmethod
    def _get_parent(self, context):
        return get_parent_presentation(context, self,
                                       convert_shorthand_to_full_type_name,
                                       'relationship_types')

    @cachedmethod
    def _get_properties(self, context):
        return FrozenDict(
            get_inherited_property_definitions(context, self, 'properties'))

    @cachedmethod
    def _get_attributes(self, context):
        return FrozenDict(
            get_inherited_property_definitions(context, self, 'attributes'))

    @cachedmethod
    def _get_interfaces(self, context):
        return FrozenDict(
            get_inherited_interface_definitions(context, self,
                                                'relationship type'))

    def _validate(self, context):
        super(RelationshipType, self)._validate(context)
        self._get_properties(context)
        self._get_attributes(context)
        self._get_interfaces(context)

    def _dump(self, context):
        self._dump_content(
            context,
            ('description', 'version', 'derived_from', 'valid_target_types',
             'properties', 'attributes', 'interfaces'))
Пример #8
0
class ArtifactType(ExtensiblePresentation):
    """
    An Artifact Type is a reusable entity that defines the type of one or more files that are used to define implementation or deployment artifacts that are referenced by nodes or relationships on their operations.
    
    See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_ENTITY_ARTIFACT_TYPE>`__
    """
    @field_validator(
        derived_from_validator(convert_shorthand_to_full_type_name,
                               'artifact_types'))
    @primitive_field(str)
    def derived_from(self):
        """
        An optional parent Artifact Type name the Artifact Type derives from.
        
        :rtype: str
        """

    @field_getter(data_type_class_getter(Version))
    @primitive_field()
    def version(self):
        """
        An optional version for the Artifact Type definition.
        
        :rtype: :class:`Version`
        """

    @object_field(Description)
    def description(self):
        """
        An optional description for the Artifact Type.
        
        :rtype: :class:`Description`
        """

    @primitive_field(str)
    def mime_type(self):
        """
        The required mime type property for the Artifact Type.
        
        :rtype: str
        """

    @primitive_list_field(str)
    def file_ext(self):
        """
        The required file extension property for the Artifact Type.
        
        :rtype: list of str
        """

    @object_dict_field(PropertyDefinition)
    def properties(self):
        """
        An optional list of property definitions for the Artifact Type.
        
        :rtype: dict of str, :class:`PropertyDefinition`
        """

    @cachedmethod
    def _get_parent(self, context):
        return get_parent_presentation(context, self,
                                       convert_shorthand_to_full_type_name,
                                       'artifact_types')

    @cachedmethod
    def _get_properties(self, context):
        return FrozenDict(
            get_inherited_property_definitions(context, self, 'properties'))

    def _validate(self, context):
        super(ArtifactType, self)._validate(context)
        self._get_properties(context)

    def _dump(self, context):
        self._dump_content(context, ('description', 'version', 'derived_from',
                                     'mime_type', 'file_ext', 'properties'))
Пример #9
0
class InterfaceType(ExtensiblePresentation):
    """
    An Interface Type is a reusable entity that describes a set of operations that can be used to interact with or manage a node or relationship in a TOSCA topology.
    
    See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_ENTITY_INTERFACE_TYPE>`__
    """
    @field_validator(
        derived_from_validator(convert_shorthand_to_full_type_name,
                               'interface_types'))
    @primitive_field(str)
    def derived_from(self):
        """
        An optional parent Interface Type name this new Interface Type derives from.
        
        :rtype: str
        """

    @object_field(Version)
    def version(self):
        """
        An optional version for the Interface Type definition.
        
        :rtype: :class:`Version`
        """

    @object_field(Description)
    def description(self):
        """
        An optional description for the Interface Type.
        
        :rtype: :class:`Description`
        """

    @object_dict_field(PropertyDefinition)
    def inputs(self):
        """
        The optional list of input parameter definitions.
        
        :rtype: dict of str, :class:`PropertyDefinition`
        """

    @object_dict_unknown_fields(OperationDefinition)
    def operations(self):
        """
        :rtype: dict of str, :class:`OperationDefinition`
        """

    @cachedmethod
    def _get_parent(self, context):
        return get_parent_presentation(context, self,
                                       convert_shorthand_to_full_type_name,
                                       'interface_types')

    @cachedmethod
    def _get_inputs(self, context):
        return FrozenDict(
            get_inherited_property_definitions(context, self, 'inputs'))

    @cachedmethod
    def _get_operations(self, context):
        return FrozenDict(get_inherited_operations(context, self))

    def _validate(self, context):
        super(InterfaceType, self)._validate(context)
        self._get_inputs(context)
        for operation in self.operations.itervalues():
            operation._validate(context)

    def _dump(self, context):
        self._dump_content(
            context,
            ('description', 'version', 'derived_from', 'inputs', 'operations'))
Пример #10
0
class CapabilityType(ExtensiblePresentation):
    """
    A Capability Type is a reusable entity that describes a kind of capability that a Node Type can declare to expose. Requirements (implicit or explicit) that are declared as part of one node can be matched to (i.e., fulfilled by) the Capabilities declared by another node.
    
    See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_ENTITY_CAPABILITY_TYPE>`__
    """
    @field_validator(
        derived_from_validator(convert_shorthand_to_full_type_name,
                               'capability_types'))
    @primitive_field(str)
    def derived_from(self):
        """
        An optional parent capability type name this new Capability Type derives from.
        
        :rtype: str
        """

    @object_field(Version)
    def version(self):
        """
        An optional version for the Capability Type definition.
        
        :rtype: :class:`Version`
        """

    @object_field(Description)
    def description(self):
        """
        An optional description for the Capability Type.
        
        :rtype: :class:`Description`
        """

    @object_dict_field(PropertyDefinition)
    def properties(self):
        """
        An optional list of property definitions for the Capability Type.

        ARIA NOTE: The spec says 'list', but the examples are all of dicts.
        
        :rtype: dict of str, :class:`PropertyDefinition`
        """

    @object_dict_field(AttributeDefinition)
    def attributes(self):
        """
        An optional list of attribute definitions for the Capability Type.
        
        :rtype: dict of str, :class:`AttributeDefinition`
        """

    @field_validator(
        list_type_validator('node type', convert_shorthand_to_full_type_name,
                            'node_types'))
    @primitive_list_field(str)
    def valid_source_types(self):
        """
        An optional list of one or more valid names of Node Types that are supported as valid sources of any relationship established to the declared Capability Type.
        
        :rtype: list of str
        """

    @cachedmethod
    def _get_parent(self, context):
        return get_parent_presentation(context, self,
                                       convert_shorthand_to_full_type_name,
                                       'capability_types')

    @cachedmethod
    def _is_descendant(self, context, the_type):
        if the_type is None:
            return False
        elif the_type._name == self._name:
            return True
        return self._is_descendant(context, the_type._get_parent(context))

    @cachedmethod
    def _get_properties(self, context):
        return FrozenDict(
            get_inherited_property_definitions(context, self, 'properties'))

    @cachedmethod
    def _get_valid_source_types(self, context):
        return get_inherited_valid_source_types(context, self)

    def _validate(self, context):
        super(CapabilityType, self)._validate(context)
        self._get_properties(context)

    def _dump(self, context):
        self._dump_content(context,
                           ('description', 'version', 'derived_from',
                            'valid_source_types', 'properties', 'attributes'))
Пример #11
0
class RelationshipType(Presentation):
    """
    You can declare your own relationship types in the relationships section in the blueprint. This is useful when you want to change the default implementation of how nodes interact.
    
    See the `Cloudify DSL v1.3 specification <http://docs.getcloudify.org/3.4.0/blueprints/spec-relationships/#declaring-relationship-types>`__
    """
    @primitive_field(str)
    def description(self):
        """
        ARIA NOTE: Not mentioned in the spec.
        
        :rtype: str
        """

    @field_validator(derived_from_validator('relationships'))
    @primitive_field(str)
    def derived_from(self):
        """
        The relationship type from which the new relationship is derived.
        
        :rtype: str
        """

    @object_dict_field(InterfaceDefinition)
    def source_interfaces(self):
        """
        A dict of interfaces.
        
        :rtype: dict of str, :class:`InterfaceDefinition`
        """

    @object_dict_field(InterfaceDefinition)
    def target_interfaces(self):
        """
        A dict of interfaces.
        
        :rtype: dict of str, :class:`InterfaceDefinition`
        """

    @object_dict_field(PropertyDefinition)
    def properties(self):
        """
        ARIA NOTE: This field is not mentioned in the spec, but is implied.
        
        :rtype: dict of str, :class:`PropertyDefinition`
        """

    @cachedmethod
    def _get_parent(self, context):
        return get_parent_presentation(context, self, 'relationships')

    @cachedmethod
    def _get_properties(self, context):
        return FrozenDict(
            get_relationship_inherited_property_definitions(context, self))

    @cachedmethod
    def _get_source_interfaces(self, context):
        return FrozenDict(
            get_inherited_interface_definitions(context, self,
                                                'relationship type',
                                                'source_interfaces'))

    @cachedmethod
    def _get_target_interfaces(self, context):
        return FrozenDict(
            get_inherited_interface_definitions(context, self,
                                                'relationship type',
                                                'target_interfaces'))

    def _validate(self, context):
        super(RelationshipType, self)._validate(context)
        self._get_properties(context)
        self._get_source_interfaces(context)
        self._get_target_interfaces(context)