185316dad7e474ff741cd57cd194c311a7f5ae9e
[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, context);
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, context);
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                                          TranslationContext context) {
1819     if(parameterId.isPresent() &&
1820         isParameterBelongsToEnrichedPortProperties(parameterId.get(), context)){
1821       addInputParameter(parameterId.get(),
1822           propertyType,
1823           propertyType.equals(PropertyType.LIST.getDisplayName()) ? entrySchema : null ,
1824           substitutionServiceTemplate);
1825     }
1826     else if (isPropertySimpleType(propertyType)) {
1827       parameterId
1828           .ifPresent(parameterIdValue -> addInputParameter(parameterIdValue,
1829               PropertyType.LIST.getDisplayName(),
1830               DataModelUtil
1831                   .createEntrySchema(propertyType.toLowerCase(), null, null),
1832               substitutionServiceTemplate));
1833
1834     } else if(propertyType.equals(PropertyTypeExt.JSON.getDisplayName()) ||
1835         (Objects.nonNull(entrySchema) && isPropertySimpleType(entrySchema.getType()))) {
1836       parameterId
1837           .ifPresent(parameterIdValue -> addInputParameter(parameterIdValue,
1838               PropertyType.LIST.getDisplayName(),
1839               DataModelUtil
1840                   .createEntrySchema(PropertyTypeExt.JSON.getDisplayName(), null, null),
1841               substitutionServiceTemplate));
1842     } else {
1843       parameterId
1844           .ifPresent(parameterIdValue -> addInputParameter(parameterIdValue,
1845               analyzeParameterType(propertyType),
1846               DataModelUtil
1847                   .createEntrySchema(analyzeEntrySchemaType(propertyType, entrySchema),
1848                       null, null),
1849               substitutionServiceTemplate));
1850     }
1851   }
1852
1853   private boolean isParameterBelongsToEnrichedPortProperties(String parameterId,
1854                                                              TranslationContext context){
1855     List enrichPortResourceProperties = context.getEnrichPortResourceProperties();
1856
1857     for(int i = 0; i < enrichPortResourceProperties.size(); i++){
1858       if(parameterId.contains((CharSequence) enrichPortResourceProperties.get(i))){
1859         return true;
1860       }
1861     }
1862
1863     return false;
1864   }
1865
1866   private boolean isPropertySimpleType(String propertyType) {
1867     return !Objects.isNull(propertyType) &&
1868         (propertyType.equalsIgnoreCase(PropertyType.STRING.getDisplayName())
1869         || propertyType.equalsIgnoreCase(PropertyType.INTEGER.getDisplayName())
1870         || propertyType.equalsIgnoreCase(PropertyType.FLOAT.getDisplayName())
1871         || propertyType.equalsIgnoreCase(PropertyType.BOOLEAN.getDisplayName()));
1872   }
1873
1874   private String analyzeParameterType(String propertyType) {
1875     return propertyType.equalsIgnoreCase(PropertyType.LIST.getDisplayName()) ? PropertyType.LIST
1876         .getDisplayName() : propertyType;
1877   }
1878
1879   private String analyzeEntrySchemaType(String propertyType, EntrySchema entrySchema) {
1880     return propertyType.equalsIgnoreCase(PropertyType.LIST.getDisplayName()) ?
1881         entrySchema.getType() : null;
1882   }
1883
1884   private void handleConsolidationEntitiesRequirementConnectivity(String nodeTemplateId,
1885                                                                   NodeTemplate nodeTemplate,
1886                                                                   ServiceTemplate
1887                                                                       substitutionServiceTemplate,
1888                                                                   TranslationContext context) {
1889     Map<String, RequirementAssignment> updatedNodeTemplateRequirements = new HashMap<>();
1890     List<Map<String, RequirementAssignment>> nodeTemplateRequirements = DataModelUtil
1891         .getNodeTemplateRequirementList(nodeTemplate);
1892     if (CollectionUtils.isEmpty(nodeTemplateRequirements)) {
1893       return;
1894     }
1895
1896     for (Map<String, RequirementAssignment> requirement : nodeTemplateRequirements) {
1897       for (Map.Entry<String, RequirementAssignment> entry : requirement.entrySet()) {
1898         RequirementAssignment requirementAssignment = entry.getValue();
1899         String requirementNode = requirementAssignment.getNode();
1900         String unifiedNodeTemplateId =
1901             context.getUnifiedSubstitutionNodeTemplateId(substitutionServiceTemplate,
1902                 requirementNode);
1903         if (unifiedNodeTemplateId != null) {
1904           //Update the node id in the requirement
1905           requirementAssignment.setNode(unifiedNodeTemplateId);
1906         }
1907       }
1908     }
1909     nodeTemplate.setRequirements(nodeTemplateRequirements);
1910   }
1911
1912   /**
1913    * Update the node references in the volume relationship templates.
1914    *
1915    * @param serviceTemplate the service template
1916    * @param context         the context
1917    */
1918   private void updateVolumeRelationshipTemplate(ServiceTemplate serviceTemplate,
1919                                                 String relationshipId,
1920                                                 TranslationContext context) {
1921     Map<String, RelationshipTemplate> relationshipTemplates = DataModelUtil
1922         .getRelationshipTemplates(serviceTemplate);
1923     if (relationshipTemplates != null) {
1924       RelationshipTemplate relationshipTemplate = relationshipTemplates.get(relationshipId);
1925       if (relationshipTemplate != null) {
1926         String relationshipTemplateType = relationshipTemplate.getType();
1927         if (relationshipTemplateType.equals(ToscaRelationshipType.CINDER_VOLUME_ATTACHES_TO)) {
1928           handleCinderVolumeAttachmentRelationshipTemplate(serviceTemplate,
1929               relationshipTemplate, context);
1930         }
1931       }
1932     }
1933   }
1934
1935
1936   private void handleCinderVolumeAttachmentRelationshipTemplate(ServiceTemplate
1937                                                                     substitutionServiceTemplate,
1938                                                                 RelationshipTemplate
1939                                                                     relationshipTemplate,
1940                                                                 TranslationContext context) {
1941     Map<String, Object> properties = relationshipTemplate.getProperties();
1942     properties.computeIfPresent(HeatConstants.INSTANCE_UUID_PROPERTY_NAME, (key, value) ->
1943         context.getUnifiedAbstractNodeTemplateId(substitutionServiceTemplate,
1944             (String) value));
1945   }
1946
1947   private String updateIdenticalProperty(String nodeTemplateId, String propertyId,
1948                                          NodeTemplate nodeTemplate,
1949                                          UnifiedCompositionEntity unifiedCompositionEntity,
1950                                          List<UnifiedCompositionData> unifiedCompositionDataList) {
1951
1952     String inputParamId;
1953     Map<String, Object> propertyVal = new HashMap<>();
1954
1955     switch (unifiedCompositionEntity) {
1956       case Compute:
1957         inputParamId = COMPUTE_IDENTICAL_VALUE_PROPERTY_PREFIX + propertyId
1958             + COMPUTE_IDENTICAL_VALUE_PROPERTY_SUFFIX;
1959
1960         propertyVal.put(ToscaFunctions.GET_INPUT.getDisplayName(), inputParamId);
1961         nodeTemplate.getProperties().put(propertyId, propertyVal);
1962
1963         return inputParamId;
1964
1965       case Port:
1966         String portType = ConsolidationDataUtil.getPortType(nodeTemplateId);
1967         ComputeTemplateConsolidationData computeTemplateConsolidationData =
1968             getConnectedComputeConsolidationData(unifiedCompositionDataList, nodeTemplateId);
1969         inputParamId = getInputParamIdForPort(nodeTemplateId, propertyId, portType,
1970             computeTemplateConsolidationData);
1971
1972         propertyVal.put(ToscaFunctions.GET_INPUT.getDisplayName(), inputParamId);
1973         nodeTemplate.getProperties().put(propertyId, propertyVal);
1974
1975         return inputParamId;
1976
1977       default:
1978         return null;
1979     }
1980   }
1981
1982   private String getInputParamIdForPort(String nodeTemplateId, String propertyId, String portType,
1983                                         ComputeTemplateConsolidationData computeTemplateConsolidationData) {
1984     String inputParamId;
1985     if (Objects.isNull(computeTemplateConsolidationData)
1986         || computeTemplateConsolidationData.getPorts().get(portType).size() > 1) {
1987       inputParamId =
1988           UnifiedCompositionEntity.Port.name().toLowerCase() + "_" + nodeTemplateId + "_" +
1989               propertyId;
1990
1991     } else {
1992       inputParamId =
1993           UnifiedCompositionEntity.Port.name().toLowerCase() + "_" + portType + "_"
1994               + propertyId;
1995     }
1996     return inputParamId;
1997   }
1998
1999   private void addInputParameter(String parameterId,
2000                                  String parameterType,
2001                                  EntrySchema entrySchema,
2002                                  ServiceTemplate serviceTemplate) {
2003
2004     ParameterDefinition parameterDefinition = DataModelUtil.createParameterDefinition
2005         (parameterType, null, null,
2006             true, null, null,
2007             entrySchema, null);
2008
2009
2010     DataModelUtil
2011         .addInputParameterToTopologyTemplate(serviceTemplate, parameterId, parameterDefinition);
2012   }
2013
2014   // Return the input parameter Id which is used in the new property value if there is one
2015   private Optional<String> updateProperty(
2016       ServiceTemplate serviceTemplate,
2017       String nodeTemplateId, NodeTemplate nodeTemplate,
2018       Map.Entry<String, Object> propertyEntry,
2019       UnifiedCompositionEntity compositionEntity,
2020       ComputeTemplateConsolidationData computeTemplateConsolidationData,
2021       List<UnifiedCompositionData> unifiedCompositionDataList,
2022       TranslationContext context) {
2023
2024     if (handleGetAttrFromConsolidationNodes(serviceTemplate, nodeTemplate, propertyEntry,
2025         unifiedCompositionDataList, context)) {
2026       return Optional.empty();
2027     }
2028     String inputParamId =
2029         getParameterId(nodeTemplateId, nodeTemplate, propertyEntry.getKey(), compositionEntity,
2030             computeTemplateConsolidationData);
2031     Map<String, List<String>> propertyVal = getPropertyValueInputParam(nodeTemplateId,
2032         nodeTemplate, inputParamId);
2033     nodeTemplate.getProperties().put(propertyEntry.getKey(), propertyVal);
2034     return Optional.of(inputParamId);
2035   }
2036
2037   private Map<String, List<String>> getPropertyValueInputParam(String nodeTemplateId,
2038                                                                NodeTemplate nodeTemplate,
2039                                                                String inputParamId) {
2040     Map<String, List<String>> propertyVal = new HashMap<>();
2041     List<String> getInputFuncParams = new ArrayList<>();
2042     getInputFuncParams.add(inputParamId);
2043     getInputFuncParams.add(ToscaConstants.INDEX_VALUE_PROPERTY_NAME);
2044     propertyVal.put(ToscaFunctions.GET_INPUT.getDisplayName(), getInputFuncParams);
2045     return propertyVal;
2046   }
2047
2048   private boolean handleGetAttrFromConsolidationNodes(
2049       ServiceTemplate serviceTemplate,
2050       NodeTemplate nodeTemplate,
2051       Map.Entry<String, Object> propertyEntry,
2052       List<UnifiedCompositionData> unifiedCompositionDataList,
2053       TranslationContext context) {
2054     Map<String, UnifiedCompositionEntity> consolidationNodeTemplateIdAndType =
2055         getAllConsolidationNodeTemplateIdAndType(unifiedCompositionDataList);
2056
2057     Set<String> consolidationNodeTemplateIds = consolidationNodeTemplateIdAndType.keySet();
2058     boolean includeGetAttrFromConsolidationNodes = false;
2059     boolean includeGetAttrFromOutsideNodes = false;
2060     List<List<Object>> getAttrFunctionList = extractGetAttrFunction(propertyEntry.getValue());
2061     for (List<Object> getAttrFunc : getAttrFunctionList) {
2062       if (consolidationNodeTemplateIds.contains(getAttrFunc.get(0))) {
2063         includeGetAttrFromConsolidationNodes = true;
2064       } else {
2065         includeGetAttrFromOutsideNodes = true;
2066       }
2067     }
2068     if ((includeGetAttrFromConsolidationNodes && includeGetAttrFromOutsideNodes)
2069         ||
2070         (includeGetAttrFromConsolidationNodes && isIncludeToscaFunc(propertyEntry.getValue(),
2071             ToscaFunctions.GET_INPUT))) {
2072       //This case is currently not supported - this property will be ignored
2073       return true;
2074     } else if (includeGetAttrFromConsolidationNodes) {
2075       Object clonedPropertyValue = getClonedPropertyValue(propertyEntry);
2076       List<List<Object>> clonedGetAttrFuncList = extractGetAttrFunction(clonedPropertyValue);
2077       for (List<Object> getAttrFunc : clonedGetAttrFuncList) {
2078         String targetNodeTemplateId = (String) getAttrFunc.get(0);
2079         if (consolidationNodeTemplateIds.contains(targetNodeTemplateId)) {
2080           updatePropertyGetAttrFunc(serviceTemplate, unifiedCompositionDataList, context,
2081               consolidationNodeTemplateIdAndType, targetNodeTemplateId, getAttrFunc);
2082         }
2083       }
2084       nodeTemplate.getProperties().put(propertyEntry.getKey(), clonedPropertyValue);
2085       return true;
2086     }
2087     return false;
2088   }
2089
2090   private void updatePropertyGetAttrFunc(
2091       ServiceTemplate serviceTemplate,
2092       List<UnifiedCompositionData> unifiedCompositionDataList,
2093       TranslationContext context,
2094       Map<String, UnifiedCompositionEntity> consolidationNodeTemplateIdAndType,
2095       String targetNodeTemplateId,
2096       List<Object> getAttrFunc) {
2097     UnifiedCompositionEntity targetCompositionEntity =
2098         consolidationNodeTemplateIdAndType.get(targetNodeTemplateId);
2099     String targetNewNodeTemplateId =
2100         getNewNodeTemplateId(serviceTemplate, unifiedCompositionDataList, targetNodeTemplateId,
2101             targetCompositionEntity);
2102     getAttrFunc.set(0, targetNewNodeTemplateId);
2103   }
2104
2105   private String getNewNodeTemplateId(ServiceTemplate serviceTemplate,
2106                                       List<UnifiedCompositionData> unifiedCompositionDataList,
2107                                       String nodeTemplateId,
2108                                       UnifiedCompositionEntity compositionEntity) {
2109     switch (compositionEntity) {
2110       case Compute:
2111         return getNewComputeNodeTemplateId(serviceTemplate, nodeTemplateId);
2112       case Port:
2113         ComputeTemplateConsolidationData connectedComputeConsolidationData =
2114             getConnectedComputeConsolidationData(
2115                 unifiedCompositionDataList, nodeTemplateId);
2116         NodeTemplate connectedComputeNodeTemplate =
2117             DataModelUtil.getNodeTemplate(serviceTemplate,
2118                 connectedComputeConsolidationData.getNodeTemplateId());
2119         return getNewPortNodeTemplateId(nodeTemplateId, connectedComputeNodeTemplate.getType(),
2120             connectedComputeConsolidationData);
2121       default:
2122         return null;
2123     }
2124   }
2125
2126   private String getNewNodeTemplateId(String origNodeTemplateId,
2127                                       String serviceTemplateFileName,
2128                                       ServiceTemplate serviceTemplate,
2129                                       TranslationContext context) {
2130     ConsolidationData consolidationData = context.getConsolidationData();
2131
2132     if (isIdIsOfExpectedType(origNodeTemplateId, UnifiedCompositionEntity.Port,
2133         serviceTemplateFileName,
2134         context)) {
2135       return handleIdOfPort(origNodeTemplateId, serviceTemplateFileName, consolidationData);
2136     } else if (isIdIsOfExpectedType(origNodeTemplateId, UnifiedCompositionEntity.Compute,
2137         serviceTemplateFileName, context)) {
2138       NodeTemplate nodeTemplate =
2139           getComputeNodeTemplate(origNodeTemplateId, serviceTemplate, context);
2140       return getComputeTypeSuffix(nodeTemplate.getType());
2141     }
2142
2143     return null;
2144   }
2145
2146   private ComputeTemplateConsolidationData getConnectedComputeConsolidationData(
2147       List<UnifiedCompositionData> unifiedCompositionDataList,
2148       String portNodeTemplateId) {
2149     for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
2150       Collection<List<String>> portsCollection =
2151           unifiedCompositionData.getComputeTemplateConsolidationData().getPorts().values();
2152       for (List<String> portIdList : portsCollection) {
2153         if (portIdList.contains(portNodeTemplateId)) {
2154           return unifiedCompositionData.getComputeTemplateConsolidationData();
2155         }
2156 //        for (String portId : portIdList) {
2157 //          if (portId.equals(portNodeTemplateId)) {
2158 //            return unifiedCompositionData.getComputeTemplateConsolidationData();
2159 //          }
2160 //        }
2161       }
2162     }
2163     return null;
2164   }
2165
2166   private Object getClonedPropertyValue(Map.Entry<String, Object> propertyEntry) {
2167     if (propertyEntry.getValue() instanceof Map) {
2168       return getClonedObject(propertyEntry.getValue(), Map.class);
2169     } else if (propertyEntry.getValue() instanceof List) {
2170       return getClonedObject(propertyEntry.getValue(), List.class);
2171     }
2172     return propertyEntry.getValue();
2173   }
2174
2175
2176   private String getParameterId(String nodeTemplateId, NodeTemplate nodeTemplate, String propertyId,
2177                                 UnifiedCompositionEntity unifiedCompositionEntity,
2178                                 ComputeTemplateConsolidationData computeTemplateConsolidationData) {
2179     switch (unifiedCompositionEntity) {
2180       case Compute:
2181         return UnifiedCompositionEntity.Compute.name().toLowerCase() + "_"
2182             + getComputeTypeSuffix(nodeTemplate.getType()) + "_" + propertyId;
2183       case Port:
2184         String portType = ConsolidationDataUtil.getPortType(nodeTemplateId);
2185         if (Objects.isNull(computeTemplateConsolidationData)
2186             || computeTemplateConsolidationData.getPorts().get(portType).size() > 1) {
2187           return UnifiedCompositionEntity.Port.name().toLowerCase() + "_" + nodeTemplateId + "_"
2188               + propertyId;
2189         }
2190         return UnifiedCompositionEntity.Port.name().toLowerCase() + "_" + portType + "_"
2191             + propertyId;
2192       default:
2193         return propertyId;
2194     }
2195   }
2196
2197   private void removeConnectivityOut(EntityConsolidationData entityConsolidationData,
2198                                      NodeTemplate nodeTemplate) {
2199     if (MapUtils.isEmpty(entityConsolidationData.getNodesConnectedOut())) {
2200       return;
2201     }
2202
2203     for (List<RequirementAssignmentData> requirementAssignmentDataList : entityConsolidationData
2204         .getNodesConnectedOut().values()) {
2205       for (RequirementAssignmentData requirementAssignmentData : requirementAssignmentDataList) {
2206         DataModelUtil.removeRequirementsAssignment(nodeTemplate.getRequirements(),
2207             requirementAssignmentData.getRequirementId());
2208       }
2209       if (nodeTemplate.getRequirements().isEmpty()) {
2210         nodeTemplate.setRequirements(null);
2211       }
2212     }
2213   }
2214
2215   private void removeVolumeConnectivity(
2216       ComputeTemplateConsolidationData computeTemplateConsolidationData,
2217       NodeTemplate computeNodeTemplate) {
2218     if (MapUtils.isEmpty(computeTemplateConsolidationData.getVolumes())) {
2219       return;
2220     }
2221     Collection<List<RequirementAssignmentData>> volumeCollection =
2222         computeTemplateConsolidationData.getVolumes().values();
2223     for (List<RequirementAssignmentData> requirementAssignmentDataList : volumeCollection) {
2224       for (RequirementAssignmentData requirementAssignmentData : requirementAssignmentDataList) {
2225         DataModelUtil.removeRequirementsAssignment(computeNodeTemplate.getRequirements(),
2226             requirementAssignmentData.getRequirementId());
2227       }
2228     }
2229     if (computeNodeTemplate.getRequirements().isEmpty()) {
2230       computeNodeTemplate.setRequirements(null);
2231     }
2232   }
2233
2234   private void createIndexInputParameter(ServiceTemplate substitutionServiceTemplate) {
2235     ParameterDefinition indexParameterDefinition =
2236         DataModelUtil.createParameterDefinition(PropertyType.INTEGER.getDisplayName(),
2237             "Index value of this substitution service template runtime instance", null,
2238             false, createIndexValueConstraint(), null, null, 0);
2239     DataModelUtil.addInputParameterToTopologyTemplate(substitutionServiceTemplate,
2240         ToscaConstants.INDEX_VALUE_PROPERTY_NAME, indexParameterDefinition);
2241   }
2242
2243
2244   private List<Constraint> createIndexValueConstraint() {
2245     List<Constraint> constraints;
2246     constraints = new ArrayList<>();
2247     Constraint constraint = new Constraint();
2248     constraint.setGreater_or_equal(0);
2249     constraints.add(constraint);
2250     return constraints;
2251   }
2252
2253   private Optional<UnifiedComposition> getUnifiedCompositionInstance(UnifiedCompositionMode mode) {
2254     String unifiedCompositionImplClassName =
2255         unifiedCompositionImplMap.get(mode.name()).getImplementationClass();
2256     if (StringUtils.isEmpty(unifiedCompositionImplClassName)) {
2257       return Optional.empty();
2258     }
2259     return Optional
2260         .of(CommonMethods.newInstance(unifiedCompositionImplClassName, UnifiedComposition.class));
2261   }
2262
2263   private Optional<Map<String, Object>> createAbstractSubstitutionProperties(
2264       ServiceTemplate serviceTemplate,
2265       ServiceTemplate substitutionServiceTemplate,
2266       List<UnifiedCompositionData> unifiedCompositionDataList,
2267       TranslationContext context) {
2268     Map<String, Object> abstractSubstituteProperties = new LinkedHashMap<>();
2269     Map<String, ParameterDefinition> substitutionTemplateInputs = DataModelUtil
2270         .getInputParameters(substitutionServiceTemplate);
2271     if (substitutionTemplateInputs == null) {
2272       return Optional.empty();
2273     }
2274     //Since all the computes have the same type fetching the type from the first entry
2275     NodeTemplate firstComputeNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate,
2276         unifiedCompositionDataList.get(0)
2277             .getComputeTemplateConsolidationData().getNodeTemplateId());
2278     String computeType = getComputeTypeSuffix(firstComputeNodeTemplate.getType());
2279     for (Map.Entry<String, ParameterDefinition> input : substitutionTemplateInputs.entrySet()) {
2280       String substitutionTemplateInputName = input.getKey();
2281       ParameterDefinition inputParameterDefinition = input.getValue();
2282       String inputType = inputParameterDefinition.getType();
2283       UnifiedCompositionEntity inputUnifiedCompositionEntity =
2284           getInputCompositionEntity(substitutionTemplateInputName);
2285
2286       if (!inputType.equalsIgnoreCase(PropertyType.LIST.getDisplayName())) {
2287         if (isIdenticalValueProperty(
2288             substitutionTemplateInputName, inputUnifiedCompositionEntity, context)) {
2289           //Handle identical value properties
2290           Optional<String> identicalValuePropertyName =
2291               getIdenticalValuePropertyName(substitutionTemplateInputName,
2292                   inputUnifiedCompositionEntity, context);
2293
2294           if (identicalValuePropertyName.isPresent()) {
2295             updateIdenticalPropertyValue(identicalValuePropertyName.get(),
2296                 substitutionTemplateInputName, computeType, inputUnifiedCompositionEntity,
2297                 unifiedCompositionDataList.get(0), serviceTemplate, abstractSubstituteProperties,
2298                 context);
2299           }
2300         }
2301         continue;
2302       }
2303
2304       //Check if the input is of type compute or port
2305       List<Object> abstractPropertyValue = new ArrayList<>();
2306       Object propertyValue = null;
2307       switch (inputUnifiedCompositionEntity) {
2308         case Compute:
2309           for (UnifiedCompositionData compositionData : unifiedCompositionDataList) {
2310             ComputeTemplateConsolidationData computeTemplateConsolidationData =
2311                 compositionData.getComputeTemplateConsolidationData();
2312             propertyValue = getComputePropertyValue(substitutionTemplateInputName,
2313                 serviceTemplate, computeTemplateConsolidationData);
2314             if (!(propertyValue instanceof Optional)) {
2315               abstractPropertyValue.add(propertyValue);
2316             }
2317           }
2318           break;
2319         case Port:
2320           for (UnifiedCompositionData compositionData : unifiedCompositionDataList) {
2321             List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
2322                 getPortTemplateConsolidationDataList(compositionData);
2323             //Get the input type for this input whether it is of type
2324             // port_<port_node_template_id>_<property_name> or port_<port_type>_<property_name>
2325             PortInputType portInputType = getPortInputType(substitutionTemplateInputName,
2326                 compositionData);
2327             for (PortTemplateConsolidationData portTemplateConsolidationData :
2328                 portTemplateConsolidationDataList) {
2329               //Get the port property value
2330               String portNodeTemplateId = portTemplateConsolidationData.getNodeTemplateId();
2331               propertyValue = getPortPropertyValue(substitutionTemplateInputName,
2332                   computeType, portInputType, serviceTemplate,
2333                   portNodeTemplateId);
2334               //If the value object is Optional.empty it implies that the property name was not
2335               // found in the input name
2336               if (!(propertyValue instanceof Optional)) {
2337                 if(!abstractPropertyValue.contains(propertyValue)) {
2338                   abstractPropertyValue.add(propertyValue);
2339                 }
2340               }
2341             }
2342           }
2343           break;
2344         default:
2345           break;
2346       }
2347       //Add the property only if it has at least one non-null value
2348       for (Object val : abstractPropertyValue) {
2349         if (Objects.nonNull(val)) {
2350           updateAbstractPropertyValue(substitutionTemplateInputName, inputParameterDefinition,
2351               abstractPropertyValue, abstractSubstituteProperties);
2352           break;
2353         }
2354       }
2355     }
2356     return Optional.ofNullable(abstractSubstituteProperties);
2357   }
2358
2359   private void updateAbstractPropertyValue(String substitutionTemplateInputName,
2360                                            ParameterDefinition parameterDefinition,
2361                                            List<Object> abstractPropertyValue,
2362                                            Map<String, Object> abstractSubstituteProperties) {
2363     if(abstractPropertyValue.size() > 1) {
2364       abstractSubstituteProperties.put(substitutionTemplateInputName, abstractPropertyValue);
2365     } else {
2366       Object propertyValue = abstractPropertyValue.get(0);
2367       String entrySchemaType = parameterDefinition.getEntry_schema().getType();
2368       if(entrySchemaType.equalsIgnoreCase(PropertyType.STRING.getDisplayName())
2369           || entrySchemaType.equalsIgnoreCase(PropertyType.INTEGER.getDisplayName())
2370           || entrySchemaType.equalsIgnoreCase(PropertyType.FLOAT.getDisplayName())
2371           || entrySchemaType.equalsIgnoreCase(PropertyType.BOOLEAN.getDisplayName())
2372           || entrySchemaType.equals(PropertyTypeExt.JSON.getDisplayName())){
2373         abstractSubstituteProperties.put(substitutionTemplateInputName, abstractPropertyValue);
2374       } else {
2375         abstractSubstituteProperties.put(substitutionTemplateInputName, propertyValue);
2376       }
2377     }
2378   }
2379
2380   private void updateIdenticalPropertyValue(String identicalValuePropertyName,
2381                                             String substitutionTemplateInputName,
2382                                             String computeType,
2383                                             UnifiedCompositionEntity entity,
2384                                             UnifiedCompositionData unifiedCompositionData,
2385                                             ServiceTemplate serviceTemplate,
2386                                             Map<String, Object> abstractSubstituteProperties,
2387                                             TranslationContext context) {
2388     Optional<Object> identicalPropertyValueByType =
2389         getIdenticalPropertyValueByType(identicalValuePropertyName, substitutionTemplateInputName,
2390             entity, unifiedCompositionData, serviceTemplate, context);
2391
2392     if (identicalPropertyValueByType.isPresent()) {
2393       abstractSubstituteProperties
2394           .put(substitutionTemplateInputName, identicalPropertyValueByType.get());
2395
2396     }
2397
2398
2399   }
2400
2401   private Optional<Object> getIdenticalPropertyValueByType(String identicalValuePropertyName,
2402                                                            String substitutionTemplateInputName,
2403                                                            UnifiedCompositionEntity entity,
2404                                                            UnifiedCompositionData unifiedCompositionData,
2405                                                            ServiceTemplate serviceTemplate,
2406                                                            TranslationContext context) {
2407
2408     ComputeTemplateConsolidationData computeTemplateConsolidationData =
2409         unifiedCompositionData.getComputeTemplateConsolidationData();
2410
2411     Optional<Object> computeIdenticalPropertyValue;
2412     switch (entity) {
2413       case Compute:
2414         computeIdenticalPropertyValue =
2415             getIdenticalPropertyValue(identicalValuePropertyName, serviceTemplate,
2416                 entity, computeTemplateConsolidationData, context);
2417         return computeIdenticalPropertyValue.isPresent() ? Optional.of(
2418             computeIdenticalPropertyValue.get()) : Optional.empty();
2419
2420       case Other:
2421         computeIdenticalPropertyValue =
2422             getIdenticalPropertyValue(identicalValuePropertyName, serviceTemplate,
2423                 entity, computeTemplateConsolidationData, context);
2424         return computeIdenticalPropertyValue.isPresent() ? Optional.of(
2425             computeIdenticalPropertyValue.get()) : Optional.empty();
2426
2427       case Port:
2428         List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
2429             unifiedCompositionData.getPortTemplateConsolidationDataList();
2430         for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) {
2431           String portType =
2432               ConsolidationDataUtil.getPortType(portTemplateConsolidationData.getNodeTemplateId());
2433           if (substitutionTemplateInputName.contains(portType)) {
2434             return getIdenticalPropertyValue(identicalValuePropertyName, serviceTemplate,
2435                 entity, portTemplateConsolidationData, context);
2436           }
2437         }
2438     }
2439
2440     return Optional.empty();
2441
2442   }
2443
2444
2445   private PortInputType getPortInputType(String inputName,
2446                                          UnifiedCompositionData unifiedCompositionData) {
2447     String portInputPrefix = UnifiedCompositionEntity.Port.name().toLowerCase() + "_";
2448     ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData
2449         .getComputeTemplateConsolidationData();
2450     List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
2451         getPortTemplateConsolidationDataList(unifiedCompositionData);
2452     //Scan the available port node template ids to check if the input is of the form
2453     // "port_<port_node_template_id>_<property_name>"
2454     for (PortTemplateConsolidationData portTemplateConsolidationData :
2455         portTemplateConsolidationDataList) {
2456       String portNodeTemplateId = portTemplateConsolidationData.getNodeTemplateId();
2457       String portNodeTemplateIdPrefix = portInputPrefix + portNodeTemplateId;
2458       if (inputName.startsWith(portNodeTemplateIdPrefix)) {
2459         return PortInputType.NodeTemplateId;
2460       }
2461     }
2462     //Check whether the input is of the form "port_<port_type>_<property_name>"
2463     Set<String> portTypes = computeTemplateConsolidationData.getPorts().keySet();
2464     for (String portType : portTypes) {
2465       String expectedPortTypeSusbtring = portInputPrefix + portType + "_";
2466       if (inputName.startsWith(expectedPortTypeSusbtring)) {
2467         return PortInputType.PortType;
2468       }
2469     }
2470     return PortInputType.Other;
2471   }
2472
2473   private void cleanServiceTemplate(ServiceTemplate serviceTemplate,
2474                                     EntityConsolidationData entity,
2475                                     TranslationContext context) {
2476     removeNodeTemplateFromServiceTemplate(serviceTemplate, entity, context);
2477     updateHeatStackGroup(serviceTemplate, entity, context);
2478   }
2479
2480   private void removeNodeTemplateFromServiceTemplate(ServiceTemplate serviceTemplate,
2481                                                      EntityConsolidationData entity,
2482                                                      TranslationContext context) {
2483     String nodeTemplateIdToRemove = entity.getNodeTemplateId();
2484     Map<String, NodeTemplate> nodeTemplates =
2485         serviceTemplate.getTopology_template().getNode_templates();
2486     NodeTemplate nodeTemplateToRemove =
2487         nodeTemplates.get(nodeTemplateIdToRemove);
2488     nodeTemplates.remove(nodeTemplateIdToRemove);
2489
2490     context.addCleanedNodeTemplate(ToscaUtil.getServiceTemplateFileName(serviceTemplate),
2491         nodeTemplateIdToRemove,
2492         entity.getClass() == ComputeTemplateConsolidationData.class
2493             ? UnifiedCompositionEntity.Compute
2494             : UnifiedCompositionEntity.Port,
2495         nodeTemplateToRemove);
2496
2497   }
2498
2499   private void removeCleanedNodeType(String cleanedNodeTemplateId,
2500                                      ServiceTemplate serviceTemplate,
2501                                      TranslationContext context) {
2502     NodeTemplate cleanedNodeTemplate =
2503         context
2504             .getCleanedNodeTemplate(ToscaUtil.getServiceTemplateFileName(serviceTemplate),
2505                 cleanedNodeTemplateId);
2506     String typeToRemove = cleanedNodeTemplate.getType();
2507
2508     if (Objects.nonNull(typeToRemove)
2509         && serviceTemplate.getNode_types().containsKey(typeToRemove)) {
2510       serviceTemplate.getNode_types().remove(typeToRemove);
2511     }
2512   }
2513
2514   private void updateHeatStackGroup(ServiceTemplate serviceTemplate,
2515                                     EntityConsolidationData entity,
2516                                     TranslationContext context) {
2517     Map<String, GroupDefinition> groups = serviceTemplate.getTopology_template()
2518         .getGroups() == null ? new HashMap<>()
2519         : serviceTemplate.getTopology_template().getGroups();
2520     String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
2521     String nodeRelatedAbstractNodeId =
2522         context.getUnifiedAbstractNodeTemplateId(serviceTemplate, entity.getNodeTemplateId());
2523
2524     for (Map.Entry<String, GroupDefinition> groupEntry : groups.entrySet()) {
2525       GroupDefinition groupDefinition = groupEntry.getValue();
2526       if (isHeatStackGroup(groupDefinition.getType())) {
2527         updateGroupMembersWithNewUnifiedNodeTemplateId(entity, nodeRelatedAbstractNodeId,
2528             groupEntry);
2529       }
2530     }
2531   }
2532
2533   private void updateGroupMembersWithNewUnifiedNodeTemplateId(
2534       EntityConsolidationData entity,
2535       String newNodetemplateId,
2536       Map.Entry<String, GroupDefinition> groupEntry) {
2537     List<String> members = groupEntry.getValue().getMembers();
2538     if (members.contains(entity.getNodeTemplateId())) {
2539       members.remove(entity.getNodeTemplateId());
2540       if (!members.contains(newNodetemplateId)) {
2541         members.add(newNodetemplateId);
2542       }
2543     }
2544     groupEntry.getValue().setMembers(members);
2545   }
2546
2547   private void updateHeatStackGroupNestedComposition(ServiceTemplate serviceTemplate,
2548                                                      EntityConsolidationData entity,
2549                                                      TranslationContext context) {
2550     Map<String, GroupDefinition> groups = serviceTemplate.getTopology_template()
2551         .getGroups() == null ? new HashMap<>() : serviceTemplate.getTopology_template().getGroups();
2552     String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
2553     Optional<String> nestedNodeTemplateId =
2554         context.getUnifiedNestedNodeTemplateId(serviceTemplateFileName, entity.getNodeTemplateId());
2555     if (nestedNodeTemplateId.isPresent()) {
2556       for (Map.Entry<String, GroupDefinition> groupEntry : groups.entrySet()) {
2557         GroupDefinition groupDefinition = groupEntry.getValue();
2558         if (isHeatStackGroup(groupDefinition.getType())) {
2559           updateGroupMembersWithNewUnifiedNodeTemplateId(entity, nestedNodeTemplateId.get(),
2560               groupEntry);
2561         }
2562       }
2563     }
2564   }
2565
2566   private void handleNestedNodeTemplateInMainServiceTemplate(String nestedNodeTemplateId,
2567                                                              ServiceTemplate mainServiceTemplate,
2568                                                              ServiceTemplate nestedServiceTemplate,
2569                                                              TranslationContext context) {
2570     NodeTemplate nestedNodeTemplate = DataModelUtil.getNodeTemplate(mainServiceTemplate,
2571         nestedNodeTemplateId);
2572     if (Objects.isNull(nestedNodeTemplate)) {
2573       return;
2574     }
2575
2576     updateNestedNodeTemplateProperties(nestedServiceTemplate, nestedNodeTemplate, context);
2577
2578     Optional<String> unifiedNestedNodeTypeId = context
2579         .getUnifiedNestedNodeTypeId(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
2580             nestedNodeTemplate.getType());
2581     unifiedNestedNodeTypeId
2582         .ifPresent(unifiedNestedNodeTypeIdVal -> updateNestedNodeTemplate(
2583             unifiedNestedNodeTypeIdVal, nestedNodeTemplateId, nestedNodeTemplate,
2584             mainServiceTemplate, nestedServiceTemplate, context));
2585   }
2586
2587   private void updateNestedNodeTemplateProperties(ServiceTemplate nestedServiceTemplate,
2588                                                   NodeTemplate nestedNodeTemplate,
2589                                                   TranslationContext context){
2590
2591     Map<String, Object> newPropertyInputParamIds =
2592         context.getAllNewPropertyInputParamIdsPerNodeTenplateId(ToscaUtil
2593             .getServiceTemplateFileName(nestedServiceTemplate));
2594
2595     for(Map.Entry<String, Object> entry : newPropertyInputParamIds.entrySet()){
2596       if(Objects.nonNull(entry.getValue())) {
2597         Object value = getClonedObject(entry.getValue());
2598         nestedNodeTemplate.getProperties().put(entry.getKey(), value);
2599       }
2600     }
2601
2602   }
2603
2604   private void handleSubstitutionMappingInNestedServiceTemplate(
2605       String newNestedNodeType,
2606       ServiceTemplate nestedServiceTemplate) {
2607     if (Objects.isNull(newNestedNodeType)) {
2608       return;
2609     }
2610
2611     SubstitutionMapping substitutionMappings =
2612         nestedServiceTemplate.getTopology_template().getSubstitution_mappings();
2613     substitutionMappings.setNode_type(newNestedNodeType);
2614   }
2615
2616   private void updateNestedNodeTemplate(String newNestedNodeTypeId,
2617                                         String nestedNodeTemplateId,
2618                                         NodeTemplate nestedNodeTemplate,
2619                                         ServiceTemplate mainServiceTemplate,
2620                                         ServiceTemplate nestedServiceTemplate,
2621                                         TranslationContext context) {
2622     String mainServiceTemplateName = ToscaUtil.getServiceTemplateFileName(mainServiceTemplate);
2623     int index =
2624         context.getHandledNestedComputeNodeTemplateIndex(mainServiceTemplateName,
2625             newNestedNodeTypeId);
2626     String newNodeTemplateId =
2627         Constants.ABSTRACT_NODE_TEMPLATE_ID_PREFIX + getComputeTypeSuffix(newNestedNodeTypeId) +
2628             "_" + index;
2629
2630     nestedNodeTemplate.setType(newNestedNodeTypeId);
2631     mainServiceTemplate.getTopology_template().getNode_templates().remove(nestedNodeTemplateId);
2632     mainServiceTemplate.getTopology_template().getNode_templates()
2633         .put(newNodeTemplateId, nestedNodeTemplate);
2634
2635     context
2636         .addUnifiedNestedNodeTemplateId(mainServiceTemplateName,
2637             nestedNodeTemplateId, newNodeTemplateId);
2638   }
2639
2640   private void handleNestedNodeTypesInGlobalSubstituteServiceTemplate(
2641       String origNestedNodeTypeId,
2642       String newNestedNodeTypeId,
2643       ServiceTemplate globalSubstitutionServiceTemplate,
2644       TranslationContext context) {
2645     Set<String> relatedNestedNodeTypeIds =
2646         context.getAllRelatedNestedNodeTypeIds();
2647
2648     if(!relatedNestedNodeTypeIds.contains(origNestedNodeTypeId)) {
2649       Map<String, NodeType> nodeTypes = globalSubstitutionServiceTemplate.getNode_types();
2650       NodeType nested = DataModelUtil.getNodeType(globalSubstitutionServiceTemplate,
2651           origNestedNodeTypeId);
2652       setNewValuesForNestedNodeType(origNestedNodeTypeId, newNestedNodeTypeId, nested, nodeTypes);
2653       context.addUnifiedNestedNodeTypeId(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
2654           origNestedNodeTypeId, newNestedNodeTypeId);
2655     }
2656   }
2657
2658   private void setNewValuesForNestedNodeType(String origNestedNodeType,
2659                                              String newNestedNodeTypeId,
2660                                              NodeType nested,
2661                                              Map<String, NodeType> nodeTypes) {
2662     if (Objects.nonNull(nested)) {
2663       nested.setDerived_from(ToscaNodeType.VFC_ABSTRACT_SUBSTITUTE);
2664       nodeTypes.remove(origNestedNodeType);
2665       nodeTypes.put(newNestedNodeTypeId, nested);
2666     }
2667   }
2668
2669   private Optional<String> getNewNestedNodeTypeId(ServiceTemplate mainServiceTemplate,
2670                                                   ServiceTemplate nestedServiceTemplate,
2671                                                   TranslationContext context) {
2672     FileComputeConsolidationData fileComputeConsolidationData =
2673         context.getConsolidationData().getComputeConsolidationData()
2674             .getFileComputeConsolidationData(
2675                 ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate));
2676
2677     if (Objects.nonNull(fileComputeConsolidationData)) {
2678       String nestedNodeTypePrefix = ToscaNodeType.ABSTRACT_NODE_TYPE_PREFIX + "heat.";
2679       return Optional
2680           .of(nestedNodeTypePrefix + getComputeTypeInNestedFile(fileComputeConsolidationData));
2681     }
2682     return Optional.empty();
2683   }
2684
2685   private String getComputeTypeInNestedFile(
2686       FileComputeConsolidationData fileComputeConsolidationData) {
2687     List<TypeComputeConsolidationData> typeComputeConsolidationDatas =
2688         new ArrayList<>(fileComputeConsolidationData.getAllTypeComputeConsolidationData());
2689     if (typeComputeConsolidationDatas.size() == 0) {
2690       return null;
2691     } else {
2692       String computeNodeType = fileComputeConsolidationData.getAllComputeTypes().iterator().next();
2693       return getComputeTypeSuffix(computeNodeType);
2694     }
2695   }
2696
2697   private void handleGetAttrInAbstractNodeTemplate(ServiceTemplate serviceTemplate,
2698                                                    TranslationContext context,
2699                                                    String serviceTemplateFileName,
2700                                                    NodeTemplate abstractNodeTemplate) {
2701     Map<String, Object> properties =
2702         abstractNodeTemplate == null || abstractNodeTemplate.getProperties() == null
2703             ? new HashMap<>()
2704             : abstractNodeTemplate.getProperties();
2705     for (Object propertyValue : properties.values()) {
2706       List<List<Object>> getAttrList = extractGetAttrFunction(propertyValue);
2707       for (List<Object> getAttrFuncValue : getAttrList) {
2708         String origNodeTemplateId = (String) getAttrFuncValue.get(0);
2709         Optional<String> nestedNodeTemplateId = context.getUnifiedNestedNodeTemplateId(ToscaUtil
2710             .getServiceTemplateFileName(serviceTemplate), origNodeTemplateId);
2711         if (nestedNodeTemplateId.isPresent()) {
2712           getAttrFuncValue.set(0, nestedNodeTemplateId.get());
2713         } else {
2714           replaceGetAttrNodeIdAndAttrName(serviceTemplate, context, serviceTemplateFileName,
2715               getAttrFuncValue);
2716         }
2717       }
2718     }
2719   }
2720
2721   private void replaceGetAttrNodeIdAndAttrName(ServiceTemplate serviceTemplate,
2722                                                TranslationContext context,
2723                                                String serviceTemplateFileName,
2724                                                List<Object> getAttrFuncValue) {
2725     String origNodeTemplateId = (String) getAttrFuncValue.get(0);
2726     String attributeName = (String) getAttrFuncValue.get(1);
2727
2728     String unifiedAbstractNodeTemplateId =
2729         context.getUnifiedAbstractNodeTemplateId(serviceTemplate, origNodeTemplateId);
2730
2731     if (Objects.isNull(unifiedAbstractNodeTemplateId)) {
2732       return;
2733     }
2734
2735     String newNodeTemplateId =
2736         getNewNodeTemplateId(origNodeTemplateId, serviceTemplateFileName, serviceTemplate, context);
2737
2738     String newSubstitutionOutputParameterId =
2739         getNewSubstitutionOutputParameterId(newNodeTemplateId, attributeName);
2740
2741     getAttrFuncValue.set(0, unifiedAbstractNodeTemplateId);
2742     getAttrFuncValue.set(1, newSubstitutionOutputParameterId);
2743   }
2744
2745   private NodeTemplate getComputeNodeTemplate(String origNodeTemplateId,
2746                                               ServiceTemplate serviceTemplate,
2747                                               TranslationContext context) {
2748     NodeTemplate computeNodeTemplate =
2749         DataModelUtil.getNodeTemplate(serviceTemplate, origNodeTemplateId);
2750     if (computeNodeTemplate == null) {
2751       computeNodeTemplate =
2752           context.getCleanedNodeTemplate(ToscaUtil.getServiceTemplateFileName(serviceTemplate),
2753               origNodeTemplateId);
2754     }
2755     return computeNodeTemplate;
2756   }
2757
2758   private String handleIdOfPort(String origNodeTemplateId, String serviceTemplateFileName,
2759                                 ConsolidationData consolidationData) {
2760     Optional<Pair<String, ComputeTemplateConsolidationData>>
2761         computeTypeAndComputeTemplateByPortId =
2762         getComputeTypeAndComputeTemplateByPortId(origNodeTemplateId, serviceTemplateFileName,
2763             consolidationData);
2764     if (computeTypeAndComputeTemplateByPortId.isPresent()) {
2765       Pair<String, ComputeTemplateConsolidationData> computeIdToComputeData =
2766           computeTypeAndComputeTemplateByPortId.get();
2767       return getNewPortNodeTemplateId(origNodeTemplateId, computeIdToComputeData.getKey(),
2768           computeIdToComputeData.getValue());
2769     }
2770
2771     return null;
2772   }
2773
2774   private Optional<Pair<String, ComputeTemplateConsolidationData>>
2775   getComputeTypeAndComputeTemplateByPortId(String portId, String serviceTemplateFileName,
2776                                            ConsolidationData consolidationData) {
2777     FileComputeConsolidationData fileComputeConsolidationData =
2778         consolidationData.getComputeConsolidationData()
2779             .getFileComputeConsolidationData(serviceTemplateFileName);
2780     Set<String> computeTypes =
2781         fileComputeConsolidationData.getAllComputeTypes();
2782
2783     for (String computeType : computeTypes) {
2784       Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDatas =
2785           fileComputeConsolidationData.getTypeComputeConsolidationData(computeType)
2786               .getAllComputeTemplateConsolidationData();
2787
2788       for (ComputeTemplateConsolidationData compute : computeTemplateConsolidationDatas) {
2789         if (ConsolidationDataUtil.isComputeReferenceToPortId(compute, portId)) {
2790           return Optional.of(new ImmutablePair<>(computeType, compute));
2791         }
2792       }
2793     }
2794
2795     return Optional.empty();
2796   }
2797
2798   private boolean isIdIsOfExpectedType(String id,
2799                                        UnifiedCompositionEntity expectedUnifiedCompositionEntity,
2800                                        String serviceTemplateFileName,
2801                                        TranslationContext context) {
2802     UnifiedSubstitutionData unifiedSubstitutionData =
2803         context.getUnifiedSubstitutionData().get(serviceTemplateFileName);
2804     if (Objects.isNull(unifiedSubstitutionData)) {
2805       return false;
2806     }
2807
2808     UnifiedCompositionEntity actualUnifiedCompositionEntity =
2809         unifiedSubstitutionData.getCleanedNodeTemplateCompositionEntity(id);
2810
2811     return actualUnifiedCompositionEntity == null ? false
2812         : actualUnifiedCompositionEntity.equals(expectedUnifiedCompositionEntity);
2813   }
2814
2815   private boolean isHeatStackGroup(String groupType) {
2816     return groupType.equals(ToscaGroupType.HEAT_STACK);
2817   }
2818
2819   private Object getPortPropertyValue(String inputName,
2820                                       String computeType,
2821                                       PortInputType portInputType,
2822                                       ServiceTemplate serviceTemplate,
2823                                       String portNodeTemplateId) {
2824     //Get the input prefix to extract the property name from the input name
2825     String portInputPrefix = getPortInputPrefix(
2826         portNodeTemplateId, portInputType);
2827     //Get the property name from the input
2828     Optional<String> propertyName = getPropertyNameFromInput(inputName,
2829         UnifiedCompositionEntity.Port, computeType, portInputPrefix);
2830     //Get the property value from the node template
2831     if (propertyName.isPresent()) {
2832       NodeTemplate portNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate,
2833           portNodeTemplateId);
2834       if (Objects.nonNull(portNodeTemplate)) {
2835         return getPropertyValueFromNodeTemplate(propertyName.get(), portNodeTemplate);
2836       }
2837     }
2838     return Optional.empty();
2839   }
2840
2841   private Optional<String> getPortTypeFromInput(
2842       String inputName,
2843       String portNodeTemplateId,
2844       ComputeTemplateConsolidationData computeTemplateConsolidationData) {
2845     String portTypeFromInput = null;
2846     String portInputPrefix = UnifiedCompositionEntity.Port.name().toLowerCase() + "_";
2847     String portNodeTemplateIdPrefix = portInputPrefix + portNodeTemplateId;
2848     if (inputName.startsWith(portNodeTemplateIdPrefix)) {
2849       return Optional.empty();
2850     }
2851     Set<String> portTypes = computeTemplateConsolidationData.getPorts().keySet();
2852     for (String portType : portTypes) {
2853       String expectedPortTypeSusbtring = "_" + portType + "_";
2854       if (inputName.contains(expectedPortTypeSusbtring)) {
2855         portTypeFromInput = portType;
2856         break;
2857       }
2858     }
2859     return Optional.ofNullable(portTypeFromInput);
2860   }
2861
2862   private Object getComputePropertyValue(
2863       String inputName,
2864       ServiceTemplate serviceTemplate,
2865       ComputeTemplateConsolidationData computeTemplateConsolidationData) {
2866     NodeTemplate nodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate,
2867         computeTemplateConsolidationData.getNodeTemplateId());
2868     String nodeType = getComputeTypeSuffix(nodeTemplate.getType());
2869     Optional<String> propertyName =
2870         getPropertyNameFromInput(inputName, UnifiedCompositionEntity.Compute, nodeType, null);
2871     if (propertyName.isPresent()) {
2872       return getPropertyValueFromNodeTemplate(propertyName.get(), nodeTemplate);
2873     }
2874     return Optional.empty();
2875   }
2876
2877   private Optional<Object> getIdenticalPropertyValue(String identicalValuePropertyName,
2878                                                      ServiceTemplate serviceTemplate,
2879                                                      UnifiedCompositionEntity unifiedCompositionEntity,
2880                                                      EntityConsolidationData entity,
2881                                                      TranslationContext context) {
2882     NodeTemplate nodeTemplate =
2883         getNodeTemplate(entity.getNodeTemplateId(), serviceTemplate, context);
2884
2885     Object propertyValueFromNodeTemplate =
2886         getPropertyValueFromNodeTemplate(identicalValuePropertyName, nodeTemplate);
2887
2888     return Objects.isNull(propertyValueFromNodeTemplate) ? Optional.empty()
2889         : Optional.of(propertyValueFromNodeTemplate);
2890   }
2891
2892   private UnifiedCompositionEntity getInputCompositionEntity(String inputName) {
2893     UnifiedCompositionEntity inputCompositionEntity = UnifiedCompositionEntity.Other;
2894     String inputType = inputName.substring(0, inputName.indexOf('_'));
2895     if (inputType.equals(UnifiedCompositionEntity.Compute.name().toLowerCase())) {
2896       inputCompositionEntity = UnifiedCompositionEntity.Compute;
2897     } else if (inputType.equals(UnifiedCompositionEntity.Port.name().toLowerCase())) {
2898       inputCompositionEntity = UnifiedCompositionEntity.Port;
2899     }
2900     return inputCompositionEntity;
2901   }
2902
2903   private Optional<String> getPropertyNameFromInput(
2904       String inputName,
2905       UnifiedCompositionEntity compositionEntity,
2906       String computeType, String portInputPrefix) {
2907     String propertyName = null;
2908     switch (compositionEntity) {
2909       case Compute:
2910         propertyName = inputName.substring(inputName.lastIndexOf(computeType)
2911             + computeType.length() + 1);
2912         break;
2913       case Port:
2914         if (inputName.startsWith(portInputPrefix)) {
2915           propertyName = inputName.split(portInputPrefix)[1];
2916         }
2917         break;
2918       default:
2919         break;
2920     }
2921     return Optional.ofNullable(propertyName);
2922   }
2923
2924   private String getPortInputPrefix(
2925       String portNodeTemplateId,
2926       PortInputType portInputType) {
2927     String portInputPrefix = UnifiedCompositionEntity.Port.name().toLowerCase() + "_";
2928     String portType = ConsolidationDataUtil.getPortType(portNodeTemplateId);
2929     if (portInputType == PortInputType.NodeTemplateId) {
2930       portInputPrefix += portNodeTemplateId + "_";
2931     } else if (portInputType == PortInputType.PortType) {
2932       portInputPrefix += portType + "_";
2933     }
2934     return portInputPrefix;
2935   }
2936
2937   private boolean isIdenticalValueProperty(String inputName,
2938                                            UnifiedCompositionEntity unifiedCompositionEntity,
2939                                            TranslationContext context) {
2940
2941     List<String> identicalValuePropertyList =
2942         consolidationService.getPropertiesWithIdenticalVal(unifiedCompositionEntity, context);
2943
2944     StringBuilder builder = getPropertyValueStringBuilder(unifiedCompositionEntity);
2945
2946     boolean isMatchingProperty = Pattern.matches(builder.toString(), inputName);
2947     return (isMatchingProperty
2948         && isPropertyFromIdenticalValuesList(inputName, unifiedCompositionEntity,
2949         identicalValuePropertyList));
2950   }
2951
2952   private boolean isPropertyFromIdenticalValuesList(String inputName,
2953                                                     UnifiedCompositionEntity unifiedCompositionEntity,
2954                                                     List<String> identicalValuePropertyList) {
2955     switch (unifiedCompositionEntity) {
2956       case Compute:
2957         return identicalValuePropertyList.contains(getIdenticalValuePropertyName(inputName,
2958             unifiedCompositionEntity, null).get());
2959
2960       case Other:
2961         return identicalValuePropertyList.contains(getIdenticalValuePropertyName(inputName,
2962             unifiedCompositionEntity, null).get());
2963
2964       case Port:
2965         return getPortPropertyNameFromInput(inputName, identicalValuePropertyList).isPresent();
2966
2967       default:
2968         return false;
2969     }
2970   }
2971
2972   private Optional<String> getPortPropertyNameFromInput(String inputName,
2973                                                         List<String> identicalValuePropertyList) {
2974     for (String identicalProperty : identicalValuePropertyList) {
2975       if (inputName.contains(identicalProperty)) {
2976         return Optional.of(identicalProperty);
2977       }
2978     }
2979     return Optional.empty();
2980   }
2981
2982   private StringBuilder getPropertyValueStringBuilder(
2983       UnifiedCompositionEntity unifiedCompositionEntity) {
2984
2985     switch (unifiedCompositionEntity) {
2986       case Compute:
2987         return getComputePropertyValueStringBuilder();
2988
2989       case Other:
2990         return getComputePropertyValueStringBuilder();
2991
2992       case Port:
2993         return getPortPropertyValueStringBuilder();
2994
2995       default:
2996         return null;
2997     }
2998   }
2999
3000   private StringBuilder getPortPropertyValueStringBuilder() {
3001     StringBuilder builder;
3002     builder = new StringBuilder(PORT_IDENTICAL_VALUE_PROPERTY_PREFIX);
3003     builder.append(".+");
3004     return builder;
3005   }
3006
3007   private StringBuilder getComputePropertyValueStringBuilder() {
3008     StringBuilder builder;
3009     builder = new StringBuilder(COMPUTE_IDENTICAL_VALUE_PROPERTY_PREFIX);
3010     builder.append("[a-z]+");
3011     builder.append(COMPUTE_IDENTICAL_VALUE_PROPERTY_SUFFIX);
3012     return builder;
3013   }
3014
3015   private Optional<String> getIdenticalValuePropertyName(String input,
3016                                                          UnifiedCompositionEntity unifiedCompositionEntity,
3017                                                          TranslationContext context) {
3018     switch (unifiedCompositionEntity) {
3019       case Compute:
3020         return Optional.of(input.split("_")[1]);
3021
3022       case Other:
3023         return Optional.of(input.split("_")[1]);
3024
3025       case Port:
3026         return getPortPropertyNameFromInput(input, consolidationService
3027             .getPropertiesWithIdenticalVal(unifiedCompositionEntity, context));
3028
3029       default:
3030         return Optional.empty();
3031     }
3032   }
3033
3034   private Object getPropertyValueFromNodeTemplate(String propertyName, NodeTemplate nodeTemplate) {
3035     Map<String, Object> nodeTemplateProperties = nodeTemplate.getProperties();
3036     if (nodeTemplateProperties != null) {
3037       Object propertyValue = nodeTemplateProperties.get(propertyName);
3038       propertyValue = getClonedObject(propertyValue);
3039       return propertyValue;
3040     }
3041     return null;
3042   }
3043
3044   private <T> Object getClonedObject(Object objectValue, Class<T> clazz) {
3045     YamlUtil yamlUtil = new YamlUtil();
3046     Object clonedObjectValue;
3047     String objectToYaml = yamlUtil.objectToYaml(objectValue);
3048     clonedObjectValue = yamlUtil.yamlToObject(objectToYaml, clazz);
3049     return clonedObjectValue;
3050   }
3051
3052   private Object getClonedObject(Object objectValue) {
3053     Object clonedObjectValue;
3054     try {
3055       ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
3056       ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
3057       objectOutputStream.writeObject(objectValue);
3058
3059       ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream
3060           .toByteArray());
3061       ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
3062       clonedObjectValue = objectInputStream.readObject();
3063     } catch (NotSerializableException ex) {
3064       return getClonedObject(objectValue, objectValue.getClass());
3065     } catch (IOException ioe) {
3066       return null;
3067     } catch (ClassNotFoundException cnfe) {
3068       return null;
3069     }
3070     return clonedObjectValue;
3071   }
3072
3073   private Map<String, UnifiedCompositionEntity> getAllConsolidationNodeTemplateIdAndType(
3074       List<UnifiedCompositionData> unifiedCompositionDataList) {
3075
3076     Map<String, UnifiedCompositionEntity> consolidationNodeTemplateIdAndType = new HashMap<>();
3077     for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
3078       ComputeTemplateConsolidationData computeTemplateConsolidationData =
3079           unifiedCompositionData.getComputeTemplateConsolidationData();
3080       if (Objects.nonNull(computeTemplateConsolidationData)) {
3081         consolidationNodeTemplateIdAndType
3082             .put(computeTemplateConsolidationData.getNodeTemplateId(),
3083                 UnifiedCompositionEntity.Compute);
3084       }
3085       List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
3086           getPortTemplateConsolidationDataList(unifiedCompositionData);
3087       for (PortTemplateConsolidationData portTemplateConsolidationData :
3088           portTemplateConsolidationDataList) {
3089         consolidationNodeTemplateIdAndType.put(portTemplateConsolidationData.getNodeTemplateId(),
3090             UnifiedCompositionEntity.Port);
3091       }
3092       NestedTemplateConsolidationData nestedTemplateConsolidationData =
3093           unifiedCompositionData.getNestedTemplateConsolidationData();
3094       if (Objects.nonNull(nestedTemplateConsolidationData)) {
3095         consolidationNodeTemplateIdAndType
3096             .put(nestedTemplateConsolidationData.getNodeTemplateId(),
3097                 UnifiedCompositionEntity.Nested);
3098       }
3099     }
3100     return consolidationNodeTemplateIdAndType;
3101   }
3102
3103   private enum PortInputType {
3104     NodeTemplateId,
3105     PortType,
3106     Other;
3107   }
3108
3109   private List<PortTemplateConsolidationData> getPortTemplateConsolidationDataList(
3110       UnifiedCompositionData unifiedCompositionData) {
3111     return unifiedCompositionData.getPortTemplateConsolidationDataList() == null ? new
3112         ArrayList<>() : unifiedCompositionData.getPortTemplateConsolidationDataList();
3113   }
3114 }