diff options
Diffstat (limited to 'jtosca/src/main/java/org/openecomp/sdc/toscaparser/NodeTemplate.java')
-rw-r--r-- | jtosca/src/main/java/org/openecomp/sdc/toscaparser/NodeTemplate.java | 764 |
1 files changed, 764 insertions, 0 deletions
diff --git a/jtosca/src/main/java/org/openecomp/sdc/toscaparser/NodeTemplate.java b/jtosca/src/main/java/org/openecomp/sdc/toscaparser/NodeTemplate.java new file mode 100644 index 0000000..1f2524a --- /dev/null +++ b/jtosca/src/main/java/org/openecomp/sdc/toscaparser/NodeTemplate.java @@ -0,0 +1,764 @@ +package org.openecomp.sdc.toscaparser; + +import org.openecomp.sdc.toscaparser.common.ExceptionCollector; +import org.openecomp.sdc.toscaparser.elements.*; +import org.openecomp.sdc.toscaparser.utils.CopyUtils; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.Map; + +public class NodeTemplate extends EntityTemplate { + + private LinkedHashMap<String,Object> templates; + private LinkedHashMap<String,Object> customDef; + private ArrayList<RelationshipTemplate> availableRelTpls; + private LinkedHashMap<String,Object> availableRelTypes; + private LinkedHashMap<NodeTemplate,RelationshipType> related; + private ArrayList<RelationshipTemplate> relationshipTpl; + private LinkedHashMap<RelationshipType,NodeTemplate> _relationships; + private SubstitutionMappings subMappingToscaTemplate; + private SubstitutionMappings subMappingToscaTemplate2; + private Metadata metadata; + + private static final String METADATA = "metadata"; + + @SuppressWarnings("unchecked") + public NodeTemplate(String name, + LinkedHashMap<String,Object> ntnodeTemplates, + LinkedHashMap<String,Object> ntcustomDef, + ArrayList<RelationshipTemplate> ntavailableRelTpls, + LinkedHashMap<String,Object> ntavailableRelTypes) { + + super(name, (LinkedHashMap<String,Object>)ntnodeTemplates.get(name), "node_type", ntcustomDef); + + templates = ntnodeTemplates; + _validateFields((LinkedHashMap<String,Object>)templates.get(name)); + customDef = ntcustomDef; + related = new LinkedHashMap<NodeTemplate,RelationshipType>(); + relationshipTpl = new ArrayList<RelationshipTemplate>(); + availableRelTpls = ntavailableRelTpls; + availableRelTypes = ntavailableRelTypes; + _relationships = new LinkedHashMap<RelationshipType,NodeTemplate>(); + subMappingToscaTemplate = null; + subMappingToscaTemplate2 = null; + metadata = _metaData(); + } + + @SuppressWarnings("unchecked") + public LinkedHashMap<RelationshipType,NodeTemplate> getRelationships() { + if(_relationships.isEmpty()) { + ArrayList<Object> requires = getRequirements(); + if(requires != null && requires instanceof ArrayList) { + for(Object ro: requires) { + LinkedHashMap<String,Object> r = (LinkedHashMap<String,Object>)ro; + for(Map.Entry<String,Object> me: r.entrySet()) { + LinkedHashMap<RelationshipType,NodeTemplate> explicit = _getExplicitRelationship(r,me.getValue()); + if(explicit != null) { + // _relationships.putAll(explicit)... + for(Map.Entry<RelationshipType,NodeTemplate> ee: explicit.entrySet()) { + _relationships.put(ee.getKey(), ee.getValue()); + } + } + } + } + } + } + return _relationships; + } + + @SuppressWarnings("unchecked") + private LinkedHashMap<RelationshipType,NodeTemplate> _getExplicitRelationship(LinkedHashMap<String,Object> req,Object value) { + // Handle explicit relationship + + // For example, + // - req: + // node: DBMS + // relationship: tosca.relationships.HostedOn + + LinkedHashMap<RelationshipType,NodeTemplate> explicitRelation = new LinkedHashMap<RelationshipType,NodeTemplate>(); + String node; + if(value instanceof LinkedHashMap) { + node = (String)((LinkedHashMap<String,Object>)value).get("node"); + } + else { + node = (String)value; + } + + if(node != null && !node.isEmpty()) { + //msg = _('Lookup by TOSCA types is not supported. ' + // 'Requirement for "%s" can not be full-filled.') % self.name + boolean bFound = false; + for(String k: EntityType.TOSCA_DEF.keySet()) { + if(k.equals(node)) { + bFound = true; + break; + } + } + if(bFound || customDef.get(node) != null) { + ExceptionCollector.appendException(String.format( + "NotImplementedError: Lookup by TOSCA types is not supported. Requirement for \"%s\" can not be full-filled", + getName())); + return null; + } + if(templates.get(node) == null) { + ExceptionCollector.appendException(String.format( + "KeyError: Node template \"%s\" was not found",node)); + return null; + } + NodeTemplate relatedTpl = new NodeTemplate(node,templates,customDef,null,null); + Object relationship = null; + String relationshipString = null; + if(value instanceof LinkedHashMap) { + relationship = ((LinkedHashMap<String,Object>)value).get("relationship"); + // here relationship can be a string or a LHM with 'type':<relationship> + } + // check if its type has relationship defined + if(relationship == null) { + ArrayList<Object> parentReqs = ((NodeType)typeDefinition).getAllRequirements(); + if(parentReqs == null) { + ExceptionCollector.appendException("ValidationError: parent_req is null"); + } + else { + for(String key: req.keySet()) { + boolean bFoundRel = false; + for(Object rdo: parentReqs) { + LinkedHashMap<String,Object> reqDict = (LinkedHashMap<String,Object>)rdo; + LinkedHashMap<String,Object> relDict = (LinkedHashMap<String,Object>)reqDict.get(key); + if(relDict != null) { + relationship = relDict.get("relationship"); + //BUG-python??? need to break twice? + bFoundRel = true; + break; + } + } + if(bFoundRel) { + break; + } + } + } + } + + if(relationship != null) { + // here relationship can be a string or a LHM with 'type':<relationship> + if(relationship instanceof String) { + relationshipString = (String)relationship; + } + else if(relationship instanceof LinkedHashMap) { + relationshipString = (String)((LinkedHashMap<String,Object>)relationship).get("type"); + } + + boolean foundRelationshipTpl = false; + // apply available relationship templates if found + if(availableRelTpls != null) { + for(RelationshipTemplate tpl: availableRelTpls) { + if(tpl.getName().equals(relationshipString)) { + RelationshipType rtype = new RelationshipType(tpl.getType(),null,customDef); + explicitRelation.put(rtype, relatedTpl); + tpl.setTarget(relatedTpl); + tpl.setSource(this); + relationshipTpl.add(tpl); + foundRelationshipTpl = true; + } + } + } + // create relationship template object. + String relPrfx = EntityType.RELATIONSHIP_PREFIX; + if(!foundRelationshipTpl) { + if(relationship instanceof LinkedHashMap) { + relationshipString = (String)((LinkedHashMap<String,Object>)relationship).get("type"); + if(relationshipString != null) { + if(availableRelTypes != null && !availableRelTypes.isEmpty() && + availableRelTypes.get(relationshipString) != null) { + ; + } + else if(!(relationshipString).startsWith(relPrfx)) { + relationshipString = relPrfx + relationshipString; + } + } + else { + ExceptionCollector.appendException(String.format( + "MissingRequiredFieldError: \"relationship\" used in template \"%s\" is missing required field \"type\"", + relatedTpl.getName())); + } + } + for(RelationshipType rtype: ((NodeType)typeDefinition).getRelationship().keySet()) { + if(rtype.getType().equals(relationshipString)) { + explicitRelation.put(rtype,relatedTpl); + relatedTpl._addRelationshipTemplate(req,rtype.getType(),this); + } + else if(availableRelTypes != null && !availableRelTypes.isEmpty()) { + LinkedHashMap<String,Object> relTypeDef = (LinkedHashMap<String,Object>)availableRelTypes.get(relationshipString); + if(relTypeDef != null) { + String superType = (String)relTypeDef.get("derived_from"); + if(superType != null) { + if(!superType.startsWith(relPrfx)) { + superType = relPrfx + superType; + } + if(rtype.getType().equals(superType)) { + explicitRelation.put(rtype,relatedTpl); + relatedTpl._addRelationshipTemplate(req,rtype.getType(),this); + } + } + } + } + } + } + } + } + return explicitRelation; + } + + @SuppressWarnings("unchecked") + private void _addRelationshipTemplate(LinkedHashMap<String,Object> requirement, String rtype, NodeTemplate source) { + LinkedHashMap<String,Object> req = (LinkedHashMap<String,Object>)CopyUtils.copyLhmOrAl(requirement); + req.put("type",rtype); + RelationshipTemplate tpl = new RelationshipTemplate(req, rtype, customDef, this, source); + relationshipTpl.add(tpl); + } + + public ArrayList<RelationshipTemplate> getRelationshipTemplate() { + return relationshipTpl; + } + + void _addNext(NodeTemplate nodetpl,RelationshipType relationship) { + related.put(nodetpl,relationship); + } + + public ArrayList<NodeTemplate> getRelatedNodes() { + if(related.isEmpty()) { + for(Map.Entry<RelationshipType,NodeType> me: ((NodeType)typeDefinition).getRelationship().entrySet()) { + RelationshipType relation = me.getKey(); + NodeType node = me.getValue(); + for(String tpl: templates.keySet()) { + if(tpl.equals(node.getType())) { + //BUG.. python has + // self.related[NodeTemplate(tpl)] = relation + // but NodeTemplate doesn't have a constructor with just name... + //???? + related.put(new NodeTemplate(tpl,null,null,null,null),relation); + } + } + } + } + return new ArrayList<NodeTemplate>(related.keySet()); + } + + public void validate(/*tosca_tpl=none is not used...*/) { + _validateCapabilities(); + _validateRequirements(); + _validateProperties(entityTpl,(NodeType)typeDefinition); + _validateInterfaces(); + for(Property prop: getPropertiesObjects()) { + prop.validate(); + } + } + + private Metadata _metaData() { + if(entityTpl.get(METADATA) != null) { + return new Metadata((Map<String,Object>)entityTpl.get(METADATA)); + } + else { + return null; + } + } + + @SuppressWarnings("unchecked") + private void _validateRequirements() { + ArrayList<Object> typeRequires = ((NodeType)typeDefinition).getAllRequirements(); + ArrayList<String> allowedReqs = new ArrayList<>(); + allowedReqs.add("template"); + if(typeRequires != null) { + for(Object to: typeRequires) { + LinkedHashMap<String,Object> treq = (LinkedHashMap<String,Object>)to; + for(Map.Entry<String,Object> me: treq.entrySet()) { + String key = me.getKey(); + Object value = me.getValue(); + allowedReqs.add(key); + if(value instanceof LinkedHashMap) { + allowedReqs.addAll(((LinkedHashMap<String,Object>)value).keySet()); + } + } + + } + } + + ArrayList<Object> requires = (ArrayList<Object>)((NodeType)typeDefinition).getValue(REQUIREMENTS, entityTpl, false); + if(requires != null) { + if(!(requires instanceof ArrayList)) { + ExceptionCollector.appendException(String.format( + "TypeMismatchError: \"requirements\" of template \"%s\" are not of type \"list\"",name)); + } + else { + for(Object ro: requires) { + LinkedHashMap<String,Object> req = (LinkedHashMap<String,Object>)ro; + for(Map.Entry<String,Object> me: req.entrySet()) { + String rl = me.getKey(); + Object vo = me.getValue(); + if(vo instanceof LinkedHashMap) { + LinkedHashMap<String,Object> value = (LinkedHashMap<String,Object>)vo; + _validateRequirementsKeys(value); + _validateRequirementsProperties(value); + allowedReqs.add(rl); + } + } + _commonValidateField(req,allowedReqs,"requirements"); + } + } + } + } + + @SuppressWarnings("unchecked") + private void _validateRequirementsProperties(LinkedHashMap<String,Object> reqs) { + // TO-DO(anyone): Only occurrences property of the requirements is + // validated here. Validation of other requirement properties are being + // validated in different files. Better to keep all the requirements + // properties validation here. + for(Map.Entry<String,Object> me: reqs.entrySet()) { + if(me.getKey().equals("occurrences")) { + ArrayList<Object> val = (ArrayList<Object>)me.getValue(); + _validateOccurrences(val); + } + + } + } + + private void _validateOccurrences(ArrayList<Object> occurrences) { + DataEntity.validateDatatype("list",occurrences,null,null,null); + for(Object val: occurrences) { + DataEntity.validateDatatype("Integer",val,null,null,null); + } + if(occurrences.size() != 2 || + !(0 <= (int)occurrences.get(0) && (int)occurrences.get(0) <= (int)occurrences.get(1)) || + (int)occurrences.get(1) == 0) { + ExceptionCollector.appendException(String.format( + "InvalidPropertyValueError: property has invalid value %s",occurrences.toString())); + } + } + + private void _validateRequirementsKeys(LinkedHashMap<String,Object> reqs) { + for(String key: reqs.keySet()) { + boolean bFound = false; + for(int i=0; i< REQUIREMENTS_SECTION.length; i++) { + if(key.equals(REQUIREMENTS_SECTION[i])) { + bFound = true; + break; + } + } + if(!bFound) { + ExceptionCollector.appendException(String.format( + "UnknownFieldError: \"requirements\" of template \"%s\" contains unknown field \"%s\"",name,key)); + } + } + } + + @SuppressWarnings("unchecked") + private void _validateInterfaces() { + LinkedHashMap<String,Object> ifaces = (LinkedHashMap<String,Object>) + ((NodeType)typeDefinition).getValue(INTERFACES, entityTpl, false); + if(ifaces != null) { + for(Map.Entry<String,Object> me: ifaces.entrySet()) { + String iname = me.getKey(); + LinkedHashMap<String,Object> value = (LinkedHashMap<String,Object>)me.getValue(); + if(iname.equals(InterfacesDef.LIFECYCLE) || iname.equals(InterfacesDef.LIFECYCLE_SHORTNAME)) { + // maybe we should convert [] to arraylist??? + ArrayList<String> inlo = new ArrayList<>(); + for(int i=0; i<InterfacesDef.interfacesNodeLifecycleOperations.length; i++) { + inlo.add(InterfacesDef.interfacesNodeLifecycleOperations[i]); + } + _commonValidateField(value,inlo,"interfaces"); + } + else if(iname.equals(InterfacesDef.CONFIGURE) || iname.equals(InterfacesDef.CONFIGURE_SHORTNAME)) { + // maybe we should convert [] to arraylist??? + ArrayList<String> irco = new ArrayList<>(); + for(int i=0; i<InterfacesDef.interfacesRelationshipConfigureOperations.length; i++) { + irco.add(InterfacesDef.interfacesRelationshipConfigureOperations[i]); + } + _commonValidateField(value,irco,"interfaces"); + } + else if(((NodeType)typeDefinition).getInterfaces().keySet().contains(iname)) { + _commonValidateField(value,_collectCustomIfaceOperations(iname),"interfaces"); + } + else { + ExceptionCollector.appendException(String.format( + "UnknownFieldError: \"interfaces\" of template \"%s\" contains unknown field %s",name,iname)); + } + } + } + } + + @SuppressWarnings("unchecked") + private ArrayList<String> _collectCustomIfaceOperations(String iname) { + ArrayList<String> allowedOperations = new ArrayList<>(); + LinkedHashMap<String,Object> nodetypeIfaceDef = (LinkedHashMap<String,Object>)((NodeType) + typeDefinition).getInterfaces().get(iname); + allowedOperations.addAll(nodetypeIfaceDef.keySet()); + String ifaceType = (String)nodetypeIfaceDef.get("type"); + if(ifaceType != null) { + LinkedHashMap<String,Object> ifaceTypeDef = null; + if(((NodeType)typeDefinition).customDef != null) { + ifaceTypeDef = (LinkedHashMap<String,Object>)((NodeType)typeDefinition).customDef.get(ifaceType); + } + if(ifaceTypeDef == null) { + ifaceTypeDef = (LinkedHashMap<String,Object>)EntityType.TOSCA_DEF.get(ifaceType); + } + allowedOperations.addAll(ifaceTypeDef.keySet()); + } + // maybe we should convert [] to arraylist??? + ArrayList<String> idrw = new ArrayList<>(); + for(int i=0; i<InterfacesDef.INTERFACE_DEF_RESERVED_WORDS.length; i++) { + idrw.add(InterfacesDef.INTERFACE_DEF_RESERVED_WORDS[i]); + } + allowedOperations.removeAll(idrw); + return allowedOperations; + } + + private void _validateFields(LinkedHashMap<String,Object> nodetemplate) { + for(String ntname: nodetemplate.keySet()) { + boolean bFound = false; + for(int i=0; i< SECTIONS.length; i++) { + if(ntname.equals(SECTIONS[i])) { + bFound = true; + break; + } + } + if(!bFound) { + for(int i=0; i< SPECIAL_SECTIONS.length; i++) { + if(ntname.equals(SPECIAL_SECTIONS[i])) { + bFound = true; + break; + } + } + + } + if(!bFound) { + ExceptionCollector.appendException(String.format( + "UnknownFieldError: Node template \"%s\" has unknown field \"%s\"",name,ntname)); + } + } + } + + // getter/setter + + public SubstitutionMappings getSubMappingToscaTemplate() { + return subMappingToscaTemplate; + } + + public void setSubMappingToscaTemplate(SubstitutionMappings sm) { + subMappingToscaTemplate = sm; + } + + // **experimental** (multilevel nesting) + public SubstitutionMappings getSubMappingToscaTemplate2() { + return subMappingToscaTemplate2; + } + + public void setSubMappingToscaTemplate2(SubstitutionMappings sm) { + subMappingToscaTemplate2 = sm; + } + + public Metadata getMetaData() { + return metadata; + } + + public void setMetaData(Metadata metadata) { + this.metadata = metadata; + } + + @Override + public String toString() { + return "NodeTemplate{" + + //"templates=" + templates + + //", customDef=" + customDef + + //", availableRelTpls=" + availableRelTpls + + //", availableRelTypes=" + availableRelTypes + + //", related=" + related + + //", relationshipTpl=" + relationshipTpl + + //", _relationships=" + _relationships + + ", subMappingToscaTemplate=" + (subMappingToscaTemplate==null?"":subMappingToscaTemplate.toLimitedString()) + + //", subMappingToscaTemplate2=" +( subMappingToscaTemplate2 ==null?"":subMappingToscaTemplate2.toLimitedString()) + + ", metadata=" + metadata + + '}'; + } +} + +/*python + +from toscaparser.common.exception import ExceptionCollector +from toscaparser.common.exception import InvalidPropertyValueError +from toscaparser.common.exception import MissingRequiredFieldError +from toscaparser.common.exception import TypeMismatchError +from toscaparser.common.exception import UnknownFieldError +from toscaparser.common.exception import ValidationError +from toscaparser.dataentity import DataEntity +from toscaparser.elements.interfaces import CONFIGURE +from toscaparser.elements.interfaces import CONFIGURE_SHORTNAME +from toscaparser.elements.interfaces import INTERFACE_DEF_RESERVED_WORDS +from toscaparser.elements.interfaces import InterfacesDef +from toscaparser.elements.interfaces import LIFECYCLE +from toscaparser.elements.interfaces import LIFECYCLE_SHORTNAME +from toscaparser.elements.relationshiptype import RelationshipType +from toscaparser.entity_template import EntityTemplate +from toscaparser.relationship_template import RelationshipTemplate +from toscaparser.utils.gettextutils import _ + +log = logging.getLogger('tosca') + + +class NodeTemplate(EntityTemplate): + '''Node template from a Tosca profile.''' + def __init__(self, name, node_templates, custom_def=None, + available_rel_tpls=None, available_rel_types=None): + super(NodeTemplate, self).__init__(name, node_templates[name], + 'node_type', + custom_def) + self.templates = node_templates + self._validate_fields(node_templates[name]) + self.custom_def = custom_def + self.related = {} + self.relationship_tpl = [] + self.available_rel_tpls = available_rel_tpls + self.available_rel_types = available_rel_types + self._relationships = {} + self.sub_mapping_tosca_template = None + + @property + def relationships(self): + if not self._relationships: + requires = self.requirements + if requires and isinstance(requires, list): + for r in requires: + for r1, value in r.items(): + explicit = self._get_explicit_relationship(r, value) + if explicit: + for key, value in explicit.items(): + self._relationships[key] = value + return self._relationships + + def _get_explicit_relationship(self, req, value): + """Handle explicit relationship + + For example, + - req: + node: DBMS + relationship: tosca.relationships.HostedOn + """ + explicit_relation = {} + node = value.get('node') if isinstance(value, dict) else value + + if node: + # TO-DO(spzala) implement look up once Glance meta data is available + # to find a matching TOSCA node using the TOSCA types + msg = _('Lookup by TOSCA types is not supported. ' + 'Requirement for "%s" can not be full-filled.') % self.name + if (node in list(self.type_definition.TOSCA_DEF.keys()) + or node in self.custom_def): + ExceptionCollector.appendException(NotImplementedError(msg)) + return + + if node not in self.templates: + ExceptionCollector.appendException( + KeyError(_('Node template "%s" was not found.') % node)) + return + + related_tpl = NodeTemplate(node, self.templates, self.custom_def) + relationship = value.get('relationship') \ + if isinstance(value, dict) else None + # check if it's type has relationship defined + if not relationship: + parent_reqs = self.type_definition.get_all_requirements() + if parent_reqs is None: + ExceptionCollector.appendException( + ValidationError(message='parent_req is ' + + str(parent_reqs))) + else: + for key in req.keys(): + for req_dict in parent_reqs: + if key in req_dict.keys(): + relationship = (req_dict.get(key). + get('relationship')) + break + if relationship: + found_relationship_tpl = False + # apply available relationship templates if found + if self.available_rel_tpls: + for tpl in self.available_rel_tpls: + if tpl.name == relationship: + rtype = RelationshipType(tpl.type, None, + self.custom_def) + explicit_relation[rtype] = related_tpl + tpl.target = related_tpl + tpl.source = self + self.relationship_tpl.append(tpl) + found_relationship_tpl = True + # create relationship template object. + rel_prfx = self.type_definition.RELATIONSHIP_PREFIX + if not found_relationship_tpl: + if isinstance(relationship, dict): + relationship = relationship.get('type') + if relationship: + if self.available_rel_types and \ + relationship in self.available_rel_types.keys(): + pass + elif not relationship.startswith(rel_prfx): + relationship = rel_prfx + relationship + else: + ExceptionCollector.appendException( + MissingRequiredFieldError( + what=_('"relationship" used in template ' + '"%s"') % related_tpl.name, + required=self.TYPE)) + for rtype in self.type_definition.relationship.keys(): + if rtype.type == relationship: + explicit_relation[rtype] = related_tpl + related_tpl._add_relationship_template(req, + rtype.type, + self) + elif self.available_rel_types: + if relationship in self.available_rel_types.keys(): + rel_type_def = self.available_rel_types.\ + get(relationship) + if 'derived_from' in rel_type_def: + super_type = \ + rel_type_def.get('derived_from') + if not super_type.startswith(rel_prfx): + super_type = rel_prfx + super_type + if rtype.type == super_type: + explicit_relation[rtype] = related_tpl + related_tpl.\ + _add_relationship_template( + req, rtype.type, self) + return explicit_relation + + def _add_relationship_template(self, requirement, rtype, source): + req = requirement.copy() + req['type'] = rtype + tpl = RelationshipTemplate(req, rtype, self.custom_def, self, source) + self.relationship_tpl.append(tpl) + + def get_relationship_template(self): + return self.relationship_tpl + + def _add_next(self, nodetpl, relationship): + self.related[nodetpl] = relationship + + @property + def related_nodes(self): + if not self.related: + for relation, node in self.type_definition.relationship.items(): + for tpl in self.templates: + if tpl == node.type: + self.related[NodeTemplate(tpl)] = relation + return self.related.keys() + + def validate(self, tosca_tpl=None): + self._validate_capabilities() + self._validate_requirements() + self._validate_properties(self.entity_tpl, self.type_definition) + self._validate_interfaces() + for prop in self.get_properties_objects(): + prop.validate() + + def _validate_requirements(self): + type_requires = self.type_definition.get_all_requirements() + allowed_reqs = ["template"] + if type_requires: + for treq in type_requires: + for key, value in treq.items(): + allowed_reqs.append(key) + if isinstance(value, dict): + for key in value: + allowed_reqs.append(key) + + requires = self.type_definition.get_value(self.REQUIREMENTS, + self.entity_tpl) + if requires: + if not isinstance(requires, list): + ExceptionCollector.appendException( + TypeMismatchError( + what='"requirements" of template "%s"' % self.name, + type='list')) + else: + for req in requires: + for r1, value in req.items(): + if isinstance(value, dict): + self._validate_requirements_keys(value) + self._validate_requirements_properties(value) + allowed_reqs.append(r1) + self._common_validate_field(req, allowed_reqs, + 'requirements') + + def _validate_requirements_properties(self, requirements): + # TO-DO(anyone): Only occurrences property of the requirements is + # validated here. Validation of other requirement properties are being + # validated in different files. Better to keep all the requirements + # properties validation here. + for key, value in requirements.items(): + if key == 'occurrences': + self._validate_occurrences(value) + break + + def _validate_occurrences(self, occurrences): + DataEntity.validate_datatype('list', occurrences) + for value in occurrences: + DataEntity.validate_datatype('integer', value) + if len(occurrences) != 2 or not (0 <= occurrences[0] <= occurrences[1]) \ + or occurrences[1] == 0: + ExceptionCollector.appendException( + InvalidPropertyValueError(what=(occurrences))) + + def _validate_requirements_keys(self, requirement): + for key in requirement.keys(): + if key not in self.REQUIREMENTS_SECTION: + ExceptionCollector.appendException( + UnknownFieldError( + what='"requirements" of template "%s"' % self.name, + field=key)) + + def _validate_interfaces(self): + ifaces = self.type_definition.get_value(self.INTERFACES, + self.entity_tpl) + if ifaces: + for name, value in ifaces.items(): + if name in (LIFECYCLE, LIFECYCLE_SHORTNAME): + self._common_validate_field( + value, InterfacesDef. + interfaces_node_lifecycle_operations, + 'interfaces') + elif name in (CONFIGURE, CONFIGURE_SHORTNAME): + self._common_validate_field( + value, InterfacesDef. + interfaces_relationship_configure_operations, + 'interfaces') + elif name in self.type_definition.interfaces.keys(): + self._common_validate_field( + value, + self._collect_custom_iface_operations(name), + 'interfaces') + else: + ExceptionCollector.appendException( + UnknownFieldError( + what='"interfaces" of template "%s"' % + self.name, field=name)) + + def _collect_custom_iface_operations(self, name): + allowed_operations = [] + nodetype_iface_def = self.type_definition.interfaces[name] + allowed_operations.extend(nodetype_iface_def.keys()) + if 'type' in nodetype_iface_def: + iface_type = nodetype_iface_def['type'] + if iface_type in self.type_definition.custom_def: + iface_type_def = self.type_definition.custom_def[iface_type] + else: + iface_type_def = self.type_definition.TOSCA_DEF[iface_type] + allowed_operations.extend(iface_type_def.keys()) + allowed_operations = [op for op in allowed_operations if + op not in INTERFACE_DEF_RESERVED_WORDS] + return allowed_operations + + def _validate_fields(self, nodetemplate): + for name in nodetemplate.keys(): + if name not in self.SECTIONS and name not in self.SPECIAL_SECTIONS: + ExceptionCollector.appendException( + UnknownFieldError(what='Node template "%s"' % self.name, + field=name))*/
\ No newline at end of file |