/* * Copyright © 2016-2018 European Support Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.openecomp.sdc.tosca.services.impl; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.StringUtils; import org.openecomp.core.utilities.CommonMethods; import org.openecomp.sdc.common.errors.CoreException; import org.openecomp.sdc.tosca.datatypes.ToscaElementTypes; import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel; import org.openecomp.sdc.tosca.datatypes.model.AttributeDefinition; import org.openecomp.sdc.tosca.datatypes.model.CapabilityDefinition; import org.openecomp.sdc.tosca.datatypes.model.CapabilityType; import org.openecomp.sdc.tosca.datatypes.model.DefinitionOfDataType; import org.openecomp.sdc.tosca.datatypes.model.DataType; import org.openecomp.sdc.tosca.datatypes.model.Import; import org.openecomp.sdc.tosca.datatypes.model.InterfaceDefinitionType; import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate; import org.openecomp.sdc.tosca.datatypes.model.NodeType; import org.openecomp.sdc.tosca.datatypes.model.ParameterDefinition; import org.openecomp.sdc.tosca.datatypes.model.PropertyDefinition; import org.openecomp.sdc.tosca.datatypes.model.PropertyType; import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment; import org.openecomp.sdc.tosca.datatypes.model.RequirementDefinition; import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate; import org.openecomp.sdc.tosca.errors.ToscaElementTypeNotFoundErrorBuilder; import org.openecomp.sdc.tosca.errors.ToscaInvalidEntryNotFoundErrorBuilder; import org.openecomp.sdc.tosca.errors.ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder; import org.openecomp.sdc.tosca.errors.ToscaInvalidSubstitutionServiceTemplateErrorBuilder; import org.openecomp.sdc.tosca.services.DataModelUtil; import org.openecomp.sdc.tosca.services.ToscaAnalyzerService; import org.openecomp.sdc.tosca.services.ToscaConstants; import org.openecomp.sdc.tosca.services.ToscaExtensionYamlUtil; import org.openecomp.sdc.tosca.services.ToscaUtil; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; public class ToscaAnalyzerServiceImpl implements ToscaAnalyzerService { private final String GET_NODE_TYPE_METHOD_NAME = "getNode_types"; private final String GET_DERIVED_FROM_METHOD_NAME = "getDerived_from"; private final String GET_TYPE_METHOD_NAME = "getType"; private final String GET_DATA_TYPE_METHOD_NAME = "getData_types"; private final String GET_INTERFACE_TYPE_METHOD_NAME = "getInterface_types"; private final String TOSCA_DOT = "tosca."; private final String DOT_ROOT = ".Root"; @Override public List> calculateExposedRequirements( List> nodeTypeRequirementsDefinitionList, Map nodeTemplateRequirementsAssignment) { if (nodeTypeRequirementsDefinitionList == null) { return Collections.emptyList(); } for (Map.Entry entry : nodeTemplateRequirementsAssignment .entrySet()) { if (entry.getValue().getNode() != null) { Optional requirementDefinition = DataModelUtil.getRequirementDefinition(nodeTypeRequirementsDefinitionList, entry .getKey()); RequirementDefinition cloneRequirementDefinition; if (requirementDefinition.isPresent()) { cloneRequirementDefinition = requirementDefinition.get().clone(); updateRequirementDefinition(nodeTypeRequirementsDefinitionList, entry, cloneRequirementDefinition); } } else { for (Map nodeTypeRequirementsMap : nodeTypeRequirementsDefinitionList) { updateMinMaxOccurencesForNodeTypeRequirement(entry, nodeTypeRequirementsMap); } } } return nodeTypeRequirementsDefinitionList; } private void updateMinMaxOccurencesForNodeTypeRequirement( Map.Entry entry, Map nodeTypeRequirementsMap) { Object max = nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences() != null && nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences().length > 0 ? nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences()[1] : 1; Object min = nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences() != null && nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences().length > 0 ? nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences()[0] : 1; nodeTypeRequirementsMap.get(entry.getKey()).setOccurrences(new Object[]{min, max}); } private void updateRequirementDefinition( List> nodeTypeRequirementsDefinitionList, Map.Entry entry, RequirementDefinition cloneRequirementDefinition) { if (!evaluateRequirementFulfillment(cloneRequirementDefinition)) { CommonMethods.mergeEntryInList(entry.getKey(), cloneRequirementDefinition, nodeTypeRequirementsDefinitionList); } else { DataModelUtil.removeRequirementsDefinition(nodeTypeRequirementsDefinitionList, entry .getKey()); } } private static boolean evaluateRequirementFulfillment(RequirementDefinition requirementDefinition) { Object[] occurrences = requirementDefinition.getOccurrences(); if (occurrences == null) { requirementDefinition.setOccurrences(new Object[]{1, 1}); return false; } if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) { return false; } if (occurrences[1].equals(1)) { return true; } occurrences[1] = (Integer) occurrences[1] - 1; return false; } @Override public Map calculateExposedCapabilities( Map nodeTypeCapabilitiesDefinition, Map> fullFilledRequirementsDefinitionMap) { String capabilityKey; String capability; String node; for (Map.Entry> entry : fullFilledRequirementsDefinitionMap.entrySet()) { for (Map.Entry fullFilledEntry : entry.getValue().entrySet()) { capability = fullFilledEntry.getValue().getCapability(); node = fullFilledEntry.getValue().getNode(); capabilityKey = capability + "_" + node; CapabilityDefinition capabilityDefinition = nodeTypeCapabilitiesDefinition.get( capabilityKey); if (capabilityDefinition != null) { CapabilityDefinition clonedCapabilityDefinition = capabilityDefinition.clone(); nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityDefinition.clone()); updateNodeTypeCapabilitiesDefinition(nodeTypeCapabilitiesDefinition, capabilityKey, clonedCapabilityDefinition); } } } Map exposedCapabilitiesDefinition = new HashMap<>(); for (Map.Entry entry : nodeTypeCapabilitiesDefinition .entrySet()) { exposedCapabilitiesDefinition.put(entry.getKey(), entry.getValue()); } return exposedCapabilitiesDefinition; } private void updateNodeTypeCapabilitiesDefinition( Map nodeTypeCapabilitiesDefinition, String capabilityKey, CapabilityDefinition clonedCapabilityDefinition) { if (evaluateCapabilityFulfillment(clonedCapabilityDefinition)) { nodeTypeCapabilitiesDefinition.remove(capabilityKey); } else { nodeTypeCapabilitiesDefinition.put(capabilityKey, clonedCapabilityDefinition); } } private static boolean evaluateCapabilityFulfillment(CapabilityDefinition capabilityDefinition) { Object[] occurrences = capabilityDefinition.getOccurrences(); if (occurrences == null) { capabilityDefinition.setOccurrences(new Object[]{1, ToscaConstants.UNBOUNDED}); return false; } if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) { return false; } if (occurrences[1].equals(1)) { return true; } occurrences[1] = (Integer) occurrences[1] - 1; return false; } /* node template with type equal to node type or derived from node type */ @Override public Map getNodeTemplatesByType(ServiceTemplate serviceTemplate, String nodeType, ToscaServiceModel toscaServiceModel) { Map nodeTemplates = new HashMap<>(); if (Objects.nonNull(serviceTemplate.getTopology_template()) && MapUtils.isNotEmpty(serviceTemplate.getTopology_template().getNode_templates())) { for (Map.Entry nodeTemplateEntry : serviceTemplate .getTopology_template().getNode_templates().entrySet()) { if (isTypeOf(nodeTemplateEntry.getValue(), nodeType, serviceTemplate, toscaServiceModel)) { nodeTemplates.put(nodeTemplateEntry.getKey(), nodeTemplateEntry.getValue()); } } } return nodeTemplates; } @Override public Optional fetchNodeType(String nodeTypeKey, Collection serviceTemplates) { Optional> nodeTypeMap = serviceTemplates.stream() .map(ServiceTemplate::getNode_types) .filter(nodeTypes -> Objects.nonNull(nodeTypes) && nodeTypes.containsKey(nodeTypeKey)) .findFirst(); return nodeTypeMap.map(stringNodeTypeMap -> stringNodeTypeMap.get(nodeTypeKey)); } @Override public boolean isTypeOf(NodeTemplate nodeTemplate, String nodeType, ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) { return isTypeOf(nodeTemplate, nodeType, GET_NODE_TYPE_METHOD_NAME, serviceTemplate, toscaServiceModel); } @Override public List getRequirements(NodeTemplate nodeTemplate, String requirementId) { List requirements = new ArrayList<>(); List> requirementList = nodeTemplate.getRequirements(); if (requirementList != null) { requirementList.stream().filter(reqMap -> reqMap.get(requirementId) != null) .forEach(reqMap -> { ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil(); RequirementAssignment reqAssignment = toscaExtensionYamlUtil .yamlToObject(toscaExtensionYamlUtil.objectToYaml(reqMap.get(requirementId)), RequirementAssignment.class); requirements.add(reqAssignment); }); } return requirements; } @Override public Optional getNodeTemplateById(ServiceTemplate serviceTemplate, String nodeTemplateId) { if ((serviceTemplate.getTopology_template() != null) && (serviceTemplate.getTopology_template().getNode_templates() != null) && (serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId) != null)) { return Optional .of(serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId)); } return Optional.empty(); } @Override public Optional getSubstituteServiceTemplateName(String substituteNodeTemplateId, NodeTemplate substitutableNodeTemplate) { if (!isSubstitutableNodeTemplate(substitutableNodeTemplate)) { return Optional.empty(); } if (substitutableNodeTemplate.getProperties() != null && substitutableNodeTemplate.getProperties() .get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME) != null) { Object serviceTemplateFilter = substitutableNodeTemplate.getProperties() .get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME); if (serviceTemplateFilter != null && serviceTemplateFilter instanceof Map) { Object substituteServiceTemplate = ((Map) serviceTemplateFilter) .get(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME); handleNoSubstituteServiceTemplate(substituteNodeTemplateId, substituteServiceTemplate); return Optional.of(substituteServiceTemplate.toString()); } } throw new CoreException( new ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder(substituteNodeTemplateId) .build()); } private void handleNoSubstituteServiceTemplate(String substituteNodeTemplateId, Object substituteServiceTemplate) { if (substituteServiceTemplate == null) { throw new CoreException( new ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder(substituteNodeTemplateId) .build()); } } @Override public Map getSubstitutableNodeTemplates(ServiceTemplate serviceTemplate) { Map substitutableNodeTemplates = new HashMap<>(); if (serviceTemplate == null || serviceTemplate.getTopology_template() == null || serviceTemplate.getTopology_template().getNode_templates() == null) { return substitutableNodeTemplates; } Map nodeTemplates = serviceTemplate.getTopology_template().getNode_templates(); for (Map.Entry entry : nodeTemplates.entrySet()) { String nodeTemplateId = entry.getKey(); NodeTemplate nodeTemplate = entry.getValue(); if (isSubstitutableNodeTemplate(nodeTemplate)) { substitutableNodeTemplates.put(nodeTemplateId, nodeTemplate); } } return substitutableNodeTemplates; } @Override public Optional> getSubstitutionMappedNodeTemplateByExposedReq( String substituteServiceTemplateFileName, ServiceTemplate substituteServiceTemplate, String requirementId) { if (isSubstitutionServiceTemplate(substituteServiceTemplateFileName, substituteServiceTemplate)) { Map> substitutionMappingRequirements = substituteServiceTemplate.getTopology_template().getSubstitution_mappings() .getRequirements(); if (substitutionMappingRequirements != null) { List requirementMapping = substitutionMappingRequirements.get(requirementId); if (requirementMapping != null && !requirementMapping.isEmpty()) { String mappedNodeTemplateId = requirementMapping.get(0); Optional mappedNodeTemplate = getNodeTemplateById(substituteServiceTemplate, mappedNodeTemplateId); mappedNodeTemplate.orElseThrow(() -> new CoreException( new ToscaInvalidEntryNotFoundErrorBuilder("Node Template", mappedNodeTemplateId) .build())); Map.Entry mappedNodeTemplateEntry = new Map.Entry() { @Override public String getKey() { return mappedNodeTemplateId; } @Override public NodeTemplate getValue() { return mappedNodeTemplate.get(); } @Override public NodeTemplate setValue(NodeTemplate value) { return null; } }; return Optional.of(mappedNodeTemplateEntry); } } } return Optional.empty(); } /* match only for the input which is not null */ @Override public boolean isDesiredRequirementAssignment(RequirementAssignment requirementAssignment, String capability, String node, String relationship) { if (isSameCapability(requirementAssignment, capability)) { return false; } if (isSameRequirement(requirementAssignment, node)) { return false; } if (isSameRelationship(requirementAssignment, relationship)) { return false; } return !(capability == null && node == null && relationship == null); } private boolean isSameRelationship(RequirementAssignment requirementAssignment, String relationship) { return relationship != null && (requirementAssignment.getRelationship() == null || !requirementAssignment.getRelationship().equals(relationship)); } private boolean isSameRequirement(RequirementAssignment requirementAssignment, String node) { return node != null && (requirementAssignment.getNode() == null || !requirementAssignment.getNode().equals(node)); } private boolean isSameCapability(RequirementAssignment requirementAssignment, String capability) { return capability != null && (requirementAssignment.getCapability() == null || !requirementAssignment.getCapability().equals(capability)); } @Override public Object getFlatEntity(ToscaElementTypes elementType, String typeId, ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel) { Object returnEntity; switch (elementType) { case CAPABILITY_TYPE: returnEntity = new CapabilityType(); break; case NODE_TYPE: returnEntity = new NodeType(); break; case DATA_TYPE: returnEntity = new DataType(); break; default: throw new RuntimeException( "Entity[" + elementType + "] id[" + typeId + "] flat not supported"); } boolean isEntityFound = scanAnFlatEntity(elementType, typeId, returnEntity, serviceTemplate, toscaModel, new ArrayList<>(), 0); if (!isEntityFound) { throw new CoreException(new ToscaElementTypeNotFoundErrorBuilder(typeId).build()); } return returnEntity; } @Override public boolean isSubstitutableNodeTemplate(NodeTemplate nodeTemplate) { return nodeTemplate.getDirectives() != null && nodeTemplate.getDirectives().contains(ToscaConstants .NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE); } private Optional isTypeExistInServiceTemplateHierarchy(String typeToMatch, String typeToSearch, String getTypesMethodName, ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel, Set analyzedImportFiles) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Map searchableTypes = (Map) serviceTemplate.getClass().getMethod(getTypesMethodName) .invoke(serviceTemplate); if (!MapUtils.isEmpty(searchableTypes)) { T typeObject = searchableTypes.get(typeToSearch); if (Objects.nonNull(typeObject)) { String derivedFromTypeVal = (String) typeObject.getClass().getMethod(GET_DERIVED_FROM_METHOD_NAME).invoke(typeObject); if (Objects.equals(derivedFromTypeVal, typeToMatch)) { return Optional.of(true); } else if (Objects.isNull(derivedFromTypeVal) || isTypeIsToscaRoot(derivedFromTypeVal)) { return Optional.of(false); } else { return isTypeExistInServiceTemplateHierarchy(typeToMatch, derivedFromTypeVal, getTypesMethodName, serviceTemplate, toscaServiceModel, null); } } else { return isTypeExistInImports(typeToMatch, typeToSearch, getTypesMethodName, serviceTemplate, toscaServiceModel, analyzedImportFiles); } } return isTypeExistInImports(typeToMatch, typeToSearch, getTypesMethodName, serviceTemplate, toscaServiceModel, analyzedImportFiles); } private Optional isTypeExistInImports(String typeToMatch, String typeToSearch, String getTypesMethodName, ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel, Set filesScanned) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { List> imports = serviceTemplate.getImports(); if (CollectionUtils.isEmpty(imports)) { return Optional.empty(); } Set createdFilesScanned = createFilesScannedSet(filesScanned); for (Map map : imports) { ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil(); Import anImport = toscaExtensionYamlUtil .yamlToObject(toscaExtensionYamlUtil.objectToYaml(map.values().iterator().next()), Import.class); handleImportWithNoFileEntry(anImport); String importFile = anImport.getFile(); ServiceTemplate template = toscaServiceModel.getServiceTemplates().get(fetchFileNameForImport(importFile, serviceTemplate.getMetadata() == null ? null : serviceTemplate.getMetadata().get("filename"))); if (Objects.isNull(template) || createdFilesScanned.contains(ToscaUtil.getServiceTemplateFileName(template))) { continue; } else { createdFilesScanned.add(ToscaUtil.getServiceTemplateFileName(template)); } Optional typeExistInServiceTemplateHierarchy = isTypeExistInServiceTemplateHierarchy(typeToMatch, typeToSearch, getTypesMethodName, template, toscaServiceModel, createdFilesScanned); if (typeExistInServiceTemplateHierarchy.isPresent() && (typeExistInServiceTemplateHierarchy.get())) { createdFilesScanned.clear(); return Optional.of(true); } } return Optional.of(false); } private void handleImportWithNoFileEntry(Import anImport) { if (Objects.isNull(anImport) || Objects.isNull(anImport.getFile())) { throw new RuntimeException("import without file entry"); } } private Set createFilesScannedSet(Set filesScanned) { Set retFileScanned = filesScanned; if (Objects.isNull(retFileScanned)) { retFileScanned = new HashSet<>(); } return retFileScanned; } private boolean isTypeIsToscaRoot(String type) { return (type.contains(TOSCA_DOT) && type.contains(DOT_ROOT)); } private boolean isSubstitutionServiceTemplate(String substituteServiceTemplateFileName, ServiceTemplate substituteServiceTemplate) { if (substituteServiceTemplate != null && substituteServiceTemplate.getTopology_template() != null && substituteServiceTemplate.getTopology_template().getSubstitution_mappings() != null) { if (substituteServiceTemplate.getTopology_template().getSubstitution_mappings() .getNode_type() == null) { throw new CoreException(new ToscaInvalidSubstitutionServiceTemplateErrorBuilder( substituteServiceTemplateFileName).build()); } return true; } return false; } private boolean scanAnFlatEntity(ToscaElementTypes elementType, String typeId, Object entity, ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel, List filesScanned, int rootScanStartInx) { boolean entityFound = enrichEntityFromCurrentServiceTemplate(elementType, typeId, entity, serviceTemplate, toscaModel, filesScanned, rootScanStartInx); if (!entityFound) { List> imports = serviceTemplate.getImports(); if (CollectionUtils.isEmpty(imports)) { return false; } boolean found = false; for (Map importMap : imports) { if (found) { return true; } found = isFlatEntity(importMap, entity, serviceTemplate, filesScanned, toscaModel, elementType, typeId); } return found; } return true; } private boolean isFlatEntity(Map importMap, Object entity, ServiceTemplate serviceTemplate, List filesScanned, ToscaServiceModel toscaModel, ToscaElementTypes elementType, String typeId) { boolean found = false; ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil(); for (Object importObject : importMap.values()) { Import importServiceTemplate = toscaExtensionYamlUtil .yamlToObject(toscaExtensionYamlUtil.objectToYaml(importObject), Import.class); String fileName = fetchFileNameForImport(importServiceTemplate.getFile(), serviceTemplate.getMetadata() == null ? null : serviceTemplate.getMetadata().get( "filename")); if (filesScanned.contains(fileName)) { return false; } else { filesScanned.add(fileName); } ServiceTemplate template = toscaModel.getServiceTemplates().get(fileName); found = scanAnFlatEntity(elementType, typeId, entity, template, toscaModel, filesScanned, filesScanned.size()); } return found; } private String fetchFileNameForImport(String importServiceTemplateFile, String currentMetadatafileName) { if (importServiceTemplateFile.contains("../")) { return importServiceTemplateFile.replace("../", ""); } else if (currentMetadatafileName != null) { return currentMetadatafileName.substring(0, currentMetadatafileName.indexOf('/')) + "/" + importServiceTemplateFile; } else { return importServiceTemplateFile; } } private boolean enrichEntityFromCurrentServiceTemplate(ToscaElementTypes elementType, String typeId, Object entity, ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel, List filesScanned, int rootScanStartInx) { switch (elementType) { case CAPABILITY_TYPE: if (enrichCapabilityType(elementType, typeId, entity, serviceTemplate, toscaModel, filesScanned, rootScanStartInx)) { return false; } break; case NODE_TYPE: if (enrichNodeTypeInfo(elementType, typeId, entity, serviceTemplate, toscaModel, filesScanned, rootScanStartInx)) { return false; } break; case DATA_TYPE: if (enrichDataTypeInfo(elementType, typeId, entity, serviceTemplate, toscaModel, filesScanned, rootScanStartInx)) { return false; } break; default: throw new RuntimeException( "Entity[" + elementType + "] id[" + typeId + "] flat not supported"); } return true; } private boolean enrichNodeTypeInfo(ToscaElementTypes elementType, String typeId, Object entity, ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel, List filesScanned, int rootScanStartInx) { String derivedFrom; if (serviceTemplate.getNode_types() != null && serviceTemplate.getNode_types().containsKey(typeId)) { filesScanned.clear(); NodeType targetNodeType = (NodeType) entity; NodeType sourceNodeType = serviceTemplate.getNode_types().get(typeId); derivedFrom = sourceNodeType.getDerived_from(); if (derivedFrom != null) { scanAnFlatEntity(elementType, derivedFrom, entity, serviceTemplate, toscaModel, filesScanned, rootScanStartInx); } combineNodeTypeInfo(sourceNodeType, targetNodeType); } else { return true; } return false; } private boolean enrichDataTypeInfo(ToscaElementTypes elementType, String typeId, Object entity, ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel, List filesScanned, int rootScanStartInx) { String derivedFrom; if (serviceTemplate.getData_types() != null && serviceTemplate.getData_types().containsKey(typeId)) { filesScanned.clear(); DataType targetDataType = (DataType) entity; DataType sourceDataType = serviceTemplate.getData_types().get(typeId); derivedFrom = sourceDataType.getDerived_from(); if (derivedFrom != null) { scanAnFlatEntity(elementType, derivedFrom, entity, serviceTemplate, toscaModel, filesScanned, rootScanStartInx); } combineDataTypeInfo(sourceDataType, targetDataType); } else { return true; } return false; } private boolean enrichCapabilityType(ToscaElementTypes elementType, String typeId, Object entity, ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel, List filesScanned, int rootScanStartInx) { String derivedFrom; if (serviceTemplate.getCapability_types() != null && serviceTemplate.getCapability_types().containsKey(typeId)) { filesScanned.clear(); CapabilityType targetCapabilityType = (CapabilityType) entity; CapabilityType sourceCapabilityType = serviceTemplate.getCapability_types().get(typeId); derivedFrom = sourceCapabilityType.getDerived_from(); if (derivedFrom != null) { scanAnFlatEntity(elementType, derivedFrom, entity, serviceTemplate, toscaModel, filesScanned, rootScanStartInx); } combineCapabilityTypeInfo(sourceCapabilityType, targetCapabilityType); } else { return true; } return false; } private void combineNodeTypeInfo(NodeType sourceNodeType, NodeType targetNodeType) { targetNodeType.setDerived_from(sourceNodeType.getDerived_from()); targetNodeType.setDescription(sourceNodeType.getDescription()); targetNodeType.setVersion(sourceNodeType.getVersion()); targetNodeType.setProperties( CommonMethods.mergeMaps(targetNodeType.getProperties(), sourceNodeType.getProperties())); targetNodeType.setInterfaces( CommonMethods.mergeMaps(targetNodeType.getInterfaces(), sourceNodeType.getInterfaces())); targetNodeType.setArtifacts( CommonMethods.mergeMaps(targetNodeType.getArtifacts(), sourceNodeType.getArtifacts())); targetNodeType.setAttributes( CommonMethods.mergeMaps(targetNodeType.getAttributes(), sourceNodeType.getAttributes())); targetNodeType.setCapabilities(CommonMethods .mergeMaps(targetNodeType.getCapabilities(), sourceNodeType.getCapabilities())); targetNodeType.setRequirements(CommonMethods .mergeListsOfMap(targetNodeType.getRequirements(), sourceNodeType.getRequirements())); } private void combineDataTypeInfo(DataType sourceDataType, DataType targetDataType) { targetDataType.setDerived_from(sourceDataType.getDerived_from()); targetDataType.setDescription(sourceDataType.getDescription()); targetDataType.setVersion(sourceDataType.getVersion()); targetDataType.setProperties( CommonMethods.mergeMaps(targetDataType.getProperties(), sourceDataType.getProperties())); targetDataType.setConstraints( CommonMethods.mergeLists(targetDataType.getConstraints(), sourceDataType.getConstraints())); } private void combineCapabilityTypeInfo(CapabilityType sourceCapabilityType, CapabilityType targetCapabilityType) { targetCapabilityType.setAttributes(CommonMethods .mergeMaps(targetCapabilityType.getAttributes(), sourceCapabilityType.getAttributes())); targetCapabilityType.setProperties(CommonMethods .mergeMaps(targetCapabilityType.getProperties(), sourceCapabilityType.getProperties())); targetCapabilityType.setValid_source_types(CommonMethods .mergeLists(targetCapabilityType.getValid_source_types(), sourceCapabilityType.getValid_source_types())); if (StringUtils.isNotEmpty(sourceCapabilityType.getDerived_from())) { targetCapabilityType.setDerived_from(sourceCapabilityType.getDerived_from()); } if (StringUtils.isNotEmpty(sourceCapabilityType.getDescription())) { targetCapabilityType.setDescription(sourceCapabilityType.getDescription()); } if (StringUtils.isNotEmpty(sourceCapabilityType.getVersion())) { targetCapabilityType.setVersion(sourceCapabilityType.getVersion()); } } /* * Create node type according to the input substitution service template, while the substitution * service template can be mappted to this node type, for substitution mapping. * * @param substitutionServiceTemplate substitution serivce template * @param nodeTypeDerivedFromValue derived from value for the created node type * @return the node type */ @Override public NodeType createInitSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate, String nodeTypeDerivedFromValue) { NodeType substitutionNodeType = new NodeType(); substitutionNodeType.setDerived_from(nodeTypeDerivedFromValue); substitutionNodeType.setDescription(substitutionServiceTemplate.getDescription()); substitutionNodeType .setProperties(manageSubstitutionNodeTypeProperties(substitutionServiceTemplate)); substitutionNodeType .setAttributes(manageSubstitutionNodeTypeAttributes(substitutionServiceTemplate)); return substitutionNodeType; } @Override public Map manageSubstitutionNodeTypeProperties( ServiceTemplate substitutionServiceTemplate) { Map substitutionNodeTypeProperties = new HashMap<>(); Map properties = substitutionServiceTemplate.getTopology_template().getInputs(); if (properties == null) { return null; } PropertyDefinition propertyDefinition; String toscaPropertyName; for (Map.Entry entry : properties.entrySet()) { toscaPropertyName = entry.getKey(); propertyDefinition = new PropertyDefinition(); ParameterDefinition parameterDefinition = substitutionServiceTemplate.getTopology_template().getInputs().get(toscaPropertyName); propertyDefinition.setType(parameterDefinition.getType()); propertyDefinition.setDescription(parameterDefinition.getDescription()); propertyDefinition.set_default(parameterDefinition.get_default()); if (parameterDefinition.getRequired() != null) { propertyDefinition.setRequired(parameterDefinition.getRequired()); } if (propertyDefinition.get_default() != null) { propertyDefinition.setRequired(false); } if (!CollectionUtils.isEmpty(parameterDefinition.getConstraints())) { propertyDefinition.setConstraints(parameterDefinition.getConstraints()); } propertyDefinition.setEntry_schema(parameterDefinition.getEntry_schema()); if (parameterDefinition.getStatus() != null) { propertyDefinition.setStatus(parameterDefinition.getStatus()); } substitutionNodeTypeProperties.put(toscaPropertyName, propertyDefinition); } return substitutionNodeTypeProperties; } private Map manageSubstitutionNodeTypeAttributes( ServiceTemplate substitutionServiceTemplate) { Map substitutionNodeTypeAttributes = new HashMap<>(); Map attributes = substitutionServiceTemplate.getTopology_template().getOutputs(); if (attributes == null) { return null; } AttributeDefinition attributeDefinition; String toscaAttributeName; for (Map.Entry entry : attributes.entrySet()) { attributeDefinition = new AttributeDefinition(); toscaAttributeName = entry.getKey(); ParameterDefinition parameterDefinition = substitutionServiceTemplate.getTopology_template().getOutputs().get(toscaAttributeName); if (parameterDefinition.getType() != null && !parameterDefinition.getType().isEmpty()) { attributeDefinition.setType(parameterDefinition.getType()); } else { attributeDefinition.setType(PropertyType.STRING.getDisplayName()); } attributeDefinition.setDescription(parameterDefinition.getDescription()); attributeDefinition.set_default(parameterDefinition.get_default()); attributeDefinition.setEntry_schema(parameterDefinition.getEntry_schema()); if (Objects.nonNull(parameterDefinition.getStatus())) { attributeDefinition.setStatus(parameterDefinition.getStatus()); } substitutionNodeTypeAttributes.put(toscaAttributeName, attributeDefinition); } return substitutionNodeTypeAttributes; } /** * Checks if the requirement exists in the node template. * * @param nodeTemplate the node template * @param requirementId the requirement id * @param requirementAssignment the requirement assignment * @return true if the requirement already exists and false otherwise */ @Override public boolean isRequirementExistInNodeTemplate(NodeTemplate nodeTemplate, String requirementId, RequirementAssignment requirementAssignment) { List> nodeTemplateRequirements = nodeTemplate .getRequirements(); return nodeTemplateRequirements != null && nodeTemplateRequirements.stream().anyMatch( requirement -> requirement.containsKey(requirementId) && DataModelUtil .compareRequirementAssignment(requirementAssignment, requirement.get(requirementId))); } @Override public boolean isTypeOf(InterfaceDefinitionType interfaceDefinition, String interfaceType, ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) { return isTypeOf(interfaceDefinition, interfaceType, GET_INTERFACE_TYPE_METHOD_NAME, serviceTemplate, toscaServiceModel); } @Override public boolean isTypeOf(DefinitionOfDataType parameterDefinition, String dataType, ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) { return isTypeOf(parameterDefinition, dataType, GET_DATA_TYPE_METHOD_NAME, serviceTemplate, toscaServiceModel); } private boolean isTypeOf(T object, String type, String getTypesMethodName, ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) { if (object == null) { return false; } try { String objectType = (String) object.getClass().getMethod(GET_TYPE_METHOD_NAME).invoke(object); if (Objects.equals(objectType, type)) { return true; } Optional typeExistInServiceTemplateHierarchy = isTypeExistInServiceTemplateHierarchy(type, objectType, getTypesMethodName, serviceTemplate, toscaServiceModel, null); return typeExistInServiceTemplateHierarchy.orElseThrow(() -> new CoreException( new ToscaElementTypeNotFoundErrorBuilder(objectType).build())); } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { throw new RuntimeException(e); } } }