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