84a9dcf4424a973cc0c7e56674f721894dfbad50
[sdc.git] /
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         List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
2906             unifiedCompositionData.getPortTemplateConsolidationDataList();
2907         for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) {
2908           String portType =
2909               ConsolidationDataUtil.getPortType(portTemplateConsolidationData.getNodeTemplateId());
2910           if (substitutionTemplateInputName.contains(portType)) {
2911             return getIdenticalPropertyValue(identicalValuePropertyName,
2912                 serviceTemplate, portTemplateConsolidationData, context);
2913           }
2914         }
2915         break;
2916       default:
2917         break;
2918     }
2919     return identicalPropertyValue;
2920   }
2921
2922
2923   private PropertyInputType getPortInputType(String inputName,
2924                                              UnifiedCompositionData unifiedCompositionData) {
2925     String portInputPrefix = UnifiedCompositionEntity.PORT.getDisplayName().toLowerCase() + "_";
2926     ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData
2927         .getComputeTemplateConsolidationData();
2928     List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
2929         getPortTemplateConsolidationDataList(unifiedCompositionData);
2930     //Scan the available port node template ids to check if the input is of the form
2931     // "port_<port_node_template_id>_<property_name>"
2932     if (portTemplateConsolidationDataList.stream().map(EntityConsolidationData::getNodeTemplateId)
2933         .map(portNodeTemplateId -> portInputPrefix + portNodeTemplateId).anyMatch(inputName::startsWith)) {
2934       return PropertyInputType.NODE_TEMPLATE_ID;
2935     }
2936     //Check whether the input is of the form "port_<port_type>_<property_name>"
2937     Set<String> portTypes = computeTemplateConsolidationData.getPorts().keySet();
2938     if (portTypes.stream().map(portType -> portInputPrefix + portType + "_").anyMatch(inputName::startsWith)) {
2939       return PropertyInputType.TYPE;
2940     }
2941     return PropertyInputType.OTHER;
2942   }
2943
2944   private PropertyInputType getSubInterfaceInputType(String inputName,
2945                                              UnifiedCompositionData unifiedCompositionData) {
2946     String subInterfaceInputPrefix = UnifiedCompositionEntity.SUB_INTERFACE.getDisplayName().toLowerCase()
2947         + "_";
2948     List<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationDataList =
2949         getSubInterfaceTemplateConsolidationDataList(unifiedCompositionData);
2950     //Scan the available port node template ids to check if the input is of the form
2951     // "subinterface_<subinterface_node_template_id>_<property_name>"
2952     if (subInterfaceTemplateConsolidationDataList.stream().map(EntityConsolidationData::getNodeTemplateId)
2953         .map(subInterfaceNodeTemplateId -> subInterfaceInputPrefix
2954             + subInterfaceNodeTemplateId)
2955         .anyMatch(inputName::startsWith)) {
2956       return PropertyInputType.NODE_TEMPLATE_ID;
2957     }
2958     //Check whether the input is of the form "subinterface_<subinterface_type>_<property_name>"
2959     Set<String> subInterfaceTypes = new HashSet<>();
2960     List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
2961         getPortTemplateConsolidationDataList(unifiedCompositionData);
2962     for (PortTemplateConsolidationData portTemplateConsolidationData :
2963         portTemplateConsolidationDataList) {
2964       subInterfaceTypes.addAll(portTemplateConsolidationData.getAllSubInterfaceNodeTypes());
2965     }
2966
2967     if (subInterfaceTypes.stream().map(UnifiedCompositionUtil::getSubInterfaceTypeSuffix)
2968         .map(subInterfaceTypeSuffix -> subInterfaceInputPrefix + subInterfaceTypeSuffix + "_")
2969         .anyMatch(inputName::startsWith)) {
2970       return PropertyInputType.TYPE;
2971     }
2972     return PropertyInputType.OTHER;
2973   }
2974
2975   private void cleanServiceTemplate(ServiceTemplate serviceTemplate,
2976                                     EntityConsolidationData entity,
2977                                     TranslationContext context) {
2978     removeNodeTemplateFromServiceTemplate(serviceTemplate, entity, context);
2979     updateHeatStackGroup(serviceTemplate, entity, context);
2980     updateSubstitutionMapping(serviceTemplate, context);
2981   }
2982
2983   private void removeNodeTemplateFromServiceTemplate(ServiceTemplate serviceTemplate,
2984                                                      EntityConsolidationData entity,
2985                                                      TranslationContext context) {
2986     String nodeTemplateIdToRemove = entity.getNodeTemplateId();
2987     Map<String, NodeTemplate> nodeTemplates =
2988         serviceTemplate.getTopology_template().getNode_templates();
2989     NodeTemplate nodeTemplateToRemove =
2990         nodeTemplates.get(nodeTemplateIdToRemove);
2991     nodeTemplates.remove(nodeTemplateIdToRemove);
2992
2993     context.addCleanedNodeTemplate(ToscaUtil.getServiceTemplateFileName(serviceTemplate),
2994         nodeTemplateIdToRemove,
2995         entity.getClass() == ComputeTemplateConsolidationData.class
2996             ? COMPUTE
2997             : UnifiedCompositionEntity.PORT,
2998         nodeTemplateToRemove);
2999
3000   }
3001
3002   private void removeCleanedNodeType(String cleanedNodeTemplateId,
3003                                      ServiceTemplate serviceTemplate,
3004                                      TranslationContext context) {
3005     NodeTemplate cleanedNodeTemplate =
3006         context
3007             .getCleanedNodeTemplate(ToscaUtil.getServiceTemplateFileName(serviceTemplate),
3008                 cleanedNodeTemplateId);
3009     String typeToRemove = cleanedNodeTemplate.getType();
3010
3011     if (Objects.nonNull(typeToRemove)
3012         && serviceTemplate.getNode_types().containsKey(typeToRemove)) {
3013       serviceTemplate.getNode_types().remove(typeToRemove);
3014     }
3015   }
3016
3017   private void updateHeatStackGroup(ServiceTemplate serviceTemplate,
3018                                     EntityConsolidationData entity,
3019                                     TranslationContext context) {
3020     Map<String, GroupDefinition> groups = serviceTemplate.getTopology_template()
3021         .getGroups() == null ? new HashMap<>()
3022         : serviceTemplate.getTopology_template().getGroups();
3023     String nodeRelatedAbstractNodeId =
3024         context.getUnifiedAbstractNodeTemplateId(serviceTemplate, entity.getNodeTemplateId());
3025
3026     for (Map.Entry<String, GroupDefinition> groupEntry : groups.entrySet()) {
3027       GroupDefinition groupDefinition = groupEntry.getValue();
3028       if (isHeatStackGroup(groupDefinition.getType())) {
3029         updateGroupMembersWithNewUnifiedNodeTemplateId(entity, nodeRelatedAbstractNodeId,
3030             groupEntry);
3031       }
3032     }
3033   }
3034
3035   private void updateGroupMembersWithNewUnifiedNodeTemplateId(
3036       EntityConsolidationData entity,
3037       String newNodetemplateId,
3038       Map.Entry<String, GroupDefinition> groupEntry) {
3039     List<String> members = groupEntry.getValue().getMembers();
3040     if (members.contains(entity.getNodeTemplateId())) {
3041       members.remove(entity.getNodeTemplateId());
3042       if (!members.contains(newNodetemplateId)) {
3043         members.add(newNodetemplateId);
3044       }
3045     }
3046     groupEntry.getValue().setMembers(members);
3047   }
3048
3049   private void updateSubstitutionMapping(ServiceTemplate serviceTemplate,
3050                                          TranslationContext context) {
3051     SubstitutionMapping substitutionMappings =
3052         DataModelUtil.getSubstitutionMappings(serviceTemplate);
3053     if (Objects.nonNull(substitutionMappings)) {
3054
3055       if (Objects.nonNull(substitutionMappings.getRequirements())) {
3056         updateSubstitutionMappingRequirements(substitutionMappings.getRequirements(),
3057             serviceTemplate, context);
3058       }
3059
3060       if (Objects.nonNull(substitutionMappings.getCapabilities())) {
3061         updateSubstitutionMappingCapabilities(substitutionMappings.getCapabilities(),
3062             serviceTemplate, context);
3063       }
3064     }
3065   }
3066
3067   private void updateSubstitutionMappingRequirements(Map<String, List<String>>
3068                                                          substitutionMappingRequirements,
3069                                                      ServiceTemplate serviceTemplate,
3070                                                      TranslationContext context) {
3071     for (Map.Entry<String, List<String>> entry : substitutionMappingRequirements.entrySet()) {
3072       List<String> requirement = entry.getValue();
3073       String oldNodeTemplateId = requirement.get(0);
3074       String newAbstractNodeTemplateId = context.getUnifiedAbstractNodeTemplateId(serviceTemplate,
3075           requirement.get(0));
3076       String newSubstitutionNodeTemplateId = context.getUnifiedSubstitutionNodeTemplateId(
3077           serviceTemplate, oldNodeTemplateId);
3078       if (Objects.nonNull(newAbstractNodeTemplateId)
3079           && Objects.nonNull(newSubstitutionNodeTemplateId)) {
3080         requirement.set(0, newAbstractNodeTemplateId);
3081         String newRequirementValue = requirement.get(1) + "_" + newSubstitutionNodeTemplateId;
3082         requirement.set(1, newRequirementValue);
3083       }
3084     }
3085   }
3086
3087   private void updateSubstitutionMappingCapabilities(Map<String, List<String>>
3088                                                          substitutionMappingCapabilities,
3089                                                      ServiceTemplate serviceTemplate,
3090                                                      TranslationContext context) {
3091     for (Map.Entry<String, List<String>> entry : substitutionMappingCapabilities.entrySet()) {
3092       List<String> capability = entry.getValue();
3093       String oldNodeTemplateId = capability.get(0);
3094       String newAbstractNodeTemplateId = context.getUnifiedAbstractNodeTemplateId(serviceTemplate,
3095           capability.get(0));
3096       String newSubstitutionNodeTemplateId = context.getUnifiedSubstitutionNodeTemplateId(
3097           serviceTemplate, oldNodeTemplateId);
3098       if (Objects.nonNull(newAbstractNodeTemplateId)
3099           && Objects.nonNull(newSubstitutionNodeTemplateId)) {
3100         capability.set(0, newAbstractNodeTemplateId);
3101         String newRequirementValue = capability.get(1) + "_" + newSubstitutionNodeTemplateId;
3102         capability.set(1, newRequirementValue);
3103       }
3104     }
3105   }
3106
3107   private void updateHeatStackGroupNestedComposition(ServiceTemplate serviceTemplate,
3108                                                      EntityConsolidationData entity,
3109                                                      TranslationContext context) {
3110     Map<String, GroupDefinition> groups = serviceTemplate.getTopology_template()
3111         .getGroups() == null ? new HashMap<>() : serviceTemplate.getTopology_template().getGroups();
3112     String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
3113     Optional<String> nestedNodeTemplateId =
3114         context.getUnifiedNestedNodeTemplateId(serviceTemplateFileName, entity.getNodeTemplateId());
3115     if (nestedNodeTemplateId.isPresent()) {
3116       for (Map.Entry<String, GroupDefinition> groupEntry : groups.entrySet()) {
3117         GroupDefinition groupDefinition = groupEntry.getValue();
3118         if (isHeatStackGroup(groupDefinition.getType())) {
3119           updateGroupMembersWithNewUnifiedNodeTemplateId(entity, nestedNodeTemplateId.get(),
3120               groupEntry);
3121         }
3122       }
3123     }
3124   }
3125
3126   private void handleNestedNodeTemplateInMainServiceTemplate(String nestedNodeTemplateId,
3127                                                              ServiceTemplate mainServiceTemplate,
3128                                                              ServiceTemplate nestedServiceTemplate,
3129                                                              TranslationContext context) {
3130     NodeTemplate nestedNodeTemplate = DataModelUtil.getNodeTemplate(mainServiceTemplate,
3131         nestedNodeTemplateId);
3132     if (Objects.isNull(nestedNodeTemplate)) {
3133       return;
3134     }
3135
3136     updateNestedNodeTemplateProperties(nestedServiceTemplate, nestedNodeTemplate, context);
3137
3138     Optional<String> unifiedNestedNodeTypeId = context
3139         .getUnifiedNestedNodeTypeId(
3140             ToscaUtil.getServiceTemplateFileName(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME),
3141             nestedNodeTemplate.getType());
3142     unifiedNestedNodeTypeId
3143         .ifPresent(unifiedNestedNodeTypeIdVal -> updateNestedNodeTemplate(
3144             unifiedNestedNodeTypeIdVal, nestedNodeTemplateId, nestedNodeTemplate,
3145             mainServiceTemplate, context));
3146   }
3147
3148   private void updateNestedNodeTemplateProperties(ServiceTemplate nestedServiceTemplate,
3149                                                   NodeTemplate nestedNodeTemplate,
3150                                                   TranslationContext context) {
3151
3152     Map<String, Object> newPropertyInputParamIds =
3153         context.getAllNewPropertyInputParamIdsPerNodeTenplateId(ToscaUtil
3154             .getServiceTemplateFileName(nestedServiceTemplate));
3155
3156     for (Map.Entry<String, Object> entry : newPropertyInputParamIds.entrySet()) {
3157       if (Objects.nonNull(entry.getValue())) {
3158         Object value = getClonedObject(entry.getValue());
3159         nestedNodeTemplate.getProperties().put(entry.getKey(), value);
3160       }
3161     }
3162
3163     String subNodeType =
3164         nestedServiceTemplate.getTopology_template().getSubstitution_mappings().getNode_type();
3165     nestedNodeTemplate.setType(subNodeType);
3166
3167   }
3168
3169   private void handleSubstitutionMappingInNestedServiceTemplate(
3170       String newNestedNodeType,
3171       ServiceTemplate nestedServiceTemplate,
3172       TranslationContext context) {
3173     if (Objects.isNull(newNestedNodeType)) {
3174       return;
3175     }
3176
3177     Set<String> relatedNestedNodeTypeIds =
3178         context.getAllRelatedNestedNodeTypeIds();
3179
3180     SubstitutionMapping substitutionMappings =
3181         nestedServiceTemplate.getTopology_template().getSubstitution_mappings();
3182     if (!relatedNestedNodeTypeIds.contains(substitutionMappings.getNode_type())) {
3183       substitutionMappings.setNode_type(newNestedNodeType);
3184     }
3185   }
3186
3187   private void updateNestedNodeTemplate(String newNestedNodeTypeId,
3188                                         String nestedNodeTemplateId,
3189                                         NodeTemplate nestedNodeTemplate,
3190                                         ServiceTemplate mainServiceTemplate,
3191                                         TranslationContext context) {
3192     String mainSTName = ToscaUtil.getServiceTemplateFileName(mainServiceTemplate);
3193     String globalSTName =
3194         ToscaUtil.getServiceTemplateFileName(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
3195     int index =
3196         context.getHandledNestedComputeNodeTemplateIndex(globalSTName, newNestedNodeTypeId);
3197     String newNodeTemplateId =
3198         Constants.ABSTRACT_NODE_TEMPLATE_ID_PREFIX + getComputeTypeSuffix(newNestedNodeTypeId)
3199             + "_" + index;
3200
3201     nestedNodeTemplate.setType(newNestedNodeTypeId);
3202     mainServiceTemplate.getTopology_template().getNode_templates().remove(nestedNodeTemplateId);
3203     mainServiceTemplate.getTopology_template().getNode_templates()
3204         .put(newNodeTemplateId, nestedNodeTemplate);
3205
3206     context.addUnifiedNestedNodeTemplateId(mainSTName, nestedNodeTemplateId, newNodeTemplateId);
3207   }
3208
3209   private void handleNestedNodeTypesInGlobalSubstituteServiceTemplate(
3210       String origNestedNodeTypeId,
3211       String newNestedNodeTypeId,
3212       ServiceTemplate globalSubstitutionServiceTemplate,
3213       TranslationContext context) {
3214     Set<String> relatedNestedNodeTypeIds =
3215         context.getAllRelatedNestedNodeTypeIds();
3216
3217     Map<String, NodeType> nodeTypes = globalSubstitutionServiceTemplate.getNode_types();
3218     if (!relatedNestedNodeTypeIds.contains(origNestedNodeTypeId)) {
3219       NodeType nested = DataModelUtil.getNodeType(globalSubstitutionServiceTemplate,
3220           origNestedNodeTypeId);
3221       setNewValuesForNestedNodeType(origNestedNodeTypeId, newNestedNodeTypeId, nested, nodeTypes);
3222     } else {
3223       NodeType nested =
3224           (NodeType) DataModelUtil.getClonedObject(
3225               DataModelUtil.getNodeType(globalSubstitutionServiceTemplate, origNestedNodeTypeId));
3226       nested.setDerived_from(ToscaNodeType.VFC_ABSTRACT_SUBSTITUTE);
3227       nodeTypes.put(newNestedNodeTypeId, nested);
3228     }
3229     context.addUnifiedNestedNodeTypeId(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
3230         origNestedNodeTypeId, newNestedNodeTypeId);
3231   }
3232
3233   private void setNewValuesForNestedNodeType(String origNestedNodeType,
3234                                              String newNestedNodeTypeId,
3235                                              NodeType nested,
3236                                              Map<String, NodeType> nodeTypes) {
3237     if (Objects.nonNull(nested)) {
3238       nested.setDerived_from(ToscaNodeType.VFC_ABSTRACT_SUBSTITUTE);
3239       nodeTypes.remove(origNestedNodeType);
3240       nodeTypes.put(newNestedNodeTypeId, nested);
3241     }
3242   }
3243
3244   private Optional<String> getNewNestedNodeTypeId(ServiceTemplate nestedServiceTemplate,
3245                                                   TranslationContext context) {
3246     FileComputeConsolidationData fileComputeConsolidationData =
3247         context.getConsolidationData().getComputeConsolidationData()
3248             .getFileComputeConsolidationData(
3249                 ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate));
3250
3251     if (Objects.nonNull(fileComputeConsolidationData)) {
3252       String nestedNodeTypePrefix = ToscaNodeType.ABSTRACT_NODE_TYPE_PREFIX + "heat.";
3253       return Optional
3254           .of(nestedNodeTypePrefix + getComputeTypeInNestedFile(fileComputeConsolidationData));
3255     }
3256     return Optional.empty();
3257   }
3258
3259   private String getComputeTypeInNestedFile(
3260       FileComputeConsolidationData fileComputeConsolidationData) {
3261     List<TypeComputeConsolidationData> typeComputeConsolidationDatas =
3262         new ArrayList<>(fileComputeConsolidationData.getAllTypeComputeConsolidationData());
3263     if (typeComputeConsolidationDatas.isEmpty()) {
3264       return null;
3265     } else {
3266       String computeNodeType = fileComputeConsolidationData.getAllComputeTypes().iterator().next();
3267       return getComputeTypeSuffix(computeNodeType);
3268     }
3269   }
3270
3271   private void handleGetAttrInAbstractNodeTemplate(ServiceTemplate serviceTemplate,
3272                                                    TranslationContext context,
3273                                                    String serviceTemplateFileName,
3274                                                    NodeTemplate abstractNodeTemplate) {
3275     Map<String, Object> properties =
3276         abstractNodeTemplate == null || abstractNodeTemplate.getProperties() == null
3277             ? new HashMap<>()
3278             : abstractNodeTemplate.getProperties();
3279     for (Object propertyValue : properties.values()) {
3280       List<List<Object>> getAttrList = extractGetAttrFunction(propertyValue);
3281       for (List<Object> getAttrFuncValue : getAttrList) {
3282         String origNodeTemplateId = (String) getAttrFuncValue.get(0);
3283         Optional<String> nestedNodeTemplateId = context.getUnifiedNestedNodeTemplateId(ToscaUtil
3284             .getServiceTemplateFileName(serviceTemplate), origNodeTemplateId);
3285         if (nestedNodeTemplateId.isPresent()) {
3286           getAttrFuncValue.set(0, nestedNodeTemplateId.get());
3287         } else {
3288           replaceGetAttrNodeIdAndAttrName(serviceTemplate, context, serviceTemplateFileName,
3289               getAttrFuncValue);
3290         }
3291       }
3292     }
3293   }
3294
3295   private void replaceGetAttrNodeIdAndAttrName(ServiceTemplate serviceTemplate,
3296                                                TranslationContext context,
3297                                                String serviceTemplateFileName,
3298                                                List<Object> getAttrFuncValue) {
3299     String origNodeTemplateId = (String) getAttrFuncValue.get(0);
3300     String attributeName = (String) getAttrFuncValue.get(1);
3301
3302     String unifiedAbstractNodeTemplateId =
3303         context.getUnifiedAbstractNodeTemplateId(serviceTemplate, origNodeTemplateId);
3304
3305     if (Objects.isNull(unifiedAbstractNodeTemplateId)) {
3306       return;
3307     }
3308
3309     String newNodeTemplateId =
3310         getNewNodeTemplateId(origNodeTemplateId, serviceTemplateFileName, serviceTemplate, context);
3311
3312     String newSubstitutionOutputParameterId =
3313         getNewSubstitutionOutputParameterId(newNodeTemplateId, attributeName);
3314
3315     getAttrFuncValue.set(0, unifiedAbstractNodeTemplateId);
3316     getAttrFuncValue.set(1, newSubstitutionOutputParameterId);
3317   }
3318
3319   private NodeTemplate getComputeNodeTemplate(String origNodeTemplateId,
3320                                               ServiceTemplate serviceTemplate,
3321                                               TranslationContext context) {
3322     NodeTemplate computeNodeTemplate =
3323         DataModelUtil.getNodeTemplate(serviceTemplate, origNodeTemplateId);
3324     if (computeNodeTemplate == null) {
3325       computeNodeTemplate =
3326           context.getCleanedNodeTemplate(ToscaUtil.getServiceTemplateFileName(serviceTemplate),
3327               origNodeTemplateId);
3328     }
3329     return computeNodeTemplate;
3330   }
3331
3332   private String handleIdOfPort(String origNodeTemplateId, String serviceTemplateFileName,
3333                                 ConsolidationData consolidationData) {
3334     Optional<Pair<String, ComputeTemplateConsolidationData>>
3335         computeTypeAndComputeTemplateByPortId =
3336         getComputeTypeAndComputeTemplateByPortId(origNodeTemplateId, serviceTemplateFileName,
3337             consolidationData);
3338     if (computeTypeAndComputeTemplateByPortId.isPresent()) {
3339       Pair<String, ComputeTemplateConsolidationData> computeIdToComputeData =
3340           computeTypeAndComputeTemplateByPortId.get();
3341       return getNewPortNodeTemplateId(origNodeTemplateId, computeIdToComputeData.getKey(),
3342           computeIdToComputeData.getValue());
3343     }
3344
3345     return null;
3346   }
3347
3348   private Optional<Pair<String, ComputeTemplateConsolidationData>>
3349   getComputeTypeAndComputeTemplateByPortId(String portId, String serviceTemplateFileName,
3350                                            ConsolidationData consolidationData) {
3351     FileComputeConsolidationData fileComputeConsolidationData =
3352         consolidationData.getComputeConsolidationData()
3353             .getFileComputeConsolidationData(serviceTemplateFileName);
3354     Set<String> computeTypes =
3355         fileComputeConsolidationData.getAllComputeTypes();
3356
3357     for (String computeType : computeTypes) {
3358       Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDatas =
3359           fileComputeConsolidationData.getTypeComputeConsolidationData(computeType)
3360               .getAllComputeTemplateConsolidationData();
3361
3362       for (ComputeTemplateConsolidationData compute : computeTemplateConsolidationDatas) {
3363         if (ConsolidationDataUtil.isComputeReferenceToPortId(compute, portId)) {
3364           return Optional.of(new ImmutablePair<>(computeType, compute));
3365         }
3366       }
3367     }
3368
3369     return Optional.empty();
3370   }
3371
3372   private boolean isIdIsOfExpectedType(String id,
3373                                        UnifiedCompositionEntity expectedUnifiedCompositionEntity,
3374                                        String serviceTemplateFileName,
3375                                        TranslationContext context) {
3376     UnifiedSubstitutionData unifiedSubstitutionData =
3377         context.getUnifiedSubstitutionData().get(serviceTemplateFileName);
3378     if (Objects.isNull(unifiedSubstitutionData)) {
3379       return false;
3380     }
3381
3382     UnifiedCompositionEntity actualUnifiedCompositionEntity =
3383         unifiedSubstitutionData.getCleanedNodeTemplateCompositionEntity(id);
3384
3385     return actualUnifiedCompositionEntity == null ? false
3386         : actualUnifiedCompositionEntity.equals(expectedUnifiedCompositionEntity);
3387   }
3388
3389   private boolean isHeatStackGroup(String groupType) {
3390     return groupType.equals(ToscaGroupType.HEAT_STACK);
3391   }
3392
3393   private Object getPortPropertyValue(String inputName,
3394                                       String computeType,
3395                                       PropertyInputType portInputType,
3396                                       ServiceTemplate serviceTemplate,
3397                                       String portNodeTemplateId) {
3398     //Get the input prefix to extract the property name from the input name
3399     String portType = ConsolidationDataUtil.getPortType(portNodeTemplateId);
3400     String portInputPrefix = getPropertyInputPrefix(
3401         portNodeTemplateId, portType, portInputType, UnifiedCompositionEntity.PORT);
3402     //Get the property name from the input
3403     Optional<String> propertyName = getPropertyNameFromInput(inputName,
3404         UnifiedCompositionEntity.PORT, computeType, portInputPrefix);
3405     //Get the property value from the node template
3406     if (propertyName.isPresent()) {
3407       NodeTemplate portNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate,
3408           portNodeTemplateId);
3409       if (Objects.nonNull(portNodeTemplate)) {
3410         return getPropertyValueFromNodeTemplate(propertyName.get(), portNodeTemplate);
3411       }
3412     }
3413     return Optional.empty();
3414   }
3415
3416   private Object getComputePropertyValue(
3417       String inputName,
3418       ServiceTemplate serviceTemplate,
3419       ComputeTemplateConsolidationData computeTemplateConsolidationData) {
3420     NodeTemplate nodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate,
3421         computeTemplateConsolidationData.getNodeTemplateId());
3422     String nodeType = getComputeTypeSuffix(nodeTemplate.getType());
3423     Optional<String> propertyName =
3424         getPropertyNameFromInput(inputName, COMPUTE, nodeType, null);
3425     if (propertyName.isPresent()) {
3426       return getPropertyValueFromNodeTemplate(propertyName.get(), nodeTemplate);
3427     }
3428     return Optional.empty();
3429   }
3430
3431   private Object getSubInterfacePropertyValue(String inputName,
3432                                       String subInterfaceTypeSuffix,
3433                                       PropertyInputType propertyInputType,
3434                                       ServiceTemplate serviceTemplate,
3435                                       String subInterfaceNodeTemplateId) {
3436     //Get the input prefix to extract the property name from the input name
3437     String propertyInputPrefix = getPropertyInputPrefix(subInterfaceNodeTemplateId,
3438         subInterfaceTypeSuffix, propertyInputType, UnifiedCompositionEntity.SUB_INTERFACE);
3439     //Get the property name from the input
3440     Optional<String> propertyName = getPropertyNameFromInput(inputName,
3441         UnifiedCompositionEntity.SUB_INTERFACE, null, propertyInputPrefix);
3442     //Get the property value from the node template
3443     if (propertyName.isPresent()) {
3444       NodeTemplate subInterfaceNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate,
3445           subInterfaceNodeTemplateId);
3446       if (Objects.nonNull(subInterfaceNodeTemplate)) {
3447         return getPropertyValueFromNodeTemplate(propertyName.get(), subInterfaceNodeTemplate);
3448       }
3449     }
3450     return Optional.empty();
3451   }
3452
3453   private Optional<Object> getIdenticalPropertyValue(String identicalValuePropertyName,
3454                                                      ServiceTemplate serviceTemplate,
3455                                                      EntityConsolidationData entity,
3456                                                      TranslationContext context) {
3457     NodeTemplate nodeTemplate =
3458         getNodeTemplate(entity.getNodeTemplateId(), serviceTemplate, context);
3459
3460     Object propertyValueFromNodeTemplate =
3461         getPropertyValueFromNodeTemplate(identicalValuePropertyName, nodeTemplate);
3462
3463     return Objects.isNull(propertyValueFromNodeTemplate) ? Optional.empty()
3464         : Optional.of(propertyValueFromNodeTemplate);
3465   }
3466
3467   private UnifiedCompositionEntity getInputCompositionEntity(String inputName) {
3468     UnifiedCompositionEntity inputCompositionEntity = UnifiedCompositionEntity.OTHER;
3469     if (inputName.indexOf('_') != -1) {
3470       String inputType = inputName.substring(0, inputName.indexOf('_'));
3471       if (inputType.equalsIgnoreCase(COMPUTE.getDisplayName())) {
3472         inputCompositionEntity = COMPUTE;
3473       } else if (inputType.equalsIgnoreCase(UnifiedCompositionEntity.PORT.getDisplayName())) {
3474         inputCompositionEntity = UnifiedCompositionEntity.PORT;
3475       } else if (inputType.equalsIgnoreCase(UnifiedCompositionEntity.SUB_INTERFACE
3476           .getDisplayName())) {
3477         inputCompositionEntity = UnifiedCompositionEntity.SUB_INTERFACE;
3478       }
3479     }
3480     return inputCompositionEntity;
3481   }
3482
3483   private Optional<String> getPropertyNameFromInput(
3484       String inputName,
3485       UnifiedCompositionEntity compositionEntity,
3486       String entityType, String propertyInputPrefix) {
3487     String propertyName = null;
3488     switch (compositionEntity) {
3489       case COMPUTE:
3490         propertyName = inputName.substring(inputName.lastIndexOf(entityType)
3491             + entityType.length() + 1);
3492         break;
3493       case PORT:
3494       case SUB_INTERFACE:
3495         if (inputName.startsWith(propertyInputPrefix)) {
3496           propertyName = inputName.split(propertyInputPrefix)[1];
3497         }
3498         break;
3499       default:
3500         break;
3501     }
3502     return Optional.ofNullable(propertyName);
3503   }
3504
3505   private String getPropertyInputPrefix(String nodeTemplateId,
3506                                         String propertyEntityType,
3507                                         PropertyInputType propertyInputType,
3508                                         UnifiedCompositionEntity unifiedCompositionEntity) {
3509     String propertyInputPrefix = unifiedCompositionEntity.getDisplayName().toLowerCase() + "_";
3510     if (propertyInputType == PropertyInputType.NODE_TEMPLATE_ID) {
3511       propertyInputPrefix += nodeTemplateId + "_";
3512     } else if (propertyInputType == PropertyInputType.TYPE) {
3513       propertyInputPrefix += propertyEntityType + "_";
3514     }
3515     return propertyInputPrefix;
3516   }
3517
3518   private boolean isIdenticalValueProperty(String inputName,
3519                                            UnifiedCompositionEntity unifiedCompositionEntity) {
3520
3521     List<String> identicalValuePropertyList =
3522         consolidationService.getPropertiesWithIdenticalVal(unifiedCompositionEntity);
3523
3524     StringBuilder builder = getPropertyValueStringBuilder(unifiedCompositionEntity);
3525     if (Objects.isNull(builder)) {
3526       return false;
3527     }
3528
3529     boolean isMatchingProperty = Pattern.matches(builder.toString(), inputName);
3530     return isMatchingProperty
3531         && isPropertyFromIdenticalValuesList(inputName, unifiedCompositionEntity,
3532         identicalValuePropertyList);
3533   }
3534
3535   private boolean isPropertyFromIdenticalValuesList(String inputName,
3536                                                     UnifiedCompositionEntity unifiedCompositionEntity,
3537                                                     List<String> identicalValuePropertyList) {
3538     switch (unifiedCompositionEntity) {
3539       case COMPUTE:
3540         return identicalValuePropertyList.contains(getIdenticalValuePropertyName(inputName,
3541             unifiedCompositionEntity).get());
3542
3543       case OTHER:
3544         return identicalValuePropertyList.contains(getIdenticalValuePropertyName(inputName,
3545             unifiedCompositionEntity).get());
3546
3547       case PORT:
3548         return getPortPropertyNameFromInput(inputName, identicalValuePropertyList).isPresent();
3549
3550       default:
3551         return false;
3552     }
3553   }
3554
3555   private Optional<String> getPortPropertyNameFromInput(String inputName,
3556                                                         List<String> identicalValuePropertyList) {
3557     for (String identicalProperty : identicalValuePropertyList) {
3558       if (inputName.contains(identicalProperty)) {
3559         return Optional.of(identicalProperty);
3560       }
3561     }
3562     return Optional.empty();
3563   }
3564
3565   private StringBuilder getPropertyValueStringBuilder(
3566       UnifiedCompositionEntity unifiedCompositionEntity) {
3567
3568     switch (unifiedCompositionEntity) {
3569       case COMPUTE:
3570         return getComputePropertyValueStringBuilder();
3571
3572       case OTHER:
3573         return getComputePropertyValueStringBuilder();
3574
3575       case PORT:
3576         return getPortPropertyValueStringBuilder();
3577
3578       case SUB_INTERFACE:
3579         return getSubInterfacePropertyValueStringBuilder();
3580
3581       default:
3582         return null;
3583     }
3584   }
3585
3586   private StringBuilder getPortPropertyValueStringBuilder() {
3587     StringBuilder builder;
3588     builder = new StringBuilder(PORT_IDENTICAL_VALUE_PROPERTY_PREFIX);
3589     builder.append(".+");
3590     return builder;
3591   }
3592
3593   private StringBuilder getComputePropertyValueStringBuilder() {
3594     StringBuilder builder;
3595     builder = new StringBuilder(COMPUTE_IDENTICAL_VALUE_PROPERTY_PREFIX);
3596     builder.append("[a-z]+");
3597     builder.append(COMPUTE_IDENTICAL_VALUE_PROPERTY_SUFFIX);
3598     return builder;
3599   }
3600
3601   private StringBuilder getSubInterfacePropertyValueStringBuilder() {
3602     StringBuilder builder;
3603     builder = new StringBuilder(SUB_INTERFACE_PROPERTY_VALUE_PREFIX);
3604     builder.append(".+");
3605     return builder;
3606   }
3607
3608   private Optional<String> getIdenticalValuePropertyName(String input,
3609                                                          UnifiedCompositionEntity
3610                                                              unifiedCompositionEntity) {
3611     switch (unifiedCompositionEntity) {
3612       case COMPUTE:
3613         return Optional.of(input.split("_")[1]);
3614
3615       case OTHER:
3616         return Optional.of(input.split("_")[1]);
3617
3618       case PORT:
3619         return getPortPropertyNameFromInput(input, consolidationService
3620             .getPropertiesWithIdenticalVal(unifiedCompositionEntity));
3621
3622       default:
3623         return Optional.empty();
3624     }
3625   }
3626
3627   private Object getPropertyValueFromNodeTemplate(String propertyName, NodeTemplate nodeTemplate) {
3628     Map<String, Object> nodeTemplateProperties = nodeTemplate.getProperties();
3629     if (nodeTemplateProperties != null) {
3630       Object propertyValue = nodeTemplateProperties.get(propertyName);
3631       propertyValue = getClonedObject(propertyValue);
3632       return propertyValue;
3633     }
3634     return null;
3635   }
3636
3637   private Map<String, UnifiedCompositionEntity> getAllConsolidationNodeTemplateIdAndType(
3638       List<UnifiedCompositionData> unifiedCompositionDataList) {
3639
3640     Map<String, UnifiedCompositionEntity> consolidationNodeTemplateIdAndType = new HashMap<>();
3641     for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
3642       ComputeTemplateConsolidationData computeTemplateConsolidationData =
3643           unifiedCompositionData.getComputeTemplateConsolidationData();
3644       if (Objects.nonNull(computeTemplateConsolidationData)) {
3645         consolidationNodeTemplateIdAndType
3646             .put(computeTemplateConsolidationData.getNodeTemplateId(),
3647                 COMPUTE);
3648       }
3649       List<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationDataList =
3650           getSubInterfaceTemplateConsolidationDataList(unifiedCompositionData);
3651       for (SubInterfaceTemplateConsolidationData subInterfaceTemplateConsolidationData :
3652           subInterfaceTemplateConsolidationDataList) {
3653         consolidationNodeTemplateIdAndType.put(subInterfaceTemplateConsolidationData.getNodeTemplateId(),
3654             UnifiedCompositionEntity.SUB_INTERFACE);
3655       }
3656       List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
3657           getPortTemplateConsolidationDataList(unifiedCompositionData);
3658       for (PortTemplateConsolidationData portTemplateConsolidationData :
3659           portTemplateConsolidationDataList) {
3660         consolidationNodeTemplateIdAndType.put(portTemplateConsolidationData.getNodeTemplateId(),
3661             UnifiedCompositionEntity.PORT);
3662       }
3663       NestedTemplateConsolidationData nestedTemplateConsolidationData =
3664           unifiedCompositionData.getNestedTemplateConsolidationData();
3665       if (Objects.nonNull(nestedTemplateConsolidationData)) {
3666         consolidationNodeTemplateIdAndType
3667             .put(nestedTemplateConsolidationData.getNodeTemplateId(),
3668                 UnifiedCompositionEntity.NESTED);
3669       }
3670     }
3671     return consolidationNodeTemplateIdAndType;
3672   }
3673
3674   private List<PortTemplateConsolidationData> getPortTemplateConsolidationDataList(
3675       UnifiedCompositionData unifiedCompositionData) {
3676     return unifiedCompositionData.getPortTemplateConsolidationDataList() == null ? new
3677         ArrayList<>() : unifiedCompositionData.getPortTemplateConsolidationDataList();
3678   }
3679
3680   private enum PropertyInputType {
3681     NODE_TEMPLATE_ID,
3682     TYPE,
3683     OTHER
3684   }
3685 }