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