/* * ============LICENSE_START======================================================= * SDC * ================================================================================ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. * ================================================================================ * 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. * ============LICENSE_END========================================================= */ package org.openecomp.sdc.translator.services.heattotosca; import org.apache.commons.collections.map.HashedMap; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import org.openecomp.config.api.Configuration; import org.openecomp.config.api.ConfigurationManager; import org.openecomp.core.utilities.CommonMethods; import org.openecomp.core.utilities.yaml.YamlUtil; import org.openecomp.sdc.datatypes.configuration.ImplementationConfiguration; import org.openecomp.sdc.heat.services.HeatConstants; import org.openecomp.sdc.logging.api.Logger; import org.openecomp.sdc.logging.api.LoggerFactory; import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage; import org.openecomp.sdc.tosca.datatypes.ToscaFunctions; import org.openecomp.sdc.tosca.datatypes.ToscaGroupType; import org.openecomp.sdc.tosca.datatypes.ToscaNodeType; import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType; import org.openecomp.sdc.tosca.datatypes.model.CapabilityDefinition; import org.openecomp.sdc.tosca.datatypes.model.Constraint; import org.openecomp.sdc.tosca.datatypes.model.EntrySchema; import org.openecomp.sdc.tosca.datatypes.model.GroupDefinition; 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.RelationshipTemplate; import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment; import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate; import org.openecomp.sdc.tosca.datatypes.model.SubstitutionMapping; import org.openecomp.sdc.tosca.datatypes.model.heatextend.PropertyTypeExt; 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.ToscaUtil; import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl; import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext; import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedCompositionData; import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedCompositionEntity; import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedCompositionMode; import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedSubstitutionData; import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.ComputeTemplateConsolidationData; import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.ConsolidationData; import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.EntityConsolidationData; import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.FileComputeConsolidationData; import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.FilePortConsolidationData; import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.GetAttrFuncData; import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.NestedTemplateConsolidationData; import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.PortTemplateConsolidationData; import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.RequirementAssignmentData; import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.TypeComputeConsolidationData; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.NotSerializableException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.regex.Pattern; import static org.openecomp.sdc.translator.services.heattotosca.Constants.ABSTRACT_NODE_TEMPLATE_ID_PREFIX; import static org.openecomp.sdc.translator.services.heattotosca.Constants.COMPUTE_IDENTICAL_VALUE_PROPERTY_PREFIX; import static org.openecomp.sdc.translator.services.heattotosca.Constants.COMPUTE_IDENTICAL_VALUE_PROPERTY_SUFFIX; import static org.openecomp.sdc.translator.services.heattotosca.Constants.PORT_IDENTICAL_VALUE_PROPERTY_PREFIX; public class UnifiedCompositionService { protected static Logger logger = (Logger) LoggerFactory.getLogger(UnifiedCompositionService.class); protected static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage(); private static Map unifiedCompositionImplMap; static { Configuration config = ConfigurationManager.lookup(); unifiedCompositionImplMap = config.populateMap(ConfigConstants.MANDATORY_UNIFIED_MODEL_NAMESPACE, ConfigConstants.UNIFIED_COMPOSITION_IMPL_KEY, ImplementationConfiguration.class); } private ConsolidationService consolidationService = new ConsolidationService(); private static List getPortConsolidationDataList( Set portIds, List unifiedCompositionDataList) { List portConsolidationDataList = new ArrayList<>(); for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) { for (PortTemplateConsolidationData portTemplateConsolidationData : unifiedCompositionData .getPortTemplateConsolidationDataList()) { if (portIds.contains(portTemplateConsolidationData.getNodeTemplateId())) { portConsolidationDataList.add(portTemplateConsolidationData); } } } return portConsolidationDataList; } /** * Create unified composition. * * @param serviceTemplate the service template * @param nestedServiceTemplate the nested service template * @param unifiedCompositionDataList the unified composition data list. In case no consolidation, * one entry will be in this list, in case of having * consolidation, all entries in the list are the once which * need to be consolidated. * @param mode the mode * @param context the context */ public void createUnifiedComposition(ServiceTemplate serviceTemplate, ServiceTemplate nestedServiceTemplate, List unifiedCompositionDataList, UnifiedCompositionMode mode, TranslationContext context) { mdcDataDebugMessage.debugEntryMessage(null, null); Optional unifiedCompositionInstance = getUnifiedCompositionInstance(mode); if (!unifiedCompositionInstance.isPresent()) { return; } unifiedCompositionInstance.get() .createUnifiedComposition(serviceTemplate, nestedServiceTemplate, unifiedCompositionDataList, context); mdcDataDebugMessage.debugExitMessage(null, null); } /** * Create unified substitution service template according to the input service template, based on * the unified composition data. * * @param serviceTemplate the service template * @param unifiedCompositionDataList the unified composition data list. In case no consolidation, * one entry will be in this list, in case of having * consolidation, all entries in the list are the once which * need to be consolidated. * @param context the translation context * @return the substitution service template */ public Optional createUnifiedSubstitutionServiceTemplate( ServiceTemplate serviceTemplate, List unifiedCompositionDataList, TranslationContext context, Integer index) { if (CollectionUtils.isEmpty(unifiedCompositionDataList)) { return Optional.empty(); } UnifiedCompositionData unifiedCompositionData = unifiedCompositionDataList.get(0); String templateName = getTemplateName(serviceTemplate, unifiedCompositionData, index); ServiceTemplate substitutionServiceTemplate = HeatToToscaUtil.createInitSubstitutionServiceTemplate(templateName); createIndexInputParameter(substitutionServiceTemplate); String computeNodeType = handleCompute(serviceTemplate, substitutionServiceTemplate, unifiedCompositionDataList, context); handlePorts(serviceTemplate, substitutionServiceTemplate, unifiedCompositionDataList, computeNodeType, context); createOutputParameters(serviceTemplate, substitutionServiceTemplate, unifiedCompositionDataList, computeNodeType); NodeType substitutionGlobalNodeType = handleSubstitutionGlobalNodeType(serviceTemplate, substitutionServiceTemplate, context, unifiedCompositionData, index); HeatToToscaUtil.handleSubstitutionMapping(context, getSubstitutionNodeTypeId(serviceTemplate, unifiedCompositionData, index), substitutionServiceTemplate, substitutionGlobalNodeType); context.getTranslatedServiceTemplates().put(templateName, substitutionServiceTemplate); return Optional.of(substitutionServiceTemplate); } /** * Create abstract substitute node template that can be substituted by the input * substitutionServiceTemplate. * * @param serviceTemplate the service template * @param substitutionServiceTemplate the subtitution service template * @param unifiedCompositionDataList the unified composition data list. In case no consolidation, * one entry will be in this list, in case of having * consolidation, all entries in the list are the once which * need to be consolidated. * @param context the translation context * @return the abstract substitute node template id */ public String createAbstractSubstituteNodeTemplate( ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate, List unifiedCompositionDataList, TranslationContext context, Integer index) { NodeTemplate substitutionNodeTemplate = new NodeTemplate(); List directiveList = new ArrayList<>(); directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE); substitutionNodeTemplate.setDirectives(directiveList); String substituteNodeTemplateType = getSubstitutionNodeTypeId(serviceTemplate, unifiedCompositionDataList.get(0), index); substitutionNodeTemplate.setType(substituteNodeTemplateType); Optional> abstractSubstitutionProperties = createAbstractSubstitutionProperties(serviceTemplate, substitutionServiceTemplate, unifiedCompositionDataList, context); abstractSubstitutionProperties.ifPresent(substitutionNodeTemplate::setProperties); //Add substitution filtering property String substitutionServiceTemplateName = ToscaUtil.getServiceTemplateFileName( substitutionServiceTemplate); int count = unifiedCompositionDataList.size(); addSubstitutionFilteringProperty(substitutionServiceTemplateName, substitutionNodeTemplate, count); //Add index_value property addIndexValueProperty(substitutionNodeTemplate); String substituteNodeTemplateId = getSubstituteNodeTemplateId(serviceTemplate, unifiedCompositionDataList.get(0), index); //Add node template id and related abstract node template id in context addUnifiedSubstitionData(context, serviceTemplate, unifiedCompositionDataList, substituteNodeTemplateId); DataModelUtil .addNodeTemplate(serviceTemplate, substituteNodeTemplateId, substitutionNodeTemplate); return substituteNodeTemplateId; } /** * Update the connectivity from/to the "moved" nodes from the original service template to the new * substitution service template. * * @param serviceTemplate the service template * @param unifiedCompositionDataList the unified composition data list. In case no consolidation, * one entry will be in this list, in case of having * consolidation, all entries in the list are the once which * need to be consolidated. * @param context the translation context */ public void updateCompositionConnectivity(ServiceTemplate serviceTemplate, List unifiedCompositionDataList, TranslationContext context) { updOutputParamGetAttrInConnectivity(serviceTemplate, unifiedCompositionDataList, context); updNodesGetAttrInConnectivity(serviceTemplate, unifiedCompositionDataList, context); updNodesConnectedOutConnectivity(serviceTemplate, unifiedCompositionDataList, context); updNodesConnectedInConnectivity(serviceTemplate, unifiedCompositionDataList, context); updVolumeConnectivity(serviceTemplate, unifiedCompositionDataList, context); updGroupsConnectivity(serviceTemplate, unifiedCompositionDataList, context); } /** * Delete the "moved" nodes from the original service template to the new substitution service * template. * * @param serviceTemplate the service template * @param unifiedCompositionDataList the unified composition data list. In case no consolidation, * one entry will be in this list, in case of having * consolidation, all entries in the list are the once which * need to be consolidated. * @param context the translation context */ public void cleanUnifiedCompositionEntities( ServiceTemplate serviceTemplate, List unifiedCompositionDataList, TranslationContext context) { for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) { ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData.getComputeTemplateConsolidationData(); cleanServiceTemplate(serviceTemplate, computeTemplateConsolidationData, context); List portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData); for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) { cleanServiceTemplate(serviceTemplate, portTemplateConsolidationData, context); } } } public void cleanNodeTypes(ServiceTemplate serviceTemplate, List unifiedCompositionDataList, TranslationContext context) { for (UnifiedCompositionData unifiedData : unifiedCompositionDataList) { removeCleanedNodeType( unifiedData.getComputeTemplateConsolidationData().getNodeTemplateId(), serviceTemplate, context); } if (MapUtils.isEmpty(serviceTemplate.getNode_types())) { serviceTemplate.setNode_types(null); } } /** * Update unified abstract nodes connectivity. * * @param serviceTemplate the service template * @param context the context */ public void updateUnifiedAbstractNodesConnectivity(ServiceTemplate serviceTemplate, TranslationContext context) { String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate); UnifiedSubstitutionData unifiedSubstitutionData = context.getUnifiedSubstitutionData() .get(serviceTemplateFileName); if (Objects.nonNull(unifiedSubstitutionData)) { //Handle get attribute in connectivity for abstarct node to abstract node templates Set abstractNodeIds = new HashSet<>(unifiedSubstitutionData.getAllRelatedAbstractNodeIds()); handleGetAttrInConnectivity(serviceTemplate, abstractNodeIds, context); //Handle get attribute in connectivity for abstract node templates to nested node template Set nestedNodeIds = new HashSet<>(unifiedSubstitutionData.getAllUnifiedNestedNodeTemplateIds()); handleGetAttrInConnectivity(serviceTemplate, nestedNodeIds, context); } } public void handleUnifiedNestedDefinition(ServiceTemplate mainServiceTemplate, ServiceTemplate nestedServiceTemplate, List unifiedCompositionDataList, TranslationContext context) { handleUnifiedNestedNodeType(mainServiceTemplate, nestedServiceTemplate, context); updateUnifiedNestedTemplates(mainServiceTemplate, nestedServiceTemplate, unifiedCompositionDataList, context); } private void handleGetAttrInConnectivity(ServiceTemplate serviceTemplate, Set unifiedNodeIds, TranslationContext context) { Map nodeTemplates = serviceTemplate.getTopology_template().getNode_templates(); String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate); for (String unifiedNodeId : unifiedNodeIds) { NodeTemplate nodeTemplate = nodeTemplates.get(unifiedNodeId); handleGetAttrInAbstractNodeTemplate(serviceTemplate, context, serviceTemplateFileName, nodeTemplate); } } private void handleUnifiedNestedNodeType(ServiceTemplate mainServiceTemplate, ServiceTemplate nestedServiceTemplate, TranslationContext context) { SubstitutionMapping substitutionMappings = nestedServiceTemplate.getTopology_template().getSubstitution_mappings(); String nodeTypeId = substitutionMappings.getNode_type(); Optional newNestedNodeTypeId = getNewNestedNodeTypeId(mainServiceTemplate, nestedServiceTemplate, context); if (isNestedServiceTemplateWasHandled(mainServiceTemplate, nestedServiceTemplate, context, newNestedNodeTypeId)) { context.updateHandledComputeType( ToscaUtil.getServiceTemplateFileName(mainServiceTemplate), ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate), newNestedNodeTypeId.get()); return; } ServiceTemplate globalSubstitutionServiceTemplate = context.getGlobalSubstitutionServiceTemplate(); newNestedNodeTypeId.ifPresent( newNestedNodeTypeIdVal -> handleNestedNodeType(nodeTypeId, newNestedNodeTypeIdVal, nestedServiceTemplate, mainServiceTemplate, globalSubstitutionServiceTemplate, context)); } private boolean isNestedServiceTemplateWasHandled(ServiceTemplate mainServiceTemplate, ServiceTemplate nestedServiceTemplate, TranslationContext context, Optional newNestedNodeTypeId) { return newNestedNodeTypeId.isPresent() && context.isNestedServiceTemplateWasHandled( ToscaUtil.getServiceTemplateFileName(mainServiceTemplate), ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate)); } private void handleNestedNodeType(String nodeTypeId, String newNestedNodeTypeId, ServiceTemplate nestedServiceTemplate, ServiceTemplate mainServiceTemplate, ServiceTemplate globalSubstitutionServiceTemplate, TranslationContext context) { updateNestedServiceTemplate(nestedServiceTemplate, context); updateNestedNodeType(nodeTypeId, newNestedNodeTypeId, nestedServiceTemplate, mainServiceTemplate, globalSubstitutionServiceTemplate, context); } private void updateNestedServiceTemplate(ServiceTemplate nestedServiceTemplate, TranslationContext context) { enrichPortProperties(nestedServiceTemplate, context); } private void enrichPortProperties(ServiceTemplate nestedServiceTemplate, TranslationContext context) { String nestedServiceTemplateFileName = ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate); FilePortConsolidationData filePortConsolidationData = context.getConsolidationData().getPortConsolidationData().getFilePortConsolidationData (nestedServiceTemplateFileName); if (Objects.nonNull(filePortConsolidationData)) { Set portNodeTemplateIds = filePortConsolidationData.getAllPortNodeTemplateIds(); if (Objects.nonNull(portNodeTemplateIds)) { for (String portNodeTemplateId : portNodeTemplateIds) { NodeTemplate portNodeTemplate = DataModelUtil.getNodeTemplate(nestedServiceTemplate, portNodeTemplateId); List portEntityConsolidationDataList = new ArrayList<>(); portEntityConsolidationDataList.add(filePortConsolidationData .getPortTemplateConsolidationData(portNodeTemplateId)); handleNodeTypeProperties(nestedServiceTemplate, portEntityConsolidationDataList, portNodeTemplate, UnifiedCompositionEntity.Port, null, context); } } } } private void updateNestedNodeType(String nodeTypeId, String newNestedNodeTypeId, ServiceTemplate nestedServiceTemplate, ServiceTemplate mainServiceTemplate, ServiceTemplate globalSubstitutionServiceTemplate, TranslationContext context) { String indexedNewNestedNodeTypeId = updateNodeTypeId(nodeTypeId, newNestedNodeTypeId, nestedServiceTemplate, mainServiceTemplate, globalSubstitutionServiceTemplate, context); updateNodeTypeProperties(nestedServiceTemplate, globalSubstitutionServiceTemplate, indexedNewNestedNodeTypeId); } private void updateNodeTypeProperties(ServiceTemplate nestedServiceTemplate, ServiceTemplate globalSubstitutionServiceTemplate, String nodeTypeId) { ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl(); Map nodeTypePropertiesDefinition = toscaAnalyzerService.manageSubstitutionNodeTypeProperties(nestedServiceTemplate); NodeType nestedNodeType = DataModelUtil.getNodeType(globalSubstitutionServiceTemplate, nodeTypeId); nestedNodeType.setProperties(nodeTypePropertiesDefinition); } private String updateNodeTypeId(String nodeTypeId, String newNestedNodeTypeId, ServiceTemplate nestedServiceTemplate, ServiceTemplate mainServiceTemplate, ServiceTemplate globalSubstitutionServiceTemplate, TranslationContext context) { context.addNestedFileToUsedNestedComputeType( ToscaUtil.getServiceTemplateFileName(mainServiceTemplate), ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate), newNestedNodeTypeId); String indexedNewNestedNodeTypeId = handleNestedNodeTypeInGlobalSubstitutionTemplate(nodeTypeId, newNestedNodeTypeId, mainServiceTemplate, globalSubstitutionServiceTemplate, context); handleSubstitutionMappingInNestedServiceTemplate(indexedNewNestedNodeTypeId, nestedServiceTemplate); context .updateHandledComputeType( ToscaUtil.getServiceTemplateFileName(mainServiceTemplate), ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate), newNestedNodeTypeId); return indexedNewNestedNodeTypeId; } private String handleNestedNodeTypeInGlobalSubstitutionTemplate(String nodeTypeId, String newNestedNodeTypeId, ServiceTemplate mainServiceTemplate, ServiceTemplate globalSubstitutionServiceTemplate, TranslationContext context) { String indexedNodeType = getIndexedGlobalNodeTypeId(newNestedNodeTypeId, mainServiceTemplate, context); handleNestedNodeTypesInGlobalSubstituteServiceTemplate(nodeTypeId, indexedNodeType, globalSubstitutionServiceTemplate, context); return indexedNodeType; } private String getIndexedGlobalNodeTypeId(String newNestedNodeTypeId, ServiceTemplate mainServiceTemplate, TranslationContext context) { int globalNodeTypeIndex = context.getGlobalNodeTypeIndex(ToscaUtil.getServiceTemplateFileName(mainServiceTemplate), newNestedNodeTypeId); return globalNodeTypeIndex > 0 ? newNestedNodeTypeId + "_" + String.valueOf(globalNodeTypeIndex) : newNestedNodeTypeId; } private void updateUnifiedNestedTemplates(ServiceTemplate mainServiceTemplate, ServiceTemplate nestedServiceTemplate, List unifiedCompositionDataList, TranslationContext context) { for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) { NestedTemplateConsolidationData nestedTemplateConsolidationData = unifiedCompositionData.getNestedTemplateConsolidationData(); if (Objects.isNull(nestedTemplateConsolidationData)) { continue; } handleNestedNodeTemplateInMainServiceTemplate( nestedTemplateConsolidationData.getNodeTemplateId(), mainServiceTemplate, nestedServiceTemplate, context); } } /** * Update connectivity for unified nested patterns. * * @param serviceTemplate the service template * @param nestedServiceTemplate the nested service template * @param unifiedCompositionDataList the unified composition data list * @param context the context */ public void updateUnifiedNestedConnectivity(ServiceTemplate serviceTemplate, ServiceTemplate nestedServiceTemplate, List unifiedCompositionDataList, TranslationContext context) { updNestedCompositionNodesConnectedInConnectivity(serviceTemplate, unifiedCompositionDataList, context); updNestedCompositionNodesGetAttrInConnectivity(serviceTemplate, unifiedCompositionDataList, context); updNestedCompositionOutputParamGetAttrInConnectivity(serviceTemplate, unifiedCompositionDataList, context); } /** * Clean unified nested entities. Update the heat stack group with the new node template ids. * * @param serviceTemplate the service template * @param unifiedCompositionDataList the unified composition data list * @param context the context */ public void cleanUnifiedNestedEntities(ServiceTemplate serviceTemplate, List unifiedCompositionDataList, TranslationContext context) { EntityConsolidationData entityConsolidationData = unifiedCompositionDataList.get(0) .getNestedTemplateConsolidationData(); updateHeatStackGroupNestedComposition(serviceTemplate, entityConsolidationData, context); } protected void updNodesConnectedOutConnectivity(ServiceTemplate serviceTemplate, List unifiedCompositionDataList, TranslationContext context) { for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) { ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData .getComputeTemplateConsolidationData(); //Add requirements in the abstract node template for nodes connected out for computes String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId()); Map> computeNodesConnectedOut = computeTemplateConsolidationData.getNodesConnectedOut(); if (computeNodesConnectedOut != null) { updateRequirementInAbstractNodeTemplate(serviceTemplate, computeTemplateConsolidationData, newComputeNodeTemplateId, computeNodesConnectedOut, context); } String computeType = getComputeTypeSuffix(serviceTemplate, computeTemplateConsolidationData .getNodeTemplateId()); //Add requirements in the abstract node template for nodes connected out for ports List portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData); for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) { String newPortNodeTemplateId = getNewPortNodeTemplateId(portTemplateConsolidationData .getNodeTemplateId(), computeType, computeTemplateConsolidationData); Map> portNodesConnectedOut = portTemplateConsolidationData.getNodesConnectedOut(); if (portNodesConnectedOut != null) { updateRequirementInAbstractNodeTemplate(serviceTemplate, portTemplateConsolidationData, newPortNodeTemplateId, portNodesConnectedOut, context); } } } } protected void updNodesConnectedInConnectivity(ServiceTemplate serviceTemplate, List unifiedCompositionDataList, TranslationContext context) { for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) { ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData .getComputeTemplateConsolidationData(); //Update requirements in the node template which pointing to the computes String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId()); updNodesConnectedInConnectivity(serviceTemplate, computeTemplateConsolidationData, newComputeNodeTemplateId, context, false); String computeType = getComputeTypeSuffix(serviceTemplate, computeTemplateConsolidationData .getNodeTemplateId()); //Update requirements in the node template which pointing to the ports List portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData); for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) { String newPortNodeTemplateId = getNewPortNodeTemplateId(portTemplateConsolidationData .getNodeTemplateId(), computeType, computeTemplateConsolidationData); updNodesConnectedInConnectivity(serviceTemplate, portTemplateConsolidationData, newPortNodeTemplateId, context, false); } } } private void updNodesConnectedInConnectivity(ServiceTemplate serviceTemplate, EntityConsolidationData entityConsolidationData, String newNodeTemplateId, TranslationContext context, boolean isNested) { Map> nodesConnectedIn = entityConsolidationData.getNodesConnectedIn(); if (nodesConnectedIn == null) { //No nodes connected in info return; } for (Map.Entry> entry : nodesConnectedIn .entrySet()) { List requirementAssignmentDataList = entry.getValue(); for (RequirementAssignmentData requirementAssignmentData : requirementAssignmentDataList) { RequirementAssignment requirementAssignment = requirementAssignmentData .getRequirementAssignment(); if (!requirementAssignment.getNode().equals(entityConsolidationData .getNodeTemplateId())) { //The requirement assignment target node should be the one which we are handling in the //consolidation object continue; } //Update the requirement assignment object in the original node template if (isNested) { updateRequirementForNestedCompositionNodesConnectedIn(serviceTemplate, requirementAssignmentData, entityConsolidationData, newNodeTemplateId, context); } else { updateRequirementForNodesConnectedIn(serviceTemplate, requirementAssignmentData, entityConsolidationData, entry.getKey(), newNodeTemplateId, context); } } } } protected void updNestedCompositionNodesConnectedInConnectivity(ServiceTemplate serviceTemplate, List unifiedCompositionDataList, TranslationContext context) { for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) { NestedTemplateConsolidationData nestedTemplateConsolidationData = unifiedCompositionData .getNestedTemplateConsolidationData(); //Update requirements in the node template which pointing to the nested nodes String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate); Optional newNestedNodeTemplateId = context.getUnifiedNestedNodeTemplateId( serviceTemplateFileName, nestedTemplateConsolidationData.getNodeTemplateId()); newNestedNodeTemplateId.ifPresent( newNestedNodeTemplateIdVal -> updNodesConnectedInConnectivity(serviceTemplate, nestedTemplateConsolidationData, newNestedNodeTemplateIdVal, context, true)); } } protected void updVolumeConnectivity(ServiceTemplate serviceTemplate, List unifiedCompositionDataList, TranslationContext context) { for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) { ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData .getComputeTemplateConsolidationData(); //Add requirements in the abstract node template for compute volumes String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId()); Map> computeVolumes = computeTemplateConsolidationData.getVolumes(); if (computeVolumes != null) { updateRequirementInAbstractNodeTemplate(serviceTemplate, computeTemplateConsolidationData, newComputeNodeTemplateId, computeVolumes, context); } } } protected void updGroupsConnectivity(ServiceTemplate serviceTemplate, List unifiedCompositionDataList, TranslationContext context) { for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) { ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData .getComputeTemplateConsolidationData(); //Add requirements in the abstract node template for nodes connected in for computes String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId()); updGroupsConnectivity(serviceTemplate, computeTemplateConsolidationData, context); String computeType = getComputeTypeSuffix(serviceTemplate, computeTemplateConsolidationData .getNodeTemplateId()); //Add requirements in the abstract node template for nodes connected in for ports List portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData); for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) { String newPortNodeTemplateId = getNewPortNodeTemplateId(portTemplateConsolidationData .getNodeTemplateId(), computeType, computeTemplateConsolidationData); updGroupsConnectivity(serviceTemplate, portTemplateConsolidationData, context); } } } private void updGroupsConnectivity(ServiceTemplate serviceTemplate, EntityConsolidationData entityConsolidationData, TranslationContext context) { List groupIds = entityConsolidationData.getGroupIds(); if (groupIds == null) { return; } String oldNodeTemplateId = entityConsolidationData.getNodeTemplateId(); String abstractNodeTemplateId = context.getUnifiedAbstractNodeTemplateId( serviceTemplate, entityConsolidationData.getNodeTemplateId()); Map groups = serviceTemplate.getTopology_template().getGroups(); if (groups != null) { for (String groupId : groupIds) { GroupDefinition groupDefinition = groups.get(groupId); if (groupDefinition != null) { List groupMembers = groupDefinition.getMembers(); if (groupMembers.contains(oldNodeTemplateId)) { //Replace the old node template id groupMembers.remove(oldNodeTemplateId); if (!groupMembers.contains(abstractNodeTemplateId)) { //Add the abstract node template id if not already present groupMembers.add(abstractNodeTemplateId); } } } } } } protected void updOutputParamGetAttrInConnectivity( ServiceTemplate serviceTemplate, List unifiedComposotionDataList, TranslationContext context) { for (UnifiedCompositionData unifiedCompositionData : unifiedComposotionDataList) { ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData.getComputeTemplateConsolidationData(); String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId()); updOutputParamGetAttrInConnectivity(serviceTemplate, computeTemplateConsolidationData, computeTemplateConsolidationData.getNodeTemplateId(), newComputeNodeTemplateId, context, false); String computeType = getComputeTypeSuffix(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId()); List portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData); for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) { String newPortNodeTemplateId = getNewPortNodeTemplateId(portTemplateConsolidationData.getNodeTemplateId(), computeType, computeTemplateConsolidationData); updOutputParamGetAttrInConnectivity(serviceTemplate, portTemplateConsolidationData, portTemplateConsolidationData.getNodeTemplateId(), newPortNodeTemplateId, context, false); } } } protected void updNodesGetAttrInConnectivity( ServiceTemplate serviceTemplate, List unifiedComposotionDataList, TranslationContext context) { Map consolidationNodeTemplateIdAndType = getAllConsolidationNodeTemplateIdAndType(unifiedComposotionDataList); for (UnifiedCompositionData unifiedCompositionData : unifiedComposotionDataList) { ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData.getComputeTemplateConsolidationData(); String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId()); updNodeGetAttrInConnectivity(serviceTemplate, computeTemplateConsolidationData, computeTemplateConsolidationData.getNodeTemplateId(), newComputeNodeTemplateId, context, consolidationNodeTemplateIdAndType, false); String computeType = getComputeTypeSuffix(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId()); List portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData); for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) { String newPotNodeTemplateId = getNewPortNodeTemplateId(portTemplateConsolidationData.getNodeTemplateId(), computeType, computeTemplateConsolidationData); updNodeGetAttrInConnectivity(serviceTemplate, portTemplateConsolidationData, portTemplateConsolidationData.getNodeTemplateId(), newPotNodeTemplateId, context, consolidationNodeTemplateIdAndType, false); } } } protected void updNestedCompositionOutputParamGetAttrInConnectivity( ServiceTemplate serviceTemplate, List unifiedComposotionDataList, TranslationContext context) { for (UnifiedCompositionData unifiedCompositionData : unifiedComposotionDataList) { NestedTemplateConsolidationData nestedTemplateConsolidationData = unifiedCompositionData.getNestedTemplateConsolidationData(); if (Objects.isNull(nestedTemplateConsolidationData)) { continue; } String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate); Optional newNestedNodeTemplateId = context.getUnifiedNestedNodeTemplateId( serviceTemplateFileName, nestedTemplateConsolidationData.getNodeTemplateId()); newNestedNodeTemplateId.ifPresent( newNestedNodeTemplateIdVal -> updOutputParamGetAttrInConnectivity(serviceTemplate, nestedTemplateConsolidationData, nestedTemplateConsolidationData.getNodeTemplateId(), newNestedNodeTemplateIdVal, context, true)); } } protected void updNestedCompositionNodesGetAttrInConnectivity( ServiceTemplate serviceTemplate, List unifiedCompositionDataList, TranslationContext context) { for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) { NestedTemplateConsolidationData nestedTemplateConsolidationData = unifiedCompositionData.getNestedTemplateConsolidationData(); if (Objects.isNull(nestedTemplateConsolidationData)) { continue; } String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate); Optional newNestedNodeTemplateId = context.getUnifiedNestedNodeTemplateId( serviceTemplateFileName, nestedTemplateConsolidationData.getNodeTemplateId()); newNestedNodeTemplateId.ifPresent( newNestedNodeTemplateIdVal -> updNodeGetAttrInConnectivity(serviceTemplate, nestedTemplateConsolidationData, nestedTemplateConsolidationData.getNodeTemplateId(), newNestedNodeTemplateIdVal, context, null, true)); } } private void updateRequirementForNodesConnectedIn( ServiceTemplate serviceTemplate, RequirementAssignmentData requirementAssignmentData, EntityConsolidationData entityConsolidationData, String originalNodeTemplateId, String newNodeTemplateId, TranslationContext context) { ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl(); RequirementAssignment requirementAssignment = requirementAssignmentData .getRequirementAssignment(); String newAbstractUnifiedNodeTemplateId = context.getUnifiedAbstractNodeTemplateId( serviceTemplate, entityConsolidationData.getNodeTemplateId()); NodeTemplate abstractUnifiedNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, newAbstractUnifiedNodeTemplateId); Optional newCapabilityId = getNewCapabilityForNodesConnectedIn(serviceTemplate, abstractUnifiedNodeTemplate, requirementAssignment, newNodeTemplateId, context); if (newCapabilityId.isPresent()) { //Creating a copy of the requirement object and checking if it already exists in the // original node template RequirementAssignment requirementAssignmentCopy = (RequirementAssignment) getClonedObject( requirementAssignmentData.getRequirementAssignment(), RequirementAssignment.class); NodeTemplate originalNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, originalNodeTemplateId); requirementAssignmentCopy.setCapability(newCapabilityId.get()); requirementAssignmentCopy.setNode(newAbstractUnifiedNodeTemplateId); if (!toscaAnalyzerService.isRequirementExistInNodeTemplate(originalNodeTemplate, requirementAssignmentData.getRequirementId(), requirementAssignmentCopy)) { //Update the existing requirement requirementAssignmentData.getRequirementAssignment().setCapability(newCapabilityId .get()); requirementAssignmentData.getRequirementAssignment() .setNode(newAbstractUnifiedNodeTemplateId); } else { //The updated requirement already exists in the node template so simply remove the // current one DataModelUtil.removeRequirementAssignment(originalNodeTemplate, requirementAssignmentData .getRequirementId(), requirementAssignmentData.getRequirementAssignment()); } } } private void updateRequirementForNestedCompositionNodesConnectedIn( ServiceTemplate serviceTemplate, RequirementAssignmentData requirementAssignmentData, EntityConsolidationData entityConsolidationData, String newNodeTemplateId, TranslationContext context) { ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl(); String newAbstractUnifiedNodeTemplateId = newNodeTemplateId; RequirementAssignment requirementAssignment = requirementAssignmentData .getRequirementAssignment(); //Creating a copy of the requirement object and checking if it already exists in the // original node template RequirementAssignment requirementAssignmentCopy = (RequirementAssignment) getClonedObject( requirementAssignmentData.getRequirementAssignment(), RequirementAssignment.class); NodeTemplate unifiedAbstractNestedNodeTemplate = DataModelUtil .getNodeTemplate(serviceTemplate, newAbstractUnifiedNodeTemplateId); requirementAssignmentCopy.setCapability(requirementAssignment.getCapability()); requirementAssignmentCopy.setNode(newAbstractUnifiedNodeTemplateId); if (!toscaAnalyzerService.isRequirementExistInNodeTemplate(unifiedAbstractNestedNodeTemplate, requirementAssignmentData.getRequirementId(), requirementAssignmentCopy)) { //Update the existing requirement requirementAssignmentData.getRequirementAssignment() .setNode(newAbstractUnifiedNodeTemplateId); } else { //The updated requirement already exists in the node template so simply remove the // current one DataModelUtil.removeRequirementAssignment(unifiedAbstractNestedNodeTemplate, requirementAssignmentData.getRequirementId(), requirementAssignmentData .getRequirementAssignment()); } } private Optional getNewCapabilityForNodesConnectedIn(ServiceTemplate serviceTemplate, NodeTemplate unifiedNodeTemplate, RequirementAssignment requirementAssignment, String newNodeTemplateId, TranslationContext context) { ServiceTemplate globalSubstitutionServiceTemplate = HeatToToscaUtil.fetchGlobalSubstitutionServiceTemplate(serviceTemplate, context); Map nodeTypes = globalSubstitutionServiceTemplate.getNode_types(); String unifiedNodeTemplateType = unifiedNodeTemplate.getType(); NodeType unifiedNodeType = nodeTypes.get(unifiedNodeTemplateType); Map abstractNodeTypeCapabilities = unifiedNodeType .getCapabilities(); for (Map.Entry entry : abstractNodeTypeCapabilities.entrySet()) { String capabilityId = entry.getKey(); CapabilityDefinition capabilityDefinition = entry.getValue(); String capabilityType = capabilityDefinition.getType(); if (capabilityType.equals(requirementAssignment.getCapability())) { //Matching capability type found..Check if the id ends with new node template id if (capabilityId.endsWith(newNodeTemplateId)) { return Optional.ofNullable(capabilityId); } } } return Optional.empty(); } private void updateRequirementInAbstractNodeTemplate(ServiceTemplate serviceTemplate, EntityConsolidationData entityConsolidationData, String newNodeTemplateId, Map> requirementAssignmentDataMap, TranslationContext context) { ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl(); for (Map.Entry> entry : requirementAssignmentDataMap .entrySet()) { String abstractNodeTemplateId = context.getUnifiedAbstractNodeTemplateId( serviceTemplate, entityConsolidationData.getNodeTemplateId()); NodeTemplate abstractNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, abstractNodeTemplateId); if (abstractNodeTemplate == null) { //The abstract node template is not found from id in the context return; } List requirementAssignmentDataList = entry.getValue(); for (RequirementAssignmentData requirementAssignmentData : requirementAssignmentDataList) { String oldRequirementId = requirementAssignmentData.getRequirementId(); RequirementAssignment abstractRequirementAssignment = (RequirementAssignment) getClonedObject(requirementAssignmentData.getRequirementAssignment(), RequirementAssignment.class); String newRequirementId = oldRequirementId + "_" + newNodeTemplateId; //Check if the requirement is not already present in the list of requirements of the // abstract node template if (!toscaAnalyzerService.isRequirementExistInNodeTemplate(abstractNodeTemplate, newRequirementId, abstractRequirementAssignment)) { DataModelUtil.addRequirementAssignment(abstractNodeTemplate, newRequirementId, abstractRequirementAssignment); //Update the volume relationship template if required updateVolumeRelationshipTemplate(serviceTemplate, abstractRequirementAssignment .getRelationship(), context); } } } } private NodeTemplate getAbstractNodeTemplate( ServiceTemplate serviceTemplate, UnifiedCompositionEntity unifiedCompositionEntity, ComputeTemplateConsolidationData computeTemplateConsolidationData, PortTemplateConsolidationData portTemplateConsolidationData, TranslationContext context) { String abstractNodeTemplateId = getAbstractNodeTemplateId(serviceTemplate, unifiedCompositionEntity, computeTemplateConsolidationData, portTemplateConsolidationData, context); return DataModelUtil.getNodeTemplate(serviceTemplate, abstractNodeTemplateId); } private String getAbstractNodeTemplateId( ServiceTemplate serviceTemplate, UnifiedCompositionEntity unifiedCompositionEntity, ComputeTemplateConsolidationData computeTemplateConsolidationData, PortTemplateConsolidationData portTemplateConsolidationData, TranslationContext context) { switch (unifiedCompositionEntity) { case Compute: return context.getUnifiedAbstractNodeTemplateId(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId()); case Port: return context.getUnifiedAbstractNodeTemplateId(serviceTemplate, portTemplateConsolidationData.getNodeTemplateId()); default: return null; } } private void updNodeGetAttrInConnectivity( ServiceTemplate serviceTemplate, EntityConsolidationData entityConsolidationData, String oldNodeTemplateId, String newNodeTemplateId, TranslationContext context, Map consolidationNodeTemplateIdAndType, boolean isNested) { Map> nodesGetAttrIn = entityConsolidationData.getNodesGetAttrIn(); if (MapUtils.isEmpty(nodesGetAttrIn)) { return; } for (String sourceNodeTemplateId : nodesGetAttrIn.keySet()) { NodeTemplate sourceNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, sourceNodeTemplateId); if (!isNested && consolidationNodeTemplateIdAndType.keySet().contains(sourceNodeTemplateId)) { continue; } List getAttrFuncDataList = nodesGetAttrIn.get(sourceNodeTemplateId); for (GetAttrFuncData getAttrFuncData : getAttrFuncDataList) { Object propertyValue = DataModelUtil.getPropertyValue(sourceNodeTemplate, getAttrFuncData.getFieldName()); String newAttrName = null; String newGetAttrAbstractNodeTemplateId = newNodeTemplateId; if (!isNested) { newGetAttrAbstractNodeTemplateId = context.getUnifiedAbstractNodeTemplateId(serviceTemplate, oldNodeTemplateId); newAttrName = getNewSubstitutionOutputParameterId(newNodeTemplateId, getAttrFuncData .getAttributeName()); } List> getAttrFuncValueList = extractGetAttrFunction(propertyValue); updateGetAttrValue(oldNodeTemplateId, getAttrFuncData, newGetAttrAbstractNodeTemplateId, newAttrName, getAttrFuncValueList, isNested); } } } private void updateGetAttrValue(String oldNodeTemplateId, GetAttrFuncData getAttrFuncData, String newNodeTemplateId, String newAttrName, List> getAttrFuncValueList, boolean isNested) { for (List getAttrFuncValue : getAttrFuncValueList) { if (oldNodeTemplateId.equals(getAttrFuncValue.get(0)) && getAttrFuncData.getAttributeName().equals(getAttrFuncValue.get(1))) { getAttrFuncValue.set(0, newNodeTemplateId); if (!isNested) { getAttrFuncValue.set(1, newAttrName); } } } } private String getTemplateName(ServiceTemplate serviceTemplate, UnifiedCompositionData unifiedCompositionData, Integer index) { ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData.getComputeTemplateConsolidationData(); String computeType = getComputeTypeSuffix(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId()); String templateName = "Nested_" + computeType; if (Objects.nonNull(index)) { templateName = templateName + "_" + index.toString(); } return templateName; } private String getComputeTypeSuffix(ServiceTemplate serviceTemplate, String computeNodeTemplateId) { NodeTemplate computeNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, computeNodeTemplateId); return getComputeTypeSuffix(computeNodeTemplate.getType()); } /** * Gets compute type. * * @param computeType the compute node type abc.def.vFSB * @return the compute type e.g.:vFSB */ private String getComputeTypeSuffix(String computeType) { return DataModelUtil.getNamespaceSuffix(computeType); } private void updOutputParamGetAttrInConnectivity(ServiceTemplate serviceTemplate, EntityConsolidationData entityConsolidationData, String oldNodeTemplateId, String newNodeTemplateId, TranslationContext context, boolean isNested) { List outputParametersGetAttrIn = entityConsolidationData.getOutputParametersGetAttrIn(); if (CollectionUtils.isEmpty(outputParametersGetAttrIn)) { return; } for (GetAttrFuncData getAttrFuncData : outputParametersGetAttrIn) { Object outputParamValue = DataModelUtil.getOuputParameter(serviceTemplate, getAttrFuncData.getFieldName()) .getValue(); String newAttrName = null; String newGetAttrAbstractNodeTemplateId = newNodeTemplateId; if (!isNested) { newGetAttrAbstractNodeTemplateId = context.getUnifiedAbstractNodeTemplateId(serviceTemplate, oldNodeTemplateId); newAttrName = getNewSubstitutionOutputParameterId(newNodeTemplateId, getAttrFuncData .getAttributeName()); } List> getAttrFuncValueList = extractGetAttrFunction(outputParamValue); updateGetAttrValue(oldNodeTemplateId, getAttrFuncData, newGetAttrAbstractNodeTemplateId, newAttrName, getAttrFuncValueList, isNested); } } private List> extractGetAttrFunction(Object valueObject) { List> getAttrValueList = new ArrayList<>(); if (valueObject instanceof Map) { if (((Map) valueObject).containsKey(ToscaFunctions.GET_ATTRIBUTE.getDisplayName())) { getAttrValueList.add( (List) ((Map) valueObject).get(ToscaFunctions.GET_ATTRIBUTE.getDisplayName())); } for (Object key : ((Map) valueObject).keySet()) { getAttrValueList.addAll(extractGetAttrFunction(((Map) valueObject).get(key))); } } else if (valueObject instanceof List) { for (Object valueEntity : (List) valueObject) { getAttrValueList.addAll(extractGetAttrFunction(valueEntity)); } } return getAttrValueList; } private boolean isIncludeGetInputFunc(Object valueObject) { if (valueObject instanceof Map) { if (((Map) valueObject).containsKey(ToscaFunctions.GET_INPUT.getDisplayName())) { return true; } Map.Entry functionMapEntry = (Map.Entry) ((Map) valueObject).entrySet().iterator().next(); return isIncludeGetInputFunc(functionMapEntry.getValue()); } else if (valueObject instanceof List) { for (Object valueEntity : (List) valueObject) { if (isIncludeGetInputFunc(valueEntity) == true) { return true; } } } return false; } private void createOutputParameters(ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate, List unifiedCompositionDataList, String computeNodeType) { createOutputParametersForCompute(serviceTemplate, substitutionServiceTemplate, unifiedCompositionDataList); createOutputParameterForPorts(serviceTemplate, substitutionServiceTemplate, unifiedCompositionDataList, computeNodeType); } private void createOutputParameterForPorts( ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate, List unifiedCompositionDataList, String connectedComputeNodeType) { for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) { List portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData); if (CollectionUtils.isEmpty(portTemplateConsolidationDataList)) { return; } for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) { String newPortNodeTemplateId = getNewPortNodeTemplateId(portTemplateConsolidationData.getNodeTemplateId(), connectedComputeNodeType, unifiedCompositionData.getComputeTemplateConsolidationData()); addOutputParameters(portTemplateConsolidationData, newPortNodeTemplateId, substitutionServiceTemplate, unifiedCompositionDataList); } } } //The ID should be _ or _ private String getNewPortNodeTemplateId( String portNodeTemplateId, String connectedComputeNodeType, ComputeTemplateConsolidationData computeTemplateConsolidationData) { StringBuilder newPortNodeTemplateId = new StringBuilder(); String portType = ConsolidationDataUtil.getPortType(portNodeTemplateId); newPortNodeTemplateId.append(DataModelUtil.getNamespaceSuffix(connectedComputeNodeType)); if (computeTemplateConsolidationData.getPorts().get(portType).size() > 1) { //single port newPortNodeTemplateId.append("_").append(portNodeTemplateId); } else { //consolidation port newPortNodeTemplateId.append("_").append(portType); } return newPortNodeTemplateId.toString(); } private void createOutputParametersForCompute( ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate, List unifiedCompositionDataList) { List computeConsolidationDataList = getComputeConsolidationDataList(unifiedCompositionDataList); for (EntityConsolidationData computeTemplateConsolidationData : computeConsolidationDataList) { String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId()); addOutputParameters(computeTemplateConsolidationData, newComputeNodeTemplateId, substitutionServiceTemplate, unifiedCompositionDataList); } } private void addOutputParameters(EntityConsolidationData entityConsolidationData, String newNodeTemplateId, ServiceTemplate substitutionServiceTemplate, List unifiedCompositionDataList) { handleNodesGetAttrIn(entityConsolidationData, newNodeTemplateId, substitutionServiceTemplate, unifiedCompositionDataList); handleOutputParamGetAttrIn(entityConsolidationData, newNodeTemplateId, substitutionServiceTemplate); } private void handleOutputParamGetAttrIn(EntityConsolidationData entityConsolidationData, String newNodeTemplateId, ServiceTemplate substitutionServiceTemplate) { List outputParametersGetAttrIn = entityConsolidationData.getOutputParametersGetAttrIn(); if (!CollectionUtils.isEmpty(outputParametersGetAttrIn)) { for (GetAttrFuncData getAttrFuncData : outputParametersGetAttrIn) { createAndAddOutputParameter(entityConsolidationData, newNodeTemplateId, substitutionServiceTemplate, getAttrFuncData); } } } private void handleNodesGetAttrIn(EntityConsolidationData entityConsolidationData, String newNodeTemplateId, ServiceTemplate substitutionServiceTemplate, List unifiedCompositionDataList) { Map> getAttrIn = entityConsolidationData.getNodesGetAttrIn(); if (!MapUtils.isEmpty(getAttrIn)) { Map consolidationNodeTemplateIdAndType = getAllConsolidationNodeTemplateIdAndType(unifiedCompositionDataList); for (String sourceNodeTemplateId : getAttrIn.keySet()) { if (!consolidationNodeTemplateIdAndType.keySet().contains(sourceNodeTemplateId)) { List getAttrFuncDataList = getAttrIn.get(sourceNodeTemplateId); for (GetAttrFuncData getAttrFuncData : getAttrFuncDataList) { createAndAddOutputParameter(entityConsolidationData, newNodeTemplateId, substitutionServiceTemplate, getAttrFuncData); } } } } } private void createAndAddOutputParameter(EntityConsolidationData entityConsolidationData, String newNodeTemplateId, ServiceTemplate substitutionServiceTemplate, GetAttrFuncData getAttrFuncData) { Map> parameterValue = new HashMap<>(); List valueList = new ArrayList<>(); valueList.add(newNodeTemplateId); valueList.add(getAttrFuncData.getAttributeName()); parameterValue.put(ToscaFunctions.GET_ATTRIBUTE.getDisplayName(), valueList); ParameterDefinition outputParameter = new ParameterDefinition(); outputParameter.setValue(parameterValue); //todo - the type need to be change based on the attribute type in the accordingly node type // of this node template - XXX, instead of list of string, list of XXXX, outputParameter.setType(PropertyType.LIST.getDisplayName()); outputParameter.setEntry_schema( DataModelUtil.createEntrySchema(PropertyType.STRING.getDisplayName(), null, null)); DataModelUtil.addOutputParameterToTopologyTemplate(substitutionServiceTemplate, getNewSubstitutionOutputParameterId(newNodeTemplateId, getAttrFuncData.getAttributeName()), outputParameter); } private String getNewSubstitutionOutputParameterId(String newNodeTemplateId, String attributeName) { return newNodeTemplateId + "_" + attributeName; } private void addUnifiedSubstitionData(TranslationContext context, ServiceTemplate serviceTemplate, List unifiedCompositionDataList, String substituteNodeTemplateId) { String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate); for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) { //Add compute node template mapping information ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData.getComputeTemplateConsolidationData(); String computeNodeTemplateId = computeTemplateConsolidationData.getNodeTemplateId(); context.addUnifiedSubstitutionData(serviceTemplateFileName, computeNodeTemplateId, substituteNodeTemplateId); //Add Port template mapping information List portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData); if (CollectionUtils.isNotEmpty(portTemplateConsolidationDataList)) { for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) { String oldPortNodeTemplateId = portTemplateConsolidationData.getNodeTemplateId(); context.addUnifiedSubstitutionData(serviceTemplateFileName, oldPortNodeTemplateId, substituteNodeTemplateId); } } } } private void addSubstitutionFilteringProperty(String templateName, NodeTemplate nodeTemplate, int count) { Map serviceTemplateFilterPropertyValue = new HashMap<>(); Map properties = nodeTemplate.getProperties(); serviceTemplateFilterPropertyValue.put(ToscaConstants .SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME, templateName); serviceTemplateFilterPropertyValue.put(ToscaConstants.COUNT_PROPERTY_NAME, count); properties.put(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME, serviceTemplateFilterPropertyValue); nodeTemplate.setProperties(properties); } private void addIndexValueProperty(NodeTemplate nodeTemplate) { List indexValueGetPropertyValue = new ArrayList<>(); indexValueGetPropertyValue.add(ToscaConstants.MODELABLE_ENTITY_NAME_SELF); indexValueGetPropertyValue.add(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME); indexValueGetPropertyValue.add(ToscaConstants.INDEX_VALUE_PROPERTY_NAME); Map indexPropertyValue = new HashMap<>(); Map properties = nodeTemplate.getProperties(); indexPropertyValue.put(ToscaFunctions.GET_PROPERTY.getDisplayName(), indexValueGetPropertyValue); properties.put(ToscaConstants.INDEX_VALUE_PROPERTY_NAME, indexPropertyValue); nodeTemplate.setProperties(properties); } private String getSubstituteNodeTemplateId(ServiceTemplate serviceTemplate, UnifiedCompositionData unifiedCompositionData, Integer index) { String computeNodeTemplateId = unifiedCompositionData.getComputeTemplateConsolidationData().getNodeTemplateId(); NodeTemplate computeNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, computeNodeTemplateId); String nodeTemplateId = ABSTRACT_NODE_TEMPLATE_ID_PREFIX + DataModelUtil .getNamespaceSuffix(computeNodeTemplate.getType()); if (Objects.nonNull(index)) { nodeTemplateId = nodeTemplateId + "_" + index.toString(); } return nodeTemplateId; } private String getSubstitutionNodeTypeId(ServiceTemplate serviceTemplate, UnifiedCompositionData unifiedCompositionData, Integer index) { String computeNodeTemplateId = unifiedCompositionData.getComputeTemplateConsolidationData().getNodeTemplateId(); NodeTemplate computeNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, computeNodeTemplateId); String nodeTypeId = ToscaNodeType.ABSTRACT_NODE_TYPE_PREFIX + DataModelUtil.getNamespaceSuffix(computeNodeTemplate.getType()); if (Objects.nonNull(index)) { nodeTypeId = nodeTypeId + "_" + index.toString(); } return nodeTypeId; } private String getNewComputeNodeTemplateId( ServiceTemplate serviceTemplate, String computeNodeTemplateId) { return getComputeTypeSuffix(serviceTemplate, computeNodeTemplateId); } private NodeType handleSubstitutionGlobalNodeType(ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate, TranslationContext context, UnifiedCompositionData unifiedCompositionData, Integer index) { String substitutionNodeTypeId = getSubstitutionNodeTypeId(serviceTemplate, unifiedCompositionData, index); NodeType substitutionNodeType = new ToscaAnalyzerServiceImpl() .createInitSubstitutionNodeType(substitutionServiceTemplate, ToscaNodeType.VFC_ABSTRACT_SUBSTITUTE); ServiceTemplate globalSubstitutionServiceTemplate = HeatToToscaUtil.fetchGlobalSubstitutionServiceTemplate(serviceTemplate, context); DataModelUtil.addNodeType(globalSubstitutionServiceTemplate, substitutionNodeTypeId, substitutionNodeType); return substitutionNodeType; } private void handlePorts(ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate, List unifiedCompositionDataList, String connectedComputeNodeType, TranslationContext context) { if (unifiedCompositionDataList.size() > 1) { handleConsolidationPorts(serviceTemplate, substitutionServiceTemplate, unifiedCompositionDataList, connectedComputeNodeType, context); } else { handleSinglePorts(serviceTemplate, substitutionServiceTemplate, connectedComputeNodeType, unifiedCompositionDataList, context); } } private void handleSinglePorts(ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate, String connectedComputeNodeType, List unifiedCompositionDataList, TranslationContext context) { UnifiedCompositionData unifiedCompositionData = unifiedCompositionDataList.get(0); List portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData); if (CollectionUtils.isEmpty(portTemplateConsolidationDataList)) { return; } for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) { List portConsolidationDataList = new ArrayList<>(); portConsolidationDataList.add(portTemplateConsolidationData); handlePortNodeTemplate(serviceTemplate, substitutionServiceTemplate, portConsolidationDataList, connectedComputeNodeType, unifiedCompositionData.getComputeTemplateConsolidationData(), unifiedCompositionDataList, context); } } private void handleConsolidationPorts(ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate, List unifiedCompositionDataList, String connectedComputeNodeType, TranslationContext context) { Collection computeConsolidationDataList = (Collection) getComputeConsolidationDataList(unifiedCompositionDataList); Map> portIdsPerPortType = UnifiedCompositionUtil .collectAllPortsFromEachTypesFromComputes(computeConsolidationDataList); for (String portType : portIdsPerPortType.keySet()) { List portTemplateConsolidationDataList = getPortConsolidationDataList(portIdsPerPortType.get(portType), unifiedCompositionDataList); if (CollectionUtils.isEmpty(portTemplateConsolidationDataList)) { continue; } handlePortNodeTemplate(serviceTemplate, substitutionServiceTemplate, portTemplateConsolidationDataList, connectedComputeNodeType, unifiedCompositionDataList.get(0).getComputeTemplateConsolidationData(), unifiedCompositionDataList, context); } } private void handlePortNodeTemplate( ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate, List portTemplateConsolidationDataList, String connectedComputeNodeType, ComputeTemplateConsolidationData computeTemplateConsolidationData, List unifiedCompositionDataList, TranslationContext context) { EntityConsolidationData portTemplateConsolidationData = portTemplateConsolidationDataList.get(0); NodeTemplate newPortNodeTemplate = getNodeTemplate( portTemplateConsolidationData.getNodeTemplateId(), serviceTemplate, context).clone(); removeConnectivityOut(portTemplateConsolidationData, newPortNodeTemplate); handleProperties(serviceTemplate, newPortNodeTemplate, substitutionServiceTemplate, UnifiedCompositionEntity.Port, portTemplateConsolidationDataList, computeTemplateConsolidationData, unifiedCompositionDataList, context); String newPortNodeTemplateId = getNewPortNodeTemplateId(portTemplateConsolidationData .getNodeTemplateId(), connectedComputeNodeType, computeTemplateConsolidationData); //Update requirements for relationships between the consolidation entities handleConsolidationEntitiesRequirementConnectivity(newPortNodeTemplateId, newPortNodeTemplate, substitutionServiceTemplate, context); DataModelUtil.addNodeTemplate(substitutionServiceTemplate, newPortNodeTemplateId, newPortNodeTemplate); //Add the node template mapping in the context for handling requirement updation context.addSubstitutionServiceTemplateUnifiedSubstitutionData(ToscaUtil .getServiceTemplateFileName(substitutionServiceTemplate), portTemplateConsolidationData.getNodeTemplateId(), newPortNodeTemplateId); } private NodeTemplate getNodeTemplate(String nodeTemplateId, ServiceTemplate serviceTemplate, TranslationContext context) { NodeTemplate nodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, nodeTemplateId); if (Objects.isNull(nodeTemplate)) { nodeTemplate = context .getCleanedNodeTemplate(ToscaUtil.getServiceTemplateFileName(serviceTemplate), nodeTemplateId); } return nodeTemplate; } private String handleCompute(ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate, List unifiedCompositionDataList, TranslationContext context) { ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionDataList.get(0).getComputeTemplateConsolidationData(); handleComputeNodeTemplate(serviceTemplate, substitutionServiceTemplate, unifiedCompositionDataList, context); return handleComputeNodeType(serviceTemplate, substitutionServiceTemplate, computeTemplateConsolidationData); } private String handleComputeNodeType( ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate, ComputeTemplateConsolidationData computeTemplateConsolidationData) { NodeTemplate computeNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId()); NodeType computeNodeType = DataModelUtil.getNodeType(serviceTemplate, computeNodeTemplate.getType()); DataModelUtil .addNodeType(substitutionServiceTemplate, computeNodeTemplate.getType(), computeNodeType); return computeNodeTemplate.getType(); } private void handleComputeNodeTemplate(ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate, List unifiedCompositionDataList, TranslationContext context) { ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionDataList.get(0).getComputeTemplateConsolidationData(); NodeTemplate newComputeNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId()).clone(); removeConnectivityOut(computeTemplateConsolidationData, newComputeNodeTemplate); removeVolumeConnectivity(computeTemplateConsolidationData, newComputeNodeTemplate); List computeConsoliadtionDataList = getComputeConsolidationDataList(unifiedCompositionDataList); handleProperties(serviceTemplate, newComputeNodeTemplate, substitutionServiceTemplate, UnifiedCompositionEntity.Compute, computeConsoliadtionDataList, computeTemplateConsolidationData, unifiedCompositionDataList, context); String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId()); //Update requirements for relationships between the consolidation entities handleConsolidationEntitiesRequirementConnectivity(newComputeNodeTemplateId, newComputeNodeTemplate, substitutionServiceTemplate, context); DataModelUtil .addNodeTemplate(substitutionServiceTemplate, newComputeNodeTemplateId, newComputeNodeTemplate); //Add the node template mapping in the context for handling requirement updation context.addSubstitutionServiceTemplateUnifiedSubstitutionData(ToscaUtil .getServiceTemplateFileName(substitutionServiceTemplate), computeTemplateConsolidationData.getNodeTemplateId(), newComputeNodeTemplateId); } private List getComputeConsolidationDataList( List unifiedCompositionDataList) { List computeConsolidationDataList = new ArrayList<>(); for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) { computeConsolidationDataList .add(unifiedCompositionData.getComputeTemplateConsolidationData()); } return computeConsolidationDataList; } private void handleProperties(ServiceTemplate serviceTemplate, NodeTemplate nodeTemplate, ServiceTemplate substitutionServiceTemplate, UnifiedCompositionEntity unifiedCompositionEntity, List entityConsolidationDataList, ComputeTemplateConsolidationData computeTemplateConsolidationData, List unifiedCompositionDataList, TranslationContext context) { nodeTemplate.setProperties(new HashedMap()); handleNodeTemplateProperties(serviceTemplate, nodeTemplate, substitutionServiceTemplate, unifiedCompositionEntity, entityConsolidationDataList, computeTemplateConsolidationData, unifiedCompositionDataList, context); //Add enrich properties from openecomp node type as input to global and substitution ST handleNodeTypeProperties(substitutionServiceTemplate, entityConsolidationDataList, nodeTemplate, unifiedCompositionEntity, computeTemplateConsolidationData, context); } private void handleNodeTemplateProperties(ServiceTemplate serviceTemplate, NodeTemplate nodeTemplate, ServiceTemplate substitutionServiceTemplate, UnifiedCompositionEntity unifiedCompositionEntity, List entityConsolidationDataList, ComputeTemplateConsolidationData computeTemplateConsolidationData, List unifiedCompositionDataList, TranslationContext context) { List propertiesWithIdenticalVal = consolidationService.getPropertiesWithIdenticalVal(unifiedCompositionEntity, context); for (EntityConsolidationData entityConsolidationData : entityConsolidationDataList) { String nodeTemplateId = entityConsolidationData.getNodeTemplateId(); Map properties = DataModelUtil.getNodeTemplateProperties(serviceTemplate, nodeTemplateId); if (MapUtils.isEmpty(properties)) { continue; } for (Map.Entry propertyEntry : properties.entrySet()) { NodeType nodeTypeWithFlatHierarchy = HeatToToscaUtil.getNodeTypeWithFlatHierarchy(nodeTemplate.getType(), serviceTemplate, context); PropertyDefinition propertyDefinition = nodeTypeWithFlatHierarchy.getProperties().get(propertyEntry.getKey()); String propertyType = propertyDefinition.getType(); if (propertiesWithIdenticalVal.contains(propertyEntry.getKey())) { String parameterId = updateIdenticalProperty(nodeTemplateId, propertyEntry.getKey(), nodeTemplate, unifiedCompositionEntity, unifiedCompositionDataList); addInputParameter( parameterId, propertyType, propertyType.equals(PropertyType.LIST.getDisplayName()) ? propertyDefinition .getEntry_schema() : null, substitutionServiceTemplate); } else { Optional parameterId = updateProperty(serviceTemplate, nodeTemplateId, nodeTemplate, propertyEntry, unifiedCompositionEntity, computeTemplateConsolidationData, unifiedCompositionDataList, context); //todo - define list of type which will match the node property type (instead of string) addPropertyInputParameter(propertyType, substitutionServiceTemplate, parameterId); } } } } private void handleNodeTypeProperties(ServiceTemplate substitutionServiceTemplate, List entityConsolidationDataList, NodeTemplate nodeTemplate, UnifiedCompositionEntity compositionEntity, ComputeTemplateConsolidationData computeTemplateConsolidationData, TranslationContext context) { ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl(); Optional enrichNodeType = Optional.empty(); List enrichProperties = new ArrayList<>(); if (compositionEntity.equals(UnifiedCompositionEntity.Port)) { enrichNodeType = toscaAnalyzerService.fetchNodeType(ToscaNodeType.NETWORK_PORT, context.getGlobalServiceTemplates().values()); enrichProperties = context.getEnrichPortResourceProperties(); if (!enrichNodeType.isPresent() || Objects.isNull(enrichProperties)) { return; } } else { return; } Map nodeTemplateProperties = nodeTemplate.getProperties(); Map enrichNodeTypeProperties = enrichNodeType.get().getProperties(); if (Objects.nonNull(enrichNodeTypeProperties)) { for (String enrichPropertyName : enrichProperties) { if (!nodeTemplateProperties.containsKey(enrichPropertyName)) { for (EntityConsolidationData entityConsolidationData : entityConsolidationDataList) { String nodeTemplateId = entityConsolidationData.getNodeTemplateId(); String inputParamId = getParameterId(nodeTemplateId, nodeTemplate, enrichPropertyName, compositionEntity, computeTemplateConsolidationData); Map> propertyVal = getPropertyValueInputParam(nodeTemplateId, nodeTemplate, inputParamId); nodeTemplate.getProperties().put(enrichPropertyName, propertyVal); String propertyType = enrichNodeType.get().getProperties().get(enrichPropertyName).getType(); addPropertyInputParameter(propertyType, substitutionServiceTemplate, Optional.of(inputParamId)); } } } } } private void addPropertyInputParameter(String propertyType, ServiceTemplate substitutionServiceTemplate, Optional parameterId) { if (propertyType.equalsIgnoreCase(PropertyType.STRING.getDisplayName()) || propertyType.equalsIgnoreCase(PropertyType.INTEGER.getDisplayName()) || propertyType.equalsIgnoreCase(PropertyType.FLOAT.getDisplayName()) || propertyType.equalsIgnoreCase(PropertyType.BOOLEAN.getDisplayName())) { parameterId .ifPresent(parameterIdValue -> addInputParameter(parameterIdValue, PropertyType.LIST.getDisplayName(), DataModelUtil .createEntrySchema(propertyType.toLowerCase(), null, null), substitutionServiceTemplate)); } else { parameterId .ifPresent(parameterIdValue -> addInputParameter(parameterIdValue, PropertyType.LIST.getDisplayName(), DataModelUtil .createEntrySchema(PropertyTypeExt.JSON.getDisplayName(), null, null), substitutionServiceTemplate)); } } private void handleConsolidationEntitiesRequirementConnectivity(String nodeTemplateId, NodeTemplate nodeTemplate, ServiceTemplate substitutionServiceTemplate, TranslationContext context) { Map updatedNodeTemplateRequirements = new HashMap<>(); List> nodeTemplateRequirements = DataModelUtil .getNodeTemplateRequirementList(nodeTemplate); if (CollectionUtils.isEmpty(nodeTemplateRequirements)) { return; } for (Map requirement : nodeTemplateRequirements) { for (Map.Entry entry : requirement.entrySet()) { RequirementAssignment requirementAssignment = entry.getValue(); String requirementNode = requirementAssignment.getNode(); String unifiedNodeTemplateId = context.getUnifiedSubstitutionNodeTemplateId(substitutionServiceTemplate, requirementNode); if (unifiedNodeTemplateId != null) { //Update the node id in the requirement requirementAssignment.setNode(unifiedNodeTemplateId); } } } nodeTemplate.setRequirements(nodeTemplateRequirements); } /** * Update the node references in the volume relationship templates. * * @param serviceTemplate the service template * @param context the context */ private void updateVolumeRelationshipTemplate(ServiceTemplate serviceTemplate, String relationshipId, TranslationContext context) { Map relationshipTemplates = DataModelUtil .getRelationshipTemplates(serviceTemplate); if (relationshipTemplates != null) { RelationshipTemplate relationshipTemplate = relationshipTemplates.get(relationshipId); if (relationshipTemplate != null) { String relationshipTemplateType = relationshipTemplate.getType(); if (relationshipTemplateType.equals(ToscaRelationshipType.CINDER_VOLUME_ATTACHES_TO)) { handleCinderVolumeAttachmentRelationshipTemplate(serviceTemplate, relationshipTemplate, context); } } } } private void handleCinderVolumeAttachmentRelationshipTemplate(ServiceTemplate substitutionServiceTemplate, RelationshipTemplate relationshipTemplate, TranslationContext context) { Map properties = relationshipTemplate.getProperties(); properties.computeIfPresent(HeatConstants.INSTANCE_UUID_PROPERTY_NAME, (key, value) -> context.getUnifiedAbstractNodeTemplateId(substitutionServiceTemplate, (String) value)); } private String updateIdenticalProperty(String nodeTemplateId, String propertyId, NodeTemplate nodeTemplate, UnifiedCompositionEntity unifiedCompositionEntity, List unifiedCompositionDataList) { String inputParamId; Map propertyVal = new HashMap<>(); switch (unifiedCompositionEntity) { case Compute: inputParamId = COMPUTE_IDENTICAL_VALUE_PROPERTY_PREFIX + propertyId + COMPUTE_IDENTICAL_VALUE_PROPERTY_SUFFIX; propertyVal.put(ToscaFunctions.GET_INPUT.getDisplayName(), inputParamId); nodeTemplate.getProperties().put(propertyId, propertyVal); return inputParamId; case Port: String portType = ConsolidationDataUtil.getPortType(nodeTemplateId); ComputeTemplateConsolidationData computeTemplateConsolidationData = getConnectedComputeConsolidationData(unifiedCompositionDataList, nodeTemplateId); inputParamId = getInputParamIdForPort(nodeTemplateId, propertyId, portType, computeTemplateConsolidationData); propertyVal.put(ToscaFunctions.GET_INPUT.getDisplayName(), inputParamId); nodeTemplate.getProperties().put(propertyId, propertyVal); return inputParamId; default: return null; } } private String getInputParamIdForPort(String nodeTemplateId, String propertyId, String portType, ComputeTemplateConsolidationData computeTemplateConsolidationData) { String inputParamId; if (Objects.isNull(computeTemplateConsolidationData) || computeTemplateConsolidationData.getPorts().get(portType).size() > 1) { inputParamId = UnifiedCompositionEntity.Port.name().toLowerCase() + "_" + nodeTemplateId + "_" + propertyId; } else { inputParamId = UnifiedCompositionEntity.Port.name().toLowerCase() + "_" + portType + "_" + propertyId; } return inputParamId; } private void addInputParameter(String parameterId, String parameterType, EntrySchema entrySchema, ServiceTemplate serviceTemplate) { ParameterDefinition parameterDefinition = DataModelUtil.createParameterDefinition(parameterType, null, null, true, null, null, entrySchema, null); DataModelUtil .addInputParameterToTopologyTemplate(serviceTemplate, parameterId, parameterDefinition); } // Return the input parameter Id which is used in the new property value if there is one private Optional updateProperty( ServiceTemplate serviceTemplate, String nodeTemplateId, NodeTemplate nodeTemplate, Map.Entry propertyEntry, UnifiedCompositionEntity compositionEntity, ComputeTemplateConsolidationData computeTemplateConsolidationData, List unifiedCompositionDataList, TranslationContext context) { if (handleGetAttrFromConsolidationNodes(serviceTemplate, nodeTemplate, propertyEntry, unifiedCompositionDataList, context)) { return Optional.empty(); } String inputParamId = getParameterId(nodeTemplateId, nodeTemplate, propertyEntry.getKey(), compositionEntity, computeTemplateConsolidationData); Map> propertyVal = getPropertyValueInputParam(nodeTemplateId, nodeTemplate, inputParamId); nodeTemplate.getProperties().put(propertyEntry.getKey(), propertyVal); return Optional.of(inputParamId); } private Map> getPropertyValueInputParam(String nodeTemplateId, NodeTemplate nodeTemplate, String inputParamId) { Map> propertyVal = new HashMap<>(); List getInputFuncParams = new ArrayList<>(); getInputFuncParams.add(inputParamId); getInputFuncParams.add(ToscaConstants.INDEX_VALUE_PROPERTY_NAME); propertyVal.put(ToscaFunctions.GET_INPUT.getDisplayName(), getInputFuncParams); return propertyVal; } private boolean handleGetAttrFromConsolidationNodes( ServiceTemplate serviceTemplate, NodeTemplate nodeTemplate, Map.Entry propertyEntry, List unifiedCompositionDataList, TranslationContext context) { Map consolidationNodeTemplateIdAndType = getAllConsolidationNodeTemplateIdAndType(unifiedCompositionDataList); Set consolidationNodeTemplateIds = consolidationNodeTemplateIdAndType.keySet(); boolean includeGetAttrFromConsolidationNodes = false; boolean includeGetAttrFromOutsideNodes = false; List> getAttrFunctionList = extractGetAttrFunction(propertyEntry.getValue()); for (List getAttrFunc : getAttrFunctionList) { if (consolidationNodeTemplateIds.contains(getAttrFunc.get(0))) { includeGetAttrFromConsolidationNodes = true; } else { includeGetAttrFromOutsideNodes = true; } } if ((includeGetAttrFromConsolidationNodes && includeGetAttrFromOutsideNodes) || (includeGetAttrFromConsolidationNodes && isIncludeGetInputFunc(propertyEntry.getValue()))) { //This case is currently not supported - this property will be ignored return true; } else if (includeGetAttrFromConsolidationNodes) { Object clonedPropertyValue = getClonedPropertyValue(propertyEntry); List> clonedGetAttrFuncList = extractGetAttrFunction(clonedPropertyValue); for (List getAttrFunc : clonedGetAttrFuncList) { String targetNodeTemplateId = (String) getAttrFunc.get(0); if (consolidationNodeTemplateIds.contains(targetNodeTemplateId)) { updatePropertyGetAttrFunc(serviceTemplate, unifiedCompositionDataList, context, consolidationNodeTemplateIdAndType, targetNodeTemplateId, getAttrFunc); } } nodeTemplate.getProperties().put(propertyEntry.getKey(), clonedPropertyValue); return true; } return false; } private void updatePropertyGetAttrFunc( ServiceTemplate serviceTemplate, List unifiedCompositionDataList, TranslationContext context, Map consolidationNodeTemplateIdAndType, String targetNodeTemplateId, List getAttrFunc) { UnifiedCompositionEntity targetCompositionEntity = consolidationNodeTemplateIdAndType.get(targetNodeTemplateId); String targetNewNodeTemplateId = getNewNodeTemplateId(serviceTemplate, unifiedCompositionDataList, targetNodeTemplateId, targetCompositionEntity); getAttrFunc.set(0, targetNewNodeTemplateId); } private String getNewNodeTemplateId(ServiceTemplate serviceTemplate, List unifiedCompositionDataList, String nodeTemplateId, UnifiedCompositionEntity compositionEntity) { switch (compositionEntity) { case Compute: return getNewComputeNodeTemplateId(serviceTemplate, nodeTemplateId); case Port: ComputeTemplateConsolidationData connectedComputeConsolidationData = getConnectedComputeConsolidationData( unifiedCompositionDataList, nodeTemplateId); NodeTemplate connectedComputeNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, connectedComputeConsolidationData.getNodeTemplateId()); return getNewPortNodeTemplateId(nodeTemplateId, connectedComputeNodeTemplate.getType(), connectedComputeConsolidationData); default: return null; } } private String getNewNodeTemplateId(String origNodeTemplateId, String serviceTemplateFileName, ServiceTemplate serviceTemplate, TranslationContext context) { ConsolidationData consolidationData = context.getConsolidationData(); if (isIdIsOfExpectedType(origNodeTemplateId, UnifiedCompositionEntity.Port, serviceTemplateFileName, context)) { return handleIdOfPort(origNodeTemplateId, serviceTemplateFileName, consolidationData); } else if (isIdIsOfExpectedType(origNodeTemplateId, UnifiedCompositionEntity.Compute, serviceTemplateFileName, context)) { NodeTemplate nodeTemplate = getComputeNodeTemplate(origNodeTemplateId, serviceTemplate, context); return getComputeTypeSuffix(nodeTemplate.getType()); } return null; } private ComputeTemplateConsolidationData getConnectedComputeConsolidationData( List unifiedCompositionDataList, String portNodeTemplateId) { for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) { Collection> portsCollection = unifiedCompositionData.getComputeTemplateConsolidationData().getPorts().values(); for (List portIdList : portsCollection) { if (portIdList.contains(portNodeTemplateId)) { return unifiedCompositionData.getComputeTemplateConsolidationData(); } // for (String portId : portIdList) { // if (portId.equals(portNodeTemplateId)) { // return unifiedCompositionData.getComputeTemplateConsolidationData(); // } // } } } return null; } private Object getClonedPropertyValue(Map.Entry propertyEntry) { if (propertyEntry.getValue() instanceof Map) { return getClonedObject(propertyEntry.getValue(), Map.class); } else if (propertyEntry.getValue() instanceof List) { return getClonedObject(propertyEntry.getValue(), List.class); } return propertyEntry.getValue(); } private String getParameterId(String nodeTemplateId, NodeTemplate nodeTemplate, String propertyId, UnifiedCompositionEntity unifiedCompositionEntity, ComputeTemplateConsolidationData computeTemplateConsolidationData) { switch (unifiedCompositionEntity) { case Compute: return UnifiedCompositionEntity.Compute.name().toLowerCase() + "_" + getComputeTypeSuffix(nodeTemplate.getType()) + "_" + propertyId; case Port: String portType = ConsolidationDataUtil.getPortType(nodeTemplateId); if (Objects.isNull(computeTemplateConsolidationData) || computeTemplateConsolidationData.getPorts().get(portType).size() > 1) { return UnifiedCompositionEntity.Port.name().toLowerCase() + "_" + nodeTemplateId + "_" + propertyId; } return UnifiedCompositionEntity.Port.name().toLowerCase() + "_" + portType + "_" + propertyId; default: return propertyId; } } private void removeConnectivityOut(EntityConsolidationData entityConsolidationData, NodeTemplate nodeTemplate) { if (MapUtils.isEmpty(entityConsolidationData.getNodesConnectedOut())) { return; } for (List requirementAssignmentDataList : entityConsolidationData .getNodesConnectedOut().values()) { for (RequirementAssignmentData requirementAssignmentData : requirementAssignmentDataList) { DataModelUtil.removeRequirementsAssignment(nodeTemplate.getRequirements(), requirementAssignmentData.getRequirementId()); } if (nodeTemplate.getRequirements().isEmpty()) { nodeTemplate.setRequirements(null); } } } private void removeVolumeConnectivity( ComputeTemplateConsolidationData computeTemplateConsolidationData, NodeTemplate computeNodeTemplate) { if (MapUtils.isEmpty(computeTemplateConsolidationData.getVolumes())) { return; } Collection> volumeCollection = computeTemplateConsolidationData.getVolumes().values(); for (List requirementAssignmentDataList : volumeCollection) { for (RequirementAssignmentData requirementAssignmentData : requirementAssignmentDataList) { DataModelUtil.removeRequirementsAssignment(computeNodeTemplate.getRequirements(), requirementAssignmentData.getRequirementId()); } } if (computeNodeTemplate.getRequirements().isEmpty()) { computeNodeTemplate.setRequirements(null); } } private void createIndexInputParameter(ServiceTemplate substitutionServiceTemplate) { ParameterDefinition indexParameterDefinition = DataModelUtil.createParameterDefinition(PropertyType.INTEGER.getDisplayName(), "Index value of this substitution service template runtime instance", null, false, createIndexValueConstraint(), null, null, 0); DataModelUtil.addInputParameterToTopologyTemplate(substitutionServiceTemplate, ToscaConstants.INDEX_VALUE_PROPERTY_NAME, indexParameterDefinition); } private List createIndexValueConstraint() { List constraints; constraints = new ArrayList<>(); Constraint constraint = new Constraint(); constraint.setGreater_or_equal(0); constraints.add(constraint); return constraints; } private Optional getUnifiedCompositionInstance(UnifiedCompositionMode mode) { String unifiedCompositionImplClassName = unifiedCompositionImplMap.get(mode.name()).getImplementationClass(); if (StringUtils.isEmpty(unifiedCompositionImplClassName)) { return Optional.empty(); } return Optional .of(CommonMethods.newInstance(unifiedCompositionImplClassName, UnifiedComposition.class)); } private Optional> createAbstractSubstitutionProperties( ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate, List unifiedCompositionDataList, TranslationContext context) { Map abstractSubstituteProperties = new LinkedHashMap<>(); Map substitutionTemplateInputs = DataModelUtil .getInputParameters(substitutionServiceTemplate); if (substitutionTemplateInputs == null) { return Optional.empty(); } //Since all the computes have the same type fetching the type from the first entry NodeTemplate firstComputeNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, unifiedCompositionDataList.get(0) .getComputeTemplateConsolidationData().getNodeTemplateId()); String computeType = getComputeTypeSuffix(firstComputeNodeTemplate.getType()); for (Map.Entry input : substitutionTemplateInputs.entrySet()) { String substitutionTemplateInputName = input.getKey(); ParameterDefinition inputParameterDefinition = input.getValue(); String inputType = inputParameterDefinition.getType(); UnifiedCompositionEntity inputUnifiedCompositionEntity = getInputCompositionEntity(substitutionTemplateInputName); if (!inputType.equalsIgnoreCase(PropertyType.LIST.getDisplayName())) { if (isIdenticalValueProperty( substitutionTemplateInputName, inputUnifiedCompositionEntity, context)) { //Handle identical value properties Optional identicalValuePropertyName = getIdenticalValuePropertyName(substitutionTemplateInputName, inputUnifiedCompositionEntity, context); if (identicalValuePropertyName.isPresent()) { updateIdenticalPropertyValue(identicalValuePropertyName.get(), substitutionTemplateInputName, computeType, inputUnifiedCompositionEntity, unifiedCompositionDataList.get(0), serviceTemplate, abstractSubstituteProperties); } } continue; } //Check if the input is of type compute or port List abstractPropertyValue = new ArrayList<>(); Object propertyValue = null; switch (inputUnifiedCompositionEntity) { case Compute: for (UnifiedCompositionData compositionData : unifiedCompositionDataList) { ComputeTemplateConsolidationData computeTemplateConsolidationData = compositionData.getComputeTemplateConsolidationData(); propertyValue = getComputePropertyValue(substitutionTemplateInputName, serviceTemplate, computeTemplateConsolidationData); if (!(propertyValue instanceof Optional)) { abstractPropertyValue.add(propertyValue); } } break; case Port: for (UnifiedCompositionData compositionData : unifiedCompositionDataList) { List portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(compositionData); //Get the input type for this input whether it is of type // port__ or port__ PortInputType portInputType = getPortInputType(substitutionTemplateInputName, compositionData); for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) { //Get the port property value String portNodeTemplateId = portTemplateConsolidationData.getNodeTemplateId(); propertyValue = getPortPropertyValue(substitutionTemplateInputName, computeType, portInputType, serviceTemplate, portNodeTemplateId); //If the value object is Optional.empty it implies that the property name was not // found in the input name if (!(propertyValue instanceof Optional)) { abstractPropertyValue.add(propertyValue); } } } break; default: break; } //Add the property only if it has at least one non-null value for (Object val : abstractPropertyValue) { if (Objects.nonNull(val)) { abstractSubstituteProperties.put(substitutionTemplateInputName, abstractPropertyValue); break; } } } return Optional.ofNullable(abstractSubstituteProperties); } private void updateIdenticalPropertyValue(String identicalValuePropertyName, String substitutionTemplateInputName, String computeType, UnifiedCompositionEntity entity, UnifiedCompositionData unifiedCompositionData, ServiceTemplate serviceTemplate, Map abstractSubstituteProperties){ Optional identicalPropertyValueByType = getIdenticalPropertyValueByType(identicalValuePropertyName, substitutionTemplateInputName, computeType, entity, unifiedCompositionData, serviceTemplate); if(identicalPropertyValueByType.isPresent()){ abstractSubstituteProperties .put(substitutionTemplateInputName, identicalPropertyValueByType.get()); } } private Optional getIdenticalPropertyValueByType(String identicalValuePropertyName, String substitutionTemplateInputName, String computeType, UnifiedCompositionEntity entity, UnifiedCompositionData unifiedCompositionData, ServiceTemplate serviceTemplate) { ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData.getComputeTemplateConsolidationData(); Optional computeIdenticalPropertyValue; switch (entity) { case Compute: computeIdenticalPropertyValue = getIdenticalPropertyValue(identicalValuePropertyName, serviceTemplate, entity, computeTemplateConsolidationData); return computeIdenticalPropertyValue.isPresent() ? Optional.of( computeIdenticalPropertyValue.get()) : Optional.empty(); case Other: computeIdenticalPropertyValue = getIdenticalPropertyValue(identicalValuePropertyName, serviceTemplate, entity, computeTemplateConsolidationData); return computeIdenticalPropertyValue.isPresent() ? Optional.of( computeIdenticalPropertyValue.get()) : Optional.empty(); case Port: List portTemplateConsolidationDataList = unifiedCompositionData.getPortTemplateConsolidationDataList(); for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) { String portType = ConsolidationDataUtil.getPortType(portTemplateConsolidationData.getNodeTemplateId()); if (substitutionTemplateInputName.contains(portType)) { return getIdenticalPropertyValue(identicalValuePropertyName, serviceTemplate, entity, portTemplateConsolidationData); } } } return Optional.empty(); } private PortInputType getPortInputType(String inputName, UnifiedCompositionData unifiedCompositionData) { String portInputPrefix = UnifiedCompositionEntity.Port.name().toLowerCase() + "_"; ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData .getComputeTemplateConsolidationData(); List portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData); //Scan the available port node template ids to check if the input is of the form // "port__" for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) { String portNodeTemplateId = portTemplateConsolidationData.getNodeTemplateId(); String portNodeTemplateIdPrefix = portInputPrefix + portNodeTemplateId; if (inputName.startsWith(portNodeTemplateIdPrefix)) { return PortInputType.NodeTemplateId; } } //Check whether the input is of the form "port__" Set portTypes = computeTemplateConsolidationData.getPorts().keySet(); for (String portType : portTypes) { String expectedPortTypeSusbtring = portInputPrefix + portType + "_"; if (inputName.startsWith(expectedPortTypeSusbtring)) { return PortInputType.PortType; } } return PortInputType.Other; } private void cleanServiceTemplate(ServiceTemplate serviceTemplate, EntityConsolidationData entity, TranslationContext context) { removeNodeTemplateFromServiceTemplate(serviceTemplate, entity, context); updateHeatStackGroup(serviceTemplate, entity, context); } private void removeNodeTemplateFromServiceTemplate(ServiceTemplate serviceTemplate, EntityConsolidationData entity, TranslationContext context) { String nodeTemplateIdToRemove = entity.getNodeTemplateId(); Map nodeTemplates = serviceTemplate.getTopology_template().getNode_templates(); NodeTemplate nodeTemplateToRemove = nodeTemplates.get(nodeTemplateIdToRemove); nodeTemplates.remove(nodeTemplateIdToRemove); context.addCleanedNodeTemplate(ToscaUtil.getServiceTemplateFileName(serviceTemplate), nodeTemplateIdToRemove, entity.getClass() == ComputeTemplateConsolidationData.class ? UnifiedCompositionEntity.Compute : UnifiedCompositionEntity.Port, nodeTemplateToRemove); } private void removeCleanedNodeType(String cleanedNodeTemplateId, ServiceTemplate serviceTemplate, TranslationContext context) { NodeTemplate cleanedNodeTemplate = context .getCleanedNodeTemplate(ToscaUtil.getServiceTemplateFileName(serviceTemplate), cleanedNodeTemplateId); String typeToRemove = cleanedNodeTemplate.getType(); if (Objects.nonNull(typeToRemove) && serviceTemplate.getNode_types().containsKey(typeToRemove)) { serviceTemplate.getNode_types().remove(typeToRemove); } } private void updateHeatStackGroup(ServiceTemplate serviceTemplate, EntityConsolidationData entity, TranslationContext context) { Map groups = serviceTemplate.getTopology_template() .getGroups() == null ? new HashMap<>() : serviceTemplate.getTopology_template().getGroups(); String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate); String nodeRelatedAbstractNodeId = context.getUnifiedAbstractNodeTemplateId(serviceTemplate, entity.getNodeTemplateId()); for (Map.Entry groupEntry : groups.entrySet()) { GroupDefinition groupDefinition = groupEntry.getValue(); if (isHeatStackGroup(groupDefinition.getType())) { updateGroupMembersWithNewUnifiedNodeTemplateId(entity, nodeRelatedAbstractNodeId, groupEntry); } } } private void updateGroupMembersWithNewUnifiedNodeTemplateId( EntityConsolidationData entity, String newNodetemplateId, Map.Entry groupEntry) { List members = groupEntry.getValue().getMembers(); if (members.contains(entity.getNodeTemplateId())) { members.remove(entity.getNodeTemplateId()); if (!members.contains(newNodetemplateId)) { members.add(newNodetemplateId); } } groupEntry.getValue().setMembers(members); } private void updateHeatStackGroupNestedComposition(ServiceTemplate serviceTemplate, EntityConsolidationData entity, TranslationContext context) { Map groups = serviceTemplate.getTopology_template() .getGroups() == null ? new HashMap<>() : serviceTemplate.getTopology_template().getGroups(); String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate); Optional nestedNodeTemplateId = context.getUnifiedNestedNodeTemplateId(serviceTemplateFileName, entity.getNodeTemplateId()); if (nestedNodeTemplateId.isPresent()) { for (Map.Entry groupEntry : groups.entrySet()) { GroupDefinition groupDefinition = groupEntry.getValue(); if (isHeatStackGroup(groupDefinition.getType())) { updateGroupMembersWithNewUnifiedNodeTemplateId(entity, nestedNodeTemplateId.get(), groupEntry); } } } } private void handleNestedNodeTemplateInMainServiceTemplate(String nestedNodeTemplateId, ServiceTemplate mainServiceTemplate, ServiceTemplate nestedServiceTemplate, TranslationContext context) { NodeTemplate nestedNodeTemplate = DataModelUtil.getNodeTemplate(mainServiceTemplate, nestedNodeTemplateId); if (Objects.isNull(nestedNodeTemplate)) { return; } Optional unifiedNestedNodeTypeId = context .getUnifiedNestedNodeTypeId(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME, nestedNodeTemplate.getType()); unifiedNestedNodeTypeId .ifPresent(unifiedNestedNodeTypeIdVal -> updateNestedNodeTemplate( unifiedNestedNodeTypeIdVal, nestedNodeTemplateId, nestedNodeTemplate, mainServiceTemplate, nestedServiceTemplate, context)); } private void handleSubstitutionMappingInNestedServiceTemplate( String newNestedNodeType, ServiceTemplate nestedServiceTemplate) { if (Objects.isNull(newNestedNodeType)) { return; } SubstitutionMapping substitutionMappings = nestedServiceTemplate.getTopology_template().getSubstitution_mappings(); substitutionMappings.setNode_type(newNestedNodeType); } private void updateNestedNodeTemplate(String newNestedNodeTypeId, String nestedNodeTemplateId, NodeTemplate nestedNodeTemplate, ServiceTemplate mainServiceTemplate, ServiceTemplate nestedServiceTemplate, TranslationContext context) { String mainServiceTemplateName = ToscaUtil.getServiceTemplateFileName(mainServiceTemplate); int index = context.getHandledNestedComputeNodeTemplateIndex(mainServiceTemplateName, newNestedNodeTypeId); String newNodeTemplateId = Constants.ABSTRACT_NODE_TEMPLATE_ID_PREFIX + getComputeTypeSuffix(newNestedNodeTypeId) + "_" + index; nestedNodeTemplate.setType(newNestedNodeTypeId); mainServiceTemplate.getTopology_template().getNode_templates().remove(nestedNodeTemplateId); mainServiceTemplate.getTopology_template().getNode_templates() .put(newNodeTemplateId, nestedNodeTemplate); context .addUnifiedNestedNodeTemplateId(mainServiceTemplateName, nestedNodeTemplateId, newNodeTemplateId); } private void handleNestedNodeTypesInGlobalSubstituteServiceTemplate( String origNestedNodeTypeId, String newNestedNodeTypeId, ServiceTemplate globalSubstitutionServiceTemplate, TranslationContext context) { Map nodeTypes = globalSubstitutionServiceTemplate.getNode_types(); NodeType nested = DataModelUtil.getNodeType(globalSubstitutionServiceTemplate, origNestedNodeTypeId); setNewValuesForNestedNodeType(origNestedNodeTypeId, newNestedNodeTypeId, nested, nodeTypes); context.addUnifiedNestedNodeTypeId(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME, origNestedNodeTypeId, newNestedNodeTypeId); } private void setNewValuesForNestedNodeType(String origNestedNodeType, String newNestedNodeTypeId, NodeType nested, Map nodeTypes) { if (Objects.nonNull(nested)) { nested.setDerived_from(ToscaNodeType.VFC_ABSTRACT_SUBSTITUTE); nodeTypes.remove(origNestedNodeType); nodeTypes.put(newNestedNodeTypeId, nested); } } private Optional getNewNestedNodeTypeId(ServiceTemplate mainServiceTemplate, ServiceTemplate nestedServiceTemplate, TranslationContext context) { FileComputeConsolidationData fileComputeConsolidationData = context.getConsolidationData().getComputeConsolidationData() .getFileComputeConsolidationData( ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate)); if (Objects.nonNull(fileComputeConsolidationData)) { String nestedNodeTypePrefix = ToscaNodeType.ABSTRACT_NODE_TYPE_PREFIX + "heat."; return Optional .of(nestedNodeTypePrefix + getComputeTypeInNestedFile(fileComputeConsolidationData)); } return Optional.empty(); } private String getComputeTypeInNestedFile( FileComputeConsolidationData fileComputeConsolidationData) { List typeComputeConsolidationDatas = new ArrayList<>(fileComputeConsolidationData.getAllTypeComputeConsolidationData()); if (typeComputeConsolidationDatas.size() == 0) { return null; } else { String computeNodeType = fileComputeConsolidationData.getAllComputeTypes().iterator().next(); return getComputeTypeSuffix(computeNodeType); } } private void handleGetAttrInAbstractNodeTemplate(ServiceTemplate serviceTemplate, TranslationContext context, String serviceTemplateFileName, NodeTemplate abstractNodeTemplate) { Map properties = abstractNodeTemplate == null || abstractNodeTemplate.getProperties() == null ? new HashMap<>() : abstractNodeTemplate.getProperties(); for (Object propertyValue : properties.values()) { List> getAttrList = extractGetAttrFunction(propertyValue); for (List getAttrFuncValue : getAttrList) { String origNodeTemplateId = (String) getAttrFuncValue.get(0); Optional nestedNodeTemplateId = context.getUnifiedNestedNodeTemplateId(ToscaUtil .getServiceTemplateFileName(serviceTemplate), origNodeTemplateId); if (nestedNodeTemplateId.isPresent()) { getAttrFuncValue.set(0, nestedNodeTemplateId.get()); } else { replaceGetAttrNodeIdAndAttrName(serviceTemplate, context, serviceTemplateFileName, getAttrFuncValue); } } } } private void replaceGetAttrNodeIdAndAttrName(ServiceTemplate serviceTemplate, TranslationContext context, String serviceTemplateFileName, List getAttrFuncValue) { String origNodeTemplateId = (String) getAttrFuncValue.get(0); String attributeName = (String) getAttrFuncValue.get(1); String unifiedAbstractNodeTemplateId = context.getUnifiedAbstractNodeTemplateId(serviceTemplate, origNodeTemplateId); if (Objects.isNull(unifiedAbstractNodeTemplateId)) { return; } String newNodeTemplateId = getNewNodeTemplateId(origNodeTemplateId, serviceTemplateFileName, serviceTemplate, context); String newSubstitutionOutputParameterId = getNewSubstitutionOutputParameterId(newNodeTemplateId, attributeName); getAttrFuncValue.set(0, unifiedAbstractNodeTemplateId); getAttrFuncValue.set(1, newSubstitutionOutputParameterId); } private NodeTemplate getComputeNodeTemplate(String origNodeTemplateId, ServiceTemplate serviceTemplate, TranslationContext context) { NodeTemplate computeNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, origNodeTemplateId); if (computeNodeTemplate == null) { computeNodeTemplate = context.getCleanedNodeTemplate(ToscaUtil.getServiceTemplateFileName(serviceTemplate), origNodeTemplateId); } return computeNodeTemplate; } private String handleIdOfPort(String origNodeTemplateId, String serviceTemplateFileName, ConsolidationData consolidationData) { Optional> computeTypeAndComputeTemplateByPortId = getComputeTypeAndComputeTemplateByPortId(origNodeTemplateId, serviceTemplateFileName, consolidationData); if (computeTypeAndComputeTemplateByPortId.isPresent()) { Pair computeIdToComputeData = computeTypeAndComputeTemplateByPortId.get(); return getNewPortNodeTemplateId(origNodeTemplateId, computeIdToComputeData.getKey(), computeIdToComputeData.getValue()); } return null; } private Optional> getComputeTypeAndComputeTemplateByPortId(String portId, String serviceTemplateFileName, ConsolidationData consolidationData) { FileComputeConsolidationData fileComputeConsolidationData = consolidationData.getComputeConsolidationData() .getFileComputeConsolidationData(serviceTemplateFileName); Set computeTypes = fileComputeConsolidationData.getAllComputeTypes(); for (String computeType : computeTypes) { Collection computeTemplateConsolidationDatas = fileComputeConsolidationData.getTypeComputeConsolidationData(computeType) .getAllComputeTemplateConsolidationData(); for (ComputeTemplateConsolidationData compute : computeTemplateConsolidationDatas) { if (ConsolidationDataUtil.isComputeReferenceToPortId(compute, portId)) { return Optional.of(new ImmutablePair<>(computeType, compute)); } } } return Optional.empty(); } private boolean isIdIsOfExpectedType(String id, UnifiedCompositionEntity expectedUnifiedCompositionEntity, String serviceTemplateFileName, TranslationContext context) { UnifiedSubstitutionData unifiedSubstitutionData = context.getUnifiedSubstitutionData().get(serviceTemplateFileName); if (Objects.isNull(unifiedSubstitutionData)) { return false; } UnifiedCompositionEntity actualUnifiedCompositionEntity = unifiedSubstitutionData.getCleanedNodeTemplateCompositionEntity(id); return actualUnifiedCompositionEntity == null ? false : actualUnifiedCompositionEntity.equals(expectedUnifiedCompositionEntity); } private boolean isHeatStackGroup(String groupType) { return groupType.equals(ToscaGroupType.HEAT_STACK); } private Object getPortPropertyValue(String inputName, String computeType, PortInputType portInputType, ServiceTemplate serviceTemplate, String portNodeTemplateId) { //Get the input prefix to extract the property name from the input name String portInputPrefix = getPortInputPrefix( portNodeTemplateId, portInputType); //Get the property name from the input Optional propertyName = getPropertyNameFromInput(inputName, UnifiedCompositionEntity.Port, computeType, portInputPrefix); //Get the property value from the node template if (propertyName.isPresent()) { NodeTemplate portNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, portNodeTemplateId); if (Objects.nonNull(portNodeTemplate)) { return getPropertyValueFromNodeTemplate(propertyName.get(), portNodeTemplate); } } return Optional.empty(); } private Optional getPortTypeFromInput( String inputName, String portNodeTemplateId, ComputeTemplateConsolidationData computeTemplateConsolidationData) { String portTypeFromInput = null; String portInputPrefix = UnifiedCompositionEntity.Port.name().toLowerCase() + "_"; String portNodeTemplateIdPrefix = portInputPrefix + portNodeTemplateId; if (inputName.startsWith(portNodeTemplateIdPrefix)) { return Optional.empty(); } Set portTypes = computeTemplateConsolidationData.getPorts().keySet(); for (String portType : portTypes) { String expectedPortTypeSusbtring = "_" + portType + "_"; if (inputName.contains(expectedPortTypeSusbtring)) { portTypeFromInput = portType; break; } } return Optional.ofNullable(portTypeFromInput); } private Object getComputePropertyValue( String inputName, ServiceTemplate serviceTemplate, ComputeTemplateConsolidationData computeTemplateConsolidationData) { NodeTemplate nodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId()); String nodeType = getComputeTypeSuffix(nodeTemplate.getType()); Optional propertyName = getPropertyNameFromInput(inputName, UnifiedCompositionEntity.Compute, nodeType, null); if (propertyName.isPresent()) { return getPropertyValueFromNodeTemplate(propertyName.get(), nodeTemplate); } return Optional.empty(); } private Optional getIdenticalPropertyValue(String identicalValuePropertyName, ServiceTemplate serviceTemplate, UnifiedCompositionEntity unifiedCompositionEntity, EntityConsolidationData entity){ NodeTemplate nodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, entity.getNodeTemplateId()); Object propertyValueFromNodeTemplate = getPropertyValueFromNodeTemplate(identicalValuePropertyName, nodeTemplate); return Objects.isNull(propertyValueFromNodeTemplate) ? Optional.empty() :Optional.of(propertyValueFromNodeTemplate); } private UnifiedCompositionEntity getInputCompositionEntity(String inputName) { UnifiedCompositionEntity inputCompositionEntity = UnifiedCompositionEntity.Other; String inputType = inputName.substring(0, inputName.indexOf('_')); if (inputType.equals(UnifiedCompositionEntity.Compute.name().toLowerCase())) { inputCompositionEntity = UnifiedCompositionEntity.Compute; } else if (inputType.equals(UnifiedCompositionEntity.Port.name().toLowerCase())) { inputCompositionEntity = UnifiedCompositionEntity.Port; } return inputCompositionEntity; } private Optional getPropertyNameFromInput( String inputName, UnifiedCompositionEntity compositionEntity, String computeType, String portInputPrefix) { String propertyName = null; switch (compositionEntity) { case Compute: propertyName = inputName.substring(inputName.lastIndexOf(computeType) + computeType.length() + 1); break; case Port: if (inputName.startsWith(portInputPrefix)) { propertyName = inputName.split(portInputPrefix)[1]; } break; default: break; } return Optional.ofNullable(propertyName); } private String getPortInputPrefix( String portNodeTemplateId, PortInputType portInputType) { String portInputPrefix = UnifiedCompositionEntity.Port.name().toLowerCase() + "_"; String portType = ConsolidationDataUtil.getPortType(portNodeTemplateId); if (portInputType == PortInputType.NodeTemplateId) { portInputPrefix += portNodeTemplateId + "_"; } else if (portInputType == PortInputType.PortType) { portInputPrefix += portType + "_"; } return portInputPrefix; } private boolean isIdenticalValueProperty(String inputName, UnifiedCompositionEntity unifiedCompositionEntity, TranslationContext context) { List identicalValuePropertyList = consolidationService.getPropertiesWithIdenticalVal(unifiedCompositionEntity, context); StringBuilder builder = getPropertyValueStringBuilder(unifiedCompositionEntity); boolean isMatchingProperty = Pattern.matches(builder.toString(), inputName); return (isMatchingProperty && isPropertyFromIdenticalValuesList(inputName, unifiedCompositionEntity, identicalValuePropertyList)); } private boolean isPropertyFromIdenticalValuesList(String inputName, UnifiedCompositionEntity unifiedCompositionEntity, List identicalValuePropertyList) { switch (unifiedCompositionEntity) { case Compute: return identicalValuePropertyList.contains(getIdenticalValuePropertyName(inputName, unifiedCompositionEntity, null).get()); case Other: return identicalValuePropertyList.contains(getIdenticalValuePropertyName(inputName, unifiedCompositionEntity, null).get()); case Port: return getPortPropertyNameFromInput(inputName, identicalValuePropertyList).isPresent(); default: return false; } } private Optional getPortPropertyNameFromInput(String inputName, List identicalValuePropertyList) { for (String identicalProperty : identicalValuePropertyList) { if (inputName.contains(identicalProperty)) { return Optional.of(identicalProperty); } } return Optional.empty(); } private StringBuilder getPropertyValueStringBuilder( UnifiedCompositionEntity unifiedCompositionEntity) { switch (unifiedCompositionEntity) { case Compute: return getComputePropertyValueStringBuilder(); case Other: return getComputePropertyValueStringBuilder(); case Port: return getPortPropertyValueStringBuilder(); default: return null; } } private StringBuilder getPortPropertyValueStringBuilder() { StringBuilder builder; builder = new StringBuilder(PORT_IDENTICAL_VALUE_PROPERTY_PREFIX); builder.append(".+"); return builder; } private StringBuilder getComputePropertyValueStringBuilder() { StringBuilder builder; builder = new StringBuilder(COMPUTE_IDENTICAL_VALUE_PROPERTY_PREFIX); builder.append("[a-z]+"); builder.append(COMPUTE_IDENTICAL_VALUE_PROPERTY_SUFFIX); return builder; } private Optional getIdenticalValuePropertyName(String input, UnifiedCompositionEntity unifiedCompositionEntity, TranslationContext context) { switch (unifiedCompositionEntity) { case Compute: return Optional.of(input.split("_")[1]); case Other: return Optional.of(input.split("_")[1]); case Port: return getPortPropertyNameFromInput(input, consolidationService .getPropertiesWithIdenticalVal(unifiedCompositionEntity, context)); default: return Optional.empty(); } } private Object getPropertyValueFromNodeTemplate(String propertyName, NodeTemplate nodeTemplate) { Map nodeTemplateProperties = nodeTemplate.getProperties(); if (nodeTemplateProperties != null) { Object propertyValue = nodeTemplateProperties.get(propertyName); propertyValue = getClonedObject(propertyValue); return propertyValue; } return null; } private Object getClonedObject(Object objectValue, Class clazz) { YamlUtil yamlUtil = new YamlUtil(); Object clonedObjectValue; String objectToYaml = yamlUtil.objectToYaml(objectValue); clonedObjectValue = yamlUtil.yamlToObject(objectToYaml, clazz); return clonedObjectValue; } private Object getClonedObject(Object objectValue) { Object clonedObjectValue; try { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); objectOutputStream.writeObject(objectValue); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream .toByteArray()); ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); clonedObjectValue = objectInputStream.readObject(); } catch (NotSerializableException ex) { return getClonedObject(objectValue, objectValue.getClass()); } catch (IOException ioe) { return null; } catch (ClassNotFoundException cnfe) { return null; } return clonedObjectValue; } private Map getAllConsolidationNodeTemplateIdAndType( List unifiedCompositionDataList) { Map consolidationNodeTemplateIdAndType = new HashMap<>(); for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) { ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData.getComputeTemplateConsolidationData(); if (Objects.nonNull(computeTemplateConsolidationData)) { consolidationNodeTemplateIdAndType .put(computeTemplateConsolidationData.getNodeTemplateId(), UnifiedCompositionEntity.Compute); } List portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData); for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) { consolidationNodeTemplateIdAndType.put(portTemplateConsolidationData.getNodeTemplateId(), UnifiedCompositionEntity.Port); } NestedTemplateConsolidationData nestedTemplateConsolidationData = unifiedCompositionData.getNestedTemplateConsolidationData(); if (Objects.nonNull(nestedTemplateConsolidationData)) { consolidationNodeTemplateIdAndType .put(nestedTemplateConsolidationData.getNodeTemplateId(), UnifiedCompositionEntity.Nested); } } return consolidationNodeTemplateIdAndType; } private enum PortInputType { NodeTemplateId, PortType, Other; } private List getPortTemplateConsolidationDataList( UnifiedCompositionData unifiedCompositionData) { return unifiedCompositionData.getPortTemplateConsolidationDataList() == null ? new ArrayList<>() : unifiedCompositionData.getPortTemplateConsolidationDataList(); } }