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