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