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