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