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.formatting import safe_repr
17 from aria.parser.validation import Issue
20 def validate_substitution_mappings_requirement(context, presentation):
22 # validate that the requirement in substitution_mapping is defined in the substitution node type
23 substitution_node_type = presentation._container._get_type(context)
24 if substitution_node_type is None:
26 for req_name, req in substitution_node_type._get_requirements(context):
27 if req_name == presentation._name:
28 substitution_type_requirement = req
31 context.validation.report(
32 'substitution mapping requirement "{0}" is not declared in node type "{1}"'.format(
33 presentation._name, substitution_node_type._name),
34 locator=presentation._locator, level=Issue.BETWEEN_TYPES)
37 if not _validate_mapping_format(presentation):
38 _report_invalid_mapping_format(context, presentation, field='requirement')
41 # validate that the mapped requirement is defined in the corresponding node template
42 node_template = _get_node_template(context, presentation)
43 if node_template is None:
44 _report_missing_node_template(context, presentation, field='requirement')
46 mapped_requirement_name = presentation._raw[1]
47 for req_name, req in node_template._get_requirements(context):
48 if req_name == mapped_requirement_name:
49 node_template_requirement = req
52 context.validation.report(
53 'substitution mapping requirement "{0}" refers to an unknown requirement of node '
54 'template "{1}": {mapped_requirement_name}'.format(
55 presentation._name, node_template._name,
56 mapped_requirement_name=safe_repr(mapped_requirement_name)),
57 locator=presentation._locator, level=Issue.BETWEEN_TYPES)
60 # validate that the requirement's capability type in substitution_mapping is derived from the
61 # requirement's capability type in the corresponding node template
62 substitution_type_requirement_capability_type = \
63 substitution_type_requirement._get_capability_type(context)
64 node_template_requirement_capability_type = \
65 node_template_requirement._get_capability(context)[0]
66 if not node_template_requirement_capability_type._is_descendant(
67 context, substitution_type_requirement_capability_type):
68 context.validation.report(
69 'substitution mapping requirement "{0}" of capability type "{1}" is not a descendant '
70 'of the mapped node template capability type "{2}"'.format(
72 substitution_type_requirement_capability_type._name,
73 node_template_requirement_capability_type._name),
74 locator=presentation._locator, level=Issue.BETWEEN_TYPES)
77 def validate_substitution_mappings_capability(context, presentation):
79 # validate that the capability in substitution_mapping is defined in the substitution node type
80 substitution_node_type = presentation._container._get_type(context)
81 if substitution_node_type is None:
83 substitution_type_capabilities = substitution_node_type._get_capabilities(context)
84 substitution_type_capability = substitution_type_capabilities.get(presentation._name)
85 if substitution_type_capability is None:
86 context.validation.report(
87 'substitution mapping capability "{0}" '
88 'is not declared in node type "{substitution_type}"'.format(
89 presentation._name, substitution_type=substitution_node_type._name),
90 locator=presentation._locator, level=Issue.BETWEEN_TYPES)
93 if not _validate_mapping_format(presentation):
94 _report_invalid_mapping_format(context, presentation, field='capability')
97 # validate that the capability in substitution_mapping is declared in the corresponding
99 node_template = _get_node_template(context, presentation)
100 if node_template is None:
101 _report_missing_node_template(context, presentation, field='capability')
103 mapped_capability_name = presentation._raw[1]
104 node_template_capability = node_template._get_capabilities(context).get(mapped_capability_name)
106 if node_template_capability is None:
107 context.validation.report(
108 'substitution mapping capability "{0}" refers to an unknown '
109 'capability of node template "{1}": {mapped_capability_name}'.format(
110 presentation._name, node_template._name,
111 mapped_capability_name=safe_repr(mapped_capability_name)),
112 locator=presentation._locator, level=Issue.BETWEEN_TYPES)
115 # validate that the capability type in substitution_mapping is derived from the capability type
116 # in the corresponding node template
117 substitution_type_capability_type = substitution_type_capability._get_type(context)
118 node_template_capability_type = node_template_capability._get_type(context)
120 if not substitution_type_capability_type._is_descendant(context, node_template_capability_type):
121 context.validation.report(
122 'node template capability type "{0}" is not a descendant of substitution mapping '
123 'capability "{1}" of type "{2}"'.format(
124 node_template_capability_type._name,
126 substitution_type_capability_type._name),
127 locator=presentation._locator, level=Issue.BETWEEN_TYPES)
134 def _validate_mapping_format(presentation):
135 """Validate that the mapping is a list of 2 strings"""
136 if not isinstance(presentation._raw, list) or \
137 len(presentation._raw) != 2 or \
138 not isinstance(presentation._raw[0], basestring) or \
139 not isinstance(presentation._raw[1], basestring):
144 def _get_node_template(context, presentation):
145 node_template_name = presentation._raw[0]
146 node_template = context.presentation.get_from_dict('service_template', 'topology_template',
147 'node_templates', node_template_name)
151 def _report_missing_node_template(context, presentation, field):
152 context.validation.report(
153 'substitution mappings {field} "{node_template_mapping}" '
154 'refers to an unknown node template: {node_template_name}'.format(
156 node_template_mapping=presentation._name,
157 node_template_name=safe_repr(presentation._raw[0])),
158 locator=presentation._locator, level=Issue.FIELD)
161 def _report_invalid_mapping_format(context, presentation, field):
162 context.validation.report(
163 'substitution mapping {field} "{field_name}" is not a list of 2 strings: {value}'.format(
165 field_name=presentation._name,
166 value=safe_repr(presentation._raw)),
167 locator=presentation._locator, level=Issue.FIELD)