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