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