/* * Copyright © 2016-2018 European Support Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.openecomp.sdc.translator.services.heattotosca; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ListMultimap; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.StringUtils; import org.openecomp.sdc.common.errors.CoreException; import org.openecomp.sdc.tosca.datatypes.ToscaNodeType; import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate; import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate; 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.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.FileNestedConsolidationData; 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.NestedConsolidationData; 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.SubInterfaceTemplateConsolidationData; import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.TypeComputeConsolidationData; import org.openecomp.sdc.translator.services.heattotosca.errors.DuplicateResourceIdsInDifferentFilesErrorBuilder; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; public class ConsolidationService { private UnifiedCompositionService unifiedCompositionService; public ConsolidationService(UnifiedCompositionService unifiedCompositionService) { this.unifiedCompositionService = unifiedCompositionService; } ConsolidationService() { } void serviceTemplateConsolidation(ServiceTemplate serviceTemplate, TranslationContext translationContext) { ConsolidationData consolidationData = translationContext.getConsolidationData(); FileComputeConsolidationData fileComputeConsolidationData = consolidationData.getComputeConsolidationData() .getFileComputeConsolidationData(ToscaUtil.getServiceTemplateFileName(serviceTemplate)); if (Objects.isNull(fileComputeConsolidationData)) { return; } for (TypeComputeConsolidationData typeComputeConsolidationData : fileComputeConsolidationData.getAllTypeComputeConsolidationData()) { boolean preConditionResult = consolidationPreCondition( serviceTemplate, consolidationData, typeComputeConsolidationData); List unifiedCompositionDataList = createUnifiedCompositionDataList( serviceTemplate, consolidationData, typeComputeConsolidationData); if (preConditionResult) { boolean consolidationRuleCheckResult = checkConsolidationRules(serviceTemplate, typeComputeConsolidationData, consolidationData); unifiedCompositionService.createUnifiedComposition( serviceTemplate, null, unifiedCompositionDataList, consolidationRuleCheckResult ? UnifiedCompositionMode.ScalingInstances : UnifiedCompositionMode.CatalogInstance, translationContext); } else { unifiedCompositionService.createUnifiedComposition( serviceTemplate, null, unifiedCompositionDataList, UnifiedCompositionMode .SingleSubstitution, translationContext); } } } static Map getConsolidationEntityIdToType(ServiceTemplate serviceTemplate, ConsolidationData consolidationData) { Map consolidationEntityIdToType = new HashMap<>(); String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate); FileComputeConsolidationData fileComputeConsolidationData = consolidationData.getComputeConsolidationData() .getFileComputeConsolidationData(serviceTemplateFileName); FilePortConsolidationData filePortConsolidationData = consolidationData.getPortConsolidationData() .getFilePortConsolidationData(serviceTemplateFileName); if (Objects.nonNull(fileComputeConsolidationData)) { for (String computeType : fileComputeConsolidationData.getAllComputeTypes()) { TypeComputeConsolidationData typeComputeConsolidationData = fileComputeConsolidationData.getTypeComputeConsolidationData(computeType); Collection computeNodeTemplateIds = typeComputeConsolidationData.getAllComputeNodeTemplateIds(); for (String computeNodeTemplateId : computeNodeTemplateIds) { consolidationEntityIdToType.put(computeNodeTemplateId, computeType); } } } if (Objects.nonNull(filePortConsolidationData)) { Set portNodeTemplateIds = filePortConsolidationData.getAllPortNodeTemplateIds(); for (String portNodeTemplateId : portNodeTemplateIds) { consolidationEntityIdToType .put(portNodeTemplateId, ConsolidationDataUtil.getPortType(portNodeTemplateId)); } } return consolidationEntityIdToType; } private boolean checkConsolidationRules(ServiceTemplate serviceTemplate, TypeComputeConsolidationData typeComputeConsolidationData, ConsolidationData consolidationData) { return checkComputeConsolidation(serviceTemplate, typeComputeConsolidationData) && checkPortConsolidation(serviceTemplate, typeComputeConsolidationData, consolidationData) && !checkGetAttrBetweenEntityConsolidationOfTheSameType(serviceTemplate, typeComputeConsolidationData, consolidationData); } private boolean checkGetAttrBetweenConsolidationDataEntitiesNotFromSameType( ServiceTemplate serviceTemplate, TypeComputeConsolidationData typeComputeConsolidationData, ConsolidationData consolidationData) { Collection computeTemplateConsolidationDataList = typeComputeConsolidationData.getAllComputeTemplateConsolidationData(); Collection computeNodeTemplateIds = typeComputeConsolidationData.getAllComputeNodeTemplateIds(); Map> portTypeToIds = UnifiedCompositionUtil .collectAllPortsFromEachTypesFromComputes(computeTemplateConsolidationDataList); return checkGetAttrOutFromEntityToPortIsLegal(computeTemplateConsolidationDataList, portTypeToIds) && checkGetAttrOutFromPortLegal(ToscaUtil.getServiceTemplateFileName(serviceTemplate), computeNodeTemplateIds, portTypeToIds, consolidationData); } private boolean checkGetAttrOutFromPortLegal(String serviceTemplateName, Collection computeNodeTemplateIds, Map> portTypeToIds, ConsolidationData consolidationData) { for (List portIdsFromSameType : portTypeToIds.values()) { List portTemplateConsolidationDataList = collectAllPortsTemplateConsolidationData(portIdsFromSameType, serviceTemplateName, consolidationData); if (!(checkGetAttrOutFromEntityToPortIsLegal(portTemplateConsolidationDataList, portTypeToIds) && checkGetAttrOutFromConsolidationEntityToEntityNotFromSameTypeIsLegal( portTemplateConsolidationDataList, computeNodeTemplateIds))) { return false; } } return true; } private boolean checkGetAttrOutFromEntityToPortIsLegal(Collection entities, Map> portTypeToIds) { for (String portType : portTypeToIds.keySet()) { if (CollectionUtils.isEmpty(entities)) { continue; } Set startingGetAttrFunc = getEntityGetAttrFuncAsSet(portType, (EntityConsolidationData) entities.iterator().next()); for (Object entity : entities) { EntityConsolidationData currentEntity = (EntityConsolidationData) entity; Set currentGetAttrFuncData = getEntityGetAttrFuncAsSet(portType, currentEntity); if (!(startingGetAttrFunc.equals(currentGetAttrFuncData))) { return false; } } } return true; } private boolean checkGetAttrOutFromConsolidationEntityToEntityNotFromSameTypeIsLegal( List entityConsolidationDataList, Collection consolidationEntityNodeTemplateIds) { if (CollectionUtils.isEmpty(entityConsolidationDataList)) { return true; } EntityConsolidationData startingEntityTemplate = (EntityConsolidationData) entityConsolidationDataList.get(0); Map> startingGetAttrOutFuncData = getConsolidationEntityGetAttrOutFuncData(startingEntityTemplate.getNodesGetAttrOut(), consolidationEntityNodeTemplateIds); for (int i = 1; i < entityConsolidationDataList.size(); i++) { EntityConsolidationData currentEntityTemplate = (EntityConsolidationData) entityConsolidationDataList.get(i); Map> currentGetAttrOutFuncData = getConsolidationEntityGetAttrOutFuncData(currentEntityTemplate.getNodesGetAttrOut(), consolidationEntityNodeTemplateIds); if (!isGetAttrRelationToEntitySimilarBetweenEntities(startingGetAttrOutFuncData, currentGetAttrOutFuncData)) { return false; } } return true; } private boolean isGetAttrRelationToEntitySimilarBetweenEntities( Map> firstMap, Map> secondMap) { if (MapUtils.isEmpty(firstMap) != MapUtils.isEmpty(secondMap)) { return false; } return (MapUtils.isEmpty(firstMap) && MapUtils.isEmpty(secondMap)) || (new ArrayList<>(firstMap.values()).equals(new ArrayList<>(secondMap.values()))); } private boolean checkSubInterfaceConsolidationPreCondition(ServiceTemplate serviceTemplate, ConsolidationData consolidationData, TypeComputeConsolidationData typeComputeConsolidationData) { FilePortConsolidationData filePortConsolidationData = consolidationData.getPortConsolidationData() .getFilePortConsolidationData(ToscaUtil.getServiceTemplateFileName(serviceTemplate)); if (Objects.isNull(filePortConsolidationData)) { return true; } Map> portTypeToPortIds = UnifiedCompositionUtil .collectAllPortsFromEachTypesFromComputes( typeComputeConsolidationData.getAllComputeTemplateConsolidationData()); Collection computeNodeTemplateIds = typeComputeConsolidationData.getAllComputeNodeTemplateIds(); for (List portIdsFromSameType : portTypeToPortIds.values()) { List portTemplateConsolidationDataList = getAllPortTemplateConsolidationData(portIdsFromSameType, filePortConsolidationData); if (!areSubInterfacePreConditionRulesValid(portTypeToPortIds, computeNodeTemplateIds, portTemplateConsolidationDataList, portTemplateConsolidationDataList.get(0))) { return false; } } return true; } private boolean areSubInterfacePreConditionRulesValid(Map> portTypeToPortIds, Collection computeNodeTemplateIds, List portTemplateConsolidationDataList, PortTemplateConsolidationData subInterfaceConsolidationData) { return areSubInterfaceTypesSimilarBetweenPorts(portTemplateConsolidationDataList, subInterfaceConsolidationData) && isNumberOfSubInterfacesPerTypeSimilar(portTemplateConsolidationDataList, subInterfaceConsolidationData) && isGetAttrFromSubInterfaceToOtherEntitiesLegal(computeNodeTemplateIds, portTypeToPortIds, portTemplateConsolidationDataList); } private boolean isGetAttrFromSubInterfaceToOtherEntitiesLegal( Collection computeNodeTemplateIds, Map> portTypeToPortIds, List portTemplateConsolidationDataList) { ListMultimap subInterfacesFromSameTypeFromPorts = collectAllSubInterfacesFromSameTypeFromPorts(portTemplateConsolidationDataList); List subInterfaceList = new ArrayList<>(subInterfacesFromSameTypeFromPorts .values()); return areGetAttrRelationshipsBetweenSubInterfaceToConsolidationEntitiesValid( computeNodeTemplateIds, portTypeToPortIds, portTemplateConsolidationDataList, subInterfaceList); } private boolean areGetAttrRelationshipsBetweenSubInterfaceToConsolidationEntitiesValid( Collection computeNodeTemplateIds, Map> portTypeToPortIds, List portTemplateConsolidationDataList, List subInterfaceList) { return checkGetAttrOutFromEntityToPortIsLegal(subInterfaceList, portTypeToPortIds) && checkGetAttrOutFromConsolidationEntityToEntityNotFromSameTypeIsLegal( portTemplateConsolidationDataList, getSubInterfaceIdsFromSameType(subInterfaceList)) && checkGetAttrOutFromConsolidationEntityToEntityNotFromSameTypeIsLegal( subInterfaceList, computeNodeTemplateIds); } private boolean areSubInterfaceTypesSimilarBetweenPorts( List portTemplateConsolidationDataList, PortTemplateConsolidationData subInterfaceConsolidationData) { return portTemplateConsolidationDataList.stream().allMatch( element -> element.hasSameSubInterfaceTypes(subInterfaceConsolidationData)); } private boolean isNumberOfSubInterfacesPerTypeSimilar( List portTemplateConsolidationDataList, PortTemplateConsolidationData subInterfaceConsolidationData) { return portTemplateConsolidationDataList.stream() .allMatch(element -> element.isNumberOfSubInterfacesPerTypeSimilar(subInterfaceConsolidationData)); } private Set getEntityGetAttrFuncAsSet( String portType, EntityConsolidationData entityConsolidationData) { Set getAttrFuncDataFromPortsWithSameType = new HashSet<>(); Map> nodesGetAttrOut = entityConsolidationData.getNodesGetAttrOut(); if (MapUtils.isEmpty(nodesGetAttrOut)) { return getAttrFuncDataFromPortsWithSameType; } for (Map.Entry> entry : nodesGetAttrOut.entrySet()) { if (portType.equals(ConsolidationDataUtil.getPortType(entry.getKey()))) { getAttrFuncDataFromPortsWithSameType.addAll(entry.getValue()); } } return getAttrFuncDataFromPortsWithSameType; } private Map> getConsolidationEntityGetAttrOutFuncData( Map> nodesGetAttrOut, Collection computeNodeTemplateIds) { Map> computeGetAttrFuncData = new HashMap<>(); if (MapUtils.isEmpty(nodesGetAttrOut)) { return computeGetAttrFuncData; } for (Map.Entry> getAttrFuncEntry : nodesGetAttrOut.entrySet()) { if (computeNodeTemplateIds.contains(getAttrFuncEntry.getKey())) { computeGetAttrFuncData.put(getAttrFuncEntry.getKey(), new HashSet<>(getAttrFuncEntry .getValue())); } } return computeGetAttrFuncData; } private boolean checkGetAttrBetweenEntityConsolidationOfTheSameType( ServiceTemplate serviceTemplate, TypeComputeConsolidationData typeComputeConsolidationData, ConsolidationData consolidationData) { return areThereGetAttrRelationsBetweenComputesOfSameType(typeComputeConsolidationData) || areThereGetAttrRelationsBetweenPortsOfTheSameType(serviceTemplate, typeComputeConsolidationData, consolidationData); } private boolean areThereGetAttrRelationsBetweenComputesOfSameType( TypeComputeConsolidationData typeComputeConsolidationData) { Collection computeTemplateConsolidationEntities = typeComputeConsolidationData.getAllComputeTemplateConsolidationData(); Collection computeNodeTemplateIds = typeComputeConsolidationData.getAllComputeNodeTemplateIds(); return checkGetAttrRelationsForEntityConsolidationData( computeTemplateConsolidationEntities, computeNodeTemplateIds, EntityConsolidationData::getNodesGetAttrIn); } private boolean areThereGetAttrRelationsBetweenPortsOfTheSameType( ServiceTemplate serviceTemplate, TypeComputeConsolidationData typeComputeConsolidationData, ConsolidationData consolidationData) { Collection computeTemplateConsolidationEntities = typeComputeConsolidationData.getAllComputeTemplateConsolidationData(); Map> portTypeToPortIds = UnifiedCompositionUtil .collectAllPortsFromEachTypesFromComputes(computeTemplateConsolidationEntities); FilePortConsolidationData filePortConsolidationData = consolidationData.getPortConsolidationData().getFilePortConsolidationData(ToscaUtil .getServiceTemplateFileName(serviceTemplate)); for (List portsOfTheSameTypeIds : portTypeToPortIds.values()) { List portTemplateConsolidationDataOfSameType = getAllPortTemplateConsolidationData(portsOfTheSameTypeIds, filePortConsolidationData); if (!checkGetAttrRelationsForEntityConsolidationData(portTemplateConsolidationDataOfSameType, portsOfTheSameTypeIds, EntityConsolidationData::getNodesGetAttrIn)) { return false; } } return true; } private boolean areThereGetAttrRelationsBetweenSubInterfacesOfSameType( List subInterfacesIdsFromSameType, List subInterfaceList) { return checkGetAttrRelationsForEntityConsolidationData(subInterfaceList, subInterfacesIdsFromSameType, EntityConsolidationData::getNodesGetAttrIn) || checkGetAttrRelationsForEntityConsolidationData(subInterfaceList, subInterfacesIdsFromSameType, EntityConsolidationData::getNodesGetAttrOut); } private List getAllPortTemplateConsolidationData( List portsIds, FilePortConsolidationData filePortConsolidationData) { List portTemplateConsolidationDataOfSameType = new ArrayList<>(); for (String portId : portsIds) { PortTemplateConsolidationData portTemplateConsolidationData = filePortConsolidationData.getPortTemplateConsolidationData(portId); if (Objects.nonNull(portTemplateConsolidationData)) { portTemplateConsolidationDataOfSameType.add(portTemplateConsolidationData); } } return portTemplateConsolidationDataOfSameType; } private boolean checkGetAttrRelationsForEntityConsolidationData(Collection entities, Collection nodeTemplateIdsOfTheSameType, Function>> getAttrValuesMethod) { for (Object entity : entities) { Map> getAttrValue = getAttrValuesMethod.apply((EntityConsolidationData) entity); Set getAttrNodeIds = getAttrValue == null ? new HashSet<>() : getAttrValue.keySet(); if (getAttrNodeIds.stream().anyMatch(nodeTemplateIdsOfTheSameType::contains)) { return true; } } return false; } private boolean checkComputeConsolidation( ServiceTemplate serviceTemplate, TypeComputeConsolidationData typeComputeConsolidationData) { Collection computeNodeTemplateIds = typeComputeConsolidationData.getAllComputeNodeTemplateIds(); List propertiesWithIdenticalVal = getComputePropertiesWithIdenticalVal(); return arePropertiesSimilarBetweenComputeNodeTemplates(serviceTemplate, computeNodeTemplateIds, propertiesWithIdenticalVal) && checkComputeRelations( typeComputeConsolidationData.getAllComputeTemplateConsolidationData()); } private boolean checkComputeRelations( Collection computeTemplateConsolidationEntities) { return checkEntityConsolidationDataRelations(computeTemplateConsolidationEntities) && checkComputesRelationsToVolume(computeTemplateConsolidationEntities); } private boolean checkEntityConsolidationDataRelations(Collection entities) { EntityConsolidationData startingEntity = (EntityConsolidationData) entities.iterator().next(); for (Object entity : entities) { EntityConsolidationData currentEntity = (EntityConsolidationData) entity; if (!(checkNodesConnectedInRelations(startingEntity, currentEntity) && (checkNodesConnectedOutRelations(startingEntity, currentEntity)) && (checkGroupIdsRelations(startingEntity, currentEntity)))) { return false; } } return true; } private boolean checkNodesConnectedInRelations(EntityConsolidationData firstEntity, EntityConsolidationData secondEntity) { return compareNodeConnectivity(firstEntity.getNodesConnectedIn(), secondEntity.getNodesConnectedIn()); } private boolean checkNodesConnectedOutRelations(EntityConsolidationData firstEntity, EntityConsolidationData secondEntity) { return compareNodeConnectivity(firstEntity.getNodesConnectedOut(), secondEntity.getNodesConnectedOut()); } private boolean compareNodeConnectivity( Map> firstEntityMap, Map> secondEntityMap) { if (MapUtils.isEmpty(firstEntityMap) && MapUtils.isEmpty(secondEntityMap)) { return true; } return !MapUtils.isEmpty(firstEntityMap) && !MapUtils.isEmpty(secondEntityMap) && firstEntityMap.keySet().equals(secondEntityMap.keySet()); } private boolean checkGroupIdsRelations(EntityConsolidationData startingEntity, EntityConsolidationData currentEntity) { return CollectionUtils.isEmpty(startingEntity.getGroupIds()) && CollectionUtils.isEmpty(currentEntity.getGroupIds()) || startingEntity.getGroupIds().equals(currentEntity.getGroupIds()); } private boolean checkComputesRelationsToVolume( Collection computeTemplateConsolidationEntities) { Iterator iterator = computeTemplateConsolidationEntities.iterator(); Map> startingVolumes = iterator.next().getVolumes(); for (ComputeTemplateConsolidationData compute : computeTemplateConsolidationEntities) { Map> currentVolumes = compute.getVolumes(); if (!compareNodeConnectivity(startingVolumes, currentVolumes)) { return false; } } return true; } private boolean checkPortConsolidation(ServiceTemplate serviceTemplate, TypeComputeConsolidationData typeComputeConsolidationData, ConsolidationData consolidationData) { return validateWantedPortProperties(serviceTemplate, typeComputeConsolidationData) && checkPortRelations(ToscaUtil.getServiceTemplateFileName(serviceTemplate), typeComputeConsolidationData, consolidationData); } private boolean validateWantedPortProperties(ServiceTemplate serviceTemplate, TypeComputeConsolidationData typeComputeConsolidationData) { Collection computeTemplateConsolidationDataCollection = typeComputeConsolidationData.getAllComputeTemplateConsolidationData(); Map> portTypeToIds = UnifiedCompositionUtil .collectAllPortsFromEachTypesFromComputes(computeTemplateConsolidationDataCollection); List propertiesWithIdenticalVal = getPortPropertiesWithIdenticalVal(); List propertiesThatNeedToHaveSameUsage = getPortPropertiesThatNeedToHaveSameUsage(); for (List portsIds : portTypeToIds.values()) { if (!arePortPropertiesValid(serviceTemplate, propertiesWithIdenticalVal, propertiesThatNeedToHaveSameUsage, portsIds)) { return false; } } return true; } private boolean arePortPropertiesValid(ServiceTemplate serviceTemplate, List propertiesWithIdenticalVal, List propertiesThatNeedToHaveSameUsage, List portsIds) { Map nodeTemplates = serviceTemplate.getTopology_template().getNode_templates(); Predicate similar = property -> isPropertyValueSimilarBetweenNodeTemplates(property, portsIds, nodeTemplates); Predicate exists = property -> isPropertyUsageSimilarBetweenAllNodeTemplates(property, portsIds, nodeTemplates); return areWantedPortPropertiesValid( propertiesWithIdenticalVal, similar) && areWantedPortPropertiesValid( propertiesThatNeedToHaveSameUsage, exists); } private boolean checkPortRelations(String serviceTemplateName, TypeComputeConsolidationData typeComputeConsolidationData, ConsolidationData consolidationData) { Collection computeTemplateConsolidationDataCollection = typeComputeConsolidationData.getAllComputeTemplateConsolidationData(); Map> portTypeToIds = UnifiedCompositionUtil .collectAllPortsFromEachTypesFromComputes(computeTemplateConsolidationDataCollection); for (List portIds : portTypeToIds.values()) { List portTemplateConsolidationDataList = collectAllPortsTemplateConsolidationData( portIds, serviceTemplateName, consolidationData); if (!checkEntityConsolidationDataRelations(portTemplateConsolidationDataList) || !checkSubInterfaceRules(portTemplateConsolidationDataList)) { return false; } } return true; } private boolean checkSubInterfaceRules(List portTemplateConsolidationDataList) { ListMultimap subInterfaceTypeToEntity = collectAllSubInterfacesFromSameTypeFromPorts(portTemplateConsolidationDataList); List subInterfaceList = new ArrayList<>(subInterfaceTypeToEntity.values()); return areSubInterfacePropertiesAndRelationsValid(subInterfaceList); } private boolean areSubInterfacePropertiesAndRelationsValid( List subInterfaceList) { return isResourceGroupPropertiesSimilarBetweenSubPorts(subInterfaceList) && checkSubInterfaceRelations(subInterfaceList) && !areThereGetAttrRelationsBetweenSubInterfacesOfSameType( getSubInterfaceIdsFromSameType(subInterfaceList), subInterfaceList); } private boolean checkSubInterfaceRelations(List subInterfaceList) { return CollectionUtils.isEmpty(subInterfaceList) || checkEntityConsolidationDataRelations(subInterfaceList); } private boolean isResourceGroupPropertiesSimilarBetweenSubPorts( List subInterfaceList) { if (CollectionUtils.isEmpty(subInterfaceList)) { return true; } SubInterfaceTemplateConsolidationData startingSubInterface = subInterfaceList.get(0); for (SubInterfaceTemplateConsolidationData subInterface : subInterfaceList) { if (!startingSubInterface.getResourceGroupCount().equals(subInterface.getResourceGroupCount()) || !StringUtils.equals(startingSubInterface.getNetworkRole(), subInterface.getNetworkRole())) { return false; } } return true; } private List getSubInterfaceIdsFromSameType(List subInterfaceList) { if (CollectionUtils.isEmpty(subInterfaceList)) { return new ArrayList<>(); } return subInterfaceList.stream().map(SubInterfaceTemplateConsolidationData::getNodeTemplateId) .collect(Collectors.toList()); } private ListMultimap collectAllSubInterfacesFromSameTypeFromPorts( List portTemplateConsolidationDataList) { ListMultimap subInterfaceTypeToEntity = ArrayListMultimap.create(); for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) { portTemplateConsolidationData.copyMappedInto(subInterfaceTypeToEntity); } return subInterfaceTypeToEntity; } private List collectAllPortsTemplateConsolidationData(List portIds, String serviceTemplateName, ConsolidationData consolidationData) { FilePortConsolidationData filePortConsolidationData = consolidationData.getPortConsolidationData() .getFilePortConsolidationData(serviceTemplateName); List portTemplateConsolidationDataList = new ArrayList<>(); for (String portId : portIds) { PortTemplateConsolidationData portTemplateConsolidationData = filePortConsolidationData .getPortTemplateConsolidationData(portId); if (Objects.nonNull(portTemplateConsolidationData)) { portTemplateConsolidationDataList.add(portTemplateConsolidationData); } } return portTemplateConsolidationDataList; } private boolean areWantedPortPropertiesValid(List propertiesToCheck, Predicate condition) { return propertiesToCheck.stream().allMatch(condition); } private boolean arePropertiesSimilarBetweenComputeNodeTemplates( ServiceTemplate serviceTemplate, Collection computeNodeTemplateIds, List propertiesThatNeedToBeSimilar) { Map idToNodeTemplate = serviceTemplate.getTopology_template().getNode_templates(); for (String property : propertiesThatNeedToBeSimilar) { if (!isPropertyValueSimilarBetweenNodeTemplates(property, computeNodeTemplateIds, idToNodeTemplate)) { return false; } } return true; } private boolean isPropertyUsageSimilarBetweenAllNodeTemplates(String propertyToCheck, List entityNodeTemplateIds, Map idToNodeTemplate) { NodeTemplate startingNodeTemplate = idToNodeTemplate.get(entityNodeTemplateIds.get(0)); if (Objects.isNull(startingNodeTemplate)) { throw new CoreException( new DuplicateResourceIdsInDifferentFilesErrorBuilder(entityNodeTemplateIds.get(0)) .build()); } boolean propertyExistCondition = isPropertyExistInNodeTemplate(propertyToCheck, startingNodeTemplate); for (int i = 1; i < entityNodeTemplateIds.size(); i++) { NodeTemplate currentNodeTemplate = idToNodeTemplate.get(entityNodeTemplateIds.get(i)); if (Objects.isNull(currentNodeTemplate)) { throw new CoreException( new DuplicateResourceIdsInDifferentFilesErrorBuilder(entityNodeTemplateIds.get(i)) .build()); } if (propertyExistCondition != isPropertyExistInNodeTemplate(propertyToCheck, currentNodeTemplate)) { return false; } } return true; } private boolean isPropertyValueSimilarBetweenNodeTemplates(String propertyToCheck, Collection entityNodeTemplateIds, Map idToNodeTemplate) { Set propertiesValues = new HashSet<>(); Iterator iterator = entityNodeTemplateIds.iterator(); handlePropertyValue(propertyToCheck, idToNodeTemplate, propertiesValues, iterator.next()); while (iterator.hasNext()) { handlePropertyValue(propertyToCheck, idToNodeTemplate, propertiesValues, iterator.next()); } return propertiesValues.size() == 1; } private void handlePropertyValue(String propertyToCheck, Map idToNodeTemplate, Set propertiesValues, String nodeId) { NodeTemplate startingNodeTemplate = idToNodeTemplate.get(nodeId); if (Objects.isNull(startingNodeTemplate)) { throw new CoreException( new DuplicateResourceIdsInDifferentFilesErrorBuilder(nodeId) .build()); } addPropertyValue(propertyToCheck, startingNodeTemplate, propertiesValues); } private void addPropertyValue(String property, NodeTemplate nodeTemplate, Set propertiesValues) { propertiesValues.add( isPropertyExistInNodeTemplate(property, nodeTemplate) ? nodeTemplate.getProperties() .get(property) : ""); } private boolean isPropertyExistInNodeTemplate(String propertyToCheck, NodeTemplate nodeTemplate) { return !(nodeTemplate.getProperties() == null || nodeTemplate.getProperties().get(propertyToCheck) == null); } void substitutionServiceTemplateConsolidation(String substituteNodeTemplateId, ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate, TranslationContext translationContext) { ConsolidationData consolidationData = translationContext.getConsolidationData(); FileComputeConsolidationData fileComputeConsolidationData = translationContext.getConsolidationData().getComputeConsolidationData() .getFileComputeConsolidationData( ToscaUtil.getServiceTemplateFileName(substitutionServiceTemplate)); boolean substitutionConsolidationRuleResult = substitutionServiceTemplateConsolidationRule(substitutionServiceTemplate, fileComputeConsolidationData, translationContext); if (substitutionConsolidationRuleResult) { List unifiedCompositionDataList = createSubstitutionUnifiedCompositionDataList(substituteNodeTemplateId, serviceTemplate, substitutionServiceTemplate, consolidationData); unifiedCompositionService .createUnifiedComposition(serviceTemplate, substitutionServiceTemplate, unifiedCompositionDataList, UnifiedCompositionMode.NestedSingleCompute, translationContext); } else { //The node template does not represent unified VFC but complexVFC //Adding the id in the context for fixing connectivity from/to nested non-unified nodes translationContext.addUnifiedNestedNodeTemplateId(ToscaUtil .getServiceTemplateFileName(serviceTemplate), substituteNodeTemplateId, substituteNodeTemplateId); if (!translationContext.isUnifiedHandledServiceTemplate(substitutionServiceTemplate)) { serviceTemplateConsolidation(substitutionServiceTemplate, translationContext); } } } private boolean substitutionServiceTemplateConsolidationRule( ServiceTemplate nestedServiceTemplate, FileComputeConsolidationData fileComputeConsolidationData, TranslationContext context) { return Objects.nonNull(fileComputeConsolidationData) && isNumberOfComputeTypesLegal(fileComputeConsolidationData) && isNumberOfComputeConsolidationDataPerTypeLegal( fileComputeConsolidationData.getAllTypeComputeConsolidationData().iterator().next()) && !isThereMoreThanOneNestedLevel(nestedServiceTemplate, context); } private boolean isNumberOfComputeTypesLegal( FileComputeConsolidationData fileComputeConsolidationData) { return fileComputeConsolidationData.getAllTypeComputeConsolidationData().size() == 1; } private boolean isNumberOfComputeConsolidationDataPerTypeLegal( TypeComputeConsolidationData typeComputeConsolidationData) { return typeComputeConsolidationData.getAllComputeTemplateConsolidationData().size() == 1; } private boolean isThereMoreThanOneNestedLevel(ServiceTemplate nestedServiceTemplate, TranslationContext context) { FileNestedConsolidationData fileNestedConsolidationData = null; String nestedServiceTemplateName = ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate); if (Objects.isNull(nestedServiceTemplateName)) { return false; } NestedConsolidationData nestedConsolidationData = context.getConsolidationData() .getNestedConsolidationData(); if (Objects.nonNull(nestedConsolidationData)) { fileNestedConsolidationData = nestedConsolidationData.getFileNestedConsolidationData(nestedServiceTemplateName); } //Condition to check if there is nested file and if file contains only sub interfaces then // return false return Objects.nonNull(fileNestedConsolidationData) && !ifNestedFileContainsOnlySubInterface(nestedServiceTemplate, context); } private boolean ifNestedFileContainsOnlySubInterface(ServiceTemplate serviceTemplate, TranslationContext context) { Map nestedNodeTemplateMap = DataModelUtil.getNodeTemplates(serviceTemplate); ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl(); Set nestedHeatFileNames = nestedNodeTemplateMap.entrySet().stream() .filter(entry -> toscaAnalyzerService.isSubstitutableNodeTemplate(entry.getValue()) && toscaAnalyzerService .getSubstituteServiceTemplateName(entry.getKey(), entry.getValue()).isPresent()) .map(entry -> toscaAnalyzerService .getSubstituteServiceTemplateName(entry.getKey(), entry.getValue()).get()) .collect(Collectors.toSet()); if (CollectionUtils.isNotEmpty(nestedHeatFileNames)) { for (Object fileName : nestedHeatFileNames) { String heatFileName = context.getNestedHeatFileName().get(String.valueOf(fileName)); if (Objects.nonNull(heatFileName) && !ifAllResourceAreSubInterface(context.getTranslatedServiceTemplates() .get(heatFileName).getTopology_template().getNode_templates().values())) { return false; } } } return true; } // Method returns true if all of the resource are sub interface private boolean ifAllResourceAreSubInterface(Collection nodeTemplates) { return nodeTemplates.stream().allMatch(nodeTemplate -> ToscaNodeType.CONTRAILV2_VLAN_SUB_INTERFACE.equals(nodeTemplate.getType())); } private List createUnifiedCompositionDataList( ServiceTemplate serviceTemplate, ConsolidationData consolidationData, TypeComputeConsolidationData typeComputeConsolidationData) { List unifiedCompositionDataList = new ArrayList<>(); for (ComputeTemplateConsolidationData computeTemplateConsolidationData : typeComputeConsolidationData .getAllComputeTemplateConsolidationData()) { UnifiedCompositionData unifiedCompositionData = new UnifiedCompositionData(); unifiedCompositionData.setComputeTemplateConsolidationData(computeTemplateConsolidationData); FilePortConsolidationData filePortConsolidationData = consolidationData.getPortConsolidationData().getFilePortConsolidationData(ToscaUtil .getServiceTemplateFileName(serviceTemplate)); setUnifiedCompositionDataWithPortTemplateData(computeTemplateConsolidationData, filePortConsolidationData, unifiedCompositionData); unifiedCompositionDataList.add(unifiedCompositionData); } return unifiedCompositionDataList; } private void setPortTemplateConsolidationData(FilePortConsolidationData filePortConsolidationData, String portId, UnifiedCompositionData unifiedCompositionData, List subInterfaceTemplateConsolidationDataList) { if (Objects.isNull(filePortConsolidationData)) { return; } PortTemplateConsolidationData portTemplateConsolidationData = filePortConsolidationData.getPortTemplateConsolidationData(portId); unifiedCompositionData.addPortTemplateConsolidationData(portTemplateConsolidationData); if (portTemplateConsolidationData != null) { portTemplateConsolidationData.copyFlatInto(subInterfaceTemplateConsolidationDataList); } } private List createSubstitutionUnifiedCompositionDataList( String substituteNodeTemplateId, ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate, ConsolidationData consolidationData) { List unifiedCompositionDataList = new ArrayList<>(); FileNestedConsolidationData fileNestedConsolidationData = consolidationData.getNestedConsolidationData() .getFileNestedConsolidationData(ToscaUtil.getServiceTemplateFileName(serviceTemplate)); if (Objects.nonNull(fileNestedConsolidationData)) { NestedTemplateConsolidationData nestedTemplateConsolidationData = fileNestedConsolidationData.getNestedTemplateConsolidationData(substituteNodeTemplateId); UnifiedCompositionData unifiedCompositionData = new UnifiedCompositionData(); unifiedCompositionData.setNestedTemplateConsolidationData(nestedTemplateConsolidationData); unifiedCompositionDataList.add(unifiedCompositionData); addSubInterfaceDataToNestedCompositionData(substitutionServiceTemplate, consolidationData, unifiedCompositionData); } return unifiedCompositionDataList; } private void addSubInterfaceDataToNestedCompositionData(ServiceTemplate substitutionServiceTemplate, ConsolidationData consolidationData, UnifiedCompositionData unifiedCompositionData) { FileComputeConsolidationData nestedFileComputeConsolidationData = consolidationData.getComputeConsolidationData() .getFileComputeConsolidationData(ToscaUtil.getServiceTemplateFileName(substitutionServiceTemplate)); FilePortConsolidationData nestedFilePortConsolidationData = consolidationData.getPortConsolidationData() .getFilePortConsolidationData(ToscaUtil.getServiceTemplateFileName(substitutionServiceTemplate)); if (Objects.isNull(nestedFileComputeConsolidationData) || Objects.isNull(nestedFilePortConsolidationData)) { return; } TypeComputeConsolidationData computeType = nestedFileComputeConsolidationData.getAllTypeComputeConsolidationData().iterator().next(); if (Objects.isNull(computeType)) { return; } ComputeTemplateConsolidationData computeTemplateConsolidationData = computeType.getAllComputeTemplateConsolidationData().iterator().next(); setUnifiedCompositionDataWithPortTemplateData(computeTemplateConsolidationData, nestedFilePortConsolidationData, unifiedCompositionData); } private void setUnifiedCompositionDataWithPortTemplateData(ComputeTemplateConsolidationData computeTemplateConsolidationData, FilePortConsolidationData filePortConsolidationData, UnifiedCompositionData unifiedCompositionData) { Collection> portCollection = computeTemplateConsolidationData.getPorts() == null ? Collections.emptyList() : computeTemplateConsolidationData.getPorts().values(); List subInterfaceTemplateConsolidationDataList = new ArrayList<>(); portCollection.stream() .flatMap(Collection::stream) .forEach(portId -> setPortTemplateConsolidationData(filePortConsolidationData, portId, unifiedCompositionData, subInterfaceTemplateConsolidationDataList)); unifiedCompositionData.setSubInterfaceTemplateConsolidationDataList( subInterfaceTemplateConsolidationDataList); } private boolean consolidationPreCondition( ServiceTemplate serviceTemplate, ConsolidationData consolidationData, TypeComputeConsolidationData typeComputeConsolidationData) { return (isThereMoreThanOneComputeTypeInstance(typeComputeConsolidationData) && isNumberOfPortsEqualsBetweenComputeNodes(typeComputeConsolidationData) && isNumberOfPortFromEachTypeLegal(typeComputeConsolidationData) && isPortTypesEqualsBetweenComputeNodes(typeComputeConsolidationData) && checkGetAttrBetweenConsolidationDataEntitiesNotFromSameType(serviceTemplate, typeComputeConsolidationData, consolidationData) && checkSubInterfaceConsolidationPreCondition(serviceTemplate, consolidationData, typeComputeConsolidationData)); } private boolean isThereMoreThanOneComputeTypeInstance( TypeComputeConsolidationData typeComputeConsolidationData) { return typeComputeConsolidationData.getAllComputeNodeTemplateIds().size() > 1; } private boolean isNumberOfPortsEqualsBetweenComputeNodes( TypeComputeConsolidationData typeComputeConsolidationData) { int startingNumberOfPorts = getNumberOfPortsPerCompute(typeComputeConsolidationData .getAllComputeTemplateConsolidationData().iterator().next()); for (ComputeTemplateConsolidationData compute : typeComputeConsolidationData .getAllComputeTemplateConsolidationData()) { if (getNumberOfPortsPerCompute(compute) != startingNumberOfPorts) { return false; } } return true; } private boolean isNumberOfPortFromEachTypeLegal( TypeComputeConsolidationData typeComputeConsolidationData) { Collection computeTemplateConsolidationDataList = typeComputeConsolidationData.getAllComputeTemplateConsolidationData(); for (ComputeTemplateConsolidationData computeTemplate : computeTemplateConsolidationDataList) { Map> currPortsMap = computeTemplate.getPorts(); if (MapUtils.isEmpty(currPortsMap)) { return true; } for (List portList : currPortsMap.values()) { if (portList.size() > 1) { return false; } } } return true; } private boolean isPortTypesEqualsBetweenComputeNodes( TypeComputeConsolidationData typeComputeConsolidationData) { Set staringPortIds = getPortsIds( typeComputeConsolidationData.getAllComputeTemplateConsolidationData().iterator().next()); for (ComputeTemplateConsolidationData compute : typeComputeConsolidationData .getAllComputeTemplateConsolidationData()) { Set currentPortIds = getPortsIds(compute); if (!currentPortIds.equals(staringPortIds)) { return false; } } return true; } private int getNumberOfPortsPerCompute( ComputeTemplateConsolidationData computeTemplateConsolidationData) { return getPortsIds(computeTemplateConsolidationData).size(); } private Set getPortsIds( ComputeTemplateConsolidationData computeTemplateConsolidationData) { return MapUtils.isEmpty(computeTemplateConsolidationData.getPorts()) ? new HashSet<>() : computeTemplateConsolidationData.getPorts().keySet(); } List getPropertiesWithIdenticalVal(UnifiedCompositionEntity entity) { switch (entity) { case COMPUTE: return getComputePropertiesWithIdenticalVal(); case OTHER: return getComputePropertiesWithIdenticalVal(); case PORT: return getPortPropertiesWithIdenticalVal(); default: return new ArrayList<>(); } } private List getComputePropertiesWithIdenticalVal() { List propertyWithIdenticalValue = new ArrayList<>(); propertyWithIdenticalValue.add(ToscaConstants.COMPUTE_IMAGE); propertyWithIdenticalValue.add(ToscaConstants.COMPUTE_FLAVOR); return propertyWithIdenticalValue; } private List getPortPropertiesWithIdenticalVal() { List propertiesThatNeedToHaveIdenticalVal = new ArrayList<>(); propertiesThatNeedToHaveIdenticalVal.add(ToscaConstants.PORT_ALLOWED_ADDRESS_PAIRS); propertiesThatNeedToHaveIdenticalVal.add(ToscaConstants.MAC_ADDRESS); propertiesThatNeedToHaveIdenticalVal .addAll(TranslationContext.getEnrichPortResourceProperties()); return propertiesThatNeedToHaveIdenticalVal; } private List getPortPropertiesThatNeedToHaveSameUsage() { List propertiesThatNeedToHaveSameUsage = new ArrayList<>(); propertiesThatNeedToHaveSameUsage.add(ToscaConstants.PORT_FIXED_IPS); propertiesThatNeedToHaveSameUsage.add(ToscaConstants.PORT_ALLOWED_ADDRESS_PAIRS); propertiesThatNeedToHaveSameUsage.add(ToscaConstants.MAC_ADDRESS); propertiesThatNeedToHaveSameUsage.addAll(TranslationContext.getEnrichPortResourceProperties()); return propertiesThatNeedToHaveSameUsage; } }