Fix use of Optional in TranslatorHeatToToscaPropertyConverter
[sdc.git] / openecomp-be / lib / openecomp-sdc-translator-lib / openecomp-sdc-translator-core / src / main / java / org / openecomp / sdc / translator / services / heattotosca / UnifiedCompositionService.java
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.openecomp.sdc.translator.services.heattotosca;
17
18 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_INPUT;
19 import static org.openecomp.sdc.tosca.datatypes.ToscaNodeType.GROUP_TYPE_PREFIX;
20 import static org.openecomp.sdc.tosca.datatypes.ToscaNodeType.VFC_INSTANCE_GROUP;
21 import static org.openecomp.sdc.tosca.services.DataModelUtil.getClonedObject;
22 import static org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedCompositionEntity.COMPUTE;
23 import static org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedCompositionEntity.PORT;
24 import static org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedCompositionEntity.SUB_INTERFACE;
25 import static org.openecomp.sdc.translator.services.heattotosca.Constants.ABSTRACT_NODE_TEMPLATE_ID_PREFIX;
26 import static org.openecomp.sdc.translator.services.heattotosca.Constants.COMPUTE_IDENTICAL_VALUE_PROPERTY_PREFIX;
27 import static org.openecomp.sdc.translator.services.heattotosca.Constants.COMPUTE_IDENTICAL_VALUE_PROPERTY_SUFFIX;
28 import static org.openecomp.sdc.translator.services.heattotosca.Constants.GROUP;
29 import static org.openecomp.sdc.translator.services.heattotosca.Constants.PORT_IDENTICAL_VALUE_PROPERTY_PREFIX;
30 import static org.openecomp.sdc.translator.services.heattotosca.Constants.SUB_INTERFACE_PROPERTY_VALUE_PREFIX;
31 import static org.openecomp.sdc.translator.services.heattotosca.Constants.SUB_INTERFACE_ROLE;
32 import static org.openecomp.sdc.translator.services.heattotosca.Constants.VFC_PARENT_PORT_ROLE;
33 import static org.openecomp.sdc.translator.services.heattotosca.UnifiedCompositionUtil.getComputeTypeSuffix;
34 import static org.openecomp.sdc.translator.services.heattotosca.UnifiedCompositionUtil.getConnectedComputeConsolidationData;
35 import static org.openecomp.sdc.translator.services.heattotosca.UnifiedCompositionUtil.getNewComputeNodeTemplateId;
36 import static org.openecomp.sdc.translator.services.heattotosca.UnifiedCompositionUtil.getNewPortNodeTemplateId;
37 import static org.openecomp.sdc.translator.services.heattotosca.UnifiedCompositionUtil.getNewSubInterfaceNodeTemplateId;
38 import static org.openecomp.sdc.translator.services.heattotosca.UnifiedCompositionUtil.getPortTemplateConsolidationDataForPort;
39 import static org.openecomp.sdc.translator.services.heattotosca.UnifiedCompositionUtil.getSubInterfaceTemplateConsolidationDataList;
40 import static org.openecomp.sdc.translator.services.heattotosca.UnifiedCompositionUtil.getSubInterfaceTypeSuffix;
41
42 import com.google.common.collect.ArrayListMultimap;
43 import com.google.common.collect.ListMultimap;
44 import com.google.common.collect.Multimap;
45 import java.util.ArrayList;
46 import java.util.Collection;
47 import java.util.EnumMap;
48 import java.util.HashMap;
49 import java.util.HashSet;
50 import java.util.LinkedHashMap;
51 import java.util.List;
52 import java.util.Map;
53 import java.util.Objects;
54 import java.util.Optional;
55 import java.util.Set;
56 import java.util.regex.Pattern;
57 import java.util.stream.Collectors;
58 import org.apache.commons.collections.map.HashedMap;
59 import org.apache.commons.collections4.CollectionUtils;
60 import org.apache.commons.collections4.MapUtils;
61 import org.apache.commons.lang3.StringUtils;
62 import org.apache.commons.lang3.tuple.ImmutablePair;
63 import org.apache.commons.lang3.tuple.Pair;
64 import org.onap.config.api.Configuration;
65 import org.onap.config.api.ConfigurationManager;
66 import org.onap.sdc.tosca.datatypes.model.AttributeDefinition;
67 import org.onap.sdc.tosca.datatypes.model.CapabilityDefinition;
68 import org.onap.sdc.tosca.datatypes.model.Constraint;
69 import org.onap.sdc.tosca.datatypes.model.EntrySchema;
70 import org.onap.sdc.tosca.datatypes.model.GroupDefinition;
71 import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
72 import org.onap.sdc.tosca.datatypes.model.NodeType;
73 import org.onap.sdc.tosca.datatypes.model.ParameterDefinition;
74 import org.onap.sdc.tosca.datatypes.model.PropertyDefinition;
75 import org.onap.sdc.tosca.datatypes.model.PropertyType;
76 import org.onap.sdc.tosca.datatypes.model.RelationshipTemplate;
77 import org.onap.sdc.tosca.datatypes.model.RequirementAssignment;
78 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
79 import org.onap.sdc.tosca.datatypes.model.SubstitutionMapping;
80 import org.onap.sdc.tosca.datatypes.model.heatextend.PropertyTypeExt;
81 import org.openecomp.core.utilities.CommonMethods;
82 import org.openecomp.sdc.common.utils.CommonUtil;
83 import org.openecomp.sdc.datatypes.configuration.ImplementationConfiguration;
84 import org.openecomp.sdc.heat.services.HeatConstants;
85 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
86 import org.openecomp.sdc.tosca.datatypes.ToscaGroupType;
87 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
88 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
89 import org.openecomp.sdc.tosca.services.DataModelUtil;
90 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
91 import org.openecomp.sdc.tosca.services.ToscaConstants;
92 import org.openecomp.sdc.tosca.services.ToscaUtil;
93 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
94 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
95 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedCompositionData;
96 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedCompositionEntity;
97 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedCompositionMode;
98 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedSubstitutionData;
99 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.commands.CommandImplNames;
100 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.commands.UnifiedSubstitutionNodeTemplateIdGenerator;
101 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.to.UnifiedCompositionTo;
102 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.ComputeTemplateConsolidationData;
103 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.ConsolidationData;
104 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.EntityConsolidationData;
105 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.FileComputeConsolidationData;
106 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.FilePortConsolidationData;
107 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.GetAttrFuncData;
108 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.NestedTemplateConsolidationData;
109 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.PortTemplateConsolidationData;
110 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.RequirementAssignmentData;
111 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.SubInterfaceTemplateConsolidationData;
112 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.TypeComputeConsolidationData;
113
114 public class UnifiedCompositionService {
115
116     private static final Map<String, ImplementationConfiguration> unifiedCompositionImplMap;
117     private static final EnumMap<UnifiedCompositionEntity, String> unifiedSubstitutionNodeTemplateIdGeneratorImplMap;
118     private static final String SUB_INTERFACE_INDICATOR_PROPERTY = "subinterface_indicator";
119
120     static {
121         Configuration config = ConfigurationManager.lookup();
122         unifiedCompositionImplMap = config
123             .populateMap(ConfigConstants.MANDATORY_UNIFIED_MODEL_NAMESPACE, ConfigConstants.UNIFIED_COMPOSITION_IMPL_KEY,
124                 ImplementationConfiguration.class);
125         unifiedSubstitutionNodeTemplateIdGeneratorImplMap = new EnumMap<>(UnifiedCompositionEntity.class);
126         initNodeTemplateIdGeneratorImplMap();
127     }
128
129     private final ConsolidationService consolidationService = new ConsolidationService();
130
131     private static void initNodeTemplateIdGeneratorImplMap() {
132         unifiedSubstitutionNodeTemplateIdGeneratorImplMap.put(COMPUTE, CommandImplNames.COMPUTE_NEW_NODE_TEMPLATE_ID_GENERATOR_IMPL);
133         unifiedSubstitutionNodeTemplateIdGeneratorImplMap.put(PORT, CommandImplNames.PORT_NEW_NODE_TEMPLATE_ID_GENERATOR_IMPL);
134         unifiedSubstitutionNodeTemplateIdGeneratorImplMap.put(SUB_INTERFACE, CommandImplNames.SUB_INTERFACE_NEW_NODE_TEMPLATE_ID_GENERATOR_IMPL);
135     }
136
137     private static List<EntityConsolidationData> getPortConsolidationDataList(List<String> portIds,
138                                                                               List<UnifiedCompositionData> unifiedCompositionDataList) {
139         return unifiedCompositionDataList.stream()
140             .flatMap(unifiedCompositionData -> unifiedCompositionData.getPortTemplateConsolidationDataList().stream())
141             .filter(portTemplateConsolidationData -> portIds.contains(portTemplateConsolidationData.getNodeTemplateId()))
142             .collect(Collectors.toList());
143     }
144
145     /**
146      * Create unified composition.
147      *
148      * @param serviceTemplate            the service template
149      * @param nestedServiceTemplate      the nested service template
150      * @param unifiedCompositionDataList the unified composition data list. In case no consolidation, one entry will be in this list, in case of
151      *                                   having consolidation, all entries in the list are the once which need to be consolidated.
152      * @param mode                       the mode
153      * @param context                    the context
154      */
155     public void createUnifiedComposition(ServiceTemplate serviceTemplate, ServiceTemplate nestedServiceTemplate,
156                                          List<UnifiedCompositionData> unifiedCompositionDataList, UnifiedCompositionMode mode,
157                                          TranslationContext context) {
158         Optional<UnifiedComposition> unifiedCompositionInstance = getUnifiedCompositionInstance(mode);
159         if (!unifiedCompositionInstance.isPresent()) {
160             return;
161         }
162         unifiedCompositionInstance.get().createUnifiedComposition(serviceTemplate, nestedServiceTemplate, unifiedCompositionDataList, context);
163     }
164
165     /**
166      * Create unified substitution service template according to the input service template, based on the unified composition data.
167      *
168      * @param serviceTemplate            the service template
169      * @param unifiedCompositionDataList the unified composition data list. In case no consolidation, one entry will be in this list, in case of
170      *                                   having consolidation, all entries in the list are the once which need to be consolidated.
171      * @param context                    the translation context
172      * @return the substitution service template
173      */
174     public Optional<ServiceTemplate> createUnifiedSubstitutionServiceTemplate(ServiceTemplate serviceTemplate,
175                                                                               List<UnifiedCompositionData> unifiedCompositionDataList,
176                                                                               TranslationContext context, String substitutionNodeTypeId,
177                                                                               Integer index) {
178         if (CollectionUtils.isEmpty(unifiedCompositionDataList)) {
179             return Optional.empty();
180         }
181         String templateName = getTemplateName(substitutionNodeTypeId, index);
182         ServiceTemplate substitutionServiceTemplate = HeatToToscaUtil.createInitSubstitutionServiceTemplate(templateName);
183         createIndexInputParameter(substitutionServiceTemplate);
184         String computeNodeType = handleCompute(serviceTemplate, substitutionServiceTemplate, unifiedCompositionDataList, context);
185         handlePorts(serviceTemplate, substitutionServiceTemplate, unifiedCompositionDataList, computeNodeType, context);
186         UnifiedCompositionTo unifiedCompositionTo = new UnifiedCompositionTo(serviceTemplate, substitutionServiceTemplate, unifiedCompositionDataList,
187             context, null);
188         handleSubInterfaces(unifiedCompositionTo);
189         createOutputParameters(unifiedCompositionTo, computeNodeType);
190         NodeType substitutionGlobalNodeType = handleSubstitutionGlobalNodeType(serviceTemplate, substitutionServiceTemplate, context,
191             substitutionNodeTypeId);
192         HeatToToscaUtil.handleSubstitutionMapping(context, substitutionNodeTypeId, substitutionServiceTemplate, substitutionGlobalNodeType);
193         context.getTranslatedServiceTemplates().put(templateName, substitutionServiceTemplate);
194         return Optional.of(substitutionServiceTemplate);
195     }
196
197     /**
198      * Create abstract substitute node template that can be substituted by the input substitutionServiceTemplate.
199      *
200      * @param serviceTemplate             the service template
201      * @param substitutionServiceTemplate the subtitution service template
202      * @param unifiedCompositionDataList  the unified composition data list. In case no consolidation, one entry will be in this list, in case of
203      *                                    having consolidation, all entries in the list are the once which need to be consolidated.
204      * @param context                     the translation context
205      * @return the abstract substitute node template id
206      */
207     public String createAbstractSubstituteNodeTemplate(ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate,
208                                                        List<UnifiedCompositionData> unifiedCompositionDataList, String substituteNodeTypeId,
209                                                        TranslationContext context, Integer index) {
210         NodeTemplate substitutionNodeTemplate = new NodeTemplate();
211         List<String> directiveList = new ArrayList<>();
212         directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
213         substitutionNodeTemplate.setDirectives(directiveList);
214         substitutionNodeTemplate.setType(substituteNodeTypeId);
215         Map<String, ParameterDefinition> substitutionTemplateInputs = DataModelUtil.getInputParameters(substitutionServiceTemplate);
216         Optional<Map<String, Object>> abstractSubstitutionProperties = Optional.empty();
217         if (Objects.nonNull(substitutionTemplateInputs)) {
218             abstractSubstitutionProperties = createAbstractSubstitutionProperties(serviceTemplate, substitutionTemplateInputs,
219                 unifiedCompositionDataList, context);
220         }
221         abstractSubstitutionProperties.ifPresent(substitutionNodeTemplate::setProperties);
222         //Add substitution filtering property
223         String substitutionServiceTemplateName = ToscaUtil.getServiceTemplateFileName(substitutionServiceTemplate);
224         int count = unifiedCompositionDataList.size();
225         DataModelUtil.addSubstitutionFilteringProperty(substitutionServiceTemplateName, substitutionNodeTemplate, count);
226         //Add index_value property
227         addIndexValueProperty(substitutionNodeTemplate);
228         String substituteNodeTemplateId = getSubstituteNodeTemplateId(substituteNodeTypeId, index);
229         //Add node template id and related abstract node template id in context
230         addUnifiedSubstitionData(context, serviceTemplate, unifiedCompositionDataList, substituteNodeTemplateId);
231         DataModelUtil.addNodeTemplate(serviceTemplate, substituteNodeTemplateId, substitutionNodeTemplate);
232         return substituteNodeTemplateId;
233     }
234
235     public void createVfcInstanceGroup(String abstractNodeTemplateId, ServiceTemplate serviceTemplate,
236                                        List<UnifiedCompositionData> unifiedCompositionDataList, TranslationContext context) {
237         if (!TranslationContext.isVfcInstanceGroupingEnabled()) {
238             return;
239         }
240         UnifiedCompositionTo unifiedCompositionTo = new UnifiedCompositionTo(serviceTemplate, null, unifiedCompositionDataList, context, null);
241         unifiedCompositionDataList.forEach(
242             unifiedCompositionData -> createSubInterfaceVfcInstanceGroup(abstractNodeTemplateId, unifiedCompositionTo, unifiedCompositionData));
243     }
244
245     private void createSubInterfaceVfcInstanceGroup(String abstractNodeTemplateId, UnifiedCompositionTo unifiedCompositionTo,
246                                                     UnifiedCompositionData unifiedCompositionData) {
247         List<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationDataList = getSubInterfaceTemplateConsolidationDataList(
248             unifiedCompositionData);
249         for (SubInterfaceTemplateConsolidationData subInterface : subInterfaceTemplateConsolidationDataList) {
250             Optional<String> parentPortNetworkRole;
251             if (Objects.isNull(unifiedCompositionTo.getSubstitutionServiceTemplate())) {
252                 parentPortNetworkRole = subInterface
253                     .getParentPortNetworkRole(unifiedCompositionTo.getServiceTemplate(), unifiedCompositionTo.getContext());
254             } else {
255                 parentPortNetworkRole = subInterface
256                     .getParentPortNetworkRole(unifiedCompositionTo.getSubstitutionServiceTemplate(), unifiedCompositionTo.getContext());
257             }
258             String subInterfaceNetworkRole = subInterface.getNetworkRole();
259             if (Objects.nonNull(subInterfaceNetworkRole) && parentPortNetworkRole.isPresent()) {
260                 createVfcInstanceGroupPerSubInterfaceNetworkRole(abstractNodeTemplateId, subInterfaceNetworkRole, parentPortNetworkRole.get(),
261                     unifiedCompositionTo.getServiceTemplate());
262             }
263         }
264     }
265
266     private void createVfcInstanceGroupPerSubInterfaceNetworkRole(String abstractNodeTemplateId, String subInterfaceNetworkRole,
267                                                                   String parentPortNetworkRole, ServiceTemplate serviceTemplate) {
268         String vfcNetworkRoleGroupId = getVfcNetworkRoleGroupId(subInterfaceNetworkRole);
269         Map<String, GroupDefinition> groups = DataModelUtil.getGroups(serviceTemplate);
270         if (!groups.containsKey(vfcNetworkRoleGroupId)) {
271             createNewVfcInstanceGroup(serviceTemplate, parentPortNetworkRole, subInterfaceNetworkRole, vfcNetworkRoleGroupId);
272         }
273         DataModelUtil.addGroupMember(serviceTemplate, vfcNetworkRoleGroupId, abstractNodeTemplateId);
274     }
275
276     private void createNewVfcInstanceGroup(ServiceTemplate serviceTemplate, String parentPortNetworkRole, String subInterfaceNetworkRole,
277                                            String vfcNetworkRoleGroupId) {
278         Map<String, Object> properties = new HashMap<>();
279         properties.put(SUB_INTERFACE_ROLE, subInterfaceNetworkRole);
280         properties.put(VFC_PARENT_PORT_ROLE, parentPortNetworkRole);
281         updateVfcInstanceGroupExposedProperties(subInterfaceNetworkRole, serviceTemplate, properties);
282         GroupDefinition groupDefinition = new GroupDefinition();
283         groupDefinition.setType(GROUP_TYPE_PREFIX + VFC_INSTANCE_GROUP);
284         groupDefinition.setProperties(properties);
285         DataModelUtil.addGroupDefinitionToTopologyTemplate(serviceTemplate, vfcNetworkRoleGroupId, groupDefinition);
286     }
287
288     private void updateVfcInstanceGroupExposedProperties(String subInterfaceNetworkRole, ServiceTemplate serviceTemplate,
289                                                          Map<String, Object> properties) {
290         List<String> exposedVfcInstanceGroupingProperties = TranslationContext.getExposedVfcInstanceGroupingProperties();
291         if (CollectionUtils.isEmpty(exposedVfcInstanceGroupingProperties)) {
292             return;
293         }
294         for (String propertyName : exposedVfcInstanceGroupingProperties) {
295             Map<String, Object> getInputMap = new HashMap<>();
296             String vfcGroupPropertyInputName = subInterfaceNetworkRole + "_" + propertyName;
297             getInputMap.put(GET_INPUT.getFunctionName(), vfcGroupPropertyInputName);
298             properties.put(propertyName, getInputMap);
299             addInputParameter(vfcGroupPropertyInputName, PropertyType.STRING.getDisplayName(), null, serviceTemplate);
300         }
301     }
302
303     private String getVfcNetworkRoleGroupId(String subInterfaceNetworkRole) {
304         StringBuilder sb = new StringBuilder();
305         sb.append(subInterfaceNetworkRole).append("_").append(GROUP);
306         return sb.toString();
307     }
308
309     /**
310      * Update the connectivity from/to the "moved" nodes from the original service template to the new substitution service template.
311      *
312      * @param serviceTemplate            the service template
313      * @param unifiedCompositionDataList the unified composition data list. In case no consolidation, one entry will be in this list, in case of
314      *                                   having consolidation, all entries in the list are the once which need to be consolidated.
315      * @param context                    the translation context
316      */
317     public void updateCompositionConnectivity(ServiceTemplate serviceTemplate, List<UnifiedCompositionData> unifiedCompositionDataList,
318                                               TranslationContext context) {
319         updOutputParamGetAttrInConnectivity(serviceTemplate, unifiedCompositionDataList, context);
320         updNodesGetAttrInConnectivity(serviceTemplate, unifiedCompositionDataList, context);
321         updNodesConnectedOutConnectivity(serviceTemplate, unifiedCompositionDataList, context);
322         updNodesConnectedInConnectivity(serviceTemplate, unifiedCompositionDataList, context);
323         updVolumeConnectivity(serviceTemplate, unifiedCompositionDataList, context);
324         updGroupsConnectivity(serviceTemplate, unifiedCompositionDataList, context);
325     }
326
327     /**
328      * Delete the "moved" nodes from the original service template to the new substitution service template.
329      *
330      * @param serviceTemplate            the service template
331      * @param unifiedCompositionDataList the unified composition data list. In case no consolidation, one entry will be in this list, in case of
332      *                                   having consolidation, all entries in the list are the once which need to be consolidated.
333      * @param context                    the translation context
334      */
335     public void cleanUnifiedCompositionEntities(ServiceTemplate serviceTemplate, List<UnifiedCompositionData> unifiedCompositionDataList,
336                                                 TranslationContext context) {
337         for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
338             //Clean compute node template data from top level service template
339             ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData.getComputeTemplateConsolidationData();
340             cleanServiceTemplate(serviceTemplate, computeTemplateConsolidationData, context);
341             //Clean port node template data from top level service template
342             List<PortTemplateConsolidationData> portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData);
343             for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) {
344                 cleanServiceTemplate(serviceTemplate, portTemplateConsolidationData, context);
345             }
346             //Clean sub-interface node template data from top level service template
347             List<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationDataList = getSubInterfaceTemplateConsolidationDataList(
348                 unifiedCompositionData);
349             for (SubInterfaceTemplateConsolidationData subInterfaceTemplateConsolidationData : subInterfaceTemplateConsolidationDataList) {
350                 cleanServiceTemplate(serviceTemplate, subInterfaceTemplateConsolidationData, context);
351             }
352         }
353     }
354
355     /**
356      * Clean node types.
357      *
358      * @param serviceTemplate            the service template
359      * @param unifiedCompositionDataList the unified composition data list
360      * @param context                    the context
361      */
362     public void cleanNodeTypes(ServiceTemplate serviceTemplate, List<UnifiedCompositionData> unifiedCompositionDataList, TranslationContext context) {
363         for (UnifiedCompositionData unifiedData : unifiedCompositionDataList) {
364             removeCleanedNodeType(unifiedData.getComputeTemplateConsolidationData().getNodeTemplateId(), serviceTemplate, context);
365         }
366         if (MapUtils.isEmpty(serviceTemplate.getNode_types())) {
367             serviceTemplate.setNode_types(null);
368         }
369     }
370
371     public void updateSubstitutionNodeTypePrefix(ServiceTemplate substitutionServiceTemplate) {
372         Map<String, NodeTemplate> nodeTemplates = substitutionServiceTemplate.getTopology_template().getNode_templates();
373         for (Map.Entry<String, NodeTemplate> nodeTemplateEntry : nodeTemplates.entrySet()) {
374             String nodeTypeId = nodeTemplateEntry.getValue().getType();
375             NodeType origNodeType = substitutionServiceTemplate.getNode_types().get(nodeTypeId);
376             if (Objects.nonNull(origNodeType) && nodeTypeId.startsWith(ToscaNodeType.VFC_TYPE_PREFIX) && origNodeType.getDerived_from()
377                 .equals(ToscaNodeType.NOVA_SERVER)) {
378                 substitutionServiceTemplate.getNode_types().remove(nodeTypeId);
379                 String newNodeTypeId = nodeTypeId.replace(ToscaNodeType.VFC_TYPE_PREFIX, ToscaNodeType.COMPUTE_TYPE_PREFIX);
380                 nodeTemplateEntry.getValue().setType(newNodeTypeId);
381                 DataModelUtil.addNodeTemplate(substitutionServiceTemplate, nodeTemplateEntry.getKey(), nodeTemplateEntry.getValue());
382                 substitutionServiceTemplate.getNode_types().put(newNodeTypeId, origNodeType);
383             }
384         }
385     }
386
387     /**
388      * Update unified abstract nodes connectivity.
389      *
390      * @param serviceTemplate the service template
391      * @param context         the context
392      */
393     public void updateUnifiedAbstractNodesConnectivity(ServiceTemplate serviceTemplate, TranslationContext context) {
394         String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
395         UnifiedSubstitutionData unifiedSubstitutionData = context.getUnifiedSubstitutionData().get(serviceTemplateFileName);
396         if (Objects.nonNull(unifiedSubstitutionData)) {
397             //Handle get attribute in connectivity for abstarct node to abstract node templates
398             Set<String> abstractNodeIds = new HashSet<>(unifiedSubstitutionData.getAllRelatedAbstractNodeIds());
399             handleGetAttrInConnectivity(serviceTemplate, abstractNodeIds, context);
400             //Handle get attribute in connectivity for abstract node templates to nested node template
401             Set<String> nestedNodeIds = new HashSet<>(unifiedSubstitutionData.getAllUnifiedNestedNodeTemplateIds());
402             handleGetAttrInConnectivity(serviceTemplate, nestedNodeIds, context);
403         }
404     }
405
406     /**
407      * Handle unified nested definition.
408      *
409      * @param unifiedCompositionTo   the unified composition data transfer object
410      * @param unifiedCompositionData the unified composition data
411      */
412     public void handleUnifiedNestedDefinition(UnifiedCompositionTo unifiedCompositionTo, UnifiedCompositionData unifiedCompositionData) {
413         handleUnifiedNestedNodeType(unifiedCompositionTo.getServiceTemplate(), unifiedCompositionTo.getSubstitutionServiceTemplate(),
414             unifiedCompositionTo.getContext());
415         updateUnifiedNestedTemplates(unifiedCompositionTo.getServiceTemplate(), unifiedCompositionTo.getSubstitutionServiceTemplate(),
416             unifiedCompositionData, unifiedCompositionTo.getContext());
417     }
418
419     private void handleGetAttrInConnectivity(ServiceTemplate serviceTemplate, Set<String> unifiedNodeIds, TranslationContext context) {
420         Map<String, NodeTemplate> nodeTemplates = serviceTemplate.getTopology_template().getNode_templates();
421         String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
422         for (String unifiedNodeId : unifiedNodeIds) {
423             NodeTemplate nodeTemplate = nodeTemplates.get(unifiedNodeId);
424             handleGetAttrInAbstractNodeTemplate(serviceTemplate, context, serviceTemplateFileName, nodeTemplate);
425         }
426     }
427
428     private void handleUnifiedNestedNodeType(ServiceTemplate mainServiceTemplate, ServiceTemplate nestedServiceTemplate, TranslationContext context) {
429         SubstitutionMapping substitutionMappings = nestedServiceTemplate.getTopology_template().getSubstitution_mappings();
430         String nodeTypeId = substitutionMappings.getNode_type();
431         Optional<String> newNestedNodeTypeId = getNewNestedNodeTypeId(nestedServiceTemplate, context);
432         ServiceTemplate globalSubstitutionServiceTemplate = context.getGlobalSubstitutionServiceTemplate();
433         if (isNestedServiceTemplateWasHandled(globalSubstitutionServiceTemplate, nestedServiceTemplate, context, newNestedNodeTypeId)) {
434             context.updateHandledComputeType(ToscaUtil.getServiceTemplateFileName(mainServiceTemplate), newNestedNodeTypeId.get(),
435                 ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate));
436             return;
437         }
438         newNestedNodeTypeId.ifPresent(
439             newNestedNodeTypeIdVal -> handleNestedNodeType(nodeTypeId, newNestedNodeTypeIdVal, nestedServiceTemplate, mainServiceTemplate,
440                 globalSubstitutionServiceTemplate, context));
441     }
442
443     private boolean isNestedServiceTemplateWasHandled(ServiceTemplate mainServiceTemplate, ServiceTemplate nestedServiceTemplate,
444                                                       TranslationContext context, Optional<String> newNestedNodeTypeId) {
445         return newNestedNodeTypeId.isPresent() && context.isNestedServiceTemplateWasHandled(ToscaUtil.getServiceTemplateFileName(mainServiceTemplate),
446             ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate));
447     }
448
449     private void handleNestedNodeType(String nodeTypeId, String newNestedNodeTypeId, ServiceTemplate nestedServiceTemplate,
450                                       ServiceTemplate mainServiceTemplate, ServiceTemplate globalSubstitutionServiceTemplate,
451                                       TranslationContext context) {
452         updateNestedServiceTemplate(nestedServiceTemplate, context);
453         updateNestedNodeType(nodeTypeId, newNestedNodeTypeId, nestedServiceTemplate, mainServiceTemplate, globalSubstitutionServiceTemplate, context);
454     }
455
456     private void updateNestedServiceTemplate(ServiceTemplate nestedServiceTemplate, TranslationContext context) {
457         enrichPortProperties(nestedServiceTemplate, context);
458     }
459
460     private void enrichPortProperties(ServiceTemplate nestedServiceTemplate, TranslationContext context) {
461         String nestedServiceTemplateFileName = ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate);
462         FilePortConsolidationData filePortConsolidationData = context.getConsolidationData().getPortConsolidationData()
463             .getFilePortConsolidationData(nestedServiceTemplateFileName);
464         if (Objects.nonNull(filePortConsolidationData)) {
465             Set<String> portNodeTemplateIds = filePortConsolidationData.getAllPortNodeTemplateIds();
466             if (Objects.nonNull(portNodeTemplateIds)) {
467                 for (String portNodeTemplateId : portNodeTemplateIds) {
468                     NodeTemplate portNodeTemplate = DataModelUtil.getNodeTemplate(nestedServiceTemplate, portNodeTemplateId);
469                     List<EntityConsolidationData> portEntityConsolidationDataList = new ArrayList<>();
470                     portEntityConsolidationDataList.add(filePortConsolidationData.getPortTemplateConsolidationData(portNodeTemplateId));
471                     handleNodeTypeProperties(nestedServiceTemplate, portEntityConsolidationDataList, portNodeTemplate, UnifiedCompositionEntity.PORT,
472                         null, context);
473                     //Add subinterface_indicator property to PORT
474                     addPortSubInterfaceIndicatorProperty(portNodeTemplate.getProperties(),
475                         filePortConsolidationData.getPortTemplateConsolidationData(portNodeTemplateId));
476                 }
477             }
478         }
479     }
480
481     private void updateNestedNodeType(String nodeTypeId, String newNestedNodeTypeId, ServiceTemplate nestedServiceTemplate,
482                                       ServiceTemplate mainServiceTemplate, ServiceTemplate globalSubstitutionServiceTemplate,
483                                       TranslationContext context) {
484         String indexedNewNestedNodeTypeId = updateNodeTypeId(nodeTypeId, newNestedNodeTypeId, nestedServiceTemplate, mainServiceTemplate,
485             globalSubstitutionServiceTemplate, context);
486         updateNodeTypeProperties(nestedServiceTemplate, globalSubstitutionServiceTemplate, indexedNewNestedNodeTypeId);
487     }
488
489     private void updateNodeTypeProperties(ServiceTemplate nestedServiceTemplate, ServiceTemplate globalSubstitutionServiceTemplate,
490                                           String nodeTypeId) {
491         ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
492         Map<String, PropertyDefinition> nodeTypePropertiesDefinition = toscaAnalyzerService
493             .manageSubstitutionNodeTypeProperties(nestedServiceTemplate);
494         NodeType nestedNodeType = DataModelUtil.getNodeType(globalSubstitutionServiceTemplate, nodeTypeId);
495         nestedNodeType.setProperties(nodeTypePropertiesDefinition);
496     }
497
498     private String updateNodeTypeId(String nodeTypeId, String newNestedNodeTypeId, ServiceTemplate nestedServiceTemplate,
499                                     ServiceTemplate mainServiceTemplate, ServiceTemplate globalSubstitutionServiceTemplate,
500                                     TranslationContext context) {
501         String indexedNewNestedNodeTypeId = handleNestedNodeTypeInGlobalSubstitutionTemplate(nodeTypeId, newNestedNodeTypeId,
502             globalSubstitutionServiceTemplate, context);
503         handleSubstitutionMappingInNestedServiceTemplate(indexedNewNestedNodeTypeId, nestedServiceTemplate, context);
504         context.updateHandledComputeType(ToscaUtil.getServiceTemplateFileName(mainServiceTemplate),
505             ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate), newNestedNodeTypeId);
506         return indexedNewNestedNodeTypeId;
507     }
508
509     private String handleNestedNodeTypeInGlobalSubstitutionTemplate(String nodeTypeId, String newNestedNodeTypeId,
510                                                                     ServiceTemplate globalSubstitutionServiceTemplate, TranslationContext context) {
511         String indexedNodeType = getIndexedGlobalNodeTypeId(newNestedNodeTypeId, context);
512         context.updateUsedTimesForNestedComputeNodeType(ToscaUtil.getServiceTemplateFileName(globalSubstitutionServiceTemplate), newNestedNodeTypeId);
513         handleNestedNodeTypesInGlobalSubstituteServiceTemplate(nodeTypeId, indexedNodeType, globalSubstitutionServiceTemplate, context);
514         return indexedNodeType;
515     }
516
517     private String getIndexedGlobalNodeTypeId(String newNestedNodeTypeId, TranslationContext context) {
518         int globalNodeTypeIndex = context
519             .getGlobalNodeTypeIndex(ToscaUtil.getServiceTemplateFileName(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME), newNestedNodeTypeId);
520         return globalNodeTypeIndex > 0 ? newNestedNodeTypeId + "_" + globalNodeTypeIndex : newNestedNodeTypeId;
521     }
522
523     private void updateUnifiedNestedTemplates(ServiceTemplate mainServiceTemplate, ServiceTemplate nestedServiceTemplate,
524                                               UnifiedCompositionData unifiedCompositionData, TranslationContext context) {
525         NestedTemplateConsolidationData nestedTemplateConsolidationData = unifiedCompositionData.getNestedTemplateConsolidationData();
526         if (Objects.isNull(nestedTemplateConsolidationData)) {
527             return;
528         }
529         handleNestedNodeTemplateInMainServiceTemplate(nestedTemplateConsolidationData.getNodeTemplateId(), mainServiceTemplate, nestedServiceTemplate,
530             context);
531     }
532
533     /**
534      * Update connectivity for unified nested patterns.
535      *
536      * @param unifiedCompositionTo   the unified composition data transfer object
537      * @param unifiedCompositionData the unified composition data
538      */
539     public void updateUnifiedNestedConnectivity(UnifiedCompositionTo unifiedCompositionTo, UnifiedCompositionData unifiedCompositionData) {
540         updNestedCompositionNodesConnectedInConnectivity(unifiedCompositionTo.getServiceTemplate(), unifiedCompositionData,
541             unifiedCompositionTo.getContext());
542         updNestedCompositionNodesConnectedOutConnectivity(unifiedCompositionTo.getServiceTemplate(),
543             unifiedCompositionTo.getSubstitutionServiceTemplate(), unifiedCompositionData, unifiedCompositionTo.getContext());
544         updNestedCompositionNodesGetAttrInConnectivity(unifiedCompositionTo.getServiceTemplate(), unifiedCompositionData,
545             unifiedCompositionTo.getContext());
546         updNestedCompositionOutputParamGetAttrInConnectivity(unifiedCompositionTo.getServiceTemplate(), unifiedCompositionData,
547             unifiedCompositionTo.getContext());
548     }
549
550     /**
551      * Clean unified nested entities. Update the heat stack group with the new node template ids.
552      *
553      * @param unifiedCompositionTo   the unified composition data transfer object
554      * @param unifiedCompositionData the unified composition data
555      */
556     public void cleanUnifiedNestedEntities(UnifiedCompositionTo unifiedCompositionTo, UnifiedCompositionData unifiedCompositionData) {
557         EntityConsolidationData entityConsolidationData = unifiedCompositionData.getNestedTemplateConsolidationData();
558         updateHeatStackGroupNestedComposition(unifiedCompositionTo.getServiceTemplate(), entityConsolidationData, unifiedCompositionTo.getContext());
559     }
560
561     public void createNestedVfcInstanceGroup(String nestedNodeTemplateId, UnifiedCompositionTo unifiedCompositionTo,
562                                              UnifiedCompositionData unifiedCompositionData) {
563         if (!TranslationContext.isVfcInstanceGroupingEnabled()) {
564             return;
565         }
566         createSubInterfaceVfcInstanceGroup(nestedNodeTemplateId, unifiedCompositionTo, unifiedCompositionData);
567     }
568
569     public void handleComplexVfcType(ServiceTemplate serviceTemplate, TranslationContext context) {
570         SubstitutionMapping substitutionMapping = serviceTemplate.getTopology_template().getSubstitution_mappings();
571         if (Objects.isNull(substitutionMapping)) {
572             return;
573         }
574         ServiceTemplate globalSubstitutionServiceTemplate = context.getGlobalSubstitutionServiceTemplate();
575         String substitutionNT = substitutionMapping.getNode_type();
576         if (globalSubstitutionServiceTemplate.getNode_types().containsKey(substitutionNT)) {
577             //This needs to be done when catalog is ready for complex VFC
578         }
579     }
580
581     protected void updNodesConnectedOutConnectivity(ServiceTemplate serviceTemplate, List<UnifiedCompositionData> unifiedCompositionDataList,
582                                                     TranslationContext context) {
583         for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
584             ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData.getComputeTemplateConsolidationData();
585             //Add requirements in the abstract node template for nodes connected out for computes
586             String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId());
587             Multimap<String, RequirementAssignmentData> computeNodesConnectedOut = computeTemplateConsolidationData.getNodesConnectedOut();
588             if (computeNodesConnectedOut != null) {
589                 updateRequirementInAbstractNodeTemplate(serviceTemplate, computeTemplateConsolidationData, newComputeNodeTemplateId,
590                     computeNodesConnectedOut, context);
591             }
592             String computeType = getComputeTypeSuffix(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId());
593             //Add requirements in the abstract node template for nodes connected out for ports
594             List<PortTemplateConsolidationData> portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData);
595             for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) {
596                 String newPortNodeTemplateId = getNewPortNodeTemplateId(portTemplateConsolidationData.getNodeTemplateId(), computeType,
597                     computeTemplateConsolidationData);
598                 Multimap<String, RequirementAssignmentData> portNodesConnectedOut = portTemplateConsolidationData.getNodesConnectedOut();
599                 if (portNodesConnectedOut != null) {
600                     updateRequirementInAbstractNodeTemplate(serviceTemplate, portTemplateConsolidationData, newPortNodeTemplateId,
601                         portNodesConnectedOut, context);
602                 }
603             }
604             //For sub-interface
605
606             //Add requirements in the abstract node template for nodes connected out for ports
607             updateSubInterfaceNodesConnectedOut(serviceTemplate, unifiedCompositionData, computeTemplateConsolidationData, computeType, context);
608         }
609     }
610
611     private void updateSubInterfaceNodesConnectedOut(ServiceTemplate serviceTemplate, UnifiedCompositionData unifiedCompositionData,
612                                                      ComputeTemplateConsolidationData computeTemplateConsolidationData, String computeType,
613                                                      TranslationContext context) {
614         List<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationDataList = getSubInterfaceTemplateConsolidationDataList(
615             unifiedCompositionData);
616         for (SubInterfaceTemplateConsolidationData subInterfaceTemplateConsolidationData : subInterfaceTemplateConsolidationDataList) {
617             String newSubInterfaceNodeTemplateId = getNewSubInterfaceNodeTemplateId(serviceTemplate, computeType, computeTemplateConsolidationData,
618                 subInterfaceTemplateConsolidationData, context);
619             Multimap<String, RequirementAssignmentData> subInterfaceNodesConnectedOut = subInterfaceTemplateConsolidationData.getNodesConnectedOut();
620             if (subInterfaceNodesConnectedOut != null) {
621                 updateRequirementInAbstractNodeTemplate(serviceTemplate, subInterfaceTemplateConsolidationData, newSubInterfaceNodeTemplateId,
622                     subInterfaceNodesConnectedOut, context);
623             }
624         }
625     }
626
627     private void updNestedCompositionNodesConnectedOutConnectivity(ServiceTemplate serviceTemplate, ServiceTemplate nestedServiceTemplate,
628                                                                    UnifiedCompositionData unifiedCompositionData, TranslationContext context) {
629         NestedTemplateConsolidationData nestedTemplateConsolidationData = unifiedCompositionData.getNestedTemplateConsolidationData();
630         Multimap<String, RequirementAssignmentData> nodesConnectedOut =
631             Objects.isNull(nestedTemplateConsolidationData) ? ArrayListMultimap.create() : nestedTemplateConsolidationData.getNodesConnectedOut();
632         FileComputeConsolidationData nestedFileComputeConsolidationData = context.getConsolidationData().getComputeConsolidationData()
633             .getFileComputeConsolidationData(ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate));
634         if (Objects.isNull(nestedFileComputeConsolidationData)) {
635             return;
636         }
637         TypeComputeConsolidationData computeType = nestedFileComputeConsolidationData.getAllTypeComputeConsolidationData().iterator().next();
638         if (Objects.isNull(computeType)) {
639             return;
640         }
641         String singleComputeId = computeType.getAllComputeNodeTemplateIds().iterator().next();
642         if (Objects.nonNull(singleComputeId) && (Objects.nonNull(nestedTemplateConsolidationData))) {
643             updateRequirementInNestedNodeTemplate(serviceTemplate, nestedTemplateConsolidationData, singleComputeId, nodesConnectedOut);
644         }
645     }
646
647     private void updNodesConnectedInConnectivity(ServiceTemplate serviceTemplate, List<UnifiedCompositionData> unifiedCompositionDataList,
648                                                  TranslationContext context) {
649         for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
650             ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData.getComputeTemplateConsolidationData();
651             //Update requirements in the node template which pointing to the computes
652             String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId());
653             updNodesConnectedInConnectivity(serviceTemplate, computeTemplateConsolidationData, newComputeNodeTemplateId, context, false);
654             String computeType = getComputeTypeSuffix(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId());
655             //Update requirements in the node template which pointing to the ports
656             List<PortTemplateConsolidationData> portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData);
657             for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) {
658                 String newPortNodeTemplateId = getNewPortNodeTemplateId(portTemplateConsolidationData.getNodeTemplateId(), computeType,
659                     computeTemplateConsolidationData);
660                 updNodesConnectedInConnectivity(serviceTemplate, portTemplateConsolidationData, newPortNodeTemplateId, context, false);
661             }
662             //Update requirements in the node template which pointing to the sub-interface
663             updateSubInterfaceNodesConnectedIn(serviceTemplate, unifiedCompositionData, computeTemplateConsolidationData, computeType, context);
664         }
665     }
666
667     private void updNodesConnectedInConnectivity(ServiceTemplate serviceTemplate, EntityConsolidationData entityConsolidationData,
668                                                  String newNodeTemplateId, TranslationContext context, boolean isNested) {
669         Multimap<String, RequirementAssignmentData> nodesConnectedIn = entityConsolidationData.getNodesConnectedIn();
670         if (nodesConnectedIn == null) {
671             //No nodes connected in info
672             return;
673         }
674         for (String key : nodesConnectedIn.keySet()) {
675             Collection<RequirementAssignmentData> requirementAssignmentDataList = nodesConnectedIn.get(key);
676             for (RequirementAssignmentData requirementAssignmentData : requirementAssignmentDataList) {
677                 RequirementAssignment requirementAssignment = requirementAssignmentData.getRequirementAssignment();
678                 if (!requirementAssignment.getNode().equals(entityConsolidationData.getNodeTemplateId())) {
679                     //The requirement assignment target node should be the one which we are handling in the
680
681                     //consolidation object
682                     continue;
683                 }
684                 //Update the requirement assignment object in the original node template
685                 if (isNested) {
686                     updateRequirementForNestedCompositionNodesConnectedIn(serviceTemplate, requirementAssignmentData, newNodeTemplateId);
687                 } else {
688                     updateRequirementForNodesConnectedIn(serviceTemplate, requirementAssignmentData, entityConsolidationData, key, newNodeTemplateId,
689                         context);
690                 }
691             }
692         }
693     }
694
695     private void updateSubInterfaceNodesConnectedIn(ServiceTemplate serviceTemplate, UnifiedCompositionData unifiedCompositionData,
696                                                     ComputeTemplateConsolidationData computeTemplateConsolidationData, String computeType,
697                                                     TranslationContext context) {
698         List<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationDataList = getSubInterfaceTemplateConsolidationDataList(
699             unifiedCompositionData);
700         for (SubInterfaceTemplateConsolidationData subInterfaceTemplateConsolidationData : subInterfaceTemplateConsolidationDataList) {
701             String newSubInterfaceNodeTemplateId = getNewSubInterfaceNodeTemplateId(serviceTemplate, computeType, computeTemplateConsolidationData,
702                 subInterfaceTemplateConsolidationData, context);
703             updNodesConnectedInConnectivity(serviceTemplate, subInterfaceTemplateConsolidationData, newSubInterfaceNodeTemplateId, context, false);
704         }
705     }
706
707     protected void updNestedCompositionNodesConnectedInConnectivity(ServiceTemplate serviceTemplate, UnifiedCompositionData unifiedCompositionData,
708                                                                     TranslationContext context) {
709         NestedTemplateConsolidationData nestedTemplateConsolidationData = unifiedCompositionData.getNestedTemplateConsolidationData();
710         //Update requirements in the node template which pointing to the nested nodes
711         String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
712         Optional<String> newNestedNodeTemplateId = context
713             .getUnifiedNestedNodeTemplateId(serviceTemplateFileName, nestedTemplateConsolidationData.getNodeTemplateId());
714         newNestedNodeTemplateId.ifPresent(
715             newNestedNodeTemplateIdVal -> updNodesConnectedInConnectivity(serviceTemplate, nestedTemplateConsolidationData,
716                 newNestedNodeTemplateIdVal, context, true));
717     }
718
719     private void updVolumeConnectivity(ServiceTemplate serviceTemplate, List<UnifiedCompositionData> unifiedCompositionDataList,
720                                        TranslationContext context) {
721         for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
722             ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData.getComputeTemplateConsolidationData();
723             //Add requirements in the abstract node template for compute volumes
724             String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId());
725             Multimap<String, RequirementAssignmentData> computeVolumes = computeTemplateConsolidationData.getVolumes();
726             if (computeVolumes != null) {
727                 updateRequirementInAbstractNodeTemplate(serviceTemplate, computeTemplateConsolidationData, newComputeNodeTemplateId, computeVolumes,
728                     context);
729             }
730         }
731     }
732
733     private void updGroupsConnectivity(ServiceTemplate serviceTemplate, List<UnifiedCompositionData> unifiedCompositionDataList,
734                                        TranslationContext context) {
735         for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
736             ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData.getComputeTemplateConsolidationData();
737             //Add requirements in the abstract node template for nodes connected in for computes
738             updGroupsConnectivity(serviceTemplate, computeTemplateConsolidationData, context);
739             //Add requirements in the abstract node template for nodes connected in for ports
740             List<PortTemplateConsolidationData> portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData);
741             for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) {
742                 updGroupsConnectivity(serviceTemplate, portTemplateConsolidationData, context);
743             }
744             //Add requirements in the abstract node template for nodes connected in for subInterface
745             List<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationDataList = getSubInterfaceTemplateConsolidationDataList(
746                 unifiedCompositionData);
747             for (SubInterfaceTemplateConsolidationData subInterfaceTemplateConsolidationData : subInterfaceTemplateConsolidationDataList) {
748                 updGroupsConnectivity(serviceTemplate, subInterfaceTemplateConsolidationData, context);
749             }
750         }
751     }
752
753     private void updGroupsConnectivity(ServiceTemplate serviceTemplate, EntityConsolidationData entityConsolidationData, TranslationContext context) {
754         List<String> groupIds = entityConsolidationData.getGroupIds();
755         if (groupIds == null) {
756             return;
757         }
758         String oldNodeTemplateId = entityConsolidationData.getNodeTemplateId();
759         String abstractNodeTemplateId = context.getUnifiedAbstractNodeTemplateId(serviceTemplate, entityConsolidationData.getNodeTemplateId());
760         Map<String, GroupDefinition> groups = serviceTemplate.getTopology_template().getGroups();
761         if (groups == null) {
762             return;
763         }
764         for (String groupId : groupIds) {
765             GroupDefinition groupDefinition = groups.get(groupId);
766             if (groupDefinition == null) {
767                 continue;
768             }
769             List<String> groupMembers = groupDefinition.getMembers();
770             if (groupMembers.contains(oldNodeTemplateId)) {
771                 //Replace the old node template id
772                 groupMembers.remove(oldNodeTemplateId);
773                 if (!groupMembers.contains(abstractNodeTemplateId)) {
774                     //Add the abstract node template id if not already present
775                     groupMembers.add(abstractNodeTemplateId);
776                 }
777             }
778         }
779     }
780
781     private void updOutputParamGetAttrInConnectivity(ServiceTemplate serviceTemplate, List<UnifiedCompositionData> unifiedComposotionDataList,
782                                                      TranslationContext context) {
783         for (UnifiedCompositionData unifiedCompositionData : unifiedComposotionDataList) {
784             ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData.getComputeTemplateConsolidationData();
785             String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId());
786             updOutputParamGetAttrInConnectivity(serviceTemplate, computeTemplateConsolidationData,
787                 computeTemplateConsolidationData.getNodeTemplateId(), newComputeNodeTemplateId, context, false);
788             String computeType = getComputeTypeSuffix(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId());
789             List<PortTemplateConsolidationData> portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData);
790             for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) {
791                 String newPortNodeTemplateId = getNewPortNodeTemplateId(portTemplateConsolidationData.getNodeTemplateId(), computeType,
792                     computeTemplateConsolidationData);
793                 updOutputParamGetAttrInConnectivity(serviceTemplate, portTemplateConsolidationData, portTemplateConsolidationData.getNodeTemplateId(),
794                     newPortNodeTemplateId, context, false);
795             }
796             updateSubInterfaceOutputParamGetAttrIn(serviceTemplate, unifiedCompositionData, computeTemplateConsolidationData, computeType, context);
797         }
798     }
799
800     private void updateSubInterfaceOutputParamGetAttrIn(ServiceTemplate serviceTemplate, UnifiedCompositionData unifiedCompositionData,
801                                                         ComputeTemplateConsolidationData computeTemplateConsolidationData, String computeType,
802                                                         TranslationContext context) {
803         List<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationDataList = getSubInterfaceTemplateConsolidationDataList(
804             unifiedCompositionData);
805         for (SubInterfaceTemplateConsolidationData subInterfaceTemplateConsolidationData : subInterfaceTemplateConsolidationDataList) {
806             String newSubInterfaceNodeTemplateId = getNewSubInterfaceNodeTemplateId(serviceTemplate, computeType, computeTemplateConsolidationData,
807                 subInterfaceTemplateConsolidationData, context);
808             updOutputParamGetAttrInConnectivity(serviceTemplate, subInterfaceTemplateConsolidationData,
809                 subInterfaceTemplateConsolidationData.getNodeTemplateId(), newSubInterfaceNodeTemplateId, context, false);
810         }
811     }
812
813     private void updNodesGetAttrInConnectivity(ServiceTemplate serviceTemplate, List<UnifiedCompositionData> unifiedComposotionDataList,
814                                                TranslationContext context) {
815         Map<String, UnifiedCompositionEntity> consolidationNodeTemplateIdAndType = getAllConsolidationNodeTemplateIdAndType(
816             unifiedComposotionDataList);
817         for (UnifiedCompositionData unifiedCompositionData : unifiedComposotionDataList) {
818             ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData.getComputeTemplateConsolidationData();
819             String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId());
820             updNodeGetAttrInConnectivity(serviceTemplate, computeTemplateConsolidationData, computeTemplateConsolidationData.getNodeTemplateId(),
821                 newComputeNodeTemplateId, context, consolidationNodeTemplateIdAndType, false);
822             String computeType = getComputeTypeSuffix(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId());
823             List<PortTemplateConsolidationData> portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData);
824             for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) {
825                 String newPotNodeTemplateId = getNewPortNodeTemplateId(portTemplateConsolidationData.getNodeTemplateId(), computeType,
826                     computeTemplateConsolidationData);
827                 updNodeGetAttrInConnectivity(serviceTemplate, portTemplateConsolidationData, portTemplateConsolidationData.getNodeTemplateId(),
828                     newPotNodeTemplateId, context, consolidationNodeTemplateIdAndType, false);
829             }
830             updateSubInterfaceNodesGetAttrIn(serviceTemplate, unifiedCompositionData, computeTemplateConsolidationData, computeType,
831                 consolidationNodeTemplateIdAndType, context);
832         }
833     }
834
835     private void updateSubInterfaceNodesGetAttrIn(ServiceTemplate serviceTemplate, UnifiedCompositionData unifiedCompositionData,
836                                                   ComputeTemplateConsolidationData computeTemplateConsolidationData, String computeType,
837                                                   Map<String, UnifiedCompositionEntity> consolidationNodeTemplateIdAndType,
838                                                   TranslationContext context) {
839         List<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationDataList = getSubInterfaceTemplateConsolidationDataList(
840             unifiedCompositionData);
841         for (SubInterfaceTemplateConsolidationData subInterfaceTemplateConsolidationData : subInterfaceTemplateConsolidationDataList) {
842             String newSubInterfaceNodeTemplateId = getNewSubInterfaceNodeTemplateId(serviceTemplate, computeType, computeTemplateConsolidationData,
843                 subInterfaceTemplateConsolidationData, context);
844             updNodeGetAttrInConnectivity(serviceTemplate, subInterfaceTemplateConsolidationData,
845                 subInterfaceTemplateConsolidationData.getNodeTemplateId(), newSubInterfaceNodeTemplateId, context, consolidationNodeTemplateIdAndType,
846                 false);
847         }
848     }
849
850     protected void updNestedCompositionOutputParamGetAttrInConnectivity(ServiceTemplate serviceTemplate,
851                                                                         UnifiedCompositionData unifiedCompositionData, TranslationContext context) {
852         NestedTemplateConsolidationData nestedTemplateConsolidationData = unifiedCompositionData.getNestedTemplateConsolidationData();
853         if (Objects.isNull(nestedTemplateConsolidationData)) {
854             return;
855         }
856         String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
857         Optional<String> newNestedNodeTemplateId = context
858             .getUnifiedNestedNodeTemplateId(serviceTemplateFileName, nestedTemplateConsolidationData.getNodeTemplateId());
859         newNestedNodeTemplateId.ifPresent(
860             newNestedNodeTemplateIdVal -> updOutputParamGetAttrInConnectivity(serviceTemplate, nestedTemplateConsolidationData,
861                 nestedTemplateConsolidationData.getNodeTemplateId(), newNestedNodeTemplateIdVal, context, true));
862     }
863
864     protected void updNestedCompositionNodesGetAttrInConnectivity(ServiceTemplate serviceTemplate, UnifiedCompositionData unifiedCompositionData,
865                                                                   TranslationContext context) {
866         NestedTemplateConsolidationData nestedTemplateConsolidationData = unifiedCompositionData.getNestedTemplateConsolidationData();
867         if (Objects.isNull(nestedTemplateConsolidationData)) {
868             return;
869         }
870         String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
871         Optional<String> newNestedNodeTemplateId = context
872             .getUnifiedNestedNodeTemplateId(serviceTemplateFileName, nestedTemplateConsolidationData.getNodeTemplateId());
873         newNestedNodeTemplateId.ifPresent(newNestedNodeTemplateIdVal -> updNodeGetAttrInConnectivity(serviceTemplate, nestedTemplateConsolidationData,
874             nestedTemplateConsolidationData.getNodeTemplateId(), newNestedNodeTemplateIdVal, context, null, true));
875     }
876
877     private void updateRequirementForNodesConnectedIn(ServiceTemplate serviceTemplate, RequirementAssignmentData requirementAssignmentData,
878                                                       EntityConsolidationData entityConsolidationData, String originalNodeTemplateId,
879                                                       String newNodeTemplateId, TranslationContext context) {
880         ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
881         RequirementAssignment requirementAssignment = requirementAssignmentData.getRequirementAssignment();
882         String newAbstractUnifiedNodeTemplateId = context
883             .getUnifiedAbstractNodeTemplateId(serviceTemplate, entityConsolidationData.getNodeTemplateId());
884         NodeTemplate abstractUnifiedNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, newAbstractUnifiedNodeTemplateId);
885         Optional<String> newCapabilityId = getNewCapabilityForNodesConnectedIn(serviceTemplate, abstractUnifiedNodeTemplate, requirementAssignment,
886             newNodeTemplateId, context);
887         if (newCapabilityId.isPresent()) {
888             //Creating a copy of the requirement object and checking if it already exists in the
889
890             // original node template
891             RequirementAssignment requirementAssignmentCopy = (RequirementAssignment) getClonedObject(
892                 requirementAssignmentData.getRequirementAssignment(), RequirementAssignment.class);
893             NodeTemplate originalNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, originalNodeTemplateId);
894             requirementAssignmentCopy.setCapability(newCapabilityId.get());
895             requirementAssignmentCopy.setNode(newAbstractUnifiedNodeTemplateId);
896             if (!toscaAnalyzerService
897                 .isRequirementExistInNodeTemplate(originalNodeTemplate, requirementAssignmentData.getRequirementId(), requirementAssignmentCopy)) {
898                 //Update the existing requirement
899                 requirementAssignmentData.getRequirementAssignment().setCapability(newCapabilityId.get());
900                 requirementAssignmentData.getRequirementAssignment().setNode(newAbstractUnifiedNodeTemplateId);
901             } else {
902                 //The updated requirement already exists in the node template so simply remove the
903
904                 // current one
905                 DataModelUtil.removeRequirementAssignment(originalNodeTemplate, requirementAssignmentData.getRequirementId(),
906                     requirementAssignmentData.getRequirementAssignment());
907             }
908         }
909     }
910
911     private void updateRequirementForNestedCompositionNodesConnectedIn(ServiceTemplate serviceTemplate,
912                                                                        RequirementAssignmentData requirementAssignmentData,
913                                                                        String newNodeTemplateId) {
914         ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
915         String newAbstractUnifiedNodeTemplateId = newNodeTemplateId;
916         RequirementAssignment requirementAssignment = requirementAssignmentData.getRequirementAssignment();
917         //Creating a copy of the requirement object and checking if it already exists in the
918
919         // original node template
920         RequirementAssignment requirementAssignmentCopy = (RequirementAssignment) getClonedObject(
921             requirementAssignmentData.getRequirementAssignment(), RequirementAssignment.class);
922         NodeTemplate unifiedAbstractNestedNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, newAbstractUnifiedNodeTemplateId);
923         requirementAssignmentCopy.setCapability(requirementAssignment.getCapability());
924         requirementAssignmentCopy.setNode(newAbstractUnifiedNodeTemplateId);
925         if (!toscaAnalyzerService.isRequirementExistInNodeTemplate(unifiedAbstractNestedNodeTemplate, requirementAssignmentData.getRequirementId(),
926             requirementAssignmentCopy)) {
927             //Update the existing requirement
928             requirementAssignmentData.getRequirementAssignment().setNode(newAbstractUnifiedNodeTemplateId);
929         } else {
930             //The updated requirement already exists in the node template so simply remove the
931
932             // current one
933             DataModelUtil.removeRequirementAssignment(unifiedAbstractNestedNodeTemplate, requirementAssignmentData.getRequirementId(),
934                 requirementAssignmentData.getRequirementAssignment());
935         }
936     }
937
938     private Optional<String> getNewCapabilityForNodesConnectedIn(ServiceTemplate serviceTemplate, NodeTemplate unifiedNodeTemplate,
939                                                                  RequirementAssignment requirementAssignment, String newNodeTemplateId,
940                                                                  TranslationContext context) {
941         ServiceTemplate globalSubstitutionServiceTemplate = HeatToToscaUtil.fetchGlobalSubstitutionServiceTemplate(serviceTemplate, context);
942         Map<String, NodeType> nodeTypes = globalSubstitutionServiceTemplate.getNode_types();
943         String unifiedNodeTemplateType = unifiedNodeTemplate.getType();
944         NodeType unifiedNodeType = nodeTypes.get(unifiedNodeTemplateType);
945         Map<String, CapabilityDefinition> abstractNodeTypeCapabilities = unifiedNodeType.getCapabilities();
946         for (Map.Entry<String, CapabilityDefinition> entry : abstractNodeTypeCapabilities.entrySet()) {
947             String capabilityId = entry.getKey();
948             CapabilityDefinition capabilityDefinition = entry.getValue();
949             String capabilityType = capabilityDefinition.getType();
950             if (capabilityType.equals(requirementAssignment.getCapability()) && capabilityId.endsWith(newNodeTemplateId)) {
951                 //Matching capability type found..Check if the id ends with new node template id
952                 return Optional.ofNullable(capabilityId);
953             }
954         }
955         return Optional.empty();
956     }
957
958     private void updateRequirementInAbstractNodeTemplate(ServiceTemplate serviceTemplate, EntityConsolidationData entityConsolidationData,
959                                                          String newNodeTemplateId,
960                                                          Multimap<String, RequirementAssignmentData> requirementAssignmentDataMap,
961                                                          TranslationContext context) {
962         ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
963         for (String key : requirementAssignmentDataMap.keySet()) {
964             String abstractNodeTemplateId = context.getUnifiedAbstractNodeTemplateId(serviceTemplate, entityConsolidationData.getNodeTemplateId());
965             NodeTemplate abstractNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, abstractNodeTemplateId);
966             if (abstractNodeTemplate == null) {
967                 //The abstract node template is not found from id in the context
968                 return;
969             }
970             Collection<RequirementAssignmentData> requirementAssignmentDataList = requirementAssignmentDataMap.get(key);
971             for (RequirementAssignmentData requirementAssignmentData : requirementAssignmentDataList) {
972                 String oldRequirementId = requirementAssignmentData.getRequirementId();
973                 RequirementAssignment abstractRequirementAssignment = (RequirementAssignment) getClonedObject(
974                     requirementAssignmentData.getRequirementAssignment(), RequirementAssignment.class);
975                 String newRequirementId = oldRequirementId + "_" + newNodeTemplateId;
976                 //Check if the requirement is not already present in the list of requirements of the
977
978                 // abstract node template
979                 if (!toscaAnalyzerService.isRequirementExistInNodeTemplate(abstractNodeTemplate, newRequirementId, abstractRequirementAssignment)) {
980                     DataModelUtil.addRequirementAssignment(abstractNodeTemplate, newRequirementId, abstractRequirementAssignment);
981                     //Update the volume relationship template if required
982                     updateVolumeRelationshipTemplate(serviceTemplate, abstractRequirementAssignment.getRelationship(), context);
983                 }
984             }
985         }
986     }
987
988     private void updateRequirementInNestedNodeTemplate(ServiceTemplate serviceTemplate, EntityConsolidationData entityConsolidationData,
989                                                        String newNodeTemplateId,
990                                                        Multimap<String, RequirementAssignmentData> requirementAssignmentDataMap) {
991         ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
992         if (CommonUtil.isMultimapEmpty(requirementAssignmentDataMap)) {
993             return;
994         }
995         for (String key : requirementAssignmentDataMap.keySet()) {
996             String nodeTemplateId = entityConsolidationData.getNodeTemplateId();
997             NodeTemplate nodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, nodeTemplateId);
998             if (nodeTemplate == null) {
999                 //The node template is not found from id in the context
1000                 return;
1001             }
1002             Collection<RequirementAssignmentData> requirementAssignmentDataList = requirementAssignmentDataMap.get(key);
1003             for (RequirementAssignmentData requirementAssignmentData : requirementAssignmentDataList) {
1004                 String oldRequirementId = requirementAssignmentData.getRequirementId();
1005                 RequirementAssignment clonedRequirementAssignment = (RequirementAssignment) getClonedObject(
1006                     requirementAssignmentData.getRequirementAssignment(), RequirementAssignment.class);
1007                 String newRequirementId = oldRequirementId + "_" + newNodeTemplateId;
1008                 //Check if the requirement is not already present in the list of requirements of the
1009
1010                 // node template
1011                 if (!toscaAnalyzerService.isRequirementExistInNodeTemplate(nodeTemplate, newRequirementId, clonedRequirementAssignment)) {
1012                     DataModelUtil.removeRequirementAssignment(nodeTemplate, oldRequirementId, requirementAssignmentData.getRequirementAssignment());
1013                     DataModelUtil.addRequirementAssignment(nodeTemplate, newRequirementId, clonedRequirementAssignment);
1014                 }
1015             }
1016         }
1017     }
1018
1019     private void updNodeGetAttrInConnectivity(ServiceTemplate serviceTemplate, EntityConsolidationData entityConsolidationData,
1020                                               String oldNodeTemplateId, String newNodeTemplateId, TranslationContext context,
1021                                               Map<String, UnifiedCompositionEntity> consolidationNodeTemplateIdAndType, boolean isNested) {
1022         Map<String, List<GetAttrFuncData>> nodesGetAttrIn = entityConsolidationData.getNodesGetAttrIn();
1023         if (MapUtils.isEmpty(nodesGetAttrIn)) {
1024             return;
1025         }
1026         for (Map.Entry<String, List<GetAttrFuncData>> nodesGetAttrInEntry : nodesGetAttrIn.entrySet()) {
1027             String sourceNodeTemplateId = nodesGetAttrInEntry.getKey();
1028             NodeTemplate sourceNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, sourceNodeTemplateId);
1029             if (!isNested && consolidationNodeTemplateIdAndType.keySet().contains(sourceNodeTemplateId)) {
1030                 continue;
1031             }
1032             List<GetAttrFuncData> getAttrFuncDataList = nodesGetAttrInEntry.getValue();
1033             for (GetAttrFuncData getAttrFuncData : getAttrFuncDataList) {
1034                 Object propertyValue = DataModelUtil.getPropertyValue(sourceNodeTemplate, getAttrFuncData.getFieldName());
1035                 String newAttrName = null;
1036                 String newGetAttrAbstractNodeTemplateId = newNodeTemplateId;
1037                 if (!isNested) {
1038                     newGetAttrAbstractNodeTemplateId = context.getUnifiedAbstractNodeTemplateId(serviceTemplate, oldNodeTemplateId);
1039                     newAttrName = getNewSubstitutionOutputParameterId(newNodeTemplateId, getAttrFuncData.getAttributeName());
1040                 }
1041                 List<List<Object>> getAttrFuncValueList = extractGetAttrFunction(propertyValue);
1042                 updateGetAttrValue(oldNodeTemplateId, getAttrFuncData, newGetAttrAbstractNodeTemplateId, newAttrName, getAttrFuncValueList, isNested);
1043             }
1044         }
1045     }
1046
1047     private void updateGetAttrValue(String oldNodeTemplateId, GetAttrFuncData getAttrFuncData, String newNodeTemplateId, String newAttrName,
1048                                     List<List<Object>> getAttrFuncValueList, boolean isNested) {
1049         for (List<Object> getAttrFuncValue : getAttrFuncValueList) {
1050             if (oldNodeTemplateId.equals(getAttrFuncValue.get(0)) && getAttrFuncData.getAttributeName().equals(getAttrFuncValue.get(1))) {
1051                 getAttrFuncValue.set(0, newNodeTemplateId);
1052                 if (!isNested) {
1053                     getAttrFuncValue.set(1, newAttrName);
1054                 }
1055             }
1056         }
1057     }
1058
1059     private String getTemplateName(String nodeTypeId, Integer index) {
1060         String computeType = getComputeTypeSuffix(nodeTypeId);
1061         String templateName = "Nested_" + computeType;
1062         if (Objects.nonNull(index)) {
1063             templateName = templateName + "_" + index.toString();
1064         }
1065         return templateName;
1066     }
1067
1068     private void updOutputParamGetAttrInConnectivity(ServiceTemplate serviceTemplate, EntityConsolidationData entityConsolidationData,
1069                                                      String oldNodeTemplateId, String newNodeTemplateId, TranslationContext context,
1070                                                      boolean isNested) {
1071         List<GetAttrFuncData> outputParametersGetAttrIn = entityConsolidationData.getOutputParametersGetAttrIn();
1072         if (CollectionUtils.isEmpty(outputParametersGetAttrIn)) {
1073             return;
1074         }
1075         for (GetAttrFuncData getAttrFuncData : outputParametersGetAttrIn) {
1076             Object outputParamValue = DataModelUtil.getOuputParameter(serviceTemplate, getAttrFuncData.getFieldName()).getValue();
1077             String newAttrName = null;
1078             String newGetAttrAbstractNodeTemplateId = newNodeTemplateId;
1079             if (!isNested) {
1080                 newGetAttrAbstractNodeTemplateId = context.getUnifiedAbstractNodeTemplateId(serviceTemplate, oldNodeTemplateId);
1081                 newAttrName = getNewSubstitutionOutputParameterId(newNodeTemplateId, getAttrFuncData.getAttributeName());
1082             }
1083             List<List<Object>> getAttrFuncValueList = extractGetAttrFunction(outputParamValue);
1084             updateGetAttrValue(oldNodeTemplateId, getAttrFuncData, newGetAttrAbstractNodeTemplateId, newAttrName, getAttrFuncValueList, isNested);
1085         }
1086     }
1087
1088     private List<List<Object>> extractGetAttrFunction(Object valueObject) {
1089         List<List<Object>> getAttrValueList = new ArrayList<>();
1090         if (valueObject instanceof Map) {
1091             if (((Map) valueObject).containsKey(ToscaFunctions.GET_ATTRIBUTE.getFunctionName())) {
1092                 getAttrValueList.add((List<Object>) ((Map) valueObject).get(ToscaFunctions.GET_ATTRIBUTE.getFunctionName()));
1093             }
1094             for (Object key : ((Map) valueObject).keySet()) {
1095                 getAttrValueList.addAll(extractGetAttrFunction(((Map) valueObject).get(key)));
1096             }
1097         } else if (valueObject instanceof List) {
1098             for (Object valueEntity : (List) valueObject) {
1099                 getAttrValueList.addAll(extractGetAttrFunction(valueEntity));
1100             }
1101         }
1102         return getAttrValueList;
1103     }
1104
1105     private boolean isIncludeToscaFunc(Object valueObject, ToscaFunctions toscaFunction) {
1106         if (valueObject instanceof Map) {
1107             if (((Map) valueObject).containsKey(toscaFunction.getFunctionName())) {
1108                 return true;
1109             }
1110             Set<Map.Entry<String, Object>> entries = ((Map<String, Object>) valueObject).entrySet();
1111             for (Map.Entry<String, Object> valueObjectEntry : entries) {
1112                 if (isIncludeToscaFunc(valueObjectEntry.getValue(), toscaFunction)) {
1113                     return true;
1114                 }
1115             }
1116         } else if (valueObject instanceof List) {
1117             for (Object valueEntity : (List) valueObject) {
1118                 if (isIncludeToscaFunc(valueEntity, toscaFunction)) {
1119                     return true;
1120                 }
1121             }
1122         }
1123         return false;
1124     }
1125
1126     private void createOutputParameters(UnifiedCompositionTo unifiedCompositionTo, String computeNodeType) {
1127         createOutputParametersForCompute(unifiedCompositionTo.getServiceTemplate(), unifiedCompositionTo.getSubstitutionServiceTemplate(),
1128             unifiedCompositionTo.getUnifiedCompositionDataList(), unifiedCompositionTo.getContext());
1129         createOutputParameterForPorts(unifiedCompositionTo.getSubstitutionServiceTemplate(), unifiedCompositionTo.getUnifiedCompositionDataList(),
1130             computeNodeType, unifiedCompositionTo.getContext());
1131         createOutputParameterForSubInterfaces(unifiedCompositionTo, computeNodeType);
1132     }
1133
1134     private void createOutputParameterForPorts(ServiceTemplate substitutionServiceTemplate, List<UnifiedCompositionData> unifiedCompositionDataList,
1135                                                String connectedComputeNodeType, TranslationContext context) {
1136         for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
1137             List<PortTemplateConsolidationData> portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData);
1138             if (CollectionUtils.isEmpty(portTemplateConsolidationDataList)) {
1139                 return;
1140             }
1141             for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) {
1142                 String newPortNodeTemplateId = getNewPortNodeTemplateId(portTemplateConsolidationData.getNodeTemplateId(), connectedComputeNodeType,
1143                     unifiedCompositionData.getComputeTemplateConsolidationData());
1144                 addOutputParameters(portTemplateConsolidationData, newPortNodeTemplateId, substitutionServiceTemplate, unifiedCompositionDataList,
1145                     context);
1146             }
1147         }
1148     }
1149
1150     private void createOutputParameterForSubInterfaces(UnifiedCompositionTo unifiedCompositionTo, String connectedComputeNodeType) {
1151         for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionTo.getUnifiedCompositionDataList()) {
1152             List<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationDataList = getSubInterfaceTemplateConsolidationDataList(
1153                 unifiedCompositionData);
1154             if (CollectionUtils.isEmpty(subInterfaceTemplateConsolidationDataList)) {
1155                 return;
1156             }
1157             for (SubInterfaceTemplateConsolidationData subInterfaceTemplateConsolidationData : subInterfaceTemplateConsolidationDataList) {
1158                 String newSubInterfaceNodeTemplateId = getNewSubInterfaceNodeTemplateId(unifiedCompositionTo.getServiceTemplate(),
1159                     connectedComputeNodeType, unifiedCompositionData.getComputeTemplateConsolidationData(), subInterfaceTemplateConsolidationData,
1160                     unifiedCompositionTo.getContext());
1161                 addOutputParameters(subInterfaceTemplateConsolidationData, newSubInterfaceNodeTemplateId,
1162                     unifiedCompositionTo.getSubstitutionServiceTemplate(), unifiedCompositionTo.getUnifiedCompositionDataList(),
1163                     unifiedCompositionTo.getContext());
1164             }
1165         }
1166     }
1167
1168     private void createOutputParametersForCompute(ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate,
1169                                                   List<UnifiedCompositionData> unifiedCompositionDataList, TranslationContext context) {
1170         List<EntityConsolidationData> computeConsolidationDataList = getComputeConsolidationDataList(unifiedCompositionDataList);
1171         for (EntityConsolidationData computeTemplateConsolidationData : computeConsolidationDataList) {
1172             String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId());
1173             addOutputParameters(computeTemplateConsolidationData, newComputeNodeTemplateId, substitutionServiceTemplate, unifiedCompositionDataList,
1174                 context);
1175         }
1176     }
1177
1178     private void addOutputParameters(EntityConsolidationData entityConsolidationData, String newNodeTemplateId,
1179                                      ServiceTemplate substitutionServiceTemplate, List<UnifiedCompositionData> unifiedCompositionDataList,
1180                                      TranslationContext context) {
1181         handleNodesGetAttrIn(entityConsolidationData, newNodeTemplateId, substitutionServiceTemplate, unifiedCompositionDataList, context);
1182         handleOutputParamGetAttrIn(entityConsolidationData, newNodeTemplateId, substitutionServiceTemplate, context);
1183     }
1184
1185     private void handleOutputParamGetAttrIn(EntityConsolidationData entityConsolidationData, String newNodeTemplateId,
1186                                             ServiceTemplate substitutionServiceTemplate, TranslationContext context) {
1187         List<GetAttrFuncData> outputParametersGetAttrIn = entityConsolidationData.getOutputParametersGetAttrIn();
1188         if (!CollectionUtils.isEmpty(outputParametersGetAttrIn)) {
1189             for (GetAttrFuncData getAttrFuncData : outputParametersGetAttrIn) {
1190                 createAndAddOutputParameter(newNodeTemplateId, substitutionServiceTemplate, getAttrFuncData, context);
1191             }
1192         }
1193     }
1194
1195     private void handleNodesGetAttrIn(EntityConsolidationData entityConsolidationData, String newNodeTemplateId,
1196                                       ServiceTemplate substitutionServiceTemplate, List<UnifiedCompositionData> unifiedCompositionDataList,
1197                                       TranslationContext context) {
1198         Map<String, List<GetAttrFuncData>> getAttrIn = entityConsolidationData.getNodesGetAttrIn();
1199         if (MapUtils.isEmpty(getAttrIn)) {
1200             return;
1201         }
1202         Map<String, UnifiedCompositionEntity> consolidationNodeTemplateIdAndType = getAllConsolidationNodeTemplateIdAndType(
1203             unifiedCompositionDataList);
1204         for (Map.Entry<String, List<GetAttrFuncData>> getAttrInEntry : getAttrIn.entrySet()) {
1205             String sourceNodeTemplateId = getAttrInEntry.getKey();
1206             if (!consolidationNodeTemplateIdAndType.keySet().contains(sourceNodeTemplateId)) {
1207                 List<GetAttrFuncData> getAttrFuncDataList = getAttrInEntry.getValue();
1208                 for (GetAttrFuncData getAttrFuncData : getAttrFuncDataList) {
1209                     createAndAddOutputParameter(newNodeTemplateId, substitutionServiceTemplate, getAttrFuncData, context);
1210                 }
1211             }
1212         }
1213     }
1214
1215     private void createAndAddOutputParameter(String newNodeTemplateId, ServiceTemplate substitutionServiceTemplate, GetAttrFuncData getAttrFuncData,
1216                                              TranslationContext context) {
1217         Map<String, List<Object>> parameterValue = new HashMap<>();
1218         List<Object> valueList = new ArrayList<>();
1219         valueList.add(newNodeTemplateId);
1220         valueList.add(getAttrFuncData.getAttributeName());
1221         parameterValue.put(ToscaFunctions.GET_ATTRIBUTE.getFunctionName(), valueList);
1222         ParameterDefinition outputParameter = new ParameterDefinition();
1223         outputParameter.setValue(parameterValue);
1224         setOutputParameterType(substitutionServiceTemplate, newNodeTemplateId, getAttrFuncData.getAttributeName(), outputParameter, context);
1225         DataModelUtil.addOutputParameterToTopologyTemplate(substitutionServiceTemplate,
1226             getNewSubstitutionOutputParameterId(newNodeTemplateId, getAttrFuncData.getAttributeName()), outputParameter);
1227     }
1228
1229     private void setOutputParameterType(ServiceTemplate substitutionServiceTemplate, String newNodeTemplateId, String outputParameterName,
1230                                         ParameterDefinition outputParameter, TranslationContext context) {
1231         NodeTemplate nodeTemplate = DataModelUtil.getNodeTemplate(substitutionServiceTemplate, newNodeTemplateId);
1232         //Get the type and entry schema of the output parameter from the node type flat hierarchy
1233         String outputParameterType;
1234         EntrySchema outputParameterEntrySchema;
1235         NodeType nodeTypeWithFlatHierarchy = HeatToToscaUtil
1236             .getNodeTypeWithFlatHierarchy(nodeTemplate.getType(), substitutionServiceTemplate, context);
1237         //Check if the parameter is present in the attributes
1238         AttributeDefinition outputParameterDefinitionFromAttributes = getOutputParameterDefinitionFromAttributes(nodeTypeWithFlatHierarchy,
1239             outputParameterName);
1240         if (Objects.nonNull(outputParameterDefinitionFromAttributes)) {
1241             outputParameterType = outputParameterDefinitionFromAttributes.getType();
1242             outputParameterEntrySchema = outputParameterDefinitionFromAttributes.getEntry_schema();
1243         } else {
1244             //If the below fails due to null pointer then we need to check if the heatToToscaMapping
1245
1246             // properties and global types are in sync. Ideally the parameter should be found in either
1247
1248             // properties or attributes collected from global types
1249             PropertyDefinition outputParameterDefinitionFromProperties = nodeTypeWithFlatHierarchy.getProperties().get(outputParameterName);
1250             outputParameterType = outputParameterDefinitionFromProperties.getType();
1251             outputParameterEntrySchema = outputParameterDefinitionFromProperties.getEntry_schema();
1252         }
1253         //Set the type and entry schema for the output param obtained from the node type hierarchy
1254         outputParameter.setType(outputParameterType);
1255         outputParameter.setEntry_schema(outputParameterEntrySchema);
1256     }
1257
1258     private AttributeDefinition getOutputParameterDefinitionFromAttributes(NodeType nodeTypeWithFlatHierarchy, String outputParameterName) {
1259         AttributeDefinition outputParameterDefinition = null;
1260         if ((Objects.nonNull(nodeTypeWithFlatHierarchy.getAttributes())) && (nodeTypeWithFlatHierarchy.getAttributes()
1261             .containsKey(outputParameterName))) {
1262             outputParameterDefinition = nodeTypeWithFlatHierarchy.getAttributes().get(outputParameterName);
1263         }
1264         return outputParameterDefinition;
1265     }
1266
1267     private String getNewSubstitutionOutputParameterId(String newNodeTemplateId, String attributeName) {
1268         return newNodeTemplateId + "_" + attributeName;
1269     }
1270
1271     private void addUnifiedSubstitionData(TranslationContext context, ServiceTemplate serviceTemplate,
1272                                           List<UnifiedCompositionData> unifiedCompositionDataList, String substituteNodeTemplateId) {
1273         String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
1274         for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
1275             //Add compute node template mapping information
1276             ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData.getComputeTemplateConsolidationData();
1277             String computeNodeTemplateId = computeTemplateConsolidationData.getNodeTemplateId();
1278             context.addUnifiedSubstitutionData(serviceTemplateFileName, computeNodeTemplateId, substituteNodeTemplateId);
1279             //Add Port template mapping information
1280             List<PortTemplateConsolidationData> portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData);
1281             if (CollectionUtils.isNotEmpty(portTemplateConsolidationDataList)) {
1282                 for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) {
1283                     String oldPortNodeTemplateId = portTemplateConsolidationData.getNodeTemplateId();
1284                     context.addUnifiedSubstitutionData(serviceTemplateFileName, oldPortNodeTemplateId, substituteNodeTemplateId);
1285                 }
1286             }
1287             //Add Sub-interface template mapping information
1288             List<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationDataList = getSubInterfaceTemplateConsolidationDataList(
1289                 unifiedCompositionData);
1290             if (CollectionUtils.isNotEmpty(subInterfaceTemplateConsolidationDataList)) {
1291                 for (SubInterfaceTemplateConsolidationData subInterfaceTemplateConsolidationData : subInterfaceTemplateConsolidationDataList) {
1292                     context.addUnifiedSubstitutionData(serviceTemplateFileName, subInterfaceTemplateConsolidationData.getNodeTemplateId(),
1293                         substituteNodeTemplateId);
1294                 }
1295             }
1296         }
1297     }
1298
1299     private void addIndexValueProperty(NodeTemplate nodeTemplate) {
1300         List<String> indexValueGetPropertyValue = new ArrayList<>();
1301         indexValueGetPropertyValue.add(ToscaConstants.MODELABLE_ENTITY_NAME_SELF);
1302         indexValueGetPropertyValue.add(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
1303         indexValueGetPropertyValue.add(ToscaConstants.INDEX_VALUE_PROPERTY_NAME);
1304         Map<String, Object> indexPropertyValue = new HashMap<>();
1305         Map<String, Object> properties = nodeTemplate.getProperties();
1306         indexPropertyValue.put(ToscaFunctions.GET_PROPERTY.getFunctionName(), indexValueGetPropertyValue);
1307         properties.put(ToscaConstants.INDEX_VALUE_PROPERTY_NAME, indexPropertyValue);
1308         nodeTemplate.setProperties(properties);
1309     }
1310
1311     private String getSubstituteNodeTemplateId(String nodeTypeId, Integer index) {
1312         String nodeTemplateId = ABSTRACT_NODE_TEMPLATE_ID_PREFIX + DataModelUtil.getNamespaceSuffix(nodeTypeId);
1313         if (Objects.nonNull(index)) {
1314             nodeTemplateId = nodeTemplateId + "_" + index.toString();
1315         }
1316         return nodeTemplateId;
1317     }
1318
1319     /**
1320      * Gets substitution node type id.
1321      *
1322      * @param serviceTemplate        the service template
1323      * @param unifiedCompositionData the unified composition data
1324      * @param index                  the index
1325      * @return the substitution node type id
1326      */
1327     public String getSubstitutionNodeTypeId(ServiceTemplate serviceTemplate, UnifiedCompositionData unifiedCompositionData, Integer index,
1328                                             TranslationContext context) {
1329         String computeNodeTemplateId = unifiedCompositionData.getComputeTemplateConsolidationData().getNodeTemplateId();
1330         NodeTemplate computeNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, computeNodeTemplateId);
1331         String computeType = computeNodeTemplate.getType();
1332         String globalSTName = ToscaUtil.getServiceTemplateFileName(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
1333         String nodeTypeId =
1334             ToscaNodeType.ABSTRACT_NODE_TYPE_PREFIX + DataModelUtil.getNamespaceSuffix(getIndexedGlobalNodeTypeId(computeType, context));
1335         context.updateUsedTimesForNestedComputeNodeType(globalSTName, computeType);
1336         if (Objects.nonNull(index)) {
1337             nodeTypeId = nodeTypeId + "_" + index.toString();
1338         }
1339         return nodeTypeId;
1340     }
1341
1342     private NodeType handleSubstitutionGlobalNodeType(ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate,
1343                                                       TranslationContext context, String substitutionNodeTypeId) {
1344         NodeType substitutionNodeType = new ToscaAnalyzerServiceImpl()
1345             .createInitSubstitutionNodeType(substitutionServiceTemplate, ToscaNodeType.VFC_ABSTRACT_SUBSTITUTE);
1346         ServiceTemplate globalSubstitutionServiceTemplate = HeatToToscaUtil.fetchGlobalSubstitutionServiceTemplate(serviceTemplate, context);
1347         DataModelUtil.addNodeType(globalSubstitutionServiceTemplate, substitutionNodeTypeId, substitutionNodeType);
1348         return substitutionNodeType;
1349     }
1350
1351     private void handlePorts(ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate,
1352                              List<UnifiedCompositionData> unifiedCompositionDataList, String connectedComputeNodeType, TranslationContext context) {
1353         if (unifiedCompositionDataList.size() > 1) {
1354             handleConsolidationPorts(serviceTemplate, substitutionServiceTemplate, unifiedCompositionDataList, connectedComputeNodeType, context);
1355         } else {
1356             handleSinglePorts(serviceTemplate, substitutionServiceTemplate, connectedComputeNodeType, unifiedCompositionDataList, context);
1357         }
1358     }
1359
1360     private void handleSinglePorts(ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate, String connectedComputeNodeType,
1361                                    List<UnifiedCompositionData> unifiedCompositionDataList, TranslationContext context) {
1362         UnifiedCompositionData unifiedCompositionData = unifiedCompositionDataList.get(0);
1363         List<PortTemplateConsolidationData> portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData);
1364         if (CollectionUtils.isEmpty(portTemplateConsolidationDataList)) {
1365             return;
1366         }
1367         for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) {
1368             List<EntityConsolidationData> portConsolidationDataList = new ArrayList<>();
1369             portConsolidationDataList.add(portTemplateConsolidationData);
1370             handlePortNodeTemplate(serviceTemplate, substitutionServiceTemplate, portConsolidationDataList, connectedComputeNodeType,
1371                 unifiedCompositionData.getComputeTemplateConsolidationData(), unifiedCompositionDataList, context);
1372         }
1373     }
1374
1375     private void handleConsolidationPorts(ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate,
1376                                           List<UnifiedCompositionData> unifiedCompositionDataList, String connectedComputeNodeType,
1377                                           TranslationContext context) {
1378         Map<String, List<String>> portIdsPerPortType = UnifiedCompositionUtil.collectAllPortsOfEachTypeFromComputes(unifiedCompositionDataList);
1379         for (Map.Entry<String, List<String>> portIdsPerPortTypeEntry : portIdsPerPortType.entrySet()) {
1380             List<EntityConsolidationData> portTemplateConsolidationDataList = getPortConsolidationDataList(portIdsPerPortTypeEntry.getValue(),
1381                 unifiedCompositionDataList);
1382             if (CollectionUtils.isEmpty(portTemplateConsolidationDataList)) {
1383                 continue;
1384             }
1385             handlePortNodeTemplate(serviceTemplate, substitutionServiceTemplate, portTemplateConsolidationDataList, connectedComputeNodeType,
1386                 unifiedCompositionDataList.get(0).getComputeTemplateConsolidationData(), unifiedCompositionDataList, context);
1387         }
1388     }
1389
1390     private void handlePortNodeTemplate(ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate,
1391                                         List<EntityConsolidationData> portTemplateConsolidationDataList, String connectedComputeNodeType,
1392                                         ComputeTemplateConsolidationData computeTemplateConsolidationData,
1393                                         List<UnifiedCompositionData> unifiedCompositionDataList, TranslationContext context) {
1394         EntityConsolidationData portTemplateConsolidationData = portTemplateConsolidationDataList.get(0);
1395         NodeTemplate newPortNodeTemplate = getNodeTemplate(portTemplateConsolidationData.getNodeTemplateId(), serviceTemplate, context).clone();
1396         removeConnectivityOut(portTemplateConsolidationData, newPortNodeTemplate);
1397         handleProperties(serviceTemplate, newPortNodeTemplate, substitutionServiceTemplate, UnifiedCompositionEntity.PORT,
1398             portTemplateConsolidationDataList, computeTemplateConsolidationData, unifiedCompositionDataList, context);
1399         //Add subinterface_indicator property to PORT
1400         portTemplateConsolidationDataList.forEach(entity -> addPortSubInterfaceIndicatorProperty(newPortNodeTemplate.getProperties(), entity));
1401         String newPortNodeTemplateId = getNewPortNodeTemplateId(portTemplateConsolidationData.getNodeTemplateId(), connectedComputeNodeType,
1402             computeTemplateConsolidationData);
1403         //Update requirements for relationships between the consolidation entities
1404         handleConsolidationEntitiesRequirementConnectivity(newPortNodeTemplate, serviceTemplate, context);
1405         DataModelUtil.addNodeTemplate(substitutionServiceTemplate, newPortNodeTemplateId, newPortNodeTemplate);
1406         //Add the node template mapping in the context for handling requirement updation
1407         for (EntityConsolidationData data : portTemplateConsolidationDataList) {
1408             String newPortTemplateId = getNewPortNodeTemplateId(data.getNodeTemplateId(), connectedComputeNodeType, computeTemplateConsolidationData);
1409             context.addSubstitutionServiceTemplateUnifiedSubstitutionData(ToscaUtil.getServiceTemplateFileName(serviceTemplate),
1410                 data.getNodeTemplateId(), newPortTemplateId);
1411         }
1412     }
1413
1414     private void handleSubInterfaces(UnifiedCompositionTo unifiedCompositionTo) {
1415         if (unifiedCompositionTo.getUnifiedCompositionDataList().size() > 1) {
1416             handleConsolidationSubInterfaces(unifiedCompositionTo);
1417         } else {
1418             handleSingleSubInterfaces(unifiedCompositionTo);
1419         }
1420     }
1421
1422     private void handleSingleSubInterfaces(UnifiedCompositionTo unifiedCompositionTo) {
1423         UnifiedCompositionData unifiedCompositionData = unifiedCompositionTo.getUnifiedCompositionDataList().get(0);
1424         List<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationDataList = getSubInterfaceTemplateConsolidationDataList(
1425             unifiedCompositionData);
1426         for (SubInterfaceTemplateConsolidationData subInterfaceTemplateConsolidationData : subInterfaceTemplateConsolidationDataList) {
1427             List<SubInterfaceTemplateConsolidationData> subInterfaceDataList = new ArrayList<>();
1428             subInterfaceDataList.add(subInterfaceTemplateConsolidationData);
1429             createSubInterfaceSubstitutionNodeTemplate(unifiedCompositionTo, subInterfaceDataList);
1430         }
1431     }
1432
1433     private void handleConsolidationSubInterfaces(UnifiedCompositionTo unifiedCompositionTo) {
1434         Map<String, List<String>> portIdsPerPortType = UnifiedCompositionUtil
1435             .collectAllPortsOfEachTypeFromComputes(unifiedCompositionTo.getUnifiedCompositionDataList());
1436         for (Map.Entry<String, List<String>> portIdsPerPortTypeEntry : portIdsPerPortType.entrySet()) {
1437             List<EntityConsolidationData> portEntityConsolidationDataList = getPortConsolidationDataList(portIdsPerPortTypeEntry.getValue(),
1438                 unifiedCompositionTo.getUnifiedCompositionDataList());
1439             if (CollectionUtils.isEmpty(portEntityConsolidationDataList)) {
1440                 continue;
1441             }
1442             List<PortTemplateConsolidationData> portTemplateConsolidationDataList = portEntityConsolidationDataList.stream()
1443                 .map(data -> (PortTemplateConsolidationData) data).collect(Collectors.toList());
1444             ListMultimap<String, SubInterfaceTemplateConsolidationData> subInterfacesByType = UnifiedCompositionUtil
1445                 .collectAllSubInterfacesOfEachTypesFromPorts(portTemplateConsolidationDataList);
1446             Set<String> subInterfaceTypes = subInterfacesByType.keySet();
1447             for (String subInterfaceType : subInterfaceTypes) {
1448                 List<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationDataList = subInterfacesByType.get(subInterfaceType);
1449                 createSubInterfaceSubstitutionNodeTemplate(unifiedCompositionTo, subInterfaceTemplateConsolidationDataList);
1450             }
1451         }
1452     }
1453
1454     private void createSubInterfaceSubstitutionNodeTemplate(UnifiedCompositionTo unifiedCompositionTo,
1455                                                             List<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationDataList) {
1456         SubInterfaceTemplateConsolidationData subInterfaceTemplateConsolidationData = subInterfaceTemplateConsolidationDataList.get(0);
1457         Optional<PortTemplateConsolidationData> portTemplateConsolidationDataOptional = subInterfaceTemplateConsolidationData
1458             .getParentPortTemplateConsolidationData(unifiedCompositionTo.getServiceTemplate(), unifiedCompositionTo.getContext());
1459         if (!portTemplateConsolidationDataOptional.isPresent()) {
1460             return;
1461         }
1462         PortTemplateConsolidationData portTemplateConsolidationData = portTemplateConsolidationDataOptional.get();
1463         String originalSubInterfaceNodeTemplateId = subInterfaceTemplateConsolidationDataList.get(0).getNodeTemplateId();
1464         NodeTemplate originalSubInterfaceNodeTemplate = DataModelUtil
1465             .getNodeTemplate(unifiedCompositionTo.getServiceTemplate(), originalSubInterfaceNodeTemplateId);
1466         if (Objects.isNull(originalSubInterfaceNodeTemplate)) {
1467             return;
1468         }
1469         NodeTemplate newSubInterfaceNodeTemplate = originalSubInterfaceNodeTemplate.clone();
1470         ComputeTemplateConsolidationData connectedComputeConsolidationData = getConnectedComputeConsolidationData(
1471             unifiedCompositionTo.getUnifiedCompositionDataList(), portTemplateConsolidationData.getNodeTemplateId());
1472         if (Objects.nonNull(connectedComputeConsolidationData)) {
1473             NodeTemplate connectedComputeNodeTemplate = DataModelUtil
1474                 .getNodeTemplate(unifiedCompositionTo.getServiceTemplate(), connectedComputeConsolidationData.getNodeTemplateId());
1475             String newSubInterfaceNodeTemplateId = getNewSubInterfaceNodeTemplateId(unifiedCompositionTo.getServiceTemplate(),
1476                 connectedComputeNodeTemplate.getType(), connectedComputeConsolidationData, subInterfaceTemplateConsolidationData,
1477                 unifiedCompositionTo.getContext());
1478             DataModelUtil
1479                 .addNodeTemplate(unifiedCompositionTo.getSubstitutionServiceTemplate(), newSubInterfaceNodeTemplateId, newSubInterfaceNodeTemplate);
1480             List<EntityConsolidationData> entityConsolidationDataList = new ArrayList<>(subInterfaceTemplateConsolidationDataList);
1481             //Remove all the existing properties as we are going to create new based on the
1482
1483             // naming convention for the substitution
1484             handleSubInterfaceProperties(unifiedCompositionTo, originalSubInterfaceNodeTemplateId, newSubInterfaceNodeTemplate,
1485                 entityConsolidationDataList, portTemplateConsolidationData);
1486             //Update requirements for relationships between the consolidation entities
1487             handleConsolidationEntitiesRequirementConnectivity(newSubInterfaceNodeTemplate, unifiedCompositionTo.getServiceTemplate(),
1488                 unifiedCompositionTo.getContext());
1489             removeConnectivityOut(subInterfaceTemplateConsolidationData, newSubInterfaceNodeTemplate);
1490         }
1491     }
1492
1493     private void handleSubInterfaceProperties(UnifiedCompositionTo unifiedCompositionTo, String subInterfaceNodeTemplateId,
1494                                               NodeTemplate newSubInterfaceNodeTemplate, List<EntityConsolidationData> entityConsolidationDataList,
1495                                               PortTemplateConsolidationData portTemplateConsolidationData) {
1496         UnifiedCompositionData unifiedCompositionData = unifiedCompositionTo.getUnifiedCompositionDataList().get(0);
1497         ServiceTemplate serviceTemplate = unifiedCompositionTo.getServiceTemplate();
1498         TranslationContext context = unifiedCompositionTo.getContext();
1499         newSubInterfaceNodeTemplate.setProperties(new HashMap<>());
1500         for (EntityConsolidationData entityConsolidationData : entityConsolidationDataList) {
1501             String nodeTemplateId = entityConsolidationData.getNodeTemplateId();
1502             Optional<List<String>> indexVarProperties = context
1503                 .getIndexVarProperties(ToscaUtil.getServiceTemplateFileName(serviceTemplate), nodeTemplateId);
1504             Map<String, Object> properties = DataModelUtil.getNodeTemplateProperties(serviceTemplate, nodeTemplateId);
1505             if (MapUtils.isEmpty(properties)) {
1506                 continue;
1507             }
1508             for (Map.Entry<String, Object> propertyEntry : properties.entrySet()) {
1509                 NodeType nodeTypeWithFlatHierarchy = HeatToToscaUtil
1510                     .getNodeTypeWithFlatHierarchy(newSubInterfaceNodeTemplate.getType(), serviceTemplate, context);
1511                 PropertyDefinition propertyDefinition = nodeTypeWithFlatHierarchy.getProperties().get(propertyEntry.getKey());
1512                 String propertyType = propertyDefinition.getType();
1513                 //Handle service_template_filter property for subinterface as we should not create inputs
1514
1515                 // for this property
1516                 if (propertyEntry.getKey().equals(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME)) {
1517                     handleSubInterfaceServiceTemplateFilterProperty(subInterfaceNodeTemplateId, newSubInterfaceNodeTemplate, propertyEntry.getKey(),
1518                         propertyEntry.getValue(), portTemplateConsolidationData, unifiedCompositionTo.getSubstitutionServiceTemplate());
1519                 } else if (indexVarProperties.isPresent() && indexVarProperties.get().contains(propertyEntry.getKey())) {
1520                     //Handle index property
1521                     handleIndexVarProperty(propertyEntry.getKey(), propertyEntry.getValue(), newSubInterfaceNodeTemplate);
1522                 } else {
1523                     Optional<String> parameterId = updateProperty(serviceTemplate, nodeTemplateId, newSubInterfaceNodeTemplate, propertyEntry,
1524                         UnifiedCompositionEntity.SUB_INTERFACE, unifiedCompositionData.getComputeTemplateConsolidationData(),
1525                         portTemplateConsolidationData, unifiedCompositionTo.getUnifiedCompositionDataList(), context);
1526                     parameterId.ifPresent(
1527                         parameterIdValue -> addPropertyInputParameter(propertyType, unifiedCompositionTo.getSubstitutionServiceTemplate(),
1528                             propertyDefinition.getEntry_schema(), parameterIdValue));
1529                 }
1530             }
1531         }
1532     }
1533
1534     private NodeTemplate getNodeTemplate(String nodeTemplateId, ServiceTemplate serviceTemplate, TranslationContext context) {
1535         NodeTemplate nodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, nodeTemplateId);
1536         if (Objects.isNull(nodeTemplate)) {
1537             nodeTemplate = context.getCleanedNodeTemplate(ToscaUtil.getServiceTemplateFileName(serviceTemplate), nodeTemplateId);
1538         }
1539         return nodeTemplate;
1540     }
1541
1542     private String handleCompute(ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate,
1543                                  List<UnifiedCompositionData> unifiedCompositionDataList, TranslationContext context) {
1544         ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionDataList.get(0).getComputeTemplateConsolidationData();
1545         handleComputeNodeTemplate(serviceTemplate, substitutionServiceTemplate, unifiedCompositionDataList, context);
1546         return handleComputeNodeType(serviceTemplate, substitutionServiceTemplate, computeTemplateConsolidationData);
1547     }
1548
1549     private String handleComputeNodeType(ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate,
1550                                          ComputeTemplateConsolidationData computeTemplateConsolidationData) {
1551         NodeTemplate computeNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId());
1552         String computeNodeTypeId = computeNodeTemplate.getType();
1553         NodeType computeNodeType = DataModelUtil.getNodeType(serviceTemplate, computeNodeTypeId);
1554         DataModelUtil.addNodeType(substitutionServiceTemplate, computeNodeTypeId, computeNodeType);
1555         return computeNodeTypeId;
1556     }
1557
1558     private void handleComputeNodeTemplate(ServiceTemplate serviceTemplate, ServiceTemplate substitutionServiceTemplate,
1559                                            List<UnifiedCompositionData> unifiedCompositionDataList, TranslationContext context) {
1560         ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionDataList.get(0).getComputeTemplateConsolidationData();
1561         NodeTemplate newComputeNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId())
1562             .clone();
1563         removeConnectivityOut(computeTemplateConsolidationData, newComputeNodeTemplate);
1564         removeVolumeConnectivity(computeTemplateConsolidationData, newComputeNodeTemplate);
1565         List<EntityConsolidationData> computeConsolidationDataList = getComputeConsolidationDataList(unifiedCompositionDataList);
1566         handleProperties(serviceTemplate, newComputeNodeTemplate, substitutionServiceTemplate, COMPUTE, computeConsolidationDataList,
1567             computeTemplateConsolidationData, unifiedCompositionDataList, context);
1568         String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId());
1569         //Update requirements for relationships between the consolidation entities
1570         handleConsolidationEntitiesRequirementConnectivity(newComputeNodeTemplate, serviceTemplate, context);
1571         DataModelUtil.addNodeTemplate(substitutionServiceTemplate, newComputeNodeTemplateId, newComputeNodeTemplate);
1572         //Add the node template mapping in the context for handling requirement updation
1573         for (EntityConsolidationData data : computeConsolidationDataList) {
1574             String newComputeTemplateId = getNewComputeNodeTemplateId(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId());
1575             context.addSubstitutionServiceTemplateUnifiedSubstitutionData(ToscaUtil.getServiceTemplateFileName(serviceTemplate),
1576                 data.getNodeTemplateId(), newComputeTemplateId);
1577         }
1578     }
1579
1580     private List<EntityConsolidationData> getComputeConsolidationDataList(List<UnifiedCompositionData> unifiedCompositionDataList) {
1581         return unifiedCompositionDataList.stream().map(UnifiedCompositionData::getComputeTemplateConsolidationData).collect(Collectors.toList());
1582     }
1583
1584     private void handleProperties(ServiceTemplate serviceTemplate, NodeTemplate nodeTemplate, ServiceTemplate substitutionServiceTemplate,
1585                                   UnifiedCompositionEntity unifiedCompositionEntity, List<EntityConsolidationData> entityConsolidationDataList,
1586                                   ComputeTemplateConsolidationData computeTemplateConsolidationData,
1587                                   List<UnifiedCompositionData> unifiedCompositionDataList, TranslationContext context) {
1588         nodeTemplate.setProperties(new HashedMap());
1589         UnifiedCompositionTo unifiedCompositionTo = new UnifiedCompositionTo(serviceTemplate, substitutionServiceTemplate, unifiedCompositionDataList,
1590             context, nodeTemplate);
1591         handleNodeTemplateProperties(unifiedCompositionTo, unifiedCompositionEntity, entityConsolidationDataList, computeTemplateConsolidationData);
1592         //Add enrich properties from openecomp node type as input to global and substitution ST
1593         handleNodeTypeProperties(substitutionServiceTemplate, entityConsolidationDataList, nodeTemplate, unifiedCompositionEntity,
1594             computeTemplateConsolidationData, context);
1595     }
1596
1597     private void addPortSubInterfaceIndicatorProperty(Map<String, Object> properties, EntityConsolidationData entityConsolidationData) {
1598         properties.put(SUB_INTERFACE_INDICATOR_PROPERTY, ((PortTemplateConsolidationData) entityConsolidationData).isPortBoundToSubInterface());
1599     }
1600
1601     private void handleNodeTemplateProperties(UnifiedCompositionTo unifiedCompositionTo, UnifiedCompositionEntity unifiedCompositionEntity,
1602                                               List<EntityConsolidationData> entityConsolidationDataList,
1603                                               ComputeTemplateConsolidationData computeTemplateConsolidationData) {
1604         List<String> propertiesWithIdenticalVal = consolidationService.getPropertiesWithIdenticalVal(unifiedCompositionEntity);
1605         for (EntityConsolidationData entityConsolidationData : entityConsolidationDataList) {
1606             String nodeTemplateId = entityConsolidationData.getNodeTemplateId();
1607             Optional<List<String>> indexVarProperties = unifiedCompositionTo.getContext()
1608                 .getIndexVarProperties(ToscaUtil.getServiceTemplateFileName(unifiedCompositionTo.getServiceTemplate()), nodeTemplateId);
1609             Map<String, Object> properties = DataModelUtil.getNodeTemplateProperties(unifiedCompositionTo.getServiceTemplate(), nodeTemplateId);
1610             if (MapUtils.isEmpty(properties)) {
1611                 continue;
1612             }
1613             for (Map.Entry<String, Object> propertyEntry : properties.entrySet()) {
1614                 NodeType nodeTypeWithFlatHierarchy = HeatToToscaUtil
1615                     .getNodeTypeWithFlatHierarchy(unifiedCompositionTo.getNodeTemplate().getType(), unifiedCompositionTo.getServiceTemplate(),
1616                         unifiedCompositionTo.getContext());
1617                 PropertyDefinition propertyDefinition = nodeTypeWithFlatHierarchy.getProperties().get(propertyEntry.getKey());
1618                 String propertyType = propertyDefinition.getType();
1619                 if (propertiesWithIdenticalVal.contains(propertyEntry.getKey())) {
1620                     String parameterId = updateIdenticalProperty(nodeTemplateId, propertyEntry.getKey(), unifiedCompositionTo.getNodeTemplate(),
1621                         unifiedCompositionEntity, unifiedCompositionTo.getUnifiedCompositionDataList());
1622                     addInputParameter(parameterId, propertyType,
1623                         propertyType.equals(PropertyType.LIST.getDisplayName()) ? propertyDefinition.getEntry_schema() : null,
1624                         unifiedCompositionTo.getSubstitutionServiceTemplate());
1625                 } else if (indexVarProperties.isPresent() && indexVarProperties.get().contains(propertyEntry.getKey())) {
1626                     //Handle index property
1627                     handleIndexVarProperty(propertyEntry.getKey(), propertyEntry.getValue(), unifiedCompositionTo.getNodeTemplate());
1628                 } else {
1629                     Optional<String> parameterId = updateProperty(unifiedCompositionTo.getServiceTemplate(), nodeTemplateId,
1630                         unifiedCompositionTo.getNodeTemplate(), propertyEntry, unifiedCompositionEntity, computeTemplateConsolidationData,
1631                         getPortTemplateConsolidationDataForPort(unifiedCompositionTo.getUnifiedCompositionDataList(), nodeTemplateId),
1632                         unifiedCompositionTo.getUnifiedCompositionDataList(), unifiedCompositionTo.getContext());
1633                     parameterId.ifPresent(
1634                         parameterIdValue -> addPropertyInputParameter(propertyType, unifiedCompositionTo.getSubstitutionServiceTemplate(),
1635                             propertyDefinition.getEntry_schema(), parameterIdValue));
1636                 }
1637             }
1638         }
1639     }
1640
1641     private void handleIndexVarProperty(String propertyKey, Object propertyValue, NodeTemplate nodeTemplate) {
1642         //Retain properties translated from %index% value in heat
1643         nodeTemplate.getProperties().put(propertyKey, propertyValue);
1644     }
1645
1646     private void handleSubInterfaceServiceTemplateFilterProperty(String subInterfaceNodeTemplateId, NodeTemplate nodeTemplate, String propertyKey,
1647                                                                  Object propertyValue, PortTemplateConsolidationData portTemplateConsolidationData,
1648                                                                  ServiceTemplate substitutionServiceTemplate) {
1649         //Retain service_template_filter (Can be present in a sub-interface resource-def)
1650         if (propertyValue instanceof Map) {
1651             Map<String, Object> serviceTemplateFilterPropertyMap = new HashMap<>((Map<String, Object>) propertyValue);
1652             handleCountProperty(subInterfaceNodeTemplateId, nodeTemplate, portTemplateConsolidationData, substitutionServiceTemplate,
1653                 serviceTemplateFilterPropertyMap);
1654             DataModelUtil.addNodeTemplateProperty(nodeTemplate, propertyKey, serviceTemplateFilterPropertyMap);
1655         }
1656     }
1657
1658     private void handleCountProperty(String subInterfaceNodeTemplateId, NodeTemplate nodeTemplate,
1659                                      PortTemplateConsolidationData portTemplateConsolidationData, ServiceTemplate substitutionServiceTemplate,
1660                                      Map<String, Object> serviceTemplatePropertyMap) {
1661         String countInputParameterId = getSubInterfaceInputParameterId(nodeTemplate.getType(), subInterfaceNodeTemplateId,
1662             ToscaConstants.SERVICE_TEMPLATE_FILTER_COUNT, portTemplateConsolidationData);
1663         EntrySchema entrySchema = new EntrySchema();
1664         entrySchema.setType(PropertyType.FLOAT.getDisplayName());
1665         addInputParameter(countInputParameterId, PropertyType.LIST.getDisplayName(), entrySchema, substitutionServiceTemplate);
1666         Map<String, List<String>> countPropertyValueInputParam = getPropertyValueInputParam(countInputParameterId);
1667         serviceTemplatePropertyMap.remove(ToscaConstants.COUNT_PROPERTY_NAME);
1668         serviceTemplatePropertyMap.put(ToscaConstants.COUNT_PROPERTY_NAME, countPropertyValueInputParam);
1669     }
1670
1671     private void handleNodeTypeProperties(ServiceTemplate substitutionServiceTemplate, List<EntityConsolidationData> entityConsolidationDataList,
1672                                           NodeTemplate nodeTemplate, UnifiedCompositionEntity compositionEntity,
1673                                           ComputeTemplateConsolidationData computeTemplateConsolidationData, TranslationContext context) {
1674         ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
1675         Optional<NodeType> enrichNodeType;
1676         List<String> enrichProperties;
1677         if (compositionEntity.equals(UnifiedCompositionEntity.PORT)) {
1678             enrichNodeType = toscaAnalyzerService.fetchNodeType(ToscaNodeType.NETWORK_PORT, context.getGlobalServiceTemplates().values());
1679             enrichProperties = TranslationContext.getEnrichPortResourceProperties();
1680             if (!enrichNodeType.isPresent() || Objects.isNull(enrichProperties)) {
1681                 return;
1682             }
1683         } else {
1684             return;
1685         }
1686         Map<String, Object> nodeTemplateProperties = nodeTemplate.getProperties();
1687         Map<String, PropertyDefinition> enrichNodeTypeProperties = enrichNodeType.get().getProperties();
1688         if (Objects.nonNull(enrichNodeTypeProperties)) {
1689             for (String enrichPropertyName : enrichProperties) {
1690                 handleEntityConsolidationDataNodeTypeProperties(enrichPropertyName, substitutionServiceTemplate, enrichNodeType.get(), nodeTemplate,
1691                     compositionEntity, computeTemplateConsolidationData, entityConsolidationDataList, nodeTemplateProperties, context);
1692             }
1693         }
1694     }
1695
1696     private void handleEntityConsolidationDataNodeTypeProperties(String enrichPropertyName, ServiceTemplate substitutionServiceTemplate,
1697                                                                  NodeType enrichNodeType, NodeTemplate nodeTemplate,
1698                                                                  UnifiedCompositionEntity compositionEntity,
1699                                                                  ComputeTemplateConsolidationData computeTemplateConsolidationData,
1700                                                                  List<EntityConsolidationData> entityConsolidationDataList,
1701                                                                  Map<String, Object> nodeTemplateProperties, TranslationContext context) {
1702         String propertyType;
1703         for (EntityConsolidationData entityConsolidationData : entityConsolidationDataList) {
1704             String nodeTemplateId = entityConsolidationData.getNodeTemplateId();
1705             String inputParamId = getParameterId(nodeTemplateId, nodeTemplate, enrichPropertyName, compositionEntity,
1706                 computeTemplateConsolidationData, (PortTemplateConsolidationData) entityConsolidationData);
1707             Map<String, String> propertyValMap = new HashMap<>();
1708             context.addNewPropertyIdToNodeTemplate(ToscaUtil.getServiceTemplateFileName(substitutionServiceTemplate), inputParamId,
1709                 nodeTemplateProperties.get(enrichPropertyName));
1710             if (nodeTemplateProperties.containsKey(enrichPropertyName)) {
1711                 handleExistingEnrichedProperty(enrichPropertyName, nodeTemplateProperties, inputParamId);
1712             } else {
1713                 propertyValMap.put(GET_INPUT.getFunctionName(), inputParamId);
1714                 nodeTemplate.getProperties().put(enrichPropertyName, propertyValMap);
1715             }
1716             propertyType = enrichNodeType.getProperties().get(enrichPropertyName).getType();
1717             addPropertyInputParameter(propertyType, substitutionServiceTemplate,
1718                 enrichNodeType.getProperties().get(enrichPropertyName).getEntry_schema(), inputParamId);
1719         }
1720     }
1721
1722     private void handleExistingEnrichedProperty(String enrichPropertyName, Map<String, Object> nodeTemplateProperties, String inputParamId) {
1723         Object enrichedProperty = nodeTemplateProperties.get(enrichPropertyName);
1724         if (!isPropertyContainsToscaFunction(enrichedProperty)) {
1725             Map<String, Object> propertyWithGetInput = new HashMap<>();
1726             propertyWithGetInput.put(ToscaFunctions.GET_INPUT.getFunctionName(), inputParamId);
1727             nodeTemplateProperties.put(enrichPropertyName, propertyWithGetInput);
1728         }
1729     }
1730
1731     private boolean isPropertyContainsToscaFunction(Object propertyValue) {
1732         ToscaFunctions[] values = ToscaFunctions.values();
1733         for (ToscaFunctions toscaFunction : values) {
1734             if (isIncludeToscaFunc(propertyValue, toscaFunction)) {
1735                 return true;
1736             }
1737         }
1738         return false;
1739     }
1740
1741     private void addPropertyInputParameter(String propertyType, ServiceTemplate substitutionServiceTemplate, EntrySchema entrySchema,
1742                                            String parameterId) {
1743         if (Objects.isNull(propertyType)) {
1744             return;
1745         }
1746         if (isParameterBelongsToEnrichedPortProperties(parameterId)) {
1747             addInputParameter(parameterId, propertyType, propertyType.equals(PropertyType.LIST.getDisplayName()) ? entrySchema : null,
1748                 substitutionServiceTemplate);
1749         } else if (isPropertySimpleType(propertyType)) {
1750             addInputParameter(parameterId, PropertyType.LIST.getDisplayName(),
1751                 DataModelUtil.createEntrySchema(propertyType.toLowerCase(), null, null), substitutionServiceTemplate);
1752         } else if (propertyType.equals(PropertyTypeExt.JSON.getDisplayName()) || (Objects.nonNull(entrySchema) && isPropertySimpleType(
1753             entrySchema.getType()))) {
1754             addInputParameter(parameterId, PropertyType.LIST.getDisplayName(),
1755                 DataModelUtil.createEntrySchema(PropertyTypeExt.JSON.getDisplayName(), null, null), substitutionServiceTemplate);
1756         } else {
1757             addInputParameter(parameterId, analyzeParameterType(propertyType),
1758                 DataModelUtil.createEntrySchema(analyzeEntrySchemaType(propertyType, entrySchema), null, null), substitutionServiceTemplate);
1759         }
1760     }
1761
1762     private boolean isParameterBelongsToEnrichedPortProperties(String parameterId) {
1763         List enrichPortResourceProperties = TranslationContext.getEnrichPortResourceProperties();
1764         for (int i = 0; i < enrichPortResourceProperties.size(); i++) {
1765             if (parameterId.contains((CharSequence) enrichPortResourceProperties.get(i))) {
1766                 return true;
1767             }
1768         }
1769         return false;
1770     }
1771
1772     private boolean isPropertySimpleType(String propertyType) {
1773         return !Objects.isNull(propertyType) && (PropertyType.getSimplePropertyTypes().contains(propertyType.toLowerCase()));
1774     }
1775
1776     private String analyzeParameterType(String propertyType) {
1777         return propertyType.equalsIgnoreCase(PropertyType.LIST.getDisplayName()) ? PropertyType.LIST.getDisplayName() : propertyType;
1778     }
1779
1780     private String analyzeEntrySchemaType(String propertyType, EntrySchema entrySchema) {
1781         return propertyType.equalsIgnoreCase(PropertyType.LIST.getDisplayName()) && entrySchema != null ? entrySchema.getType() : null;
1782     }
1783
1784     private void handleConsolidationEntitiesRequirementConnectivity(NodeTemplate nodeTemplate, ServiceTemplate serviceTemplate,
1785                                                                     TranslationContext context) {
1786         List<Map<String, RequirementAssignment>> nodeTemplateRequirements = DataModelUtil.getNodeTemplateRequirementList(nodeTemplate);
1787         if (CollectionUtils.isEmpty(nodeTemplateRequirements)) {
1788             return;
1789         }
1790         for (Map<String, RequirementAssignment> requirement : nodeTemplateRequirements) {
1791             for (Map.Entry<String, RequirementAssignment> entry : requirement.entrySet()) {
1792                 RequirementAssignment requirementAssignment = entry.getValue();
1793                 String requirementNode = requirementAssignment.getNode();
1794                 String unifiedNodeTemplateId = context.getUnifiedSubstitutionNodeTemplateId(serviceTemplate, requirementNode);
1795                 if (unifiedNodeTemplateId != null) {
1796                     //Update the node id in the requirement
1797                     requirementAssignment.setNode(unifiedNodeTemplateId);
1798                 }
1799             }
1800         }
1801         nodeTemplate.setRequirements(nodeTemplateRequirements);
1802     }
1803
1804     /**
1805      * Update the node references in the volume relationship templates.
1806      *
1807      * @param serviceTemplate the service template
1808      * @param context         the context
1809      */
1810     private void updateVolumeRelationshipTemplate(ServiceTemplate serviceTemplate, String relationshipId, TranslationContext context) {
1811         Map<String, RelationshipTemplate> relationshipTemplates = DataModelUtil.getRelationshipTemplates(serviceTemplate);
1812         if (relationshipTemplates != null) {
1813             RelationshipTemplate relationshipTemplate = relationshipTemplates.get(relationshipId);
1814             if (relationshipTemplate != null) {
1815                 String relationshipTemplateType = relationshipTemplate.getType();
1816                 if (relationshipTemplateType.equals(ToscaRelationshipType.CINDER_VOLUME_ATTACHES_TO)) {
1817                     handleCinderVolumeAttachmentRelationshipTemplate(serviceTemplate, relationshipTemplate, context);
1818                 }
1819             }
1820         }
1821     }
1822
1823     private void handleCinderVolumeAttachmentRelationshipTemplate(ServiceTemplate substitutionServiceTemplate,
1824                                                                   RelationshipTemplate relationshipTemplate, TranslationContext context) {
1825         Map<String, Object> properties = relationshipTemplate.getProperties();
1826         properties.computeIfPresent(HeatConstants.INSTANCE_UUID_PROPERTY_NAME,
1827             (key, value) -> context.getUnifiedAbstractNodeTemplateId(substitutionServiceTemplate, (String) value));
1828     }
1829
1830     private String updateIdenticalProperty(String nodeTemplateId, String propertyId, NodeTemplate nodeTemplate,
1831                                            UnifiedCompositionEntity unifiedCompositionEntity,
1832                                            List<UnifiedCompositionData> unifiedCompositionDataList) {
1833         String inputParamId = null;
1834         Map<String, Object> propertyVal = new HashMap<>();
1835         switch (unifiedCompositionEntity) {
1836             case COMPUTE:
1837                 inputParamId = COMPUTE_IDENTICAL_VALUE_PROPERTY_PREFIX + propertyId + COMPUTE_IDENTICAL_VALUE_PROPERTY_SUFFIX;
1838                 propertyVal.put(ToscaFunctions.GET_INPUT.getFunctionName(), inputParamId);
1839                 nodeTemplate.getProperties().put(propertyId, propertyVal);
1840                 break;
1841             case PORT:
1842                 PortTemplateConsolidationData portTemplateConsolidationData = getPortTemplateConsolidationDataForPort(unifiedCompositionDataList,
1843                     nodeTemplateId);
1844                 String portType = null;
1845                 if (Objects.nonNull(portTemplateConsolidationData)) {
1846                     portType = portTemplateConsolidationData.getPortType();
1847                 }
1848                 ComputeTemplateConsolidationData computeTemplateConsolidationData = getConnectedComputeConsolidationData(unifiedCompositionDataList,
1849                     nodeTemplateId);
1850                 inputParamId = getInputParamIdForPort(nodeTemplateId, propertyId, portType, computeTemplateConsolidationData);
1851                 propertyVal.put(ToscaFunctions.GET_INPUT.getFunctionName(), inputParamId);
1852                 nodeTemplate.getProperties().put(propertyId, propertyVal);
1853                 break;
1854             default:
1855                 break;
1856         }
1857         return inputParamId;
1858     }
1859
1860     private String getInputParamIdForPort(String nodeTemplateId, String propertyId, String portType,
1861                                           ComputeTemplateConsolidationData computeTemplateConsolidationData) {
1862         String inputParamId;
1863         if (Objects.isNull(computeTemplateConsolidationData) || computeTemplateConsolidationData.getPorts().get(portType).size() > 1) {
1864             inputParamId = UnifiedCompositionEntity.PORT.getDisplayName().toLowerCase() + "_" + nodeTemplateId + "_" + propertyId;
1865         } else {
1866             inputParamId = UnifiedCompositionEntity.PORT.getDisplayName().toLowerCase() + "_" + portType + "_" + propertyId;
1867         }
1868         return inputParamId;
1869     }
1870
1871     private void addInputParameter(String parameterId, String parameterType, EntrySchema entrySchema, ServiceTemplate serviceTemplate) {
1872         ParameterDefinition parameterDefinition = DataModelUtil.createParameterDefinition(parameterType, null, true, null, entrySchema, null);
1873         DataModelUtil.addInputParameterToTopologyTemplate(serviceTemplate, parameterId, parameterDefinition);
1874     }
1875
1876     // Return the input parameter Id which is used in the new property value if there is one
1877     private Optional<String> updateProperty(ServiceTemplate serviceTemplate, String nodeTemplateId, NodeTemplate nodeTemplate,
1878                                             Map.Entry<String, Object> propertyEntry, UnifiedCompositionEntity compositionEntity,
1879                                             ComputeTemplateConsolidationData computeTemplateConsolidationData,
1880                                             PortTemplateConsolidationData portTemplateConsolidationData,
1881                                             List<UnifiedCompositionData> unifiedCompositionDataList, TranslationContext context) {
1882         if (handleGetAttrFromConsolidationNodes(serviceTemplate, nodeTemplateId, nodeTemplate, propertyEntry, unifiedCompositionDataList, context)) {
1883             return Optional.empty();
1884         }
1885         String inputParamId = getParameterId(nodeTemplateId, nodeTemplate, propertyEntry.getKey(), compositionEntity,
1886             computeTemplateConsolidationData, portTemplateConsolidationData);
1887         Map<String, List<String>> propertyVal = getPropertyValueInputParam(inputParamId);
1888         nodeTemplate.getProperties().put(propertyEntry.getKey(), propertyVal);
1889         return Optional.of(inputParamId);
1890     }
1891
1892     private Map<String, List<String>> getPropertyValueInputParam(String inputParamId) {
1893         Map<String, List<String>> propertyVal = new HashMap<>();
1894         List<String> getInputFuncParams = new ArrayList<>();
1895         getInputFuncParams.add(inputParamId);
1896         getInputFuncParams.add(ToscaConstants.INDEX_VALUE_PROPERTY_NAME);
1897         propertyVal.put(ToscaFunctions.GET_INPUT.getFunctionName(), getInputFuncParams);
1898         return propertyVal;
1899     }
1900
1901     private boolean handleGetAttrFromConsolidationNodes(ServiceTemplate serviceTemplate, String nodeTemplateId, NodeTemplate nodeTemplate,
1902                                                         Map.Entry<String, Object> propertyEntry,
1903                                                         List<UnifiedCompositionData> unifiedCompositionDataList, TranslationContext context) {
1904         Map<String, UnifiedCompositionEntity> consolidationNodeTemplateIdAndType = getAllConsolidationNodeTemplateIdAndType(
1905             unifiedCompositionDataList);
1906         Set<String> consolidationNodeTemplateIds = consolidationNodeTemplateIdAndType.keySet();
1907         Map<String, String> entityIdToType = ConsolidationService.getConsolidationEntityIdToType(serviceTemplate, context.getConsolidationData());
1908         boolean includeGetAttrFromConsolidationNodes = false;
1909         boolean includeGetAttrFromOutsideNodes = false;
1910         boolean isGetAttrFromConsolidationIsFromSameType = false;
1911         List<List<Object>> getAttrFunctionList = extractGetAttrFunction(propertyEntry.getValue());
1912         for (List<Object> getAttrFunc : getAttrFunctionList) {
1913             String getAttrNodeId = (String) getAttrFunc.get(0);
1914             if (consolidationNodeTemplateIds.contains(getAttrNodeId)) {
1915                 includeGetAttrFromConsolidationNodes = true;
1916                 if (isGetAttrNodeTemplateFromSameType(nodeTemplateId, getAttrNodeId, entityIdToType)) {
1917                     isGetAttrFromConsolidationIsFromSameType = true;
1918                 }
1919             } else {
1920                 includeGetAttrFromOutsideNodes = true;
1921             }
1922         }
1923         if ((includeGetAttrFromConsolidationNodes && includeGetAttrFromOutsideNodes) || (includeGetAttrFromConsolidationNodes && isIncludeToscaFunc(
1924             propertyEntry.getValue(), ToscaFunctions.GET_INPUT))) {
1925             //This case is currently not supported - this property will be ignored
1926             return true;
1927         } else if (includeGetAttrFromConsolidationNodes && !isGetAttrFromConsolidationIsFromSameType) {
1928             Object clonedPropertyValue = getClonedPropertyValue(propertyEntry);
1929             List<List<Object>> clonedGetAttrFuncList = extractGetAttrFunction(clonedPropertyValue);
1930             for (List<Object> getAttrFunc : clonedGetAttrFuncList) {
1931                 String targetNodeTemplateId = (String) getAttrFunc.get(0);
1932                 if (consolidationNodeTemplateIds.contains(targetNodeTemplateId)) {
1933                     updatePropertyGetAttrFunc(serviceTemplate, unifiedCompositionDataList, consolidationNodeTemplateIdAndType, targetNodeTemplateId,
1934                         getAttrFunc, context);
1935                 }
1936             }
1937             nodeTemplate.getProperties().put(propertyEntry.getKey(), clonedPropertyValue);
1938             return true;
1939         }
1940         return false;
1941     }
1942
1943     private boolean isGetAttrNodeTemplateFromSameType(String sourceNodeTemplateId, String targetNodeTemplateId,
1944                                                       Map<String, String> nodeTemplateIdToType) {
1945         if (Objects.isNull(nodeTemplateIdToType.get(sourceNodeTemplateId)) || Objects.isNull(nodeTemplateIdToType.get(targetNodeTemplateId))) {
1946             return false;
1947         }
1948         return nodeTemplateIdToType.get(sourceNodeTemplateId).equals(nodeTemplateIdToType.get(targetNodeTemplateId));
1949     }
1950
1951     private void updatePropertyGetAttrFunc(ServiceTemplate serviceTemplate, List<UnifiedCompositionData> unifiedCompositionDataList,
1952                                            Map<String, UnifiedCompositionEntity> consolidationNodeTemplateIdAndType, String targetNodeTemplateId,
1953                                            List<Object> getAttrFunc, TranslationContext context) {
1954         UnifiedCompositionEntity targetCompositionEntity = consolidationNodeTemplateIdAndType.get(targetNodeTemplateId);
1955         String targetNewNodeTemplateId = getNewNodeTemplateId(serviceTemplate, unifiedCompositionDataList, targetNodeTemplateId,
1956             targetCompositionEntity, context);
1957         getAttrFunc.set(0, targetNewNodeTemplateId);
1958     }
1959
1960     private String getNewNodeTemplateId(ServiceTemplate serviceTemplate, List<UnifiedCompositionData> unifiedCompositionDataList,
1961                                         String nodeTemplateId, UnifiedCompositionEntity compositionEntity, TranslationContext context) {
1962         String newNodeTemplateId = nodeTemplateId;
1963         String nodeTemplateIdGeneratorImpl = unifiedSubstitutionNodeTemplateIdGeneratorImplMap.get(compositionEntity);
1964         UnifiedSubstitutionNodeTemplateIdGenerator nodeTemplateIdGenerator = CommonMethods
1965             .newInstance(nodeTemplateIdGeneratorImpl, UnifiedSubstitutionNodeTemplateIdGenerator.class);
1966         UnifiedCompositionTo unifiedCompositionTo = new UnifiedCompositionTo(serviceTemplate, null, unifiedCompositionDataList, context, null);
1967         Optional<String> generatedNodeTemplateId = nodeTemplateIdGenerator.generate(unifiedCompositionTo, nodeTemplateId);
1968         if (generatedNodeTemplateId.isPresent()) {
1969             newNodeTemplateId = generatedNodeTemplateId.get();
1970         }
1971         return newNodeTemplateId;
1972     }
1973
1974     private String getNewNodeTemplateId(String origNodeTemplateId, String serviceTemplateFileName, ServiceTemplate serviceTemplate,
1975                                         TranslationContext context) {
1976         ConsolidationData consolidationData = context.getConsolidationData();
1977         if (isIdIsOfExpectedType(origNodeTemplateId, UnifiedCompositionEntity.PORT, serviceTemplateFileName, context)) {
1978             return handleIdOfPort(origNodeTemplateId, serviceTemplateFileName, consolidationData);
1979         } else if (isIdIsOfExpectedType(origNodeTemplateId, COMPUTE, serviceTemplateFileName, context)) {
1980             NodeTemplate nodeTemplate = getComputeNodeTemplate(origNodeTemplateId, serviceTemplate, context);
1981             return getComputeTypeSuffix(nodeTemplate.getType());
1982         }
1983         return null;
1984     }
1985
1986     private Object getClonedPropertyValue(Map.Entry<String, Object> propertyEntry) {
1987         if (propertyEntry.getValue() instanceof Map) {
1988             return getClonedObject(propertyEntry.getValue(), Map.class);
1989         } else if (propertyEntry.getValue() instanceof List) {
1990             return getClonedObject(propertyEntry.getValue(), List.class);
1991         }
1992         return propertyEntry.getValue();
1993     }
1994
1995     private String getParameterId(String nodeTemplateId, NodeTemplate nodeTemplate, String propertyId,
1996                                   UnifiedCompositionEntity unifiedCompositionEntity,
1997                                   ComputeTemplateConsolidationData computeTemplateConsolidationData,
1998                                   PortTemplateConsolidationData portTemplateConsolidationData) {
1999         String paramterId = propertyId;
2000         switch (unifiedCompositionEntity) {
2001             case COMPUTE:
2002                 paramterId = COMPUTE.getDisplayName().toLowerCase() + "_" + getComputeTypeSuffix(nodeTemplate.getType()) + "_" + propertyId;
2003                 break;
2004             case PORT:
2005                 String portType = portTemplateConsolidationData.getPortType();
2006                 if (Objects.isNull(computeTemplateConsolidationData) || (computeTemplateConsolidationData.getPorts().get(portType) != null
2007                     && computeTemplateConsolidationData.getPorts().get(portType).size() > 1)) {
2008                     paramterId = UnifiedCompositionEntity.PORT.getDisplayName().toLowerCase() + "_" + nodeTemplateId + "_" + propertyId;
2009                 } else {
2010                     paramterId = UnifiedCompositionEntity.PORT.getDisplayName().toLowerCase() + "_" + portType + "_" + propertyId;
2011                 }
2012                 break;
2013             case SUB_INTERFACE:
2014                 paramterId = getSubInterfaceInputParameterId(nodeTemplate.getType(), nodeTemplateId, propertyId, portTemplateConsolidationData);
2015                 break;
2016             default:
2017                 break;
2018         }
2019         return paramterId;
2020     }
2021
2022     private String getSubInterfaceInputParameterId(String type, String nodeTemplateId, String propertyId,
2023                                                    PortTemplateConsolidationData portTemplateConsolidationData) {
2024         String subInterfaceType = getSubInterfaceTypeSuffix(type);
2025         if (Objects.isNull(portTemplateConsolidationData) || portTemplateConsolidationData.isSubInterfaceNodeTemplateIdParameter(type)) {
2026             return UnifiedCompositionEntity.SUB_INTERFACE.getDisplayName().toLowerCase() + "_" + nodeTemplateId + "_" + propertyId;
2027         }
2028         return UnifiedCompositionEntity.SUB_INTERFACE.getDisplayName().toLowerCase() + "_" + subInterfaceType + "_" + propertyId;
2029     }
2030
2031     private void removeConnectivityOut(EntityConsolidationData entityConsolidationData, NodeTemplate nodeTemplate) {
2032         Multimap<String, RequirementAssignmentData> nodesConnectedOut = entityConsolidationData.getNodesConnectedOut();
2033         if (CommonUtil.isMultimapEmpty(nodesConnectedOut)) {
2034             return;
2035         }
2036         nodesConnectedOut.values().forEach(requirementAssignmentData -> DataModelUtil
2037             .removeRequirementsAssignment(nodeTemplate.getRequirements(), requirementAssignmentData.getRequirementId()));
2038         if (nodeTemplate.getRequirements().isEmpty()) {
2039             nodeTemplate.setRequirements(null);
2040         }
2041     }
2042
2043     private void removeVolumeConnectivity(ComputeTemplateConsolidationData computeTemplateConsolidationData, NodeTemplate computeNodeTemplate) {
2044         if (CommonUtil.isMultimapEmpty(computeTemplateConsolidationData.getVolumes())) {
2045             return;
2046         }
2047         computeTemplateConsolidationData.getVolumes().values().forEach(requirementAssignmentData -> DataModelUtil
2048             .removeRequirementsAssignment(computeNodeTemplate.getRequirements(), requirementAssignmentData.getRequirementId()));
2049         if (computeNodeTemplate.getRequirements().isEmpty()) {
2050             computeNodeTemplate.setRequirements(null);
2051         }
2052     }
2053
2054     private void createIndexInputParameter(ServiceTemplate substitutionServiceTemplate) {
2055         ParameterDefinition indexParameterDefinition = DataModelUtil
2056             .createParameterDefinition(PropertyType.INTEGER.getDisplayName(), "Index value of this substitution service template runtime instance",
2057                 false, createIndexValueConstraint(), null, 0);
2058         DataModelUtil
2059             .addInputParameterToTopologyTemplate(substitutionServiceTemplate, ToscaConstants.INDEX_VALUE_PROPERTY_NAME, indexParameterDefinition);
2060     }
2061
2062     private List<Constraint> createIndexValueConstraint() {
2063         List<Constraint> constraints;
2064         constraints = new ArrayList<>();
2065         Constraint constraint = new Constraint();
2066         constraint.setGreater_or_equal(0);
2067         constraints.add(constraint);
2068         return constraints;
2069     }
2070
2071     private Optional<UnifiedComposition> getUnifiedCompositionInstance(UnifiedCompositionMode mode) {
2072         String unifiedCompositionImplClassName = unifiedCompositionImplMap.get(mode.name()).getImplementationClass();
2073         if (StringUtils.isEmpty(unifiedCompositionImplClassName)) {
2074             return Optional.empty();
2075         }
2076         return Optional.of(CommonMethods.newInstance(unifiedCompositionImplClassName, UnifiedComposition.class));
2077     }
2078
2079     private Optional<Map<String, Object>> createAbstractSubstitutionProperties(ServiceTemplate serviceTemplate,
2080                                                                                Map<String, ParameterDefinition> substitutionTemplateInputs,
2081                                                                                List<UnifiedCompositionData> unifiedCompositionDataList,
2082                                                                                TranslationContext context) {
2083         Map<String, Object> abstractSubstituteProperties = new LinkedHashMap<>();
2084         //Since all the computes have the same type fetching the type from the first entry
2085         NodeTemplate firstComputeNodeTemplate = DataModelUtil
2086             .getNodeTemplate(serviceTemplate, unifiedCompositionDataList.get(0).getComputeTemplateConsolidationData().getNodeTemplateId());
2087         String computeType = getComputeTypeSuffix(firstComputeNodeTemplate.getType());
2088         for (Map.Entry<String, ParameterDefinition> input : substitutionTemplateInputs.entrySet()) {
2089             String substitutionTemplateInputName = input.getKey();
2090             ParameterDefinition inputParameterDefinition = input.getValue();
2091             String inputType = inputParameterDefinition.getType();
2092             UnifiedCompositionEntity inputUnifiedCompositionEntity = getInputCompositionEntity(substitutionTemplateInputName);
2093             if (isIdenticalValueProperty(substitutionTemplateInputName, inputUnifiedCompositionEntity) || !inputType
2094                 .equalsIgnoreCase(PropertyType.LIST.getDisplayName())) {
2095                 //Handle identical value properties
2096                 Optional<String> identicalValuePropertyName = getIdenticalValuePropertyName(substitutionTemplateInputName,
2097                     inputUnifiedCompositionEntity);
2098                 identicalValuePropertyName.ifPresent(
2099                     propertyName -> updateIdenticalPropertyValue(propertyName, substitutionTemplateInputName, inputUnifiedCompositionEntity,
2100                         unifiedCompositionDataList.get(0), serviceTemplate, abstractSubstituteProperties, context));
2101                 continue;
2102             }
2103             //Check if the input is of type compute, port or sub interface
2104             List<Object> abstractPropertyValue = new ArrayList<>();
2105             switch (inputUnifiedCompositionEntity) {
2106                 case COMPUTE:
2107                     createAbstractComputeProperties(unifiedCompositionDataList, substitutionTemplateInputName, serviceTemplate,
2108                         abstractPropertyValue);
2109                     break;
2110                 case PORT:
2111                     createAbstractPortProperties(unifiedCompositionDataList, substitutionTemplateInputName, computeType, serviceTemplate,
2112                         abstractPropertyValue);
2113                     break;
2114                 case SUB_INTERFACE:
2115                     createAbstractSubInterfaceProperties(unifiedCompositionDataList, substitutionTemplateInputName, serviceTemplate,
2116                         abstractPropertyValue);
2117                     break;
2118                 default:
2119                     break;
2120             }
2121             //Add the property only if it has at least one non-null value
2122             if (abstractPropertyValue.stream().anyMatch(Objects::nonNull)) {
2123                 updateAbstractPropertyValue(substitutionTemplateInputName, inputParameterDefinition, abstractPropertyValue,
2124                     abstractSubstituteProperties);
2125             }
2126         }
2127         return Optional.ofNullable(abstractSubstituteProperties);
2128     }
2129
2130     private void createAbstractComputeProperties(List<UnifiedCompositionData> unifiedCompositionDataList, String substitutionTemplateInputName,
2131                                                  ServiceTemplate serviceTemplate, List<Object> abstractPropertyValue) {
2132         for (UnifiedCompositionData compositionData : unifiedCompositionDataList) {
2133             ComputeTemplateConsolidationData computeTemplateConsolidationData = compositionData.getComputeTemplateConsolidationData();
2134             Object propertyValue = getComputePropertyValue(substitutionTemplateInputName, serviceTemplate, computeTemplateConsolidationData);
2135             if (!(propertyValue instanceof Optional)) {
2136                 abstractPropertyValue.add(propertyValue);
2137             }
2138         }
2139     }
2140
2141     private void createAbstractPortProperties(List<UnifiedCompositionData> unifiedCompositionDataList, String substitutionTemplateInputName,
2142                                               String computeType, ServiceTemplate serviceTemplate, List<Object> abstractPropertyValue) {
2143         for (UnifiedCompositionData compositionData : unifiedCompositionDataList) {
2144             List<PortTemplateConsolidationData> portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(compositionData);
2145             //Get the input type for this input whether it is of type
2146
2147             // port_<port_node_template_id>_<property_name> or port_<port_type>_<property_name>
2148             PropertyInputType portInputType = getPortInputType(substitutionTemplateInputName, compositionData);
2149             for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) {
2150                 //Get the port property value
2151                 String portNodeTemplateId = portTemplateConsolidationData.getNodeTemplateId();
2152                 Object propertyValue = getPortPropertyValue(substitutionTemplateInputName, computeType, portInputType, serviceTemplate,
2153                     portNodeTemplateId, portTemplateConsolidationData);
2154                 //If the value object is Optional.empty it implies that the property name was not
2155
2156                 // found in the input name
2157                 if (!(propertyValue instanceof Optional)) {
2158                     abstractPropertyValue.add(propertyValue);
2159                 }
2160             }
2161         }
2162     }
2163
2164     private void createAbstractSubInterfaceProperties(List<UnifiedCompositionData> unifiedCompositionDataList, String substitutionTemplateInputName,
2165                                                       ServiceTemplate serviceTemplate, List<Object> abstractPropertyValue) {
2166         for (UnifiedCompositionData compositionData : unifiedCompositionDataList) {
2167             List<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationDataList = getSubInterfaceTemplateConsolidationDataList(
2168                 compositionData);
2169             //Get the input type for this input whether it is of type
2170
2171             // subInterface_<subinterface_node_template_id>_<property_name> or
2172
2173             // subInterface_<subinterface_type>_<property_name>
2174             PropertyInputType subInterfaceInputType = getSubInterfaceInputType(substitutionTemplateInputName, compositionData);
2175             for (SubInterfaceTemplateConsolidationData subInterfaceTemplateConsolidationData : subInterfaceTemplateConsolidationDataList) {
2176                 //Get the subInterface property value
2177                 String subInterfaceNodeTemplateId = subInterfaceTemplateConsolidationData.getNodeTemplateId();
2178                 NodeTemplate subInterfaceNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, subInterfaceNodeTemplateId);
2179                 String subInterfaceType = getSubInterfaceTypeSuffix(subInterfaceNodeTemplate.getType());
2180                 Object propertyValue = getSubInterfacePropertyValue(substitutionTemplateInputName, subInterfaceType, subInterfaceInputType,
2181                     serviceTemplate, subInterfaceNodeTemplateId);
2182                 //If the value object is Optional.empty it implies that the property name was not
2183
2184                 // found in the input name
2185                 if (!(propertyValue instanceof Optional)) {
2186                     abstractPropertyValue.add(propertyValue);
2187                 }
2188             }
2189         }
2190     }
2191
2192     private void updateAbstractPropertyValue(String substitutionTemplateInputName, ParameterDefinition parameterDefinition,
2193                                              List<Object> abstractPropertyValue, Map<String, Object> abstractSubstituteProperties) {
2194         if (abstractPropertyValue.size() > 1) {
2195             abstractSubstituteProperties.put(substitutionTemplateInputName, abstractPropertyValue);
2196         } else {
2197             Object propertyValue = abstractPropertyValue.get(0);
2198             String entrySchemaType = parameterDefinition.getEntry_schema().getType();
2199             if (PropertyType.getSimplePropertyTypes().contains(entrySchemaType.toLowerCase()) || entrySchemaType
2200                 .equals(PropertyTypeExt.JSON.getDisplayName())) {
2201                 abstractSubstituteProperties.put(substitutionTemplateInputName, abstractPropertyValue);
2202             } else {
2203                 abstractSubstituteProperties.put(substitutionTemplateInputName, propertyValue);
2204             }
2205         }
2206     }
2207
2208     private void updateIdenticalPropertyValue(String identicalValuePropertyName, String substitutionTemplateInputName,
2209                                               UnifiedCompositionEntity entity, UnifiedCompositionData unifiedCompositionData,
2210                                               ServiceTemplate serviceTemplate, Map<String, Object> abstractSubstituteProperties,
2211                                               TranslationContext context) {
2212         Optional<Object> identicalPropertyValueByType = getIdenticalPropertyValueByType(identicalValuePropertyName, substitutionTemplateInputName,
2213             entity, unifiedCompositionData, serviceTemplate, context);
2214         if (identicalPropertyValueByType.isPresent()) {
2215             abstractSubstituteProperties.put(substitutionTemplateInputName, identicalPropertyValueByType.get());
2216         }
2217     }
2218
2219     private Optional<Object> getIdenticalPropertyValueByType(String identicalValuePropertyName, String substitutionTemplateInputName,
2220                                                              UnifiedCompositionEntity entity, UnifiedCompositionData unifiedCompositionData,
2221                                                              ServiceTemplate serviceTemplate, TranslationContext context) {
2222         ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData.getComputeTemplateConsolidationData();
2223         Optional<Object> identicalPropertyValue = Optional.empty();
2224         switch (entity) {
2225             case COMPUTE:
2226                 identicalPropertyValue = getIdenticalPropertyValue(identicalValuePropertyName, serviceTemplate, computeTemplateConsolidationData,
2227                     context);
2228                 break;
2229             case OTHER:
2230                 identicalPropertyValue = getIdenticalPropertyValue(identicalValuePropertyName, serviceTemplate, computeTemplateConsolidationData,
2231                     context);
2232                 break;
2233             case PORT:
2234                 PropertyInputType portInputType = getPortInputType(substitutionTemplateInputName, unifiedCompositionData);
2235                 Optional<PortTemplateConsolidationData> portTemplateConsolidationData = unifiedCompositionData.getPortTemplateConsolidationDataList()
2236                     .stream().filter(s -> substitutionTemplateInputName
2237                         .contains(getPropertyInputPrefix(s.getNodeTemplateId(), s.getPortType(), portInputType, UnifiedCompositionEntity.PORT)))
2238                     .findFirst();
2239                 if (portTemplateConsolidationData.isPresent()) {
2240                     return getIdenticalPropertyValue(identicalValuePropertyName, serviceTemplate, portTemplateConsolidationData.get(), context);
2241                 }
2242                 break;
2243             default:
2244                 break;
2245         }
2246         return identicalPropertyValue;
2247     }
2248
2249     private PropertyInputType getPortInputType(String inputName, UnifiedCompositionData unifiedCompositionData) {
2250         String portInputPrefix = UnifiedCompositionEntity.PORT.getDisplayName().toLowerCase() + "_";
2251         ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData.getComputeTemplateConsolidationData();
2252         List<PortTemplateConsolidationData> portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData);
2253         //Scan the available port node template ids to check if the input is of the form
2254
2255         // "port_<port_node_template_id>_<property_name>"
2256         if (portTemplateConsolidationDataList.stream().map(EntityConsolidationData::getNodeTemplateId)
2257             .map(portNodeTemplateId -> portInputPrefix + portNodeTemplateId).anyMatch(inputName::startsWith)) {
2258             return PropertyInputType.NODE_TEMPLATE_ID;
2259         }
2260         //Check whether the input is of the form "port_<port_type>_<property_name>"
2261         Set<String> portTypes = computeTemplateConsolidationData.getPorts().keySet();
2262         if (portTypes.stream().map(portType -> portInputPrefix + portType + "_").anyMatch(inputName::startsWith)) {
2263             return PropertyInputType.TYPE;
2264         }
2265         return PropertyInputType.OTHER;
2266     }
2267
2268     private PropertyInputType getSubInterfaceInputType(String inputName, UnifiedCompositionData unifiedCompositionData) {
2269         String subInterfaceInputPrefix = UnifiedCompositionEntity.SUB_INTERFACE.getDisplayName().toLowerCase() + "_";
2270         List<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationDataList = getSubInterfaceTemplateConsolidationDataList(
2271             unifiedCompositionData);
2272         //Scan the available port node template ids to check if the input is of the form
2273
2274         // "subinterface_<subinterface_node_template_id>_<property_name>"
2275         if (subInterfaceTemplateConsolidationDataList.stream().map(EntityConsolidationData::getNodeTemplateId)
2276             .map(subInterfaceNodeTemplateId -> subInterfaceInputPrefix + subInterfaceNodeTemplateId).anyMatch(inputName::startsWith)) {
2277             return PropertyInputType.NODE_TEMPLATE_ID;
2278         }
2279         //Check whether the input is of the form "subinterface_<subinterface_type>_<property_name>"
2280         Set<String> subInterfaceTypes = new HashSet<>();
2281         List<PortTemplateConsolidationData> portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData);
2282         for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) {
2283             ListMultimap<String, SubInterfaceTemplateConsolidationData> subInterfaceTypeToEntity = ArrayListMultimap.create();
2284             portTemplateConsolidationData.copyMappedInto(subInterfaceTypeToEntity);
2285             subInterfaceTypes.addAll(subInterfaceTypeToEntity.keySet());
2286         }
2287         if (subInterfaceTypes.stream().map(UnifiedCompositionUtil::getSubInterfaceTypeSuffix)
2288             .map(subInterfaceTypeSuffix -> subInterfaceInputPrefix + subInterfaceTypeSuffix + "_").anyMatch(inputName::startsWith)) {
2289             return PropertyInputType.TYPE;
2290         }
2291         return PropertyInputType.OTHER;
2292     }
2293
2294     private void cleanServiceTemplate(ServiceTemplate serviceTemplate, EntityConsolidationData entity, TranslationContext context) {
2295         removeNodeTemplateFromServiceTemplate(serviceTemplate, entity, context);
2296         updateHeatStackGroup(serviceTemplate, entity, context);
2297         updateSubstitutionMapping(serviceTemplate, context);
2298     }
2299
2300     private void removeNodeTemplateFromServiceTemplate(ServiceTemplate serviceTemplate, EntityConsolidationData entity, TranslationContext context) {
2301         String nodeTemplateIdToRemove = entity.getNodeTemplateId();
2302         Map<String, NodeTemplate> nodeTemplates = serviceTemplate.getTopology_template().getNode_templates();
2303         NodeTemplate nodeTemplateToRemove = nodeTemplates.get(nodeTemplateIdToRemove);
2304         nodeTemplates.remove(nodeTemplateIdToRemove);
2305         context.addCleanedNodeTemplate(ToscaUtil.getServiceTemplateFileName(serviceTemplate), nodeTemplateIdToRemove,
2306             entity.getClass() == ComputeTemplateConsolidationData.class ? COMPUTE : UnifiedCompositionEntity.PORT, nodeTemplateToRemove);
2307     }
2308
2309     private void removeCleanedNodeType(String cleanedNodeTemplateId, ServiceTemplate serviceTemplate, TranslationContext context) {
2310         NodeTemplate cleanedNodeTemplate = context
2311             .getCleanedNodeTemplate(ToscaUtil.getServiceTemplateFileName(serviceTemplate), cleanedNodeTemplateId);
2312         String typeToRemove = cleanedNodeTemplate.getType();
2313         if (Objects.nonNull(typeToRemove) && serviceTemplate.getNode_types().containsKey(typeToRemove)) {
2314             serviceTemplate.getNode_types().remove(typeToRemove);
2315         }
2316     }
2317
2318     private void updateHeatStackGroup(ServiceTemplate serviceTemplate, EntityConsolidationData entity, TranslationContext context) {
2319         Map<String, GroupDefinition> groups =
2320             serviceTemplate.getTopology_template().getGroups() == null ? new HashMap<>() : serviceTemplate.getTopology_template().getGroups();
2321         String nodeRelatedAbstractNodeId = context.getUnifiedAbstractNodeTemplateId(serviceTemplate, entity.getNodeTemplateId());
2322         for (Map.Entry<String, GroupDefinition> groupEntry : groups.entrySet()) {
2323             GroupDefinition groupDefinition = groupEntry.getValue();
2324             if (isHeatStackGroup(groupDefinition.getType())) {
2325                 updateGroupMembersWithNewUnifiedNodeTemplateId(entity, nodeRelatedAbstractNodeId, groupEntry);
2326             }
2327         }
2328     }
2329
2330     private void updateGroupMembersWithNewUnifiedNodeTemplateId(EntityConsolidationData entity, String newNodetemplateId,
2331                                                                 Map.Entry<String, GroupDefinition> groupEntry) {
2332         List<String> members = groupEntry.getValue().getMembers();
2333         if (members.contains(entity.getNodeTemplateId())) {
2334             members.remove(entity.getNodeTemplateId());
2335             if (!members.contains(newNodetemplateId)) {
2336                 members.add(newNodetemplateId);
2337             }
2338         }
2339         groupEntry.getValue().setMembers(members);
2340     }
2341
2342     private void updateSubstitutionMapping(ServiceTemplate serviceTemplate, TranslationContext context) {
2343         SubstitutionMapping substitutionMappings = DataModelUtil.getSubstitutionMappings(serviceTemplate);
2344         if (Objects.nonNull(substitutionMappings)) {
2345             if (Objects.nonNull(substitutionMappings.getRequirements())) {
2346                 updateSubstitutionMappingRequirements(substitutionMappings.getRequirements(), serviceTemplate, context);
2347             }
2348             if (Objects.nonNull(substitutionMappings.getCapabilities())) {
2349                 updateSubstitutionMappingCapabilities(substitutionMappings.getCapabilities(), serviceTemplate, context);
2350             }
2351         }
2352     }
2353
2354     private void updateSubstitutionMappingRequirements(Map<String, List<String>> substitutionMappingRequirements, ServiceTemplate serviceTemplate,
2355                                                        TranslationContext context) {
2356         for (Map.Entry<String, List<String>> entry : substitutionMappingRequirements.entrySet()) {
2357             List<String> requirement = entry.getValue();
2358             String oldNodeTemplateId = requirement.get(0);
2359             String newAbstractNodeTemplateId = context.getUnifiedAbstractNodeTemplateId(serviceTemplate, requirement.get(0));
2360             String newSubstitutionNodeTemplateId = context.getUnifiedSubstitutionNodeTemplateId(serviceTemplate, oldNodeTemplateId);
2361             if (Objects.nonNull(newAbstractNodeTemplateId) && Objects.nonNull(newSubstitutionNodeTemplateId)) {
2362                 requirement.set(0, newAbstractNodeTemplateId);
2363                 String newRequirementValue = requirement.get(1) + "_" + newSubstitutionNodeTemplateId;
2364                 requirement.set(1, newRequirementValue);
2365             }
2366         }
2367     }
2368
2369     private void updateSubstitutionMappingCapabilities(Map<String, List<String>> substitutionMappingCapabilities, ServiceTemplate serviceTemplate,
2370                                                        TranslationContext context) {
2371         for (Map.Entry<String, List<String>> entry : substitutionMappingCapabilities.entrySet()) {
2372             List<String> capability = entry.getValue();
2373             String oldNodeTemplateId = capability.get(0);
2374             String newAbstractNodeTemplateId = context.getUnifiedAbstractNodeTemplateId(serviceTemplate, capability.get(0));
2375             String newSubstitutionNodeTemplateId = context.getUnifiedSubstitutionNodeTemplateId(serviceTemplate, oldNodeTemplateId);
2376             if (Objects.nonNull(newAbstractNodeTemplateId) && Objects.nonNull(newSubstitutionNodeTemplateId)) {
2377                 capability.set(0, newAbstractNodeTemplateId);
2378                 String newRequirementValue = capability.get(1) + "_" + newSubstitutionNodeTemplateId;
2379                 capability.set(1, newRequirementValue);
2380             }
2381         }
2382     }
2383
2384     private void updateHeatStackGroupNestedComposition(ServiceTemplate serviceTemplate, EntityConsolidationData entity, TranslationContext context) {
2385         Map<String, GroupDefinition> groups =
2386             serviceTemplate.getTopology_template().getGroups() == null ? new HashMap<>() : serviceTemplate.getTopology_template().getGroups();
2387         String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
2388         Optional<String> nestedNodeTemplateId = context.getUnifiedNestedNodeTemplateId(serviceTemplateFileName, entity.getNodeTemplateId());
2389         if (nestedNodeTemplateId.isPresent()) {
2390             for (Map.Entry<String, GroupDefinition> groupEntry : groups.entrySet()) {
2391                 GroupDefinition groupDefinition = groupEntry.getValue();
2392                 if (isHeatStackGroup(groupDefinition.getType())) {
2393                     updateGroupMembersWithNewUnifiedNodeTemplateId(entity, nestedNodeTemplateId.get(), groupEntry);
2394                 }
2395             }
2396         }
2397     }
2398
2399     private void handleNestedNodeTemplateInMainServiceTemplate(String nestedNodeTemplateId, ServiceTemplate mainServiceTemplate,
2400                                                                ServiceTemplate nestedServiceTemplate, TranslationContext context) {
2401         NodeTemplate nestedNodeTemplate = DataModelUtil.getNodeTemplate(mainServiceTemplate, nestedNodeTemplateId);
2402         if (Objects.isNull(nestedNodeTemplate)) {
2403             return;
2404         }
2405         updateNestedNodeTemplateProperties(nestedServiceTemplate, nestedNodeTemplate, context);
2406         Optional<String> unifiedNestedNodeTypeId = context
2407             .getUnifiedNestedNodeTypeId(ToscaUtil.getServiceTemplateFileName(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME),
2408                 nestedNodeTemplate.getType());
2409         unifiedNestedNodeTypeId.ifPresent(
2410             unifiedNestedNodeTypeIdVal -> updateNestedNodeTemplate(unifiedNestedNodeTypeIdVal, nestedNodeTemplateId, nestedNodeTemplate,
2411                 mainServiceTemplate, context));
2412     }
2413
2414     private void updateNestedNodeTemplateProperties(ServiceTemplate nestedServiceTemplate, NodeTemplate nestedNodeTemplate,
2415                                                     TranslationContext context) {
2416         Map<String, Object> newPropertyInputParamIds = context
2417             .getAllNewPropertyInputParamIdsPerNodeTenplateId(ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate));
2418         for (Map.Entry<String, Object> entry : newPropertyInputParamIds.entrySet()) {
2419             if (Objects.nonNull(entry.getValue())) {
2420                 Object value = getClonedObject(entry.getValue());
2421                 nestedNodeTemplate.getProperties().put(entry.getKey(), value);
2422             }
2423         }
2424         String subNodeType = nestedServiceTemplate.getTopology_template().getSubstitution_mappings().getNode_type();
2425         nestedNodeTemplate.setType(subNodeType);
2426     }
2427
2428     private void handleSubstitutionMappingInNestedServiceTemplate(String newNestedNodeType, ServiceTemplate nestedServiceTemplate,
2429                                                                   TranslationContext context) {
2430         if (Objects.isNull(newNestedNodeType)) {
2431             return;
2432         }
2433         Set<String> relatedNestedNodeTypeIds = context.getAllRelatedNestedNodeTypeIds();
2434         SubstitutionMapping substitutionMappings = nestedServiceTemplate.getTopology_template().getSubstitution_mappings();
2435         if (!relatedNestedNodeTypeIds.contains(substitutionMappings.getNode_type())) {
2436             substitutionMappings.setNode_type(newNestedNodeType);
2437         }
2438     }
2439
2440     private void updateNestedNodeTemplate(String newNestedNodeTypeId, String nestedNodeTemplateId, NodeTemplate nestedNodeTemplate,
2441                                           ServiceTemplate mainServiceTemplate, TranslationContext context) {
2442         String mainSTName = ToscaUtil.getServiceTemplateFileName(mainServiceTemplate);
2443         String globalSTName = ToscaUtil.getServiceTemplateFileName(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
2444         int index = context.getHandledNestedComputeNodeTemplateIndex(globalSTName, newNestedNodeTypeId);
2445         String newNodeTemplateId = Constants.ABSTRACT_NODE_TEMPLATE_ID_PREFIX + getComputeTypeSuffix(newNestedNodeTypeId) + "_" + index;
2446         nestedNodeTemplate.setType(newNestedNodeTypeId);
2447         mainServiceTemplate.getTopology_template().getNode_templates().remove(nestedNodeTemplateId);
2448         mainServiceTemplate.getTopology_template().getNode_templates().put(newNodeTemplateId, nestedNodeTemplate);
2449         context.addUnifiedNestedNodeTemplateId(mainSTName, nestedNodeTemplateId, newNodeTemplateId);
2450     }
2451
2452     private void handleNestedNodeTypesInGlobalSubstituteServiceTemplate(String origNestedNodeTypeId, String newNestedNodeTypeId,
2453                                                                         ServiceTemplate globalSubstitutionServiceTemplate,
2454                                                                         TranslationContext context) {
2455         Set<String> relatedNestedNodeTypeIds = context.getAllRelatedNestedNodeTypeIds();
2456         Map<String, NodeType> nodeTypes = globalSubstitutionServiceTemplate.getNode_types();
2457         if (!relatedNestedNodeTypeIds.contains(origNestedNodeTypeId)) {
2458             NodeType nested = DataModelUtil.getNodeType(globalSubstitutionServiceTemplate, origNestedNodeTypeId);
2459             setNewValuesForNestedNodeType(origNestedNodeTypeId, newNestedNodeTypeId, nested, nodeTypes);
2460         } else {
2461             NodeType nested = (NodeType) DataModelUtil
2462                 .getClonedObject(DataModelUtil.getNodeType(globalSubstitutionServiceTemplate, origNestedNodeTypeId));
2463             nested.setDerived_from(ToscaNodeType.VFC_ABSTRACT_SUBSTITUTE);
2464             nodeTypes.put(newNestedNodeTypeId, nested);
2465         }
2466         context.addUnifiedNestedNodeTypeId(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME, origNestedNodeTypeId, newNestedNodeTypeId);
2467     }
2468
2469     private void setNewValuesForNestedNodeType(String origNestedNodeType, String newNestedNodeTypeId, NodeType nested,
2470                                                Map<String, NodeType> nodeTypes) {
2471         if (Objects.nonNull(nested)) {
2472             nested.setDerived_from(ToscaNodeType.VFC_ABSTRACT_SUBSTITUTE);
2473             nodeTypes.remove(origNestedNodeType);
2474             nodeTypes.put(newNestedNodeTypeId, nested);
2475         }
2476     }
2477
2478     private Optional<String> getNewNestedNodeTypeId(ServiceTemplate nestedServiceTemplate, TranslationContext context) {
2479         FileComputeConsolidationData fileComputeConsolidationData = context.getConsolidationData().getComputeConsolidationData()
2480             .getFileComputeConsolidationData(ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate));
2481         if (Objects.nonNull(fileComputeConsolidationData)) {
2482             String nestedNodeTypePrefix = ToscaNodeType.ABSTRACT_NODE_TYPE_PREFIX + "heat.";
2483             return Optional.of(nestedNodeTypePrefix + getComputeTypeInNestedFile(fileComputeConsolidationData));
2484         }
2485         return Optional.empty();
2486     }
2487
2488     private String getComputeTypeInNestedFile(FileComputeConsolidationData fileComputeConsolidationData) {
2489         List<TypeComputeConsolidationData> typeComputeConsolidationDatas = new ArrayList<>(
2490             fileComputeConsolidationData.getAllTypeComputeConsolidationData());
2491         if (typeComputeConsolidationDatas.isEmpty()) {
2492             return null;
2493         } else {
2494             String computeNodeType = fileComputeConsolidationData.getAllComputeTypes().iterator().next();
2495             return getComputeTypeSuffix(computeNodeType);
2496         }
2497     }
2498
2499     private void handleGetAttrInAbstractNodeTemplate(ServiceTemplate serviceTemplate, TranslationContext context, String serviceTemplateFileName,
2500                                                      NodeTemplate abstractNodeTemplate) {
2501         Map<String, Object> properties =
2502             abstractNodeTemplate == null || abstractNodeTemplate.getProperties() == null ? new HashMap<>() : abstractNodeTemplate.getProperties();
2503         for (Object propertyValue : properties.values()) {
2504             List<List<Object>> getAttrList = extractGetAttrFunction(propertyValue);
2505             for (List<Object> getAttrFuncValue : getAttrList) {
2506                 String origNodeTemplateId = (String) getAttrFuncValue.get(0);
2507                 Optional<String> nestedNodeTemplateId = context
2508                     .getUnifiedNestedNodeTemplateId(ToscaUtil.getServiceTemplateFileName(serviceTemplate), origNodeTemplateId);
2509                 if (nestedNodeTemplateId.isPresent()) {
2510                     getAttrFuncValue.set(0, nestedNodeTemplateId.get());
2511                 } else {
2512                     replaceGetAttrNodeIdAndAttrName(serviceTemplate, context, serviceTemplateFileName, getAttrFuncValue);
2513                 }
2514             }
2515         }
2516     }
2517
2518     private void replaceGetAttrNodeIdAndAttrName(ServiceTemplate serviceTemplate, TranslationContext context, String serviceTemplateFileName,
2519                                                  List<Object> getAttrFuncValue) {
2520         String origNodeTemplateId = (String) getAttrFuncValue.get(0);
2521         String attributeName = (String) getAttrFuncValue.get(1);
2522         String unifiedAbstractNodeTemplateId = context.getUnifiedAbstractNodeTemplateId(serviceTemplate, origNodeTemplateId);
2523         if (Objects.isNull(unifiedAbstractNodeTemplateId)) {
2524             return;
2525         }
2526         String newNodeTemplateId = getNewNodeTemplateId(origNodeTemplateId, serviceTemplateFileName, serviceTemplate, context);
2527         String newSubstitutionOutputParameterId = getNewSubstitutionOutputParameterId(newNodeTemplateId, attributeName);
2528         getAttrFuncValue.set(0, unifiedAbstractNodeTemplateId);
2529         getAttrFuncValue.set(1, newSubstitutionOutputParameterId);
2530     }
2531
2532     private NodeTemplate getComputeNodeTemplate(String origNodeTemplateId, ServiceTemplate serviceTemplate, TranslationContext context) {
2533         NodeTemplate computeNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, origNodeTemplateId);
2534         if (computeNodeTemplate == null) {
2535             computeNodeTemplate = context.getCleanedNodeTemplate(ToscaUtil.getServiceTemplateFileName(serviceTemplate), origNodeTemplateId);
2536         }
2537         return computeNodeTemplate;
2538     }
2539
2540     private String handleIdOfPort(String origNodeTemplateId, String serviceTemplateFileName, ConsolidationData consolidationData) {
2541         Optional<Pair<String, ComputeTemplateConsolidationData>> computeTypeAndComputeTemplateByPortId = getComputeTypeAndComputeTemplateByPortId(
2542             origNodeTemplateId, serviceTemplateFileName, consolidationData);
2543         if (computeTypeAndComputeTemplateByPortId.isPresent()) {
2544             Pair<String, ComputeTemplateConsolidationData> computeIdToComputeData = computeTypeAndComputeTemplateByPortId.get();
2545             return getNewPortNodeTemplateId(origNodeTemplateId, computeIdToComputeData.getKey(), computeIdToComputeData.getValue());
2546         }
2547         return null;
2548     }
2549
2550     private Optional<Pair<String, ComputeTemplateConsolidationData>> getComputeTypeAndComputeTemplateByPortId(String portId,
2551                                                                                                               String serviceTemplateFileName,
2552                                                                                                               ConsolidationData consolidationData) {
2553         FileComputeConsolidationData fileComputeConsolidationData = consolidationData.getComputeConsolidationData()
2554             .getFileComputeConsolidationData(serviceTemplateFileName);
2555         Set<String> computeTypes = fileComputeConsolidationData.getAllComputeTypes();
2556         for (String computeType : computeTypes) {
2557             Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDatas = fileComputeConsolidationData
2558                 .getTypeComputeConsolidationData(computeType).getAllComputeTemplateConsolidationData();
2559             for (ComputeTemplateConsolidationData compute : computeTemplateConsolidationDatas) {
2560                 if (ConsolidationDataUtil.isComputeReferenceToPortId(compute, portId)) {
2561                     return Optional.of(new ImmutablePair<>(computeType, compute));
2562                 }
2563             }
2564         }
2565         return Optional.empty();
2566     }
2567
2568     private boolean isIdIsOfExpectedType(String id, UnifiedCompositionEntity expectedUnifiedCompositionEntity, String serviceTemplateFileName,
2569                                          TranslationContext context) {
2570         UnifiedSubstitutionData unifiedSubstitutionData = context.getUnifiedSubstitutionData().get(serviceTemplateFileName);
2571         if (Objects.isNull(unifiedSubstitutionData)) {
2572             return false;
2573         }
2574         UnifiedCompositionEntity actualUnifiedCompositionEntity = unifiedSubstitutionData.getCleanedNodeTemplateCompositionEntity(id);
2575         return actualUnifiedCompositionEntity == null ? false : actualUnifiedCompositionEntity.equals(expectedUnifiedCompositionEntity);
2576     }
2577
2578     private boolean isHeatStackGroup(String groupType) {
2579         return groupType.equals(ToscaGroupType.HEAT_STACK);
2580     }
2581
2582     private Object getPortPropertyValue(String inputName, String computeType, PropertyInputType portInputType, ServiceTemplate serviceTemplate,
2583                                         String portNodeTemplateId, PortTemplateConsolidationData portTemplateConsolidationData) {
2584         //Get the input prefix to extract the property name from the input name
2585         String portType = portTemplateConsolidationData.getPortType();
2586         String portInputPrefix = getPropertyInputPrefix(portNodeTemplateId, portType, portInputType, UnifiedCompositionEntity.PORT);
2587         //Get the property name from the input
2588         Optional<String> propertyName = getPropertyNameFromInput(inputName, UnifiedCompositionEntity.PORT, computeType, portInputPrefix);
2589         //Get the property value from the node template
2590         if (propertyName.isPresent()) {
2591             NodeTemplate portNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, portNodeTemplateId);
2592             if (Objects.nonNull(portNodeTemplate)) {
2593                 return getPropertyValueFromNodeTemplate(propertyName.get(), portNodeTemplate);
2594             }
2595         }
2596         return Optional.empty();
2597     }
2598
2599     private Object getComputePropertyValue(String inputName, ServiceTemplate serviceTemplate,
2600                                            ComputeTemplateConsolidationData computeTemplateConsolidationData) {
2601         NodeTemplate nodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId());
2602         String nodeType = getComputeTypeSuffix(nodeTemplate.getType());
2603         Optional<String> propertyName = getPropertyNameFromInput(inputName, COMPUTE, nodeType, null);
2604         if (propertyName.isPresent()) {
2605             return getPropertyValueFromNodeTemplate(propertyName.get(), nodeTemplate);
2606         }
2607         return Optional.empty();
2608     }
2609
2610     private Object getSubInterfacePropertyValue(String inputName, String subInterfaceTypeSuffix, PropertyInputType propertyInputType,
2611                                                 ServiceTemplate serviceTemplate, String subInterfaceNodeTemplateId) {
2612         //Get the input prefix to extract the property name from the input name
2613         String propertyInputPrefix = getPropertyInputPrefix(subInterfaceNodeTemplateId, subInterfaceTypeSuffix, propertyInputType,
2614             UnifiedCompositionEntity.SUB_INTERFACE);
2615         //Get the property name from the input
2616         Optional<String> propertyName = getPropertyNameFromInput(inputName, UnifiedCompositionEntity.SUB_INTERFACE, null, propertyInputPrefix);
2617         //Get the property value from the node template
2618         if (propertyName.isPresent()) {
2619             NodeTemplate subInterfaceNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, subInterfaceNodeTemplateId);
2620             if (Objects.nonNull(subInterfaceNodeTemplate)) {
2621                 return getPropertyValueFromNodeTemplate(propertyName.get(), subInterfaceNodeTemplate);
2622             }
2623         }
2624         return Optional.empty();
2625     }
2626
2627     private Optional<Object> getIdenticalPropertyValue(String identicalValuePropertyName, ServiceTemplate serviceTemplate,
2628                                                        EntityConsolidationData entity, TranslationContext context) {
2629         NodeTemplate nodeTemplate = getNodeTemplate(entity.getNodeTemplateId(), serviceTemplate, context);
2630         Object propertyValueFromNodeTemplate = getPropertyValueFromNodeTemplate(identicalValuePropertyName, nodeTemplate);
2631         return Objects.isNull(propertyValueFromNodeTemplate) ? Optional.empty() : Optional.of(propertyValueFromNodeTemplate);
2632     }
2633
2634     private UnifiedCompositionEntity getInputCompositionEntity(String inputName) {
2635         UnifiedCompositionEntity inputCompositionEntity = UnifiedCompositionEntity.OTHER;
2636         if (inputName.indexOf('_') != -1) {
2637             String inputType = inputName.substring(0, inputName.indexOf('_'));
2638             if (inputType.equalsIgnoreCase(COMPUTE.getDisplayName())) {
2639                 inputCompositionEntity = COMPUTE;
2640             } else if (inputType.equalsIgnoreCase(UnifiedCompositionEntity.PORT.getDisplayName())) {
2641                 inputCompositionEntity = UnifiedCompositionEntity.PORT;
2642             } else if (inputType.equalsIgnoreCase(UnifiedCompositionEntity.SUB_INTERFACE.getDisplayName())) {
2643                 inputCompositionEntity = UnifiedCompositionEntity.SUB_INTERFACE;
2644             }
2645         }
2646         return inputCompositionEntity;
2647     }
2648
2649     private Optional<String> getPropertyNameFromInput(String inputName, UnifiedCompositionEntity compositionEntity, String entityType,
2650                                                       String propertyInputPrefix) {
2651         String propertyName = null;
2652         switch (compositionEntity) {
2653             case COMPUTE:
2654                 propertyName = inputName.substring(inputName.lastIndexOf(entityType) + entityType.length() + 1);
2655                 break;
2656             case PORT:
2657             case SUB_INTERFACE:
2658                 if (inputName.startsWith(propertyInputPrefix)) {
2659                     propertyName = inputName.split(propertyInputPrefix)[1];
2660                 }
2661                 break;
2662             default:
2663                 break;
2664         }
2665         return Optional.ofNullable(propertyName);
2666     }
2667
2668     private String getPropertyInputPrefix(String nodeTemplateId, String propertyEntityType, PropertyInputType propertyInputType,
2669                                           UnifiedCompositionEntity unifiedCompositionEntity) {
2670         String propertyInputPrefix = unifiedCompositionEntity.getDisplayName().toLowerCase() + "_";
2671         if (propertyInputType == PropertyInputType.NODE_TEMPLATE_ID) {
2672             propertyInputPrefix += nodeTemplateId + "_";
2673         } else if (propertyInputType == PropertyInputType.TYPE) {
2674             propertyInputPrefix += propertyEntityType + "_";
2675         }
2676         return propertyInputPrefix;
2677     }
2678
2679     private boolean isIdenticalValueProperty(String inputName, UnifiedCompositionEntity unifiedCompositionEntity) {
2680         List<String> identicalValuePropertyList = consolidationService.getPropertiesWithIdenticalVal(unifiedCompositionEntity);
2681         StringBuilder builder = getPropertyValueStringBuilder(unifiedCompositionEntity);
2682         if (Objects.isNull(builder)) {
2683             return false;
2684         }
2685         boolean isMatchingProperty = Pattern.matches(builder.toString(), inputName);
2686         return isMatchingProperty && isPropertyFromIdenticalValuesList(inputName, unifiedCompositionEntity, identicalValuePropertyList);
2687     }
2688
2689     private boolean isPropertyFromIdenticalValuesList(String inputName, UnifiedCompositionEntity unifiedCompositionEntity,
2690                                                       List<String> identicalValuePropertyList) {
2691         switch (unifiedCompositionEntity) {
2692             case COMPUTE:
2693             case OTHER:
2694                 Optional<String> identicalValueProperty = getIdenticalValuePropertyName(inputName, unifiedCompositionEntity);
2695                 return identicalValueProperty.filter(identicalValuePropertyList::contains).isPresent();
2696             case PORT:
2697                 return getPortPropertyNameFromInput(inputName, identicalValuePropertyList).isPresent();
2698             default:
2699                 return false;
2700         }
2701     }
2702
2703     private Optional<String> getPortPropertyNameFromInput(String inputName, List<String> identicalValuePropertyList) {
2704         for (String identicalProperty : identicalValuePropertyList) {
2705             if (inputName.endsWith(identicalProperty)) {
2706                 return Optional.of(identicalProperty);
2707             }
2708         }
2709         return Optional.empty();
2710     }
2711
2712     private StringBuilder getPropertyValueStringBuilder(UnifiedCompositionEntity unifiedCompositionEntity) {
2713         switch (unifiedCompositionEntity) {
2714             case COMPUTE:
2715                 return getComputePropertyValueStringBuilder();
2716             case OTHER:
2717                 return getComputePropertyValueStringBuilder();
2718             case PORT:
2719                 return getPortPropertyValueStringBuilder();
2720             case SUB_INTERFACE:
2721                 return getSubInterfacePropertyValueStringBuilder();
2722             default:
2723                 return null;
2724         }
2725     }
2726
2727     private StringBuilder getPortPropertyValueStringBuilder() {
2728         StringBuilder builder;
2729         builder = new StringBuilder(PORT_IDENTICAL_VALUE_PROPERTY_PREFIX);
2730         builder.append(".+");
2731         return builder;
2732     }
2733
2734     private StringBuilder getComputePropertyValueStringBuilder() {
2735         StringBuilder builder;
2736         builder = new StringBuilder(COMPUTE_IDENTICAL_VALUE_PROPERTY_PREFIX);
2737         builder.append("[a-z]+");
2738         builder.append(COMPUTE_IDENTICAL_VALUE_PROPERTY_SUFFIX);
2739         return builder;
2740     }
2741
2742     private StringBuilder getSubInterfacePropertyValueStringBuilder() {
2743         StringBuilder builder;
2744         builder = new StringBuilder(SUB_INTERFACE_PROPERTY_VALUE_PREFIX);
2745         builder.append(".+");
2746         return builder;
2747     }
2748
2749     private Optional<String> getIdenticalValuePropertyName(String input, UnifiedCompositionEntity unifiedCompositionEntity) {
2750         switch (unifiedCompositionEntity) {
2751             case COMPUTE:
2752                 return Optional.of(input.split("_")[1]);
2753             case OTHER:
2754                 return Optional.of(input.split("_")[1]);
2755             case PORT:
2756                 return getPortPropertyNameFromInput(input, consolidationService.getPropertiesWithIdenticalVal(unifiedCompositionEntity));
2757             default:
2758                 return Optional.empty();
2759         }
2760     }
2761
2762     private Object getPropertyValueFromNodeTemplate(String propertyName, NodeTemplate nodeTemplate) {
2763         Map<String, Object> nodeTemplateProperties = nodeTemplate.getProperties();
2764         if (nodeTemplateProperties != null) {
2765             Object propertyValue;
2766             if (propertyName.startsWith(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME)) {
2767                 propertyValue = getServiceTemplateFilterPropertyValue(propertyName, nodeTemplateProperties);
2768             } else {
2769                 propertyValue = nodeTemplateProperties.get(propertyName);
2770                 propertyValue = getClonedObject(propertyValue);
2771             }
2772             return propertyValue;
2773         }
2774         return null;
2775     }
2776
2777     private Object getServiceTemplateFilterPropertyValue(String propertyName, Map<String, Object> nodeTemplateProperties) {
2778         Object propertyValue = null;
2779         Object serviceTemplateFilterProperties = nodeTemplateProperties.get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
2780         String serviceTemplateFilterPropertyName = propertyName.replace(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME + "_", "");
2781         if (Objects.nonNull(serviceTemplateFilterProperties) && serviceTemplateFilterProperties instanceof Map) {
2782             propertyValue = ((Map<String, Object>) serviceTemplateFilterProperties).get(serviceTemplateFilterPropertyName);
2783         }
2784         return propertyValue;
2785     }
2786
2787     private Map<String, UnifiedCompositionEntity> getAllConsolidationNodeTemplateIdAndType(List<UnifiedCompositionData> unifiedCompositionDataList) {
2788         Map<String, UnifiedCompositionEntity> consolidationNodeTemplateIdAndType = new HashMap<>();
2789         for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
2790             ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData.getComputeTemplateConsolidationData();
2791             if (Objects.nonNull(computeTemplateConsolidationData)) {
2792                 consolidationNodeTemplateIdAndType.put(computeTemplateConsolidationData.getNodeTemplateId(), COMPUTE);
2793             }
2794             List<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationDataList = getSubInterfaceTemplateConsolidationDataList(
2795                 unifiedCompositionData);
2796             for (SubInterfaceTemplateConsolidationData subInterfaceTemplateConsolidationData : subInterfaceTemplateConsolidationDataList) {
2797                 consolidationNodeTemplateIdAndType
2798                     .put(subInterfaceTemplateConsolidationData.getNodeTemplateId(), UnifiedCompositionEntity.SUB_INTERFACE);
2799             }
2800             List<PortTemplateConsolidationData> portTemplateConsolidationDataList = getPortTemplateConsolidationDataList(unifiedCompositionData);
2801             for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) {
2802                 consolidationNodeTemplateIdAndType.put(portTemplateConsolidationData.getNodeTemplateId(), UnifiedCompositionEntity.PORT);
2803             }
2804             NestedTemplateConsolidationData nestedTemplateConsolidationData = unifiedCompositionData.getNestedTemplateConsolidationData();
2805             if (Objects.nonNull(nestedTemplateConsolidationData)) {
2806                 consolidationNodeTemplateIdAndType.put(nestedTemplateConsolidationData.getNodeTemplateId(), UnifiedCompositionEntity.NESTED);
2807             }
2808         }
2809         return consolidationNodeTemplateIdAndType;
2810     }
2811
2812     private List<PortTemplateConsolidationData> getPortTemplateConsolidationDataList(UnifiedCompositionData unifiedCompositionData) {
2813         return unifiedCompositionData.getPortTemplateConsolidationDataList() == null ? new ArrayList<>()
2814             : unifiedCompositionData.getPortTemplateConsolidationDataList();
2815     }
2816
2817     private enum PropertyInputType {NODE_TEMPLATE_ID, TYPE, OTHER}
2818 }