2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.sdc.toscaparser.api;
23 import org.onap.sdc.toscaparser.api.common.JToscaValidationIssue;
24 import org.onap.sdc.toscaparser.api.elements.EntityType;
25 import org.onap.sdc.toscaparser.api.elements.InterfacesDef;
26 import org.onap.sdc.toscaparser.api.elements.Metadata;
27 import org.onap.sdc.toscaparser.api.elements.NodeType;
28 import org.onap.sdc.toscaparser.api.elements.RelationshipType;
29 import org.onap.sdc.toscaparser.api.utils.CopyUtils;
30 import org.onap.sdc.toscaparser.api.utils.ThreadLocalsHolder;
32 import java.util.ArrayList;
33 import java.util.LinkedHashMap;
34 import java.util.List;
37 import static org.onap.sdc.toscaparser.api.elements.EntityType.TOSCA_DEF;
39 public class NodeTemplate extends EntityTemplate {
41 private LinkedHashMap<String, Object> templates;
42 private LinkedHashMap<String, Object> customDef;
43 private ArrayList<RelationshipTemplate> availableRelTpls;
44 private LinkedHashMap<String, Object> availableRelTypes;
45 private LinkedHashMap<NodeTemplate, RelationshipType> related;
46 private ArrayList<RelationshipTemplate> relationshipTpl;
47 private LinkedHashMap<RelationshipType, NodeTemplate> _relationships;
48 private SubstitutionMappings subMappingToscaTemplate;
49 private TopologyTemplate originComponentTemplate;
50 private Metadata metadata;
52 private static final String METADATA = "metadata";
54 public NodeTemplate(String name,
55 LinkedHashMap<String, Object> ntnodeTemplates,
56 LinkedHashMap<String, Object> ntcustomDef,
57 ArrayList<RelationshipTemplate> ntavailableRelTpls,
58 LinkedHashMap<String, Object> ntavailableRelTypes) {
59 this(name, ntnodeTemplates, ntcustomDef, ntavailableRelTpls,
60 ntavailableRelTypes, null);
63 @SuppressWarnings("unchecked")
64 public NodeTemplate(String name,
65 LinkedHashMap<String, Object> ntnodeTemplates,
66 LinkedHashMap<String, Object> ntcustomDef,
67 ArrayList<RelationshipTemplate> ntavailableRelTpls,
68 LinkedHashMap<String, Object> ntavailableRelTypes,
69 NodeTemplate parentNodeTemplate) {
71 super(name, (LinkedHashMap<String, Object>) ntnodeTemplates.get(name),
72 "node_type", ntcustomDef, parentNodeTemplate);
74 templates = ntnodeTemplates;
75 _validateFields((LinkedHashMap<String, Object>) templates.get(name));
76 customDef = ntcustomDef;
77 related = new LinkedHashMap<NodeTemplate, RelationshipType>();
78 relationshipTpl = new ArrayList<RelationshipTemplate>();
79 availableRelTpls = ntavailableRelTpls;
80 availableRelTypes = ntavailableRelTypes;
81 _relationships = new LinkedHashMap<RelationshipType, NodeTemplate>();
82 subMappingToscaTemplate = null;
83 metadata = _metaData();
86 @SuppressWarnings("unchecked")
87 public LinkedHashMap<RelationshipType, NodeTemplate> getRelationships() {
88 if (_relationships.isEmpty()) {
89 List<RequirementAssignment> requires = getRequirements().getAll();
90 if (requires != null && requires instanceof List) {
91 for (RequirementAssignment r : requires) {
92 LinkedHashMap<RelationshipType, NodeTemplate> explicit = _getExplicitRelationship(r);
93 if (explicit != null) {
94 // _relationships.putAll(explicit)...
95 for (Map.Entry<RelationshipType, NodeTemplate> ee : explicit.entrySet()) {
96 _relationships.put(ee.getKey(), ee.getValue());
102 return _relationships;
105 @SuppressWarnings("unchecked")
106 private LinkedHashMap<RelationshipType, NodeTemplate> _getExplicitRelationship(RequirementAssignment req) {
107 // Handle explicit relationship
112 // relationship: tosca.relationships.HostedOn
114 LinkedHashMap<RelationshipType, NodeTemplate> explicitRelation = new LinkedHashMap<RelationshipType, NodeTemplate>();
115 String node = req.getNodeTemplateName();
117 if (node != null && !node.isEmpty()) {
118 //msg = _('Lookup by TOSCA types is not supported. '
119 // 'Requirement for "%s" can not be full-filled.') % self.name
120 boolean bFound = false;
121 for (String k : EntityType.TOSCA_DEF.keySet()) {
122 if (k.equals(node)) {
127 if (bFound || customDef.get(node) != null) {
128 ThreadLocalsHolder.getCollector().appendValidationIssue(new JToscaValidationIssue("JE205", String.format(
129 "NotImplementedError: Lookup by TOSCA types is not supported. Requirement for \"%s\" can not be full-filled",
133 if (templates.get(node) == null) {
134 ThreadLocalsHolder.getCollector().appendValidationIssue(new JToscaValidationIssue("JE206", String.format(
135 "KeyError: Node template \"%s\" was not found", node)));
138 NodeTemplate relatedTpl = new NodeTemplate(node, templates, customDef, null, null);
139 Object relationship = req.getRelationship();
140 String relationshipString = null;
141 // // here relationship can be a string or a LHM with 'type':<relationship>
143 // check if its type has relationship defined
144 if (relationship == null) {
145 ArrayList<Object> parentReqs = ((NodeType) typeDefinition).getAllRequirements();
146 if (parentReqs == null) {
147 ThreadLocalsHolder.getCollector().appendValidationIssue(new JToscaValidationIssue("JE207", "ValidationError: parent_req is null"));
149 // for(String key: req.keySet()) {
150 // boolean bFoundRel = false;
151 for (Object rdo : parentReqs) {
152 LinkedHashMap<String, Object> reqDict = (LinkedHashMap<String, Object>) rdo;
153 LinkedHashMap<String, Object> relDict = (LinkedHashMap<String, Object>) reqDict.get(req.getName());
154 if (relDict != null) {
155 relationship = relDict.get("relationship");
156 //BUG-python??? need to break twice?
168 if (relationship != null) {
169 // here relationship can be a string or a LHM with 'type':<relationship>
170 if (relationship instanceof String) {
171 relationshipString = (String) relationship;
172 } else if (relationship instanceof LinkedHashMap) {
173 relationshipString = (String) ((LinkedHashMap<String, Object>) relationship).get("type");
176 boolean foundRelationshipTpl = false;
177 // apply available relationship templates if found
178 if (availableRelTpls != null) {
179 for (RelationshipTemplate tpl : availableRelTpls) {
180 if (tpl.getName().equals(relationshipString)) {
181 RelationshipType rtype = new RelationshipType(tpl.getType(), null, customDef);
182 explicitRelation.put(rtype, relatedTpl);
183 tpl.setTarget(relatedTpl);
185 relationshipTpl.add(tpl);
186 foundRelationshipTpl = true;
190 // create relationship template object.
191 String relPrfx = EntityType.RELATIONSHIP_PREFIX;
192 if (!foundRelationshipTpl) {
193 if (relationship instanceof LinkedHashMap) {
194 relationshipString = (String) ((LinkedHashMap<String, Object>) relationship).get("type");
195 if (relationshipString != null) {
196 if (availableRelTypes != null && !availableRelTypes.isEmpty() &&
197 availableRelTypes.get(relationshipString) != null) {
199 } else if (!(relationshipString).startsWith(relPrfx)) {
200 relationshipString = relPrfx + relationshipString;
203 ThreadLocalsHolder.getCollector().appendValidationIssue(new JToscaValidationIssue("JE208", String.format(
204 "MissingRequiredFieldError: \"relationship\" used in template \"%s\" is missing required field \"type\"",
205 relatedTpl.getName())));
208 for (RelationshipType rtype : ((NodeType) typeDefinition).getRelationship().keySet()) {
209 if (rtype.getType().equals(relationshipString)) {
210 explicitRelation.put(rtype, relatedTpl);
211 relatedTpl._addRelationshipTemplate(req, rtype.getType(), this);
212 } else if (availableRelTypes != null && !availableRelTypes.isEmpty()) {
213 LinkedHashMap<String, Object> relTypeDef = (LinkedHashMap<String, Object>) availableRelTypes.get(relationshipString);
214 if (relTypeDef != null) {
215 String superType = (String) relTypeDef.get("derived_from");
216 if (superType != null) {
217 if (!superType.startsWith(relPrfx)) {
218 superType = relPrfx + superType;
220 if (rtype.getType().equals(superType)) {
221 explicitRelation.put(rtype, relatedTpl);
222 relatedTpl._addRelationshipTemplate(req, rtype.getType(), this);
231 return explicitRelation;
234 @SuppressWarnings("unchecked")
235 private void _addRelationshipTemplate(RequirementAssignment requirement, String rtype, NodeTemplate source) {
236 LinkedHashMap<String, Object> req = new LinkedHashMap<>();
237 req.put("relationship", CopyUtils.copyLhmOrAl(requirement.getRelationship()));
238 req.put("type", rtype);
239 RelationshipTemplate tpl = new RelationshipTemplate(req, rtype, customDef, this, source, getParentNodeTemplate());
240 relationshipTpl.add(tpl);
243 public ArrayList<RelationshipTemplate> getRelationshipTemplate() {
244 return relationshipTpl;
247 void _addNext(NodeTemplate nodetpl, RelationshipType relationship) {
248 related.put(nodetpl, relationship);
251 public ArrayList<NodeTemplate> getRelatedNodes() {
252 if (related.isEmpty()) {
253 for (Map.Entry<RelationshipType, NodeType> me : ((NodeType) typeDefinition).getRelationship().entrySet()) {
254 RelationshipType relation = me.getKey();
255 NodeType node = me.getValue();
256 for (String tpl : templates.keySet()) {
257 if (tpl.equals(node.getType())) {
259 // self.related[NodeTemplate(tpl)] = relation
260 // but NodeTemplate doesn't have a constructor with just name...
262 related.put(new NodeTemplate(tpl, null, null, null, null), relation);
267 return new ArrayList<NodeTemplate>(related.keySet());
270 public void validate(/*tosca_tpl=none is not used...*/) {
271 _validateCapabilities();
272 _validateRequirements();
273 _validateProperties(entityTpl, (NodeType) typeDefinition);
274 _validateInterfaces();
275 for (Property prop : getPropertiesObjects()) {
280 public Object getPropertyValueFromTemplatesByName(String propertyName) {
281 LinkedHashMap<String, Object> nodeObject = (LinkedHashMap<String, Object>) templates.get(name);
282 if (nodeObject != null) {
283 LinkedHashMap<String, Object> properties = (LinkedHashMap<String, Object>) nodeObject.get(PROPERTIES);
284 if (properties != null) {
285 return properties.get(propertyName);
291 private Metadata _metaData() {
292 if (entityTpl.get(METADATA) != null) {
293 return new Metadata((Map<String, Object>) entityTpl.get(METADATA));
299 @SuppressWarnings("unchecked")
300 private void _validateRequirements() {
301 ArrayList<Object> typeRequires = ((NodeType) typeDefinition).getAllRequirements();
302 ArrayList<String> allowedReqs = new ArrayList<>();
303 allowedReqs.add("template");
304 if (typeRequires != null) {
305 for (Object to : typeRequires) {
306 LinkedHashMap<String, Object> treq = (LinkedHashMap<String, Object>) to;
307 for (Map.Entry<String, Object> me : treq.entrySet()) {
308 String key = me.getKey();
309 Object value = me.getValue();
310 allowedReqs.add(key);
311 if (value instanceof LinkedHashMap) {
312 allowedReqs.addAll(((LinkedHashMap<String, Object>) value).keySet());
319 ArrayList<Object> requires = (ArrayList<Object>) ((NodeType) typeDefinition).getValue(REQUIREMENTS, entityTpl, false);
320 if (requires != null) {
321 if (!(requires instanceof ArrayList)) {
322 ThreadLocalsHolder.getCollector().appendValidationIssue(new JToscaValidationIssue("JE209", String.format(
323 "TypeMismatchError: \"requirements\" of template \"%s\" are not of type \"list\"", name)));
325 for (Object ro : requires) {
326 LinkedHashMap<String, Object> req = (LinkedHashMap<String, Object>) ro;
327 for (Map.Entry<String, Object> me : req.entrySet()) {
328 String rl = me.getKey();
329 Object vo = me.getValue();
330 if (vo instanceof LinkedHashMap) {
331 LinkedHashMap<String, Object> value = (LinkedHashMap<String, Object>) vo;
332 _validateRequirementsKeys(value);
333 _validateRequirementsProperties(value);
337 _commonValidateField(req, allowedReqs, "requirements");
343 @SuppressWarnings("unchecked")
344 private void _validateRequirementsProperties(LinkedHashMap<String, Object> reqs) {
345 // TO-DO(anyone): Only occurrences property of the requirements is
346 // validated here. Validation of other requirement properties are being
347 // validated in different files. Better to keep all the requirements
348 // properties validation here.
349 for (Map.Entry<String, Object> me : reqs.entrySet()) {
350 if (me.getKey().equals("occurrences")) {
351 ArrayList<Object> val = (ArrayList<Object>) me.getValue();
352 _validateOccurrences(val);
358 private void _validateOccurrences(ArrayList<Object> occurrences) {
359 DataEntity.validateDatatype("list", occurrences, null, null, null);
360 for (Object val : occurrences) {
361 DataEntity.validateDatatype("Integer", val, null, null, null);
363 if (occurrences.size() != 2 ||
364 !(0 <= (int) occurrences.get(0) && (int) occurrences.get(0) <= (int) occurrences.get(1)) ||
365 (int) occurrences.get(1) == 0) {
366 ThreadLocalsHolder.getCollector().appendValidationIssue(new JToscaValidationIssue("JE210", String.format(
367 "InvalidPropertyValueError: property has invalid value %s", occurrences.toString())));
371 private void _validateRequirementsKeys(LinkedHashMap<String, Object> reqs) {
372 for (String key : reqs.keySet()) {
373 boolean bFound = false;
374 for (int i = 0; i < REQUIREMENTS_SECTION.length; i++) {
375 if (key.equals(REQUIREMENTS_SECTION[i])) {
381 ThreadLocalsHolder.getCollector().appendValidationIssue(new JToscaValidationIssue("JE211", String.format(
382 "UnknownFieldError: \"requirements\" of template \"%s\" contains unknown field \"%s\"", name, key)));
387 @SuppressWarnings("unchecked")
388 private void _validateInterfaces() {
389 LinkedHashMap<String, Object> ifaces = (LinkedHashMap<String, Object>)
390 ((NodeType) typeDefinition).getValue(INTERFACES, entityTpl, false);
391 if (ifaces != null) {
392 for (Map.Entry<String, Object> me : ifaces.entrySet()) {
393 String iname = me.getKey();
394 LinkedHashMap<String, Object> value = (LinkedHashMap<String, Object>) me.getValue();
395 if (iname.equals(InterfacesDef.LIFECYCLE) || iname.equals(InterfacesDef.LIFECYCLE_SHORTNAME)) {
396 // maybe we should convert [] to arraylist???
397 ArrayList<String> inlo = new ArrayList<>();
398 for (int i = 0; i < InterfacesDef.INTERFACE_NODE_LIFECYCLE_OPERATIONS.length; i++) {
399 inlo.add(InterfacesDef.INTERFACE_NODE_LIFECYCLE_OPERATIONS[i]);
401 _commonValidateField(value, inlo, "interfaces");
402 } else if (iname.equals(InterfacesDef.CONFIGURE) || iname.equals(InterfacesDef.CONFIGURE_SHORTNAME)) {
403 // maybe we should convert [] to arraylist???
404 ArrayList<String> irco = new ArrayList<>();
405 for (int i = 0; i < InterfacesDef.INTERFACE_RELATIONSHIP_CONFIGURE_OPERATIONS.length; i++) {
406 irco.add(InterfacesDef.INTERFACE_RELATIONSHIP_CONFIGURE_OPERATIONS[i]);
408 _commonValidateField(value, irco, "interfaces");
409 } else if (((NodeType) typeDefinition).getInterfaces().keySet().contains(iname)) {
410 _commonValidateField(value, _collectCustomIfaceOperations(iname), "interfaces");
412 ThreadLocalsHolder.getCollector().appendValidationIssue(new JToscaValidationIssue("JE212", String.format(
413 "UnknownFieldError: \"interfaces\" of template \"%s\" contains unknown field %s", name, iname)));
419 @SuppressWarnings("unchecked")
420 private ArrayList<String> _collectCustomIfaceOperations(String iname) {
421 ArrayList<String> allowedOperations = new ArrayList<>();
422 LinkedHashMap<String, Object> nodetypeIfaceDef = (LinkedHashMap<String, Object>) ((NodeType)
423 typeDefinition).getInterfaces().get(iname);
424 allowedOperations.addAll(nodetypeIfaceDef.keySet());
425 String ifaceType = (String) nodetypeIfaceDef.get("type");
426 if (ifaceType != null) {
427 LinkedHashMap<String, Object> ifaceTypeDef = null;
428 if (((NodeType) typeDefinition).customDef != null) {
429 ifaceTypeDef = (LinkedHashMap<String, Object>) ((NodeType) typeDefinition).customDef.get(ifaceType);
431 if (ifaceTypeDef == null) {
432 ifaceTypeDef = (LinkedHashMap<String, Object>) EntityType.TOSCA_DEF.get(ifaceType);
434 allowedOperations.addAll(ifaceTypeDef.keySet());
436 // maybe we should convert [] to arraylist???
437 ArrayList<String> idrw = new ArrayList<>();
438 for (int i = 0; i < InterfacesDef.INTERFACE_DEF_RESERVED_WORDS.length; i++) {
439 idrw.add(InterfacesDef.INTERFACE_DEF_RESERVED_WORDS[i]);
441 allowedOperations.removeAll(idrw);
442 return allowedOperations;
446 * Get all interface details for given node template.<br>
448 * @return Map that contains the list of all interfaces and their definitions.
449 * If none found, an empty map will be returned.
451 public Map<String, List<InterfacesDef>> getAllInterfaceDetailsForNodeType() {
452 Map<String, List<InterfacesDef>> interfaceMap = new LinkedHashMap<>();
454 // Get custom interface details
455 Map<String, Object> customInterfacesDetails = ((NodeType) typeDefinition).getInterfaces();
456 // Get native interface details from tosca definitions
457 Object nativeInterfaceDetails = TOSCA_DEF.get(InterfacesDef.LIFECYCLE);
458 Map<String, Object> allInterfaceDetails = new LinkedHashMap<>();
459 allInterfaceDetails.putAll(customInterfacesDetails);
460 if (nativeInterfaceDetails != null) {
461 allInterfaceDetails.put(InterfacesDef.LIFECYCLE, nativeInterfaceDetails);
464 // Process all interface details from combined collection and return an interface Map with
465 // interface names and their definitions
466 for (Map.Entry<String, Object> me : allInterfaceDetails.entrySet()) {
467 ArrayList<InterfacesDef> interfaces = new ArrayList<>();
468 String interfaceType = me.getKey();
469 Map<String, Object> interfaceValue = (Map<String, Object>) me.getValue();
470 if (interfaceValue.containsKey("type")) {
471 interfaceType = (String) interfaceValue.get("type");
474 for (Map.Entry<String, Object> ve : interfaceValue.entrySet()) {
475 // Filter type as this is a reserved key and not an operation
476 if (!ve.getKey().equals("type")) {
477 InterfacesDef iface = new InterfacesDef(typeDefinition, interfaceType, this, ve.getKey(), ve.getValue());
478 interfaces.add(iface);
481 interfaceMap.put(interfaceType, interfaces);
486 private void _validateFields(LinkedHashMap<String, Object> nodetemplate) {
487 for (String ntname : nodetemplate.keySet()) {
488 boolean bFound = false;
489 for (int i = 0; i < SECTIONS.length; i++) {
490 if (ntname.equals(SECTIONS[i])) {
496 for (int i = 0; i < SPECIAL_SECTIONS.length; i++) {
497 if (ntname.equals(SPECIAL_SECTIONS[i])) {
505 ThreadLocalsHolder.getCollector().appendValidationIssue(new JToscaValidationIssue("JE213", String.format(
506 "UnknownFieldError: Node template \"%s\" has unknown field \"%s\"", name, ntname)));
513 // multilevel nesting
514 public SubstitutionMappings getSubMappingToscaTemplate() {
515 return subMappingToscaTemplate;
518 public void setSubMappingToscaTemplate(SubstitutionMappings sm) {
519 subMappingToscaTemplate = sm;
522 public Metadata getMetaData() {
526 public void setMetaData(Metadata metadata) {
527 this.metadata = metadata;
531 public String toString() {
535 public TopologyTemplate getOriginComponentTemplate() {
536 return originComponentTemplate;
539 public void setOriginComponentTemplate(TopologyTemplate originComponentTemplate) {
540 this.originComponentTemplate = originComponentTemplate;
547 from toscaparser.common.exception import ValidationIssueCollector
548 from toscaparser.common.exception import InvalidPropertyValueError
549 from toscaparser.common.exception import MissingRequiredFieldError
550 from toscaparser.common.exception import TypeMismatchError
551 from toscaparser.common.exception import UnknownFieldError
552 from toscaparser.common.exception import ValidationError
553 from toscaparser.dataentity import DataEntity
554 from toscaparser.elements.interfaces import CONFIGURE
555 from toscaparser.elements.interfaces import CONFIGURE_SHORTNAME
556 from toscaparser.elements.interfaces import INTERFACE_DEF_RESERVED_WORDS
557 from toscaparser.elements.interfaces import InterfacesDef
558 from toscaparser.elements.interfaces import LIFECYCLE
559 from toscaparser.elements.interfaces import LIFECYCLE_SHORTNAME
560 from toscaparser.elements.relationshiptype import RelationshipType
561 from toscaparser.entity_template import EntityTemplate
562 from toscaparser.relationship_template import RelationshipTemplate
563 from toscaparser.utils.gettextutils import _
565 log = logging.getLogger('tosca')
568 class NodeTemplate(EntityTemplate):
569 '''Node template from a Tosca profile.'''
570 def __init__(self, name, node_templates, custom_def=None,
571 available_rel_tpls=None, available_rel_types=None):
572 super(NodeTemplate, self).__init__(name, node_templates[name],
575 self.templates = node_templates
576 self._validate_fields(node_templates[name])
577 self.custom_def = custom_def
579 self.relationship_tpl = []
580 self.available_rel_tpls = available_rel_tpls
581 self.available_rel_types = available_rel_types
582 self._relationships = {}
583 self.sub_mapping_tosca_template = None
586 def relationships(self):
587 if not self._relationships:
588 requires = self.requirements
589 if requires and isinstance(requires, list):
591 for r1, value in r.items():
592 explicit = self._get_explicit_relationship(r, value)
594 for key, value in explicit.items():
595 self._relationships[key] = value
596 return self._relationships
598 def _get_explicit_relationship(self, req, value):
599 """Handle explicit relationship
604 relationship: tosca.relationships.HostedOn
606 explicit_relation = {}
607 node = value.get('node') if isinstance(value, dict) else value
610 # TO-DO(spzala) implement look up once Glance meta data is available
611 # to find a matching TOSCA node using the TOSCA types
612 msg = _('Lookup by TOSCA types is not supported. '
613 'Requirement for "%s" can not be full-filled.') % self.name
614 if (node in list(self.type_definition.TOSCA_DEF.keys())
615 or node in self.custom_def):
616 ValidationIssueCollector.appendException(NotImplementedError(msg))
619 if node not in self.templates:
620 ValidationIssueCollector.appendException(
621 KeyError(_('Node template "%s" was not found.') % node))
624 related_tpl = NodeTemplate(node, self.templates, self.custom_def)
625 relationship = value.get('relationship') \
626 if isinstance(value, dict) else None
627 # check if it's type has relationship defined
629 parent_reqs = self.type_definition.get_all_requirements()
630 if parent_reqs is None:
631 ValidationIssueCollector.appendException(
632 ValidationError(message='parent_req is ' +
635 for key in req.keys():
636 for req_dict in parent_reqs:
637 if key in req_dict.keys():
638 relationship = (req_dict.get(key).
642 found_relationship_tpl = False
643 # apply available relationship templates if found
644 if self.available_rel_tpls:
645 for tpl in self.available_rel_tpls:
646 if tpl.name == relationship:
647 rtype = RelationshipType(tpl.type, None,
649 explicit_relation[rtype] = related_tpl
650 tpl.target = related_tpl
652 self.relationship_tpl.append(tpl)
653 found_relationship_tpl = True
654 # create relationship template object.
655 rel_prfx = self.type_definition.RELATIONSHIP_PREFIX
656 if not found_relationship_tpl:
657 if isinstance(relationship, dict):
658 relationship = relationship.get('type')
660 if self.available_rel_types and \
661 relationship in self.available_rel_types.keys():
663 elif not relationship.startswith(rel_prfx):
664 relationship = rel_prfx + relationship
666 ValidationIssueCollector.appendException(
667 MissingRequiredFieldError(
668 what=_('"relationship" used in template '
669 '"%s"') % related_tpl.name,
671 for rtype in self.type_definition.relationship.keys():
672 if rtype.type == relationship:
673 explicit_relation[rtype] = related_tpl
674 related_tpl._add_relationship_template(req,
677 elif self.available_rel_types:
678 if relationship in self.available_rel_types.keys():
679 rel_type_def = self.available_rel_types.\
681 if 'derived_from' in rel_type_def:
683 rel_type_def.get('derived_from')
684 if not super_type.startswith(rel_prfx):
685 super_type = rel_prfx + super_type
686 if rtype.type == super_type:
687 explicit_relation[rtype] = related_tpl
689 _add_relationship_template(
690 req, rtype.type, self)
691 return explicit_relation
693 def _add_relationship_template(self, requirement, rtype, source):
694 req = requirement.copy()
696 tpl = RelationshipTemplate(req, rtype, self.custom_def, self, source)
697 self.relationship_tpl.append(tpl)
699 def get_relationship_template(self):
700 return self.relationship_tpl
702 def _add_next(self, nodetpl, relationship):
703 self.related[nodetpl] = relationship
706 def related_nodes(self):
708 for relation, node in self.type_definition.relationship.items():
709 for tpl in self.templates:
711 self.related[NodeTemplate(tpl)] = relation
712 return self.related.keys()
714 def validate(self, tosca_tpl=None):
715 self._validate_capabilities()
716 self._validate_requirements()
717 self._validate_properties(self.entity_tpl, self.type_definition)
718 self._validate_interfaces()
719 for prop in self.get_properties_objects():
722 def _validate_requirements(self):
723 type_requires = self.type_definition.get_all_requirements()
724 allowed_reqs = ["template"]
726 for treq in type_requires:
727 for key, value in treq.items():
728 allowed_reqs.append(key)
729 if isinstance(value, dict):
731 allowed_reqs.append(key)
733 requires = self.type_definition.get_value(self.REQUIREMENTS,
736 if not isinstance(requires, list):
737 ValidationIssueCollector.appendException(
739 what='"requirements" of template "%s"' % self.name,
743 for r1, value in req.items():
744 if isinstance(value, dict):
745 self._validate_requirements_keys(value)
746 self._validate_requirements_properties(value)
747 allowed_reqs.append(r1)
748 self._common_validate_field(req, allowed_reqs,
751 def _validate_requirements_properties(self, requirements):
752 # TO-DO(anyone): Only occurrences property of the requirements is
753 # validated here. Validation of other requirement properties are being
754 # validated in different files. Better to keep all the requirements
755 # properties validation here.
756 for key, value in requirements.items():
757 if key == 'occurrences':
758 self._validate_occurrences(value)
761 def _validate_occurrences(self, occurrences):
762 DataEntity.validate_datatype('list', occurrences)
763 for value in occurrences:
764 DataEntity.validate_datatype('integer', value)
765 if len(occurrences) != 2 or not (0 <= occurrences[0] <= occurrences[1]) \
766 or occurrences[1] == 0:
767 ValidationIssueCollector.appendException(
768 InvalidPropertyValueError(what=(occurrences)))
770 def _validate_requirements_keys(self, requirement):
771 for key in requirement.keys():
772 if key not in self.REQUIREMENTS_SECTION:
773 ValidationIssueCollector.appendException(
775 what='"requirements" of template "%s"' % self.name,
778 def _validate_interfaces(self):
779 ifaces = self.type_definition.get_value(self.INTERFACES,
782 for name, value in ifaces.items():
783 if name in (LIFECYCLE, LIFECYCLE_SHORTNAME):
784 self._common_validate_field(
785 value, InterfacesDef.
786 interfaces_node_lifecycle_operations,
788 elif name in (CONFIGURE, CONFIGURE_SHORTNAME):
789 self._common_validate_field(
790 value, InterfacesDef.
791 interfaces_relationship_configure_operations,
793 elif name in self.type_definition.interfaces.keys():
794 self._common_validate_field(
796 self._collect_custom_iface_operations(name),
799 ValidationIssueCollector.appendException(
801 what='"interfaces" of template "%s"' %
802 self.name, field=name))
804 def _collect_custom_iface_operations(self, name):
805 allowed_operations = []
806 nodetype_iface_def = self.type_definition.interfaces[name]
807 allowed_operations.extend(nodetype_iface_def.keys())
808 if 'type' in nodetype_iface_def:
809 iface_type = nodetype_iface_def['type']
810 if iface_type in self.type_definition.custom_def:
811 iface_type_def = self.type_definition.custom_def[iface_type]
813 iface_type_def = self.type_definition.TOSCA_DEF[iface_type]
814 allowed_operations.extend(iface_type_def.keys())
815 allowed_operations = [op for op in allowed_operations if
816 op not in INTERFACE_DEF_RESERVED_WORDS]
817 return allowed_operations
819 def _validate_fields(self, nodetemplate):
820 for name in nodetemplate.keys():
821 if name not in self.SECTIONS and name not in self.SPECIAL_SECTIONS:
822 ValidationIssueCollector.appendException(
823 UnknownFieldError(what='Node template "%s"' % self.name,