[SDC-29] rebase continue work to align source
[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  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.translator.services.heattotosca;
22
23 import org.apache.commons.collections.map.HashedMap;
24 import org.apache.commons.collections4.CollectionUtils;
25 import org.apache.commons.collections4.MapUtils;
26 import org.apache.commons.lang3.StringUtils;
27 import org.apache.commons.lang3.tuple.ImmutablePair;
28 import org.apache.commons.lang3.tuple.Pair;
29 import org.openecomp.config.api.Configuration;
30 import org.openecomp.config.api.ConfigurationManager;
31 import org.openecomp.core.utilities.CommonMethods;
32 import org.openecomp.core.utilities.yaml.YamlUtil;
33 import org.openecomp.sdc.datatypes.configuration.ImplementationConfiguration;
34 import org.openecomp.sdc.heat.services.HeatConstants;
35 import org.openecomp.sdc.logging.api.Logger;
36 import org.openecomp.sdc.logging.api.LoggerFactory;
37 import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage;
38 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
39 import org.openecomp.sdc.tosca.datatypes.ToscaGroupType;
40 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
41 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
42 import org.openecomp.sdc.tosca.datatypes.model.CapabilityDefinition;
43 import org.openecomp.sdc.tosca.datatypes.model.Constraint;
44 import org.openecomp.sdc.tosca.datatypes.model.EntrySchema;
45 import org.openecomp.sdc.tosca.datatypes.model.GroupDefinition;
46 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
47 import org.openecomp.sdc.tosca.datatypes.model.NodeType;
48 import org.openecomp.sdc.tosca.datatypes.model.ParameterDefinition;
49 import org.openecomp.sdc.tosca.datatypes.model.PropertyDefinition;
50 import org.openecomp.sdc.tosca.datatypes.model.PropertyType;
51 import org.openecomp.sdc.tosca.datatypes.model.RelationshipTemplate;
52 import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
53 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
54 import org.openecomp.sdc.tosca.datatypes.model.SubstitutionMapping;
55 import org.openecomp.sdc.tosca.datatypes.model.heatextend.PropertyTypeExt;
56 import org.openecomp.sdc.tosca.services.DataModelUtil;
57 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
58 import org.openecomp.sdc.tosca.services.ToscaConstants;
59 import org.openecomp.sdc.tosca.services.ToscaUtil;
60 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
61 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
62 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedCompositionData;
63 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedCompositionEntity;
64 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedCompositionMode;
65 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedSubstitutionData;
66 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.ComputeTemplateConsolidationData;
67 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.ConsolidationData;
68 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.EntityConsolidationData;
69 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.FileComputeConsolidationData;
70 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.FilePortConsolidationData;
71 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.GetAttrFuncData;
72 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.NestedTemplateConsolidationData;
73 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.PortTemplateConsolidationData;
74 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.RequirementAssignmentData;
75 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.TypeComputeConsolidationData;
76
77 import java.io.ByteArrayInputStream;
78 import java.io.ByteArrayOutputStream;
79 import java.io.IOException;
80 import java.io.NotSerializableException;
81 import java.io.ObjectInputStream;
82 import java.io.ObjectOutputStream;
83 import java.util.ArrayList;
84 import java.util.Collection;
85 import java.util.HashMap;
86 import java.util.HashSet;
87 import java.util.LinkedHashMap;
88 import java.util.List;
89 import java.util.Map;
90 import java.util.Objects;
91 import java.util.Optional;
92 import java.util.Set;
93 import java.util.regex.Pattern;
94
95 import static org.openecomp.sdc.translator.services.heattotosca.Constants.ABSTRACT_NODE_TEMPLATE_ID_PREFIX;
96 import static org.openecomp.sdc.translator.services.heattotosca.Constants.IDENTICAL_VALUE_PROPERTY_PREFIX;
97 import static org.openecomp.sdc.translator.services.heattotosca.Constants.IDENTICAL_VALUE_PROPERTY_SUFFIX;
98
99 public class UnifiedCompositionService {
100
101   protected static Logger logger =
102       (Logger) LoggerFactory.getLogger(UnifiedCompositionService.class);
103   protected static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
104   private static Map<String, ImplementationConfiguration> unifiedCompositionImplMap;
105
106   static {
107     Configuration config = ConfigurationManager.lookup();
108     unifiedCompositionImplMap =
109         config.populateMap(ConfigConstants.MANDATORY_UNIFIED_MODEL_NAMESPACE,
110             ConfigConstants.UNIFIED_COMPOSITION_IMPL_KEY, ImplementationConfiguration.class);
111
112   }
113
114   private ConsolidationService consolidationService = new ConsolidationService();
115
116   private static List<EntityConsolidationData> getPortConsolidationDataList(
117       Set<String> portIds,
118       List<UnifiedCompositionData> unifiedCompositionDataList) {
119     List<EntityConsolidationData> portConsolidationDataList = new ArrayList<>();
120     for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
121       for (PortTemplateConsolidationData portTemplateConsolidationData : unifiedCompositionData
122           .getPortTemplateConsolidationDataList()) {
123         if (portIds.contains(portTemplateConsolidationData.getNodeTemplateId())) {
124           portConsolidationDataList.add(portTemplateConsolidationData);
125         }
126       }
127     }
128     return portConsolidationDataList;
129   }
130
131   /**
132    * Create unified composition.
133    *
134    * @param serviceTemplate            the service template
135    * @param nestedServiceTemplate      the nested service template
136    * @param unifiedCompositionDataList the unified composition data list. In case no consolidation,
137    *                                   one entry will be in this list, in case of having
138    *                                   consolidation, all entries in the list are the once which
139    *                                   need to be consolidated.
140    * @param mode                       the mode
141    * @param context                    the context
142    */
143   public void createUnifiedComposition(ServiceTemplate serviceTemplate,
144                                        ServiceTemplate nestedServiceTemplate,
145                                        List<UnifiedCompositionData> unifiedCompositionDataList,
146                                        UnifiedCompositionMode mode, TranslationContext context) {
147     mdcDataDebugMessage.debugEntryMessage(null, null);
148     Optional<UnifiedComposition> unifiedCompositionInstance = getUnifiedCompositionInstance(mode);
149     if (!unifiedCompositionInstance.isPresent()) {
150       return;
151     }
152     unifiedCompositionInstance.get()
153         .createUnifiedComposition(serviceTemplate, nestedServiceTemplate,
154             unifiedCompositionDataList, context);
155     mdcDataDebugMessage.debugExitMessage(null, null);
156   }
157
158   /**
159    * Create unified substitution service template according to the input service template, based on
160    * the unified composition data.
161    *
162    * @param serviceTemplate            the service template
163    * @param unifiedCompositionDataList the unified composition data list. In case no consolidation,
164    *                                   one entry will be in this list, in case of having
165    *                                   consolidation, all entries in the list are the once which
166    *                                   need to be consolidated.
167    * @param context                    the translation context
168    * @return the substitution service template
169    */
170   public Optional<ServiceTemplate> createUnifiedSubstitutionServiceTemplate(
171       ServiceTemplate serviceTemplate, List<UnifiedCompositionData> unifiedCompositionDataList,
172       TranslationContext context, Integer index) {
173     if (CollectionUtils.isEmpty(unifiedCompositionDataList)) {
174       return Optional.empty();
175     }
176     UnifiedCompositionData unifiedCompositionData = unifiedCompositionDataList.get(0);
177     String templateName =
178         getTemplateName(serviceTemplate, unifiedCompositionData, index);
179     ServiceTemplate substitutionServiceTemplate =
180         HeatToToscaUtil.createInitSubstitutionServiceTemplate(templateName);
181
182     createIndexInputParameter(substitutionServiceTemplate);
183
184     String computeNodeType =
185         handleCompute(serviceTemplate, substitutionServiceTemplate, unifiedCompositionDataList,
186             context);
187     handlePorts(serviceTemplate, substitutionServiceTemplate, unifiedCompositionDataList,
188         computeNodeType, context);
189     createOutputParameters(serviceTemplate, substitutionServiceTemplate, unifiedCompositionDataList,
190         computeNodeType);
191     NodeType substitutionGlobalNodeType =
192         handleSubstitutionGlobalNodeType(serviceTemplate, substitutionServiceTemplate,
193             context, unifiedCompositionData, index);
194
195     HeatToToscaUtil.handleSubstitutionMapping(context,
196         getSubstitutionNodeTypeId(serviceTemplate, unifiedCompositionData, index),
197         substitutionServiceTemplate, substitutionGlobalNodeType);
198
199     context.getTranslatedServiceTemplates().put(templateName, substitutionServiceTemplate);
200     return Optional.of(substitutionServiceTemplate);
201   }
202
203   /**
204    * Create abstract substitute node template that can be substituted by the input
205    * substitutionServiceTemplate.
206    *
207    * @param serviceTemplate             the service template
208    * @param substitutionServiceTemplate the subtitution service template
209    * @param unifiedCompositionDataList  the unified composition data list. In case no consolidation,
210    *                                    one entry will be in this list, in case of having
211    *                                    consolidation, all entries in the list are the once which
212    *                                    need to be consolidated.
213    * @param context                     the translation context
214    * @return the abstract substitute node template id
215    */
216   public String createAbstractSubstituteNodeTemplate(
217       ServiceTemplate serviceTemplate,
218       ServiceTemplate substitutionServiceTemplate,
219       List<UnifiedCompositionData> unifiedCompositionDataList,
220       TranslationContext context,
221       Integer index) {
222
223     NodeTemplate substitutionNodeTemplate = new NodeTemplate();
224     List<String> directiveList = new ArrayList<>();
225     directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
226     substitutionNodeTemplate.setDirectives(directiveList);
227     String substituteNodeTemplateType =
228         getSubstitutionNodeTypeId(serviceTemplate, unifiedCompositionDataList.get(0), index);
229     substitutionNodeTemplate.setType(substituteNodeTemplateType);
230     Optional<Map<String, Object>> abstractSubstitutionProperties =
231         createAbstractSubstitutionProperties(serviceTemplate,
232             substitutionServiceTemplate, unifiedCompositionDataList);
233     abstractSubstitutionProperties.ifPresent(substitutionNodeTemplate::setProperties);
234
235     //Add substitution filtering property
236     String substitutionServiceTemplateName = ToscaUtil.getServiceTemplateFileName(
237         substitutionServiceTemplate);
238     int count = unifiedCompositionDataList.size();
239     addSubstitutionFilteringProperty(substitutionServiceTemplateName, substitutionNodeTemplate,
240         count);
241     //Add index_value property
242     addIndexValueProperty(substitutionNodeTemplate);
243     String substituteNodeTemplateId =
244         getSubstituteNodeTemplateId(serviceTemplate, unifiedCompositionDataList.get(0), index);
245     //Add node template id and related abstract node template id in context
246     addUnifiedSubstitionData(context, serviceTemplate, unifiedCompositionDataList,
247         substituteNodeTemplateId);
248     DataModelUtil
249         .addNodeTemplate(serviceTemplate, substituteNodeTemplateId, substitutionNodeTemplate);
250     return substituteNodeTemplateId;
251
252   }
253
254   /**
255    * Update the connectivity from/to the "moved" nodes from the original service template to the new
256    * substitution service template.
257    *
258    * @param serviceTemplate            the service template
259    * @param unifiedCompositionDataList the unified composition data list. In case no consolidation,
260    *                                   one entry will be in this list, in case of having
261    *                                   consolidation, all entries in the list are the once which
262    *                                   need to be consolidated.
263    * @param context                    the translation context
264    */
265   public void updateCompositionConnectivity(ServiceTemplate serviceTemplate,
266                                             List<UnifiedCompositionData> unifiedCompositionDataList,
267                                             TranslationContext context) {
268     updOutputParamGetAttrInConnectivity(serviceTemplate, unifiedCompositionDataList, context);
269     updNodesGetAttrInConnectivity(serviceTemplate, unifiedCompositionDataList, context);
270     updNodesConnectedOutConnectivity(serviceTemplate, unifiedCompositionDataList, context);
271     updNodesConnectedInConnectivity(serviceTemplate, unifiedCompositionDataList, context);
272     updVolumeConnectivity(serviceTemplate, unifiedCompositionDataList, context);
273     updGroupsConnectivity(serviceTemplate, unifiedCompositionDataList, context);
274   }
275
276   /**
277    * Delete the "moved" nodes from the original service template to the new substitution service
278    * template.
279    *
280    * @param serviceTemplate            the service template
281    * @param unifiedCompositionDataList the unified composition data list. In case no consolidation,
282    *                                   one entry will be in this list, in case of having
283    *                                   consolidation, all entries in the list are the once which
284    *                                   need to be consolidated.
285    * @param context                    the translation context
286    */
287   public void cleanUnifiedCompositionEntities(
288       ServiceTemplate serviceTemplate,
289       List<UnifiedCompositionData> unifiedCompositionDataList,
290       TranslationContext context) {
291     for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
292       ComputeTemplateConsolidationData computeTemplateConsolidationData =
293           unifiedCompositionData.getComputeTemplateConsolidationData();
294       cleanServiceTemplate(serviceTemplate, computeTemplateConsolidationData, context);
295
296       List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
297           getPortTemplateConsolidationDataList(unifiedCompositionData);
298       for (PortTemplateConsolidationData portTemplateConsolidationData :
299           portTemplateConsolidationDataList) {
300         cleanServiceTemplate(serviceTemplate, portTemplateConsolidationData, context);
301       }
302     }
303
304   }
305
306   public void cleanNodeTypes(ServiceTemplate serviceTemplate,
307                              List<UnifiedCompositionData> unifiedCompositionDataList,
308                              TranslationContext context) {
309     for (UnifiedCompositionData unifiedData : unifiedCompositionDataList) {
310       removeCleanedNodeType(
311           unifiedData.getComputeTemplateConsolidationData().getNodeTemplateId(), serviceTemplate,
312           context);
313     }
314
315     if (MapUtils.isEmpty(serviceTemplate.getNode_types())) {
316       serviceTemplate.setNode_types(null);
317     }
318   }
319
320   /**
321    * Update unified abstract nodes connectivity.
322    *
323    * @param serviceTemplate the service template
324    * @param context         the context
325    */
326   public void updateUnifiedAbstractNodesConnectivity(ServiceTemplate serviceTemplate,
327                                                      TranslationContext context) {
328
329
330     String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
331     UnifiedSubstitutionData unifiedSubstitutionData = context.getUnifiedSubstitutionData()
332         .get(serviceTemplateFileName);
333
334     if (Objects.nonNull(unifiedSubstitutionData)) {
335       //Handle get attribute in connectivity for abstarct node to abstract node templates
336       Set<String> abstractNodeIds =
337           new HashSet<>(unifiedSubstitutionData.getAllRelatedAbstractNodeIds());
338       handleGetAttrInConnectivity(serviceTemplate, abstractNodeIds, context);
339       //Handle get attribute in connectivity for abstract node templates to nested node template
340       Set<String> nestedNodeIds =
341           new HashSet<>(unifiedSubstitutionData.getAllUnifiedNestedNodeTemplateIds());
342       handleGetAttrInConnectivity(serviceTemplate, nestedNodeIds, context);
343     }
344   }
345
346   public void handleUnifiedNestedDefinition(ServiceTemplate mainServiceTemplate,
347                                             ServiceTemplate nestedServiceTemplate,
348                                             List<UnifiedCompositionData> unifiedCompositionDataList,
349                                             TranslationContext context) {
350     handleUnifiedNestedNodeType(mainServiceTemplate, nestedServiceTemplate, context);
351     updateUnifiedNestedTemplates(mainServiceTemplate, nestedServiceTemplate,
352         unifiedCompositionDataList, context);
353   }
354
355   private void handleGetAttrInConnectivity(ServiceTemplate serviceTemplate,
356                                            Set<String> unifiedNodeIds,
357                                            TranslationContext context) {
358     Map<String, NodeTemplate> nodeTemplates =
359         serviceTemplate.getTopology_template().getNode_templates();
360     String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
361     for (String unifiedNodeId : unifiedNodeIds) {
362       NodeTemplate nodeTemplate = nodeTemplates.get(unifiedNodeId);
363       handleGetAttrInAbstractNodeTemplate(serviceTemplate, context, serviceTemplateFileName,
364           nodeTemplate);
365     }
366   }
367
368   private void handleUnifiedNestedNodeType(ServiceTemplate mainServiceTemplate,
369                                            ServiceTemplate nestedServiceTemplate,
370                                            TranslationContext context) {
371
372
373     SubstitutionMapping substitutionMappings =
374         nestedServiceTemplate.getTopology_template().getSubstitution_mappings();
375     String nodeTypeId = substitutionMappings.getNode_type();
376
377     Optional<String> newNestedNodeTypeId =
378         getNewNestedNodeTypeId(mainServiceTemplate, nestedServiceTemplate, context);
379
380     if (isNestedServiceTemplateWasHandled(mainServiceTemplate, nestedServiceTemplate, context,
381         newNestedNodeTypeId)) {
382       context.updateHandledComputeType(
383           ToscaUtil.getServiceTemplateFileName(mainServiceTemplate),
384           ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate),
385           newNestedNodeTypeId.get());
386       return;
387     }
388
389     ServiceTemplate globalSubstitutionServiceTemplate =
390         context.getGlobalSubstitutionServiceTemplate();
391
392     newNestedNodeTypeId.ifPresent(
393         newNestedNodeTypeIdVal -> handleNestedNodeType(nodeTypeId, newNestedNodeTypeIdVal,
394             nestedServiceTemplate, mainServiceTemplate, globalSubstitutionServiceTemplate,
395             context));
396
397   }
398
399   private boolean isNestedServiceTemplateWasHandled(ServiceTemplate mainServiceTemplate,
400                                                     ServiceTemplate nestedServiceTemplate,
401                                                     TranslationContext context,
402                                                     Optional<String> newNestedNodeTypeId) {
403     return newNestedNodeTypeId.isPresent()
404         && context.isNestedServiceTemplateWasHandled(
405         ToscaUtil.getServiceTemplateFileName(mainServiceTemplate),
406         ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate));
407   }
408
409   private void handleNestedNodeType(String nodeTypeId, String newNestedNodeTypeId,
410                                     ServiceTemplate nestedServiceTemplate,
411                                     ServiceTemplate mainServiceTemplate,
412                                     ServiceTemplate globalSubstitutionServiceTemplate,
413                                     TranslationContext context) {
414     updateNestedServiceTemplate(nestedServiceTemplate, context);
415     updateNestedNodeType(nodeTypeId, newNestedNodeTypeId, nestedServiceTemplate,
416         mainServiceTemplate,
417         globalSubstitutionServiceTemplate, context);
418
419
420   }
421
422   private void updateNestedServiceTemplate(ServiceTemplate nestedServiceTemplate,
423                                            TranslationContext context) {
424     enrichPortProperties(nestedServiceTemplate, context);
425   }
426
427   private void enrichPortProperties(ServiceTemplate nestedServiceTemplate,
428                                     TranslationContext context) {
429     String nestedServiceTemplateFileName =
430         ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate);
431     FilePortConsolidationData filePortConsolidationData =
432         context.getConsolidationData().getPortConsolidationData().getFilePortConsolidationData
433             (nestedServiceTemplateFileName);
434
435     if (Objects.nonNull(filePortConsolidationData)) {
436       Set<String> portNodeTemplateIds = filePortConsolidationData.getAllPortNodeTemplateIds();
437       if (Objects.nonNull(portNodeTemplateIds)) {
438         for (String portNodeTemplateId : portNodeTemplateIds) {
439           NodeTemplate portNodeTemplate = DataModelUtil.getNodeTemplate(nestedServiceTemplate,
440               portNodeTemplateId);
441           List<EntityConsolidationData> portEntityConsolidationDataList = new ArrayList<>();
442           portEntityConsolidationDataList.add(filePortConsolidationData
443               .getPortTemplateConsolidationData(portNodeTemplateId));
444
445           handleNodeTypeProperties(nestedServiceTemplate,
446               portEntityConsolidationDataList, portNodeTemplate, UnifiedCompositionEntity.Port,
447               null, context);
448         }
449       }
450     }
451   }
452
453   private void updateNestedNodeType(String nodeTypeId, String newNestedNodeTypeId,
454                                     ServiceTemplate nestedServiceTemplate,
455                                     ServiceTemplate mainServiceTemplate,
456                                     ServiceTemplate globalSubstitutionServiceTemplate,
457                                     TranslationContext context) {
458     String indexedNewNestedNodeTypeId =
459         updateNodeTypeId(nodeTypeId, newNestedNodeTypeId, nestedServiceTemplate,
460             mainServiceTemplate,
461             globalSubstitutionServiceTemplate, context);
462
463     updateNodeTypeProperties(nestedServiceTemplate, globalSubstitutionServiceTemplate,
464         indexedNewNestedNodeTypeId);
465   }
466
467   private void updateNodeTypeProperties(ServiceTemplate nestedServiceTemplate,
468                                         ServiceTemplate globalSubstitutionServiceTemplate,
469                                         String nodeTypeId) {
470     ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
471     Map<String, PropertyDefinition> nodeTypePropertiesDefinition =
472         toscaAnalyzerService.manageSubstitutionNodeTypeProperties(nestedServiceTemplate);
473     NodeType nestedNodeType =
474         DataModelUtil.getNodeType(globalSubstitutionServiceTemplate, nodeTypeId);
475     nestedNodeType.setProperties(nodeTypePropertiesDefinition);
476   }
477
478   private String updateNodeTypeId(String nodeTypeId, String newNestedNodeTypeId,
479                                   ServiceTemplate nestedServiceTemplate,
480                                   ServiceTemplate mainServiceTemplate,
481                                   ServiceTemplate globalSubstitutionServiceTemplate,
482                                   TranslationContext context) {
483     context.addNestedFileToUsedNestedComputeType(
484         ToscaUtil.getServiceTemplateFileName(mainServiceTemplate),
485         ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate),
486         newNestedNodeTypeId);
487     String indexedNewNestedNodeTypeId =
488         handleNestedNodeTypeInGlobalSubstitutionTemplate(nodeTypeId, newNestedNodeTypeId,
489             mainServiceTemplate, globalSubstitutionServiceTemplate, context);
490
491     handleSubstitutionMappingInNestedServiceTemplate(indexedNewNestedNodeTypeId,
492         nestedServiceTemplate);
493
494     context
495         .updateHandledComputeType(
496             ToscaUtil.getServiceTemplateFileName(mainServiceTemplate),
497             ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate),
498             newNestedNodeTypeId);
499     return indexedNewNestedNodeTypeId;
500   }
501
502   private String handleNestedNodeTypeInGlobalSubstitutionTemplate(String nodeTypeId,
503                                                                   String newNestedNodeTypeId,
504                                                                   ServiceTemplate mainServiceTemplate,
505                                                                   ServiceTemplate globalSubstitutionServiceTemplate,
506                                                                   TranslationContext context) {
507     String indexedNodeType =
508         getIndexedGlobalNodeTypeId(newNestedNodeTypeId, mainServiceTemplate, context);
509     handleNestedNodeTypesInGlobalSubstituteServiceTemplate(nodeTypeId, indexedNodeType,
510         globalSubstitutionServiceTemplate, context);
511     return indexedNodeType;
512   }
513
514   private String getIndexedGlobalNodeTypeId(String newNestedNodeTypeId,
515                                             ServiceTemplate mainServiceTemplate,
516                                             TranslationContext context) {
517     int globalNodeTypeIndex =
518         context.getGlobalNodeTypeIndex(ToscaUtil.getServiceTemplateFileName(mainServiceTemplate),
519             newNestedNodeTypeId);
520     return globalNodeTypeIndex > 0 ?
521         newNestedNodeTypeId + "_" + String.valueOf(globalNodeTypeIndex) : newNestedNodeTypeId;
522   }
523
524   private void updateUnifiedNestedTemplates(ServiceTemplate mainServiceTemplate,
525                                             ServiceTemplate nestedServiceTemplate,
526                                             List<UnifiedCompositionData> unifiedCompositionDataList,
527                                             TranslationContext context) {
528
529     for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
530       NestedTemplateConsolidationData nestedTemplateConsolidationData =
531           unifiedCompositionData.getNestedTemplateConsolidationData();
532       if (Objects.isNull(nestedTemplateConsolidationData)) {
533         continue;
534       }
535       handleNestedNodeTemplateInMainServiceTemplate(
536           nestedTemplateConsolidationData.getNodeTemplateId(), mainServiceTemplate,
537           nestedServiceTemplate, context);
538     }
539   }
540
541   /**
542    * Update connectivity for unified nested patterns.
543    *
544    * @param serviceTemplate            the service template
545    * @param nestedServiceTemplate      the nested service template
546    * @param unifiedCompositionDataList the unified composition data list
547    * @param context                    the context
548    */
549   public void updateUnifiedNestedConnectivity(ServiceTemplate serviceTemplate,
550                                               ServiceTemplate nestedServiceTemplate,
551                                               List<UnifiedCompositionData>
552                                                   unifiedCompositionDataList,
553                                               TranslationContext context) {
554
555     updNestedCompositionNodesConnectedInConnectivity(serviceTemplate, unifiedCompositionDataList,
556         context);
557     updNestedCompositionNodesGetAttrInConnectivity(serviceTemplate, unifiedCompositionDataList,
558         context);
559     updNestedCompositionOutputParamGetAttrInConnectivity(serviceTemplate,
560         unifiedCompositionDataList, context);
561   }
562
563
564   /**
565    * Clean unified nested entities. Update the heat stack group with the new node template ids.
566    *
567    * @param serviceTemplate            the service template
568    * @param unifiedCompositionDataList the unified composition data list
569    * @param context                    the context
570    */
571   public void cleanUnifiedNestedEntities(ServiceTemplate serviceTemplate,
572                                          List<UnifiedCompositionData> unifiedCompositionDataList,
573                                          TranslationContext context) {
574     EntityConsolidationData entityConsolidationData = unifiedCompositionDataList.get(0)
575         .getNestedTemplateConsolidationData();
576     updateHeatStackGroupNestedComposition(serviceTemplate, entityConsolidationData, context);
577
578   }
579
580   protected void updNodesConnectedOutConnectivity(ServiceTemplate serviceTemplate,
581                                                   List<UnifiedCompositionData>
582                                                       unifiedCompositionDataList,
583                                                   TranslationContext context) {
584     for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
585       ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData
586           .getComputeTemplateConsolidationData();
587       //Add requirements in the abstract node template for nodes connected out for computes
588       String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate,
589           computeTemplateConsolidationData.getNodeTemplateId());
590       Map<String, List<RequirementAssignmentData>> computeNodesConnectedOut =
591           computeTemplateConsolidationData.getNodesConnectedOut();
592       if (computeNodesConnectedOut != null) {
593         updateRequirementInAbstractNodeTemplate(serviceTemplate, computeTemplateConsolidationData,
594             newComputeNodeTemplateId, computeNodesConnectedOut, context);
595       }
596       String computeType = getComputeTypeSuffix(serviceTemplate, computeTemplateConsolidationData
597           .getNodeTemplateId());
598       //Add requirements in the abstract node template for nodes connected out for ports
599       List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
600           getPortTemplateConsolidationDataList(unifiedCompositionData);
601       for (PortTemplateConsolidationData portTemplateConsolidationData :
602           portTemplateConsolidationDataList) {
603         String newPortNodeTemplateId = getNewPortNodeTemplateId(portTemplateConsolidationData
604             .getNodeTemplateId(), computeType, computeTemplateConsolidationData);
605         Map<String, List<RequirementAssignmentData>> portNodesConnectedOut =
606             portTemplateConsolidationData.getNodesConnectedOut();
607         if (portNodesConnectedOut != null) {
608           updateRequirementInAbstractNodeTemplate(serviceTemplate, portTemplateConsolidationData,
609               newPortNodeTemplateId, portNodesConnectedOut, context);
610         }
611       }
612     }
613   }
614
615   protected void updNodesConnectedInConnectivity(ServiceTemplate serviceTemplate,
616                                                  List<UnifiedCompositionData>
617                                                      unifiedCompositionDataList,
618                                                  TranslationContext context) {
619     for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
620       ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData
621           .getComputeTemplateConsolidationData();
622       //Update requirements in the node template which pointing to the computes
623       String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate,
624           computeTemplateConsolidationData.getNodeTemplateId());
625       updNodesConnectedInConnectivity(serviceTemplate, computeTemplateConsolidationData,
626           newComputeNodeTemplateId, context, false);
627
628       String computeType = getComputeTypeSuffix(serviceTemplate, computeTemplateConsolidationData
629           .getNodeTemplateId());
630       //Update requirements in the node template which pointing to the ports
631       List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
632           getPortTemplateConsolidationDataList(unifiedCompositionData);
633       for (PortTemplateConsolidationData portTemplateConsolidationData :
634           portTemplateConsolidationDataList) {
635         String newPortNodeTemplateId = getNewPortNodeTemplateId(portTemplateConsolidationData
636             .getNodeTemplateId(), computeType, computeTemplateConsolidationData);
637         updNodesConnectedInConnectivity(serviceTemplate, portTemplateConsolidationData,
638             newPortNodeTemplateId, context, false);
639       }
640     }
641   }
642
643   private void updNodesConnectedInConnectivity(ServiceTemplate serviceTemplate,
644                                                EntityConsolidationData entityConsolidationData,
645                                                String newNodeTemplateId,
646                                                TranslationContext context,
647                                                boolean isNested) {
648     Map<String, List<RequirementAssignmentData>> nodesConnectedIn =
649         entityConsolidationData.getNodesConnectedIn();
650     if (nodesConnectedIn == null) {
651       //No nodes connected in info
652       return;
653     }
654     for (Map.Entry<String, List<RequirementAssignmentData>> entry : nodesConnectedIn
655         .entrySet()) {
656       List<RequirementAssignmentData> requirementAssignmentDataList = entry.getValue();
657       for (RequirementAssignmentData requirementAssignmentData : requirementAssignmentDataList) {
658         RequirementAssignment requirementAssignment = requirementAssignmentData
659             .getRequirementAssignment();
660         if (!requirementAssignment.getNode().equals(entityConsolidationData
661             .getNodeTemplateId())) {
662           //The requirement assignment target node should be the one which we are handling in the
663           //consolidation object
664           continue;
665         }
666         //Update the requirement assignment object in the original node template
667         if (isNested) {
668           updateRequirementForNestedCompositionNodesConnectedIn(serviceTemplate,
669               requirementAssignmentData, entityConsolidationData, newNodeTemplateId, context);
670         } else {
671           updateRequirementForNodesConnectedIn(serviceTemplate, requirementAssignmentData,
672               entityConsolidationData, entry.getKey(), newNodeTemplateId, context);
673         }
674
675       }
676     }
677   }
678
679   protected void updNestedCompositionNodesConnectedInConnectivity(ServiceTemplate serviceTemplate,
680                                                                   List<UnifiedCompositionData>
681                                                                       unifiedCompositionDataList,
682                                                                   TranslationContext context) {
683     for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
684       NestedTemplateConsolidationData nestedTemplateConsolidationData = unifiedCompositionData
685           .getNestedTemplateConsolidationData();
686       //Update requirements in the node template which pointing to the nested nodes
687       String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
688       Optional<String> newNestedNodeTemplateId = context.getUnifiedNestedNodeTemplateId(
689           serviceTemplateFileName, nestedTemplateConsolidationData.getNodeTemplateId());
690       newNestedNodeTemplateId.ifPresent(
691           newNestedNodeTemplateIdVal -> updNodesConnectedInConnectivity(serviceTemplate,
692               nestedTemplateConsolidationData,
693               newNestedNodeTemplateIdVal, context, true));
694     }
695   }
696
697   protected void updVolumeConnectivity(ServiceTemplate serviceTemplate,
698                                        List<UnifiedCompositionData>
699                                            unifiedCompositionDataList,
700                                        TranslationContext context) {
701     for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
702       ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData
703           .getComputeTemplateConsolidationData();
704       //Add requirements in the abstract node template for compute volumes
705       String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate,
706           computeTemplateConsolidationData.getNodeTemplateId());
707       Map<String, List<RequirementAssignmentData>> computeVolumes =
708           computeTemplateConsolidationData.getVolumes();
709       if (computeVolumes != null) {
710         updateRequirementInAbstractNodeTemplate(serviceTemplate, computeTemplateConsolidationData,
711             newComputeNodeTemplateId, computeVolumes, context);
712       }
713     }
714   }
715
716   protected void updGroupsConnectivity(ServiceTemplate serviceTemplate,
717                                        List<UnifiedCompositionData>
718                                            unifiedCompositionDataList,
719                                        TranslationContext context) {
720     for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
721       ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData
722           .getComputeTemplateConsolidationData();
723       //Add requirements in the abstract node template for nodes connected in for computes
724       String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate,
725           computeTemplateConsolidationData.getNodeTemplateId());
726       updGroupsConnectivity(serviceTemplate, computeTemplateConsolidationData, context);
727
728       String computeType = getComputeTypeSuffix(serviceTemplate, computeTemplateConsolidationData
729           .getNodeTemplateId());
730       //Add requirements in the abstract node template for nodes connected in for ports
731       List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
732           getPortTemplateConsolidationDataList(unifiedCompositionData);
733       for (PortTemplateConsolidationData portTemplateConsolidationData :
734           portTemplateConsolidationDataList) {
735         String newPortNodeTemplateId = getNewPortNodeTemplateId(portTemplateConsolidationData
736             .getNodeTemplateId(), computeType, computeTemplateConsolidationData);
737         updGroupsConnectivity(serviceTemplate, portTemplateConsolidationData, context);
738       }
739     }
740   }
741
742   private void updGroupsConnectivity(ServiceTemplate serviceTemplate, EntityConsolidationData
743       entityConsolidationData, TranslationContext context) {
744     List<String> groupIds = entityConsolidationData.getGroupIds();
745     if (groupIds == null) {
746       return;
747     }
748     String oldNodeTemplateId = entityConsolidationData.getNodeTemplateId();
749     String abstractNodeTemplateId = context.getUnifiedAbstractNodeTemplateId(
750         serviceTemplate, entityConsolidationData.getNodeTemplateId());
751     Map<String, GroupDefinition> groups = serviceTemplate.getTopology_template().getGroups();
752     if (groups != null) {
753       for (String groupId : groupIds) {
754         GroupDefinition groupDefinition = groups.get(groupId);
755         if (groupDefinition != null) {
756           List<String> groupMembers = groupDefinition.getMembers();
757           if (groupMembers.contains(oldNodeTemplateId)) {
758             //Replace the old node template id
759             groupMembers.remove(oldNodeTemplateId);
760             if (!groupMembers.contains(abstractNodeTemplateId)) {
761               //Add the abstract node template id if not already present
762               groupMembers.add(abstractNodeTemplateId);
763             }
764           }
765         }
766       }
767     }
768   }
769
770   protected void updOutputParamGetAttrInConnectivity(
771       ServiceTemplate serviceTemplate, List<UnifiedCompositionData> unifiedComposotionDataList,
772       TranslationContext context) {
773     for (UnifiedCompositionData unifiedCompositionData : unifiedComposotionDataList) {
774       ComputeTemplateConsolidationData computeTemplateConsolidationData =
775           unifiedCompositionData.getComputeTemplateConsolidationData();
776       String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate,
777           computeTemplateConsolidationData.getNodeTemplateId());
778
779       updOutputParamGetAttrInConnectivity(serviceTemplate, computeTemplateConsolidationData,
780           computeTemplateConsolidationData.getNodeTemplateId(), newComputeNodeTemplateId,
781           context, false);
782
783       String computeType =
784           getComputeTypeSuffix(serviceTemplate,
785               computeTemplateConsolidationData.getNodeTemplateId());
786       List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
787           getPortTemplateConsolidationDataList(unifiedCompositionData);
788       for (PortTemplateConsolidationData portTemplateConsolidationData :
789           portTemplateConsolidationDataList) {
790         String newPortNodeTemplateId =
791             getNewPortNodeTemplateId(portTemplateConsolidationData.getNodeTemplateId(), computeType,
792                 computeTemplateConsolidationData);
793
794         updOutputParamGetAttrInConnectivity(serviceTemplate, portTemplateConsolidationData,
795             portTemplateConsolidationData.getNodeTemplateId(), newPortNodeTemplateId, context,
796             false);
797       }
798     }
799   }
800
801   protected void updNodesGetAttrInConnectivity(
802       ServiceTemplate serviceTemplate,
803       List<UnifiedCompositionData> unifiedComposotionDataList,
804       TranslationContext context) {
805     Map<String, UnifiedCompositionEntity> consolidationNodeTemplateIdAndType =
806         getAllConsolidationNodeTemplateIdAndType(unifiedComposotionDataList);
807     for (UnifiedCompositionData unifiedCompositionData : unifiedComposotionDataList) {
808       ComputeTemplateConsolidationData computeTemplateConsolidationData =
809           unifiedCompositionData.getComputeTemplateConsolidationData();
810       String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate,
811           computeTemplateConsolidationData.getNodeTemplateId());
812
813       updNodeGetAttrInConnectivity(serviceTemplate, computeTemplateConsolidationData,
814           computeTemplateConsolidationData.getNodeTemplateId(),
815           newComputeNodeTemplateId, context, consolidationNodeTemplateIdAndType, false);
816
817       String computeType =
818           getComputeTypeSuffix(serviceTemplate,
819               computeTemplateConsolidationData.getNodeTemplateId());
820
821       List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
822           getPortTemplateConsolidationDataList(unifiedCompositionData);
823       for (PortTemplateConsolidationData portTemplateConsolidationData :
824           portTemplateConsolidationDataList) {
825         String newPotNodeTemplateId =
826             getNewPortNodeTemplateId(portTemplateConsolidationData.getNodeTemplateId(), computeType,
827                 computeTemplateConsolidationData);
828
829         updNodeGetAttrInConnectivity(serviceTemplate, portTemplateConsolidationData,
830             portTemplateConsolidationData.getNodeTemplateId(),
831             newPotNodeTemplateId, context, consolidationNodeTemplateIdAndType, false);
832       }
833     }
834   }
835
836   protected void updNestedCompositionOutputParamGetAttrInConnectivity(
837       ServiceTemplate serviceTemplate, List<UnifiedCompositionData> unifiedComposotionDataList,
838       TranslationContext context) {
839     for (UnifiedCompositionData unifiedCompositionData : unifiedComposotionDataList) {
840       NestedTemplateConsolidationData nestedTemplateConsolidationData =
841           unifiedCompositionData.getNestedTemplateConsolidationData();
842       if (Objects.isNull(nestedTemplateConsolidationData)) {
843         continue;
844       }
845       String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
846       Optional<String> newNestedNodeTemplateId = context.getUnifiedNestedNodeTemplateId(
847           serviceTemplateFileName, nestedTemplateConsolidationData.getNodeTemplateId());
848
849       newNestedNodeTemplateId.ifPresent(
850           newNestedNodeTemplateIdVal -> updOutputParamGetAttrInConnectivity(serviceTemplate,
851               nestedTemplateConsolidationData, nestedTemplateConsolidationData.getNodeTemplateId(),
852               newNestedNodeTemplateIdVal, context, true));
853     }
854   }
855
856   protected void updNestedCompositionNodesGetAttrInConnectivity(
857       ServiceTemplate serviceTemplate,
858       List<UnifiedCompositionData> unifiedCompositionDataList,
859       TranslationContext context) {
860     for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
861       NestedTemplateConsolidationData nestedTemplateConsolidationData =
862           unifiedCompositionData.getNestedTemplateConsolidationData();
863       if (Objects.isNull(nestedTemplateConsolidationData)) {
864         continue;
865       }
866       String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
867       Optional<String> newNestedNodeTemplateId = context.getUnifiedNestedNodeTemplateId(
868           serviceTemplateFileName, nestedTemplateConsolidationData.getNodeTemplateId());
869
870       newNestedNodeTemplateId.ifPresent(
871           newNestedNodeTemplateIdVal -> updNodeGetAttrInConnectivity(serviceTemplate,
872               nestedTemplateConsolidationData, nestedTemplateConsolidationData.getNodeTemplateId(),
873               newNestedNodeTemplateIdVal, context, null, true));
874     }
875   }
876
877   private void updateRequirementForNodesConnectedIn(
878       ServiceTemplate serviceTemplate,
879       RequirementAssignmentData requirementAssignmentData,
880       EntityConsolidationData entityConsolidationData,
881       String originalNodeTemplateId,
882       String newNodeTemplateId,
883       TranslationContext context) {
884     ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
885     RequirementAssignment requirementAssignment = requirementAssignmentData
886         .getRequirementAssignment();
887     String newAbstractUnifiedNodeTemplateId = context.getUnifiedAbstractNodeTemplateId(
888         serviceTemplate, entityConsolidationData.getNodeTemplateId());
889     NodeTemplate abstractUnifiedNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate,
890         newAbstractUnifiedNodeTemplateId);
891     Optional<String> newCapabilityId = getNewCapabilityForNodesConnectedIn(serviceTemplate,
892         abstractUnifiedNodeTemplate, requirementAssignment, newNodeTemplateId, context);
893     if (newCapabilityId.isPresent()) {
894       //Creating a copy of the requirement object and checking if it already exists in the
895       // original node template
896       RequirementAssignment requirementAssignmentCopy = (RequirementAssignment) getClonedObject(
897           requirementAssignmentData.getRequirementAssignment(), RequirementAssignment.class);
898       NodeTemplate originalNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate,
899           originalNodeTemplateId);
900       requirementAssignmentCopy.setCapability(newCapabilityId.get());
901       requirementAssignmentCopy.setNode(newAbstractUnifiedNodeTemplateId);
902       if (!toscaAnalyzerService.isRequirementExistInNodeTemplate(originalNodeTemplate,
903           requirementAssignmentData.getRequirementId(), requirementAssignmentCopy)) {
904         //Update the existing requirement
905         requirementAssignmentData.getRequirementAssignment().setCapability(newCapabilityId
906             .get());
907         requirementAssignmentData.getRequirementAssignment()
908             .setNode(newAbstractUnifiedNodeTemplateId);
909       } else {
910         //The updated requirement already exists in the node template so simply remove the
911         // current one
912         DataModelUtil.removeRequirementAssignment(originalNodeTemplate, requirementAssignmentData
913             .getRequirementId(), requirementAssignmentData.getRequirementAssignment());
914       }
915     }
916   }
917
918   private void updateRequirementForNestedCompositionNodesConnectedIn(
919       ServiceTemplate serviceTemplate,
920       RequirementAssignmentData requirementAssignmentData,
921       EntityConsolidationData entityConsolidationData,
922       String newNodeTemplateId,
923       TranslationContext context) {
924     ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
925     String newAbstractUnifiedNodeTemplateId = newNodeTemplateId;
926     RequirementAssignment requirementAssignment = requirementAssignmentData
927         .getRequirementAssignment();
928     //Creating a copy of the requirement object and checking if it already exists in the
929     // original node template
930     RequirementAssignment requirementAssignmentCopy = (RequirementAssignment) getClonedObject(
931         requirementAssignmentData.getRequirementAssignment(), RequirementAssignment.class);
932     NodeTemplate unifiedAbstractNestedNodeTemplate = DataModelUtil
933         .getNodeTemplate(serviceTemplate, newAbstractUnifiedNodeTemplateId);
934     requirementAssignmentCopy.setCapability(requirementAssignment.getCapability());
935     requirementAssignmentCopy.setNode(newAbstractUnifiedNodeTemplateId);
936     if (!toscaAnalyzerService.isRequirementExistInNodeTemplate(unifiedAbstractNestedNodeTemplate,
937         requirementAssignmentData.getRequirementId(), requirementAssignmentCopy)) {
938       //Update the existing requirement
939       requirementAssignmentData.getRequirementAssignment()
940           .setNode(newAbstractUnifiedNodeTemplateId);
941     } else {
942       //The updated requirement already exists in the node template so simply remove the
943       // current one
944       DataModelUtil.removeRequirementAssignment(unifiedAbstractNestedNodeTemplate,
945           requirementAssignmentData.getRequirementId(), requirementAssignmentData
946               .getRequirementAssignment());
947     }
948   }
949
950   private Optional<String> getNewCapabilityForNodesConnectedIn(ServiceTemplate serviceTemplate,
951                                                                NodeTemplate unifiedNodeTemplate,
952                                                                RequirementAssignment
953                                                                    requirementAssignment,
954                                                                String newNodeTemplateId,
955                                                                TranslationContext context) {
956     ServiceTemplate globalSubstitutionServiceTemplate =
957         HeatToToscaUtil.fetchGlobalSubstitutionServiceTemplate(serviceTemplate, context);
958     Map<String, NodeType> nodeTypes = globalSubstitutionServiceTemplate.getNode_types();
959     String unifiedNodeTemplateType = unifiedNodeTemplate.getType();
960     NodeType unifiedNodeType = nodeTypes.get(unifiedNodeTemplateType);
961     Map<String, CapabilityDefinition> abstractNodeTypeCapabilities = unifiedNodeType
962         .getCapabilities();
963     for (Map.Entry<String, CapabilityDefinition> entry : abstractNodeTypeCapabilities.entrySet()) {
964       String capabilityId = entry.getKey();
965       CapabilityDefinition capabilityDefinition = entry.getValue();
966       String capabilityType = capabilityDefinition.getType();
967       if (capabilityType.equals(requirementAssignment.getCapability())) {
968         //Matching capability type found..Check if the id ends with new node template id
969         if (capabilityId.endsWith(newNodeTemplateId)) {
970           return Optional.ofNullable(capabilityId);
971         }
972       }
973     }
974     return Optional.empty();
975   }
976
977
978   private void updateRequirementInAbstractNodeTemplate(ServiceTemplate serviceTemplate,
979                                                        EntityConsolidationData
980                                                            entityConsolidationData,
981                                                        String newNodeTemplateId,
982                                                        Map<String, List<RequirementAssignmentData>>
983                                                            requirementAssignmentDataMap,
984                                                        TranslationContext context) {
985     ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
986     for (Map.Entry<String, List<RequirementAssignmentData>> entry : requirementAssignmentDataMap
987         .entrySet()) {
988       String abstractNodeTemplateId = context.getUnifiedAbstractNodeTemplateId(
989           serviceTemplate, entityConsolidationData.getNodeTemplateId());
990       NodeTemplate abstractNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate,
991           abstractNodeTemplateId);
992       if (abstractNodeTemplate == null) {
993         //The abstract node template is not found from id in the context
994         return;
995       }
996       List<RequirementAssignmentData> requirementAssignmentDataList = entry.getValue();
997       for (RequirementAssignmentData requirementAssignmentData : requirementAssignmentDataList) {
998         String oldRequirementId = requirementAssignmentData.getRequirementId();
999         RequirementAssignment abstractRequirementAssignment = (RequirementAssignment)
1000             getClonedObject(requirementAssignmentData.getRequirementAssignment(),
1001                 RequirementAssignment.class);
1002         String newRequirementId = oldRequirementId + "_" + newNodeTemplateId;
1003         //Check if the requirement is not already present in the list of requirements of the
1004         // abstract node template
1005         if (!toscaAnalyzerService.isRequirementExistInNodeTemplate(abstractNodeTemplate,
1006             newRequirementId, abstractRequirementAssignment)) {
1007           DataModelUtil.addRequirementAssignment(abstractNodeTemplate, newRequirementId,
1008               abstractRequirementAssignment);
1009           //Update the volume relationship template if required
1010           updateVolumeRelationshipTemplate(serviceTemplate, abstractRequirementAssignment
1011               .getRelationship(), context);
1012         }
1013       }
1014     }
1015   }
1016
1017   private NodeTemplate getAbstractNodeTemplate(
1018       ServiceTemplate serviceTemplate,
1019       UnifiedCompositionEntity unifiedCompositionEntity,
1020       ComputeTemplateConsolidationData computeTemplateConsolidationData,
1021       PortTemplateConsolidationData portTemplateConsolidationData,
1022       TranslationContext context) {
1023     String abstractNodeTemplateId =
1024         getAbstractNodeTemplateId(serviceTemplate, unifiedCompositionEntity,
1025             computeTemplateConsolidationData, portTemplateConsolidationData, context);
1026
1027     return DataModelUtil.getNodeTemplate(serviceTemplate,
1028         abstractNodeTemplateId);
1029   }
1030
1031   private String getAbstractNodeTemplateId(
1032       ServiceTemplate serviceTemplate,
1033       UnifiedCompositionEntity unifiedCompositionEntity,
1034       ComputeTemplateConsolidationData computeTemplateConsolidationData,
1035       PortTemplateConsolidationData portTemplateConsolidationData,
1036       TranslationContext context) {
1037     switch (unifiedCompositionEntity) {
1038       case Compute:
1039         return context.getUnifiedAbstractNodeTemplateId(serviceTemplate,
1040             computeTemplateConsolidationData.getNodeTemplateId());
1041       case Port:
1042         return context.getUnifiedAbstractNodeTemplateId(serviceTemplate,
1043             portTemplateConsolidationData.getNodeTemplateId());
1044       default:
1045         return null;
1046     }
1047   }
1048
1049   private void updNodeGetAttrInConnectivity(
1050       ServiceTemplate serviceTemplate,
1051       EntityConsolidationData entityConsolidationData,
1052       String oldNodeTemplateId, String newNodeTemplateId,
1053       TranslationContext context,
1054       Map<String, UnifiedCompositionEntity> consolidationNodeTemplateIdAndType,
1055       boolean isNested) {
1056     Map<String, List<GetAttrFuncData>> nodesGetAttrIn = entityConsolidationData.getNodesGetAttrIn();
1057     if (MapUtils.isEmpty(nodesGetAttrIn)) {
1058       return;
1059     }
1060
1061     for (String sourceNodeTemplateId : nodesGetAttrIn.keySet()) {
1062       NodeTemplate sourceNodeTemplate =
1063           DataModelUtil.getNodeTemplate(serviceTemplate, sourceNodeTemplateId);
1064       if (!isNested && consolidationNodeTemplateIdAndType.keySet().contains(sourceNodeTemplateId)) {
1065         continue;
1066       }
1067       List<GetAttrFuncData> getAttrFuncDataList = nodesGetAttrIn.get(sourceNodeTemplateId);
1068       for (GetAttrFuncData getAttrFuncData : getAttrFuncDataList) {
1069         Object propertyValue =
1070             DataModelUtil.getPropertyValue(sourceNodeTemplate, getAttrFuncData.getFieldName());
1071         String newAttrName = null;
1072         String newGetAttrAbstractNodeTemplateId = newNodeTemplateId;
1073         if (!isNested) {
1074           newGetAttrAbstractNodeTemplateId =
1075               context.getUnifiedAbstractNodeTemplateId(serviceTemplate, oldNodeTemplateId);
1076           newAttrName = getNewSubstitutionOutputParameterId(newNodeTemplateId, getAttrFuncData
1077               .getAttributeName());
1078         }
1079         List<List<Object>> getAttrFuncValueList = extractGetAttrFunction(propertyValue);
1080         updateGetAttrValue(oldNodeTemplateId, getAttrFuncData, newGetAttrAbstractNodeTemplateId,
1081             newAttrName, getAttrFuncValueList, isNested);
1082       }
1083     }
1084   }
1085
1086   private void updateGetAttrValue(String oldNodeTemplateId, GetAttrFuncData getAttrFuncData,
1087                                   String newNodeTemplateId, String newAttrName,
1088                                   List<List<Object>> getAttrFuncValueList, boolean isNested) {
1089     for (List<Object> getAttrFuncValue : getAttrFuncValueList) {
1090       if (oldNodeTemplateId.equals(getAttrFuncValue.get(0))
1091           && getAttrFuncData.getAttributeName().equals(getAttrFuncValue.get(1))) {
1092         getAttrFuncValue.set(0, newNodeTemplateId);
1093         if (!isNested) {
1094           getAttrFuncValue.set(1, newAttrName);
1095         }
1096       }
1097     }
1098   }
1099
1100   private String getTemplateName(ServiceTemplate serviceTemplate,
1101                                  UnifiedCompositionData unifiedCompositionData,
1102                                  Integer index) {
1103     ComputeTemplateConsolidationData computeTemplateConsolidationData =
1104         unifiedCompositionData.getComputeTemplateConsolidationData();
1105     String computeType =
1106         getComputeTypeSuffix(serviceTemplate, computeTemplateConsolidationData.getNodeTemplateId());
1107     String templateName = "Nested_" + computeType;
1108     if (Objects.nonNull(index)) {
1109       templateName = templateName + "_" + index.toString();
1110     }
1111     return templateName;
1112   }
1113
1114   private String getComputeTypeSuffix(ServiceTemplate serviceTemplate,
1115                                       String computeNodeTemplateId) {
1116     NodeTemplate computeNodeTemplate =
1117         DataModelUtil.getNodeTemplate(serviceTemplate, computeNodeTemplateId);
1118     return getComputeTypeSuffix(computeNodeTemplate.getType());
1119   }
1120
1121   /**
1122    * Gets compute type.
1123    *
1124    * @param computeType the compute node type abc.def.vFSB
1125    * @return the compute type e.g.:vFSB
1126    */
1127   private String getComputeTypeSuffix(String computeType) {
1128     return DataModelUtil.getNamespaceSuffix(computeType);
1129   }
1130
1131   private void updOutputParamGetAttrInConnectivity(ServiceTemplate serviceTemplate,
1132                                                    EntityConsolidationData entityConsolidationData,
1133                                                    String oldNodeTemplateId,
1134                                                    String newNodeTemplateId,
1135                                                    TranslationContext context,
1136                                                    boolean isNested) {
1137     List<GetAttrFuncData> outputParametersGetAttrIn =
1138         entityConsolidationData.getOutputParametersGetAttrIn();
1139     if (CollectionUtils.isEmpty(outputParametersGetAttrIn)) {
1140       return;
1141     }
1142     for (GetAttrFuncData getAttrFuncData : outputParametersGetAttrIn) {
1143       Object outputParamValue =
1144           DataModelUtil.getOuputParameter(serviceTemplate, getAttrFuncData.getFieldName())
1145               .getValue();
1146       String newAttrName = null;
1147       String newGetAttrAbstractNodeTemplateId = newNodeTemplateId;
1148       if (!isNested) {
1149         newGetAttrAbstractNodeTemplateId =
1150             context.getUnifiedAbstractNodeTemplateId(serviceTemplate, oldNodeTemplateId);
1151         newAttrName = getNewSubstitutionOutputParameterId(newNodeTemplateId, getAttrFuncData
1152             .getAttributeName());
1153       }
1154       List<List<Object>> getAttrFuncValueList = extractGetAttrFunction(outputParamValue);
1155       updateGetAttrValue(oldNodeTemplateId, getAttrFuncData, newGetAttrAbstractNodeTemplateId,
1156           newAttrName,
1157           getAttrFuncValueList, isNested);
1158     }
1159
1160   }
1161
1162   private List<List<Object>> extractGetAttrFunction(Object valueObject) {
1163
1164     List<List<Object>> getAttrValueList = new ArrayList<>();
1165
1166     if (valueObject instanceof Map) {
1167       if (((Map) valueObject).containsKey(ToscaFunctions.GET_ATTRIBUTE.getDisplayName())) {
1168         getAttrValueList.add(
1169             (List<Object>) ((Map) valueObject).get(ToscaFunctions.GET_ATTRIBUTE.getDisplayName()));
1170       }
1171
1172       for (Object key : ((Map) valueObject).keySet()) {
1173         getAttrValueList.addAll(extractGetAttrFunction(((Map) valueObject).get(key)));
1174       }
1175
1176
1177     } else if (valueObject instanceof List) {
1178       for (Object valueEntity : (List) valueObject) {
1179         getAttrValueList.addAll(extractGetAttrFunction(valueEntity));
1180       }
1181     }
1182     return getAttrValueList;
1183   }
1184
1185   private boolean isIncludeGetInputFunc(Object valueObject) {
1186     if (valueObject instanceof Map) {
1187       if (((Map) valueObject).containsKey(ToscaFunctions.GET_INPUT.getDisplayName())) {
1188         return true;
1189       }
1190       Map.Entry<String, Object> functionMapEntry =
1191           (Map.Entry<String, Object>) ((Map) valueObject).entrySet().iterator().next();
1192       return isIncludeGetInputFunc(functionMapEntry.getValue());
1193
1194     } else if (valueObject instanceof List) {
1195       for (Object valueEntity : (List) valueObject) {
1196         if (isIncludeGetInputFunc(valueEntity) == true) {
1197           return true;
1198         }
1199       }
1200     }
1201     return false;
1202   }
1203
1204   private void createOutputParameters(ServiceTemplate serviceTemplate,
1205                                       ServiceTemplate substitutionServiceTemplate,
1206                                       List<UnifiedCompositionData> unifiedCompositionDataList,
1207                                       String computeNodeType) {
1208
1209     createOutputParametersForCompute(serviceTemplate, substitutionServiceTemplate,
1210         unifiedCompositionDataList);
1211     createOutputParameterForPorts(serviceTemplate, substitutionServiceTemplate,
1212         unifiedCompositionDataList, computeNodeType);
1213   }
1214
1215   private void createOutputParameterForPorts(
1216       ServiceTemplate serviceTemplate,
1217       ServiceTemplate substitutionServiceTemplate,
1218       List<UnifiedCompositionData> unifiedCompositionDataList,
1219       String connectedComputeNodeType) {
1220     for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
1221       List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
1222           getPortTemplateConsolidationDataList(unifiedCompositionData);
1223       if (CollectionUtils.isEmpty(portTemplateConsolidationDataList)) {
1224         return;
1225       }
1226
1227       for (PortTemplateConsolidationData portTemplateConsolidationData :
1228           portTemplateConsolidationDataList) {
1229         String newPortNodeTemplateId =
1230             getNewPortNodeTemplateId(portTemplateConsolidationData.getNodeTemplateId(),
1231                 connectedComputeNodeType,
1232                 unifiedCompositionData.getComputeTemplateConsolidationData());
1233         addOutputParameters(portTemplateConsolidationData, newPortNodeTemplateId,
1234             substitutionServiceTemplate, unifiedCompositionDataList);
1235       }
1236     }
1237   }
1238
1239   //The ID should be <vm_type>_<port_type> or <vm_type>_<portNodeTemplateId>
1240   private String getNewPortNodeTemplateId(
1241       String portNodeTemplateId,
1242       String connectedComputeNodeType,
1243       ComputeTemplateConsolidationData computeTemplateConsolidationData) {
1244
1245     StringBuilder newPortNodeTemplateId = new StringBuilder();
1246     String portType = ConsolidationDataUtil.getPortType(portNodeTemplateId);
1247     newPortNodeTemplateId.append(DataModelUtil.getNamespaceSuffix(connectedComputeNodeType));
1248     if (computeTemplateConsolidationData.getPorts().get(portType).size() > 1) {
1249       //single port
1250       newPortNodeTemplateId.append("_").append(portNodeTemplateId);
1251     } else {
1252       //consolidation port
1253       newPortNodeTemplateId.append("_").append(portType);
1254     }
1255     return newPortNodeTemplateId.toString();
1256   }
1257
1258   private void createOutputParametersForCompute(
1259       ServiceTemplate serviceTemplate,
1260       ServiceTemplate substitutionServiceTemplate,
1261       List<UnifiedCompositionData>
1262           unifiedCompositionDataList) {
1263     List<EntityConsolidationData> computeConsolidationDataList =
1264         getComputeConsolidationDataList(unifiedCompositionDataList);
1265
1266     for (EntityConsolidationData computeTemplateConsolidationData : computeConsolidationDataList) {
1267       String newComputeNodeTemplateId =
1268           getNewComputeNodeTemplateId(serviceTemplate,
1269               computeTemplateConsolidationData.getNodeTemplateId());
1270       addOutputParameters(computeTemplateConsolidationData, newComputeNodeTemplateId,
1271           substitutionServiceTemplate, unifiedCompositionDataList);
1272     }
1273   }
1274
1275   private void addOutputParameters(EntityConsolidationData entityConsolidationData,
1276                                    String newNodeTemplateId,
1277                                    ServiceTemplate substitutionServiceTemplate,
1278                                    List<UnifiedCompositionData> unifiedCompositionDataList) {
1279     handleNodesGetAttrIn(entityConsolidationData, newNodeTemplateId, substitutionServiceTemplate,
1280         unifiedCompositionDataList);
1281
1282     handleOutputParamGetAttrIn(entityConsolidationData, newNodeTemplateId,
1283         substitutionServiceTemplate);
1284   }
1285
1286   private void handleOutputParamGetAttrIn(EntityConsolidationData entityConsolidationData,
1287                                           String newNodeTemplateId,
1288                                           ServiceTemplate substitutionServiceTemplate) {
1289     List<GetAttrFuncData> outputParametersGetAttrIn =
1290         entityConsolidationData.getOutputParametersGetAttrIn();
1291     if (!CollectionUtils.isEmpty(outputParametersGetAttrIn)) {
1292       for (GetAttrFuncData getAttrFuncData : outputParametersGetAttrIn) {
1293         createAndAddOutputParameter(entityConsolidationData, newNodeTemplateId,
1294             substitutionServiceTemplate, getAttrFuncData);
1295       }
1296     }
1297   }
1298
1299   private void handleNodesGetAttrIn(EntityConsolidationData entityConsolidationData,
1300                                     String newNodeTemplateId,
1301                                     ServiceTemplate substitutionServiceTemplate,
1302                                     List<UnifiedCompositionData> unifiedCompositionDataList) {
1303     Map<String, List<GetAttrFuncData>> getAttrIn = entityConsolidationData.getNodesGetAttrIn();
1304
1305     if (!MapUtils.isEmpty(getAttrIn)) {
1306       Map<String, UnifiedCompositionEntity> consolidationNodeTemplateIdAndType =
1307           getAllConsolidationNodeTemplateIdAndType(unifiedCompositionDataList);
1308       for (String sourceNodeTemplateId : getAttrIn.keySet()) {
1309         if (!consolidationNodeTemplateIdAndType.keySet().contains(sourceNodeTemplateId)) {
1310           List<GetAttrFuncData> getAttrFuncDataList = getAttrIn.get(sourceNodeTemplateId);
1311           for (GetAttrFuncData getAttrFuncData : getAttrFuncDataList) {
1312             createAndAddOutputParameter(entityConsolidationData, newNodeTemplateId,
1313                 substitutionServiceTemplate, getAttrFuncData);
1314           }
1315         }
1316       }
1317     }
1318   }
1319
1320   private void createAndAddOutputParameter(EntityConsolidationData entityConsolidationData,
1321                                            String newNodeTemplateId,
1322                                            ServiceTemplate substitutionServiceTemplate,
1323                                            GetAttrFuncData getAttrFuncData) {
1324     Map<String, List<Object>> parameterValue = new HashMap<>();
1325     List<Object> valueList = new ArrayList<>();
1326     valueList.add(newNodeTemplateId);
1327     valueList.add(getAttrFuncData.getAttributeName());
1328     parameterValue.put(ToscaFunctions.GET_ATTRIBUTE.getDisplayName(), valueList);
1329     ParameterDefinition outputParameter = new ParameterDefinition();
1330     outputParameter.setValue(parameterValue);
1331     //todo - the type need to be change based on the attribute type in the accordingly node type
1332     // of this node template - XXX, instead of list of string, list of XXXX,
1333     outputParameter.setType(PropertyType.LIST.getDisplayName());
1334     outputParameter.setEntry_schema(
1335         DataModelUtil.createEntrySchema(PropertyType.STRING.getDisplayName(), null, null));
1336     DataModelUtil.addOutputParameterToTopologyTemplate(substitutionServiceTemplate,
1337         getNewSubstitutionOutputParameterId(newNodeTemplateId, getAttrFuncData.getAttributeName()),
1338         outputParameter);
1339   }
1340
1341   private String getNewSubstitutionOutputParameterId(String newNodeTemplateId,
1342                                                      String attributeName) {
1343     return newNodeTemplateId + "_" + attributeName;
1344   }
1345
1346   private void addUnifiedSubstitionData(TranslationContext context, ServiceTemplate
1347       serviceTemplate, List<UnifiedCompositionData> unifiedCompositionDataList, String
1348                                             substituteNodeTemplateId) {
1349     String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
1350     for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
1351       //Add compute node template mapping information
1352       ComputeTemplateConsolidationData computeTemplateConsolidationData =
1353           unifiedCompositionData.getComputeTemplateConsolidationData();
1354       String computeNodeTemplateId = computeTemplateConsolidationData.getNodeTemplateId();
1355       context.addUnifiedSubstitutionData(serviceTemplateFileName, computeNodeTemplateId,
1356           substituteNodeTemplateId);
1357       //Add Port template mapping information
1358       List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
1359           getPortTemplateConsolidationDataList(unifiedCompositionData);
1360
1361       if (CollectionUtils.isNotEmpty(portTemplateConsolidationDataList)) {
1362         for (PortTemplateConsolidationData portTemplateConsolidationData :
1363             portTemplateConsolidationDataList) {
1364           String oldPortNodeTemplateId = portTemplateConsolidationData.getNodeTemplateId();
1365           context.addUnifiedSubstitutionData(serviceTemplateFileName, oldPortNodeTemplateId,
1366               substituteNodeTemplateId);
1367         }
1368       }
1369     }
1370   }
1371
1372   private void addSubstitutionFilteringProperty(String templateName, NodeTemplate nodeTemplate,
1373                                                 int count) {
1374     Map<String, Object> serviceTemplateFilterPropertyValue = new HashMap<>();
1375     Map<String, Object> properties = nodeTemplate.getProperties();
1376     serviceTemplateFilterPropertyValue.put(ToscaConstants
1377         .SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME, templateName);
1378     serviceTemplateFilterPropertyValue.put(ToscaConstants.COUNT_PROPERTY_NAME, count);
1379     properties.put(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME,
1380         serviceTemplateFilterPropertyValue);
1381     nodeTemplate.setProperties(properties);
1382   }
1383
1384   private void addIndexValueProperty(NodeTemplate nodeTemplate) {
1385     List<String> indexValueGetPropertyValue = new ArrayList<>();
1386     indexValueGetPropertyValue.add(ToscaConstants.MODELABLE_ENTITY_NAME_SELF);
1387     indexValueGetPropertyValue.add(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
1388     indexValueGetPropertyValue.add(ToscaConstants.INDEX_VALUE_PROPERTY_NAME);
1389
1390     Map<String, Object> indexPropertyValue = new HashMap<>();
1391     Map<String, Object> properties = nodeTemplate.getProperties();
1392     indexPropertyValue.put(ToscaFunctions.GET_PROPERTY.getDisplayName(),
1393         indexValueGetPropertyValue);
1394     properties.put(ToscaConstants.INDEX_VALUE_PROPERTY_NAME,
1395         indexPropertyValue);
1396     nodeTemplate.setProperties(properties);
1397   }
1398
1399   private String getSubstituteNodeTemplateId(ServiceTemplate serviceTemplate,
1400                                              UnifiedCompositionData unifiedCompositionData,
1401                                              Integer index) {
1402     String computeNodeTemplateId =
1403         unifiedCompositionData.getComputeTemplateConsolidationData().getNodeTemplateId();
1404     NodeTemplate computeNodeTemplate =
1405         DataModelUtil.getNodeTemplate(serviceTemplate, computeNodeTemplateId);
1406     String nodeTemplateId = ABSTRACT_NODE_TEMPLATE_ID_PREFIX + DataModelUtil
1407         .getNamespaceSuffix(computeNodeTemplate.getType());
1408     if (Objects.nonNull(index)) {
1409       nodeTemplateId = nodeTemplateId + "_" + index.toString();
1410     }
1411     return nodeTemplateId;
1412   }
1413
1414   private String getSubstitutionNodeTypeId(ServiceTemplate serviceTemplate,
1415                                            UnifiedCompositionData unifiedCompositionData,
1416                                            Integer index) {
1417     String computeNodeTemplateId =
1418         unifiedCompositionData.getComputeTemplateConsolidationData().getNodeTemplateId();
1419     NodeTemplate computeNodeTemplate =
1420         DataModelUtil.getNodeTemplate(serviceTemplate, computeNodeTemplateId);
1421     String nodeTypeId = ToscaNodeType.ABSTRACT_NODE_TYPE_PREFIX
1422         + DataModelUtil.getNamespaceSuffix(computeNodeTemplate.getType());
1423     if (Objects.nonNull(index)) {
1424       nodeTypeId = nodeTypeId + "_" + index.toString();
1425     }
1426     return nodeTypeId;
1427   }
1428
1429   private String getNewComputeNodeTemplateId(
1430       ServiceTemplate serviceTemplate,
1431       String computeNodeTemplateId) {
1432     return getComputeTypeSuffix(serviceTemplate, computeNodeTemplateId);
1433   }
1434
1435   private NodeType handleSubstitutionGlobalNodeType(ServiceTemplate serviceTemplate,
1436                                                     ServiceTemplate substitutionServiceTemplate,
1437                                                     TranslationContext context,
1438                                                     UnifiedCompositionData unifiedCompositionData,
1439                                                     Integer index) {
1440     String substitutionNodeTypeId =
1441         getSubstitutionNodeTypeId(serviceTemplate, unifiedCompositionData, index);
1442     NodeType substitutionNodeType = new ToscaAnalyzerServiceImpl()
1443         .createInitSubstitutionNodeType(substitutionServiceTemplate,
1444             ToscaNodeType.VFC_ABSTRACT_SUBSTITUTE);
1445     ServiceTemplate globalSubstitutionServiceTemplate =
1446         HeatToToscaUtil.fetchGlobalSubstitutionServiceTemplate(serviceTemplate, context);
1447     DataModelUtil.addNodeType(globalSubstitutionServiceTemplate, substitutionNodeTypeId,
1448         substitutionNodeType);
1449
1450     return substitutionNodeType;
1451   }
1452
1453   private void handlePorts(ServiceTemplate serviceTemplate,
1454                            ServiceTemplate substitutionServiceTemplate,
1455                            List<UnifiedCompositionData> unifiedCompositionDataList,
1456                            String connectedComputeNodeType,
1457                            TranslationContext context) {
1458
1459     if (unifiedCompositionDataList.size() > 1) {
1460       handleConsolidationPorts(serviceTemplate, substitutionServiceTemplate,
1461           unifiedCompositionDataList, connectedComputeNodeType, context);
1462     } else {
1463       handleSinglePorts(serviceTemplate, substitutionServiceTemplate, connectedComputeNodeType,
1464           unifiedCompositionDataList, context);
1465     }
1466   }
1467
1468   private void handleSinglePorts(ServiceTemplate serviceTemplate,
1469                                  ServiceTemplate substitutionServiceTemplate,
1470                                  String connectedComputeNodeType,
1471                                  List<UnifiedCompositionData> unifiedCompositionDataList,
1472                                  TranslationContext context) {
1473     UnifiedCompositionData unifiedCompositionData = unifiedCompositionDataList.get(0);
1474     List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
1475         getPortTemplateConsolidationDataList(unifiedCompositionData);
1476     if (CollectionUtils.isEmpty(portTemplateConsolidationDataList)) {
1477       return;
1478     }
1479     for (PortTemplateConsolidationData portTemplateConsolidationData :
1480         portTemplateConsolidationDataList) {
1481       List<EntityConsolidationData> portConsolidationDataList = new ArrayList<>();
1482       portConsolidationDataList.add(portTemplateConsolidationData);
1483       handlePortNodeTemplate(serviceTemplate, substitutionServiceTemplate,
1484           portConsolidationDataList, connectedComputeNodeType,
1485           unifiedCompositionData.getComputeTemplateConsolidationData(),
1486           unifiedCompositionDataList, context);
1487     }
1488   }
1489
1490   private void handleConsolidationPorts(ServiceTemplate serviceTemplate,
1491                                         ServiceTemplate substitutionServiceTemplate,
1492                                         List<UnifiedCompositionData> unifiedCompositionDataList,
1493                                         String connectedComputeNodeType,
1494                                         TranslationContext context) {
1495     Collection<ComputeTemplateConsolidationData> computeConsolidationDataList =
1496         (Collection) getComputeConsolidationDataList(unifiedCompositionDataList);
1497
1498     Map<String, Set<String>> portIdsPerPortType = UnifiedCompositionUtil
1499         .collectAllPortsFromEachTypesFromComputes(computeConsolidationDataList);
1500
1501     for (String portType : portIdsPerPortType.keySet()) {
1502       List<EntityConsolidationData> portTemplateConsolidationDataList =
1503           getPortConsolidationDataList(portIdsPerPortType.get(portType),
1504               unifiedCompositionDataList);
1505       if (CollectionUtils.isEmpty(portTemplateConsolidationDataList)) {
1506         continue;
1507       }
1508
1509       handlePortNodeTemplate(serviceTemplate, substitutionServiceTemplate,
1510           portTemplateConsolidationDataList, connectedComputeNodeType,
1511           unifiedCompositionDataList.get(0).getComputeTemplateConsolidationData(),
1512           unifiedCompositionDataList, context);
1513     }
1514   }
1515
1516   private void handlePortNodeTemplate(
1517       ServiceTemplate serviceTemplate,
1518       ServiceTemplate substitutionServiceTemplate,
1519       List<EntityConsolidationData> portTemplateConsolidationDataList,
1520       String connectedComputeNodeType,
1521       ComputeTemplateConsolidationData computeTemplateConsolidationData,
1522       List<UnifiedCompositionData> unifiedCompositionDataList,
1523       TranslationContext context) {
1524     EntityConsolidationData portTemplateConsolidationData =
1525         portTemplateConsolidationDataList.get(0);
1526     NodeTemplate newPortNodeTemplate = getNodeTemplate(
1527         portTemplateConsolidationData.getNodeTemplateId(), serviceTemplate, context).clone();
1528
1529     removeConnectivityOut(portTemplateConsolidationData, newPortNodeTemplate);
1530     handleProperties(serviceTemplate, newPortNodeTemplate, substitutionServiceTemplate,
1531         UnifiedCompositionEntity.Port, portTemplateConsolidationDataList,
1532         computeTemplateConsolidationData, unifiedCompositionDataList, context);
1533
1534     String newPortNodeTemplateId =
1535         getNewPortNodeTemplateId(portTemplateConsolidationData
1536                 .getNodeTemplateId(), connectedComputeNodeType,
1537             computeTemplateConsolidationData);
1538     //Update requirements for relationships between the consolidation entities
1539     handleConsolidationEntitiesRequirementConnectivity(newPortNodeTemplateId, newPortNodeTemplate,
1540         substitutionServiceTemplate, context);
1541     DataModelUtil.addNodeTemplate(substitutionServiceTemplate, newPortNodeTemplateId,
1542         newPortNodeTemplate);
1543
1544     //Add the node template mapping in the context for handling requirement updation
1545     context.addSubstitutionServiceTemplateUnifiedSubstitutionData(ToscaUtil
1546             .getServiceTemplateFileName(substitutionServiceTemplate),
1547         portTemplateConsolidationData.getNodeTemplateId(), newPortNodeTemplateId);
1548   }
1549
1550
1551   private NodeTemplate getNodeTemplate(String nodeTemplateId, ServiceTemplate serviceTemplate,
1552                                        TranslationContext context) {
1553
1554     NodeTemplate nodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate, nodeTemplateId);
1555
1556     if (Objects.isNull(nodeTemplate)) {
1557       nodeTemplate = context
1558           .getCleanedNodeTemplate(ToscaUtil.getServiceTemplateFileName(serviceTemplate),
1559               nodeTemplateId);
1560
1561     }
1562     return nodeTemplate;
1563   }
1564
1565
1566   private String handleCompute(ServiceTemplate serviceTemplate,
1567                                ServiceTemplate substitutionServiceTemplate,
1568                                List<UnifiedCompositionData> unifiedCompositionDataList,
1569                                TranslationContext context) {
1570     ComputeTemplateConsolidationData computeTemplateConsolidationData =
1571         unifiedCompositionDataList.get(0).getComputeTemplateConsolidationData();
1572     handleComputeNodeTemplate(serviceTemplate, substitutionServiceTemplate,
1573         unifiedCompositionDataList, context);
1574     return handleComputeNodeType(serviceTemplate, substitutionServiceTemplate,
1575         computeTemplateConsolidationData);
1576   }
1577
1578   private String handleComputeNodeType(
1579       ServiceTemplate serviceTemplate,
1580       ServiceTemplate substitutionServiceTemplate,
1581       ComputeTemplateConsolidationData computeTemplateConsolidationData) {
1582     NodeTemplate computeNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate,
1583         computeTemplateConsolidationData.getNodeTemplateId());
1584     NodeType computeNodeType =
1585         DataModelUtil.getNodeType(serviceTemplate, computeNodeTemplate.getType());
1586     DataModelUtil
1587         .addNodeType(substitutionServiceTemplate, computeNodeTemplate.getType(), computeNodeType);
1588
1589     return computeNodeTemplate.getType();
1590   }
1591
1592   private void handleComputeNodeTemplate(ServiceTemplate serviceTemplate,
1593                                          ServiceTemplate substitutionServiceTemplate,
1594                                          List<UnifiedCompositionData> unifiedCompositionDataList,
1595                                          TranslationContext context) {
1596     ComputeTemplateConsolidationData computeTemplateConsolidationData =
1597         unifiedCompositionDataList.get(0).getComputeTemplateConsolidationData();
1598     NodeTemplate newComputeNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate,
1599         computeTemplateConsolidationData.getNodeTemplateId()).clone();
1600
1601     removeConnectivityOut(computeTemplateConsolidationData, newComputeNodeTemplate);
1602     removeVolumeConnectivity(computeTemplateConsolidationData, newComputeNodeTemplate);
1603
1604     List<EntityConsolidationData> computeConsoliadtionDataList =
1605         getComputeConsolidationDataList(unifiedCompositionDataList);
1606
1607     handleProperties(serviceTemplate, newComputeNodeTemplate, substitutionServiceTemplate,
1608         UnifiedCompositionEntity.Compute, computeConsoliadtionDataList,
1609         computeTemplateConsolidationData, unifiedCompositionDataList, context);
1610
1611     String newComputeNodeTemplateId = getNewComputeNodeTemplateId(serviceTemplate,
1612         computeTemplateConsolidationData.getNodeTemplateId());
1613     //Update requirements for relationships between the consolidation entities
1614     handleConsolidationEntitiesRequirementConnectivity(newComputeNodeTemplateId,
1615         newComputeNodeTemplate,
1616         substitutionServiceTemplate, context);
1617     DataModelUtil
1618         .addNodeTemplate(substitutionServiceTemplate,
1619             newComputeNodeTemplateId, newComputeNodeTemplate);
1620     //Add the node template mapping in the context for handling requirement updation
1621     context.addSubstitutionServiceTemplateUnifiedSubstitutionData(ToscaUtil
1622             .getServiceTemplateFileName(substitutionServiceTemplate),
1623         computeTemplateConsolidationData.getNodeTemplateId(), newComputeNodeTemplateId);
1624
1625   }
1626
1627   private List<EntityConsolidationData> getComputeConsolidationDataList(
1628       List<UnifiedCompositionData> unifiedCompositionDataList) {
1629     List<EntityConsolidationData> computeConsolidationDataList = new ArrayList<>();
1630     for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
1631       computeConsolidationDataList
1632           .add(unifiedCompositionData.getComputeTemplateConsolidationData());
1633     }
1634     return computeConsolidationDataList;
1635   }
1636
1637
1638   private void handleProperties(ServiceTemplate serviceTemplate, NodeTemplate nodeTemplate,
1639                                 ServiceTemplate substitutionServiceTemplate,
1640                                 UnifiedCompositionEntity unifiedCompositionEntity,
1641                                 List<EntityConsolidationData> entityConsolidationDataList,
1642                                 ComputeTemplateConsolidationData computeTemplateConsolidationData,
1643                                 List<UnifiedCompositionData> unifiedCompositionDataList,
1644                                 TranslationContext context) {
1645
1646     nodeTemplate.setProperties(new HashedMap());
1647     handleNodeTemplateProperties(serviceTemplate, nodeTemplate, substitutionServiceTemplate,
1648         unifiedCompositionEntity, entityConsolidationDataList, computeTemplateConsolidationData,
1649         unifiedCompositionDataList, context);
1650     //Add enrich properties from openecomp node type as input to global and substitution ST
1651     handleNodeTypeProperties(substitutionServiceTemplate,
1652         entityConsolidationDataList, nodeTemplate, unifiedCompositionEntity,
1653         computeTemplateConsolidationData, context);
1654
1655   }
1656
1657   private void handleNodeTemplateProperties(ServiceTemplate serviceTemplate,
1658                                             NodeTemplate nodeTemplate,
1659                                             ServiceTemplate substitutionServiceTemplate,
1660                                             UnifiedCompositionEntity unifiedCompositionEntity,
1661                                             List<EntityConsolidationData>
1662                                                 entityConsolidationDataList,
1663                                             ComputeTemplateConsolidationData
1664                                                 computeTemplateConsolidationData,
1665                                             List<UnifiedCompositionData> unifiedCompositionDataList,
1666                                             TranslationContext context) {
1667     List<String> propertiesWithIdenticalVal = consolidationService.getPropertiesWithIdenticalVal();
1668     for (EntityConsolidationData entityConsolidationData : entityConsolidationDataList) {
1669       String nodeTemplateId = entityConsolidationData.getNodeTemplateId();
1670       Map<String, Object> properties =
1671           DataModelUtil.getNodeTemplateProperties(serviceTemplate, nodeTemplateId);
1672       if (MapUtils.isEmpty(properties)) {
1673         continue;
1674       }
1675
1676       for (Map.Entry<String, Object> propertyEntry : properties.entrySet()) {
1677         if (propertiesWithIdenticalVal.contains(propertyEntry.getKey())) {
1678           String parameterId = updateIdenticalProperty(nodeTemplate, propertyEntry.getKey());
1679           addInputParameter(parameterId, PropertyType.STRING.getDisplayName(), null,
1680               substitutionServiceTemplate);
1681         } else {
1682           Optional<String> parameterId =
1683               updateProperty(serviceTemplate, nodeTemplateId, nodeTemplate, propertyEntry,
1684                   unifiedCompositionEntity, computeTemplateConsolidationData,
1685                   unifiedCompositionDataList,
1686                   context);
1687           //todo - define list of type which will match the node property type (instead of string)
1688           NodeType nodeTypeWithFlatHierarchy =
1689               HeatToToscaUtil.getNodeTypeWithFlatHierarchy(nodeTemplate.getType(), serviceTemplate,
1690                   context);
1691           String propertyType =
1692               nodeTypeWithFlatHierarchy.getProperties().get(propertyEntry.getKey())
1693                   .getType();
1694           addPropertyInputParameter(propertyType, substitutionServiceTemplate, parameterId);
1695         }
1696       }
1697     }
1698   }
1699
1700   private void handleNodeTypeProperties(ServiceTemplate substitutionServiceTemplate,
1701                                         List<EntityConsolidationData> entityConsolidationDataList,
1702                                         NodeTemplate nodeTemplate,
1703                                         UnifiedCompositionEntity compositionEntity,
1704                                         ComputeTemplateConsolidationData
1705                                             computeTemplateConsolidationData,
1706                                         TranslationContext context) {
1707     ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
1708     Optional<NodeType> enrichNodeType = Optional.empty();
1709     List<String> enrichProperties = new ArrayList<>();
1710
1711     if (compositionEntity.equals(UnifiedCompositionEntity.Port)) {
1712       enrichNodeType =
1713           toscaAnalyzerService.fetchNodeType(ToscaNodeType.NETWORK_PORT,
1714               context.getGlobalServiceTemplates().values());
1715       enrichProperties = context.getEnrichPortResourceProperties();
1716       if (!enrichNodeType.isPresent() || Objects.isNull(enrichProperties)) {
1717         return;
1718       }
1719     } else {
1720       return;
1721     }
1722
1723     Map<String, Object> nodeTemplateProperties = nodeTemplate.getProperties();
1724     Map<String, PropertyDefinition> enrichNodeTypeProperties = enrichNodeType.get().getProperties();
1725     if (Objects.nonNull(enrichNodeTypeProperties)) {
1726       for (String enrichPropertyName : enrichProperties) {
1727         if (!nodeTemplateProperties.containsKey(enrichPropertyName)) {
1728           for (EntityConsolidationData entityConsolidationData : entityConsolidationDataList) {
1729             String nodeTemplateId = entityConsolidationData.getNodeTemplateId();
1730             String inputParamId =
1731                 getParameterId(nodeTemplateId, nodeTemplate, enrichPropertyName,
1732                     compositionEntity, computeTemplateConsolidationData);
1733             Map<String, List<String>> propertyVal = getPropertyValueInputParam(nodeTemplateId,
1734                 nodeTemplate, inputParamId);
1735             nodeTemplate.getProperties().put(enrichPropertyName, propertyVal);
1736             String propertyType =
1737                 enrichNodeType.get().getProperties().get(enrichPropertyName).getType();
1738             addPropertyInputParameter(propertyType, substitutionServiceTemplate,
1739                 Optional.of(inputParamId));
1740           }
1741         }
1742       }
1743     }
1744   }
1745
1746
1747   private void addPropertyInputParameter(String propertyType,
1748                                          ServiceTemplate substitutionServiceTemplate,
1749                                          Optional<String> parameterId) {
1750     if (propertyType.equalsIgnoreCase(PropertyType.STRING.getDisplayName())
1751         || propertyType.equalsIgnoreCase(PropertyType.INTEGER.getDisplayName())
1752         || propertyType.equalsIgnoreCase(PropertyType.FLOAT.getDisplayName())
1753         || propertyType.equalsIgnoreCase(PropertyType.BOOLEAN.getDisplayName())) {
1754       parameterId
1755           .ifPresent(parameterIdValue -> addInputParameter(parameterIdValue,
1756               PropertyType.LIST.getDisplayName(),
1757               DataModelUtil
1758                   .createEntrySchema(propertyType.toLowerCase(), null, null),
1759               substitutionServiceTemplate));
1760     } else {
1761       parameterId
1762           .ifPresent(parameterIdValue -> addInputParameter(parameterIdValue,
1763               PropertyType.LIST.getDisplayName(),
1764               DataModelUtil
1765                   .createEntrySchema(PropertyTypeExt.JSON.getDisplayName(), null, null),
1766               substitutionServiceTemplate));
1767     }
1768   }
1769
1770   private void handleConsolidationEntitiesRequirementConnectivity(String nodeTemplateId,
1771                                                                   NodeTemplate nodeTemplate,
1772                                                                   ServiceTemplate
1773                                                                       substitutionServiceTemplate,
1774                                                                   TranslationContext context) {
1775     Map<String, RequirementAssignment> updatedNodeTemplateRequirements = new HashMap<>();
1776     List<Map<String, RequirementAssignment>> nodeTemplateRequirements = DataModelUtil
1777         .getNodeTemplateRequirementList(nodeTemplate);
1778     if (CollectionUtils.isEmpty(nodeTemplateRequirements)) {
1779       return;
1780     }
1781
1782     for (Map<String, RequirementAssignment> requirement : nodeTemplateRequirements) {
1783       for (Map.Entry<String, RequirementAssignment> entry : requirement.entrySet()) {
1784         RequirementAssignment requirementAssignment = entry.getValue();
1785         String requirementNode = requirementAssignment.getNode();
1786         String unifiedNodeTemplateId =
1787             context.getUnifiedSubstitutionNodeTemplateId(substitutionServiceTemplate,
1788                 requirementNode);
1789         if (unifiedNodeTemplateId != null) {
1790           //Update the node id in the requirement
1791           requirementAssignment.setNode(unifiedNodeTemplateId);
1792         }
1793       }
1794     }
1795     nodeTemplate.setRequirements(nodeTemplateRequirements);
1796   }
1797
1798   /**
1799    * Update the node references in the volume relationship templates.
1800    *
1801    * @param serviceTemplate the service template
1802    * @param context         the context
1803    */
1804   private void updateVolumeRelationshipTemplate(ServiceTemplate serviceTemplate,
1805                                                 String relationshipId,
1806                                                 TranslationContext context) {
1807     Map<String, RelationshipTemplate> relationshipTemplates = DataModelUtil
1808         .getRelationshipTemplates(serviceTemplate);
1809     if (relationshipTemplates != null) {
1810       RelationshipTemplate relationshipTemplate = relationshipTemplates.get(relationshipId);
1811       if (relationshipTemplate != null) {
1812         String relationshipTemplateType = relationshipTemplate.getType();
1813         if (relationshipTemplateType.equals(ToscaRelationshipType.CINDER_VOLUME_ATTACHES_TO)) {
1814           handleCinderVolumeAttachmentRelationshipTemplate(serviceTemplate,
1815               relationshipTemplate, context);
1816         }
1817       }
1818     }
1819   }
1820
1821
1822   private void handleCinderVolumeAttachmentRelationshipTemplate(ServiceTemplate
1823                                                                     substitutionServiceTemplate,
1824                                                                 RelationshipTemplate
1825                                                                     relationshipTemplate,
1826                                                                 TranslationContext context) {
1827     Map<String, Object> properties = relationshipTemplate.getProperties();
1828     properties.computeIfPresent(HeatConstants.INSTANCE_UUID_PROPERTY_NAME, (key, value) ->
1829         context.getUnifiedAbstractNodeTemplateId(substitutionServiceTemplate,
1830             (String) value));
1831   }
1832
1833   private String updateIdenticalProperty(NodeTemplate nodeTemplate, String propertyId) {
1834     Map<String, String> propertyVal = new HashMap<>();
1835     String inputParamId = IDENTICAL_VALUE_PROPERTY_PREFIX + propertyId
1836         + IDENTICAL_VALUE_PROPERTY_SUFFIX;
1837     propertyVal.put(ToscaFunctions.GET_INPUT.getDisplayName(), inputParamId);
1838     nodeTemplate.getProperties().put(propertyId, propertyVal);
1839     return inputParamId;
1840   }
1841
1842   private void addInputParameter(String parameterId, String parameterType, EntrySchema entrySchema,
1843                                  ServiceTemplate serviceTemplate) {
1844
1845     ParameterDefinition parameterDefinition =
1846         DataModelUtil.createParameterDefinition(parameterType, null, null,
1847             true, null, null, entrySchema, null);
1848     DataModelUtil
1849         .addInputParameterToTopologyTemplate(serviceTemplate, parameterId, parameterDefinition);
1850   }
1851
1852   // Return the input parameter Id which is used in the new property value if there is one
1853   private Optional<String> updateProperty(
1854       ServiceTemplate serviceTemplate,
1855       String nodeTemplateId, NodeTemplate nodeTemplate,
1856       Map.Entry<String, Object> propertyEntry,
1857       UnifiedCompositionEntity compositionEntity,
1858       ComputeTemplateConsolidationData computeTemplateConsolidationData,
1859       List<UnifiedCompositionData> unifiedCompositionDataList,
1860       TranslationContext context) {
1861
1862     if (handleGetAttrFromConsolidationNodes(serviceTemplate, nodeTemplate, propertyEntry,
1863         unifiedCompositionDataList, context)) {
1864       return Optional.empty();
1865     }
1866     String inputParamId =
1867         getParameterId(nodeTemplateId, nodeTemplate, propertyEntry.getKey(), compositionEntity,
1868             computeTemplateConsolidationData);
1869     Map<String, List<String>> propertyVal = getPropertyValueInputParam(nodeTemplateId,
1870         nodeTemplate, inputParamId);
1871     nodeTemplate.getProperties().put(propertyEntry.getKey(), propertyVal);
1872     return Optional.of(inputParamId);
1873   }
1874
1875   private Map<String, List<String>> getPropertyValueInputParam(String nodeTemplateId,
1876                                                                NodeTemplate nodeTemplate,
1877                                                                String inputParamId) {
1878     Map<String, List<String>> propertyVal = new HashMap<>();
1879     List<String> getInputFuncParams = new ArrayList<>();
1880     getInputFuncParams.add(inputParamId);
1881     getInputFuncParams.add(ToscaConstants.INDEX_VALUE_PROPERTY_NAME);
1882     propertyVal.put(ToscaFunctions.GET_INPUT.getDisplayName(), getInputFuncParams);
1883     return propertyVal;
1884   }
1885
1886   private boolean handleGetAttrFromConsolidationNodes(
1887       ServiceTemplate serviceTemplate,
1888       NodeTemplate nodeTemplate,
1889       Map.Entry<String, Object> propertyEntry,
1890       List<UnifiedCompositionData> unifiedCompositionDataList,
1891       TranslationContext context) {
1892     Map<String, UnifiedCompositionEntity> consolidationNodeTemplateIdAndType =
1893         getAllConsolidationNodeTemplateIdAndType(unifiedCompositionDataList);
1894
1895     Set<String> consolidationNodeTemplateIds = consolidationNodeTemplateIdAndType.keySet();
1896     boolean includeGetAttrFromConsolidationNodes = false;
1897     boolean includeGetAttrFromOutsideNodes = false;
1898     List<List<Object>> getAttrFunctionList = extractGetAttrFunction(propertyEntry.getValue());
1899     for (List<Object> getAttrFunc : getAttrFunctionList) {
1900       if (consolidationNodeTemplateIds.contains(getAttrFunc.get(0))) {
1901         includeGetAttrFromConsolidationNodes = true;
1902       } else {
1903         includeGetAttrFromOutsideNodes = true;
1904       }
1905     }
1906     if ((includeGetAttrFromConsolidationNodes && includeGetAttrFromOutsideNodes)
1907         ||
1908         (includeGetAttrFromConsolidationNodes && isIncludeGetInputFunc(propertyEntry.getValue()))) {
1909       //This case is currently not supported - this property will be ignored
1910       return true;
1911     } else if (includeGetAttrFromConsolidationNodes) {
1912       Object clonedPropertyValue = getClonedPropertyValue(propertyEntry);
1913       List<List<Object>> clonedGetAttrFuncList = extractGetAttrFunction(clonedPropertyValue);
1914       for (List<Object> getAttrFunc : clonedGetAttrFuncList) {
1915         String targetNodeTemplateId = (String) getAttrFunc.get(0);
1916         if (consolidationNodeTemplateIds.contains(targetNodeTemplateId)) {
1917           updatePropertyGetAttrFunc(serviceTemplate, unifiedCompositionDataList, context,
1918               consolidationNodeTemplateIdAndType, targetNodeTemplateId, getAttrFunc);
1919         }
1920       }
1921       nodeTemplate.getProperties().put(propertyEntry.getKey(), clonedPropertyValue);
1922       return true;
1923     }
1924     return false;
1925   }
1926
1927   private void updatePropertyGetAttrFunc(
1928       ServiceTemplate serviceTemplate,
1929       List<UnifiedCompositionData> unifiedCompositionDataList,
1930       TranslationContext context,
1931       Map<String, UnifiedCompositionEntity> consolidationNodeTemplateIdAndType,
1932       String targetNodeTemplateId,
1933       List<Object> getAttrFunc) {
1934     UnifiedCompositionEntity targetCompositionEntity =
1935         consolidationNodeTemplateIdAndType.get(targetNodeTemplateId);
1936     String targetNewNodeTemplateId =
1937         getNewNodeTemplateId(serviceTemplate, unifiedCompositionDataList, targetNodeTemplateId,
1938             targetCompositionEntity);
1939     getAttrFunc.set(0, targetNewNodeTemplateId);
1940   }
1941
1942   private String getNewNodeTemplateId(ServiceTemplate serviceTemplate,
1943                                       List<UnifiedCompositionData> unifiedCompositionDataList,
1944                                       String nodeTemplateId,
1945                                       UnifiedCompositionEntity compositionEntity) {
1946     switch (compositionEntity) {
1947       case Compute:
1948         return getNewComputeNodeTemplateId(serviceTemplate, nodeTemplateId);
1949       case Port:
1950         ComputeTemplateConsolidationData connectedComputeConsolidationData =
1951             getConnectedComputeConsolidationData(serviceTemplate,
1952                 unifiedCompositionDataList, nodeTemplateId);
1953         NodeTemplate connectedComputeNodeTemplate =
1954             DataModelUtil.getNodeTemplate(serviceTemplate,
1955                 connectedComputeConsolidationData.getNodeTemplateId());
1956         return getNewPortNodeTemplateId(nodeTemplateId, connectedComputeNodeTemplate.getType(),
1957             connectedComputeConsolidationData);
1958       default:
1959         return null;
1960     }
1961   }
1962
1963   private String getNewNodeTemplateId(String origNodeTemplateId,
1964                                       String serviceTemplateFileName,
1965                                       ServiceTemplate serviceTemplate,
1966                                       TranslationContext context) {
1967     ConsolidationData consolidationData = context.getConsolidationData();
1968
1969     if (isIdIsOfExpectedType(origNodeTemplateId, UnifiedCompositionEntity.Port,
1970         serviceTemplateFileName,
1971         consolidationData, context)) {
1972       return handleIdOfPort(origNodeTemplateId, serviceTemplateFileName, consolidationData);
1973     } else if (isIdIsOfExpectedType(origNodeTemplateId, UnifiedCompositionEntity.Compute,
1974         serviceTemplateFileName, consolidationData, context)) {
1975       NodeTemplate nodeTemplate =
1976           getComputeNodeTemplate(origNodeTemplateId, serviceTemplate, context);
1977       return getComputeTypeSuffix(nodeTemplate.getType());
1978     }
1979
1980     return null;
1981   }
1982
1983   private ComputeTemplateConsolidationData getConnectedComputeConsolidationData(
1984       ServiceTemplate serviceTemplate,
1985       List<UnifiedCompositionData> unifiedCompositionDataList,
1986       String portNodeTemplateId) {
1987     for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
1988       Collection<List<String>> portsCollection =
1989           unifiedCompositionData.getComputeTemplateConsolidationData().getPorts().values();
1990       for (List<String> portIdList : portsCollection) {
1991         for (String portId : portIdList) {
1992           if (portId.equals(portNodeTemplateId)) {
1993             return unifiedCompositionData.getComputeTemplateConsolidationData();
1994           }
1995         }
1996       }
1997     }
1998     return null;
1999   }
2000
2001   private Object getClonedPropertyValue(Map.Entry<String, Object> propertyEntry) {
2002     if (propertyEntry.getValue() instanceof Map) {
2003       return getClonedObject(propertyEntry.getValue(), Map.class);
2004     } else if (propertyEntry.getValue() instanceof List) {
2005       return getClonedObject(propertyEntry.getValue(), List.class);
2006     }
2007     return propertyEntry.getValue();
2008   }
2009
2010
2011   private String getParameterId(String nodeTemplateId, NodeTemplate nodeTemplate, String propertyId,
2012                                 UnifiedCompositionEntity unifiedCompositionEntity,
2013                                 ComputeTemplateConsolidationData computeTemplateConsolidationData) {
2014     switch (unifiedCompositionEntity) {
2015       case Compute:
2016         return UnifiedCompositionEntity.Compute.name().toLowerCase() + "_"
2017             + getComputeTypeSuffix(nodeTemplate.getType()) + "_" + propertyId;
2018       case Port:
2019         String portType = ConsolidationDataUtil.getPortType(nodeTemplateId);
2020         if (Objects.isNull(computeTemplateConsolidationData)
2021             || computeTemplateConsolidationData.getPorts().get(portType).size() > 1) {
2022           return UnifiedCompositionEntity.Port.name().toLowerCase() + "_" + nodeTemplateId + "_"
2023               + propertyId;
2024         }
2025         return UnifiedCompositionEntity.Port.name().toLowerCase() + "_" + portType + "_"
2026             + propertyId;
2027       default:
2028         return propertyId;
2029     }
2030   }
2031
2032   private void removeConnectivityOut(EntityConsolidationData entityConsolidationData,
2033                                      NodeTemplate nodeTemplate) {
2034     if (MapUtils.isEmpty(entityConsolidationData.getNodesConnectedOut())) {
2035       return;
2036     }
2037
2038     for (List<RequirementAssignmentData> requirementAssignmentDataList : entityConsolidationData
2039         .getNodesConnectedOut().values()) {
2040       for (RequirementAssignmentData requirementAssignmentData : requirementAssignmentDataList) {
2041         DataModelUtil.removeRequirementsAssignment(nodeTemplate.getRequirements(),
2042             requirementAssignmentData.getRequirementId());
2043       }
2044       if (nodeTemplate.getRequirements().isEmpty()) {
2045         nodeTemplate.setRequirements(null);
2046       }
2047     }
2048   }
2049
2050   private void removeVolumeConnectivity(
2051       ComputeTemplateConsolidationData computeTemplateConsolidationData,
2052       NodeTemplate computeNodeTemplate) {
2053     if (MapUtils.isEmpty(computeTemplateConsolidationData.getVolumes())) {
2054       return;
2055     }
2056     Collection<List<RequirementAssignmentData>> volumeCollection =
2057         computeTemplateConsolidationData.getVolumes().values();
2058     for (List<RequirementAssignmentData> requirementAssignmentDataList : volumeCollection) {
2059       for (RequirementAssignmentData requirementAssignmentData : requirementAssignmentDataList) {
2060         DataModelUtil.removeRequirementsAssignment(computeNodeTemplate.getRequirements(),
2061             requirementAssignmentData.getRequirementId());
2062       }
2063     }
2064     if (computeNodeTemplate.getRequirements().isEmpty()) {
2065       computeNodeTemplate.setRequirements(null);
2066     }
2067   }
2068
2069   private void createIndexInputParameter(ServiceTemplate substitutionServiceTemplate) {
2070     ParameterDefinition indexParameterDefinition =
2071         DataModelUtil.createParameterDefinition(PropertyType.INTEGER.getDisplayName(),
2072             "Index value of this substitution service template runtime instance", null,
2073             false, createIndexValueConstraint(), null, null, 0);
2074     DataModelUtil.addInputParameterToTopologyTemplate(substitutionServiceTemplate,
2075         ToscaConstants.INDEX_VALUE_PROPERTY_NAME, indexParameterDefinition);
2076   }
2077
2078
2079   private List<Constraint> createIndexValueConstraint() {
2080     List<Constraint> constraints;
2081     constraints = new ArrayList<>();
2082     Constraint constraint = new Constraint();
2083     constraint.setGreater_or_equal(0);
2084     constraints.add(constraint);
2085     return constraints;
2086   }
2087
2088   private Optional<UnifiedComposition> getUnifiedCompositionInstance(UnifiedCompositionMode mode) {
2089     String unifiedCompositionImplClassName =
2090         unifiedCompositionImplMap.get(mode.name()).getImplementationClass();
2091     if (StringUtils.isEmpty(unifiedCompositionImplClassName)) {
2092       return Optional.empty();
2093     }
2094     return Optional
2095         .of(CommonMethods.newInstance(unifiedCompositionImplClassName, UnifiedComposition.class));
2096   }
2097
2098   private Optional<Map<String, Object>> createAbstractSubstitutionProperties(
2099       ServiceTemplate serviceTemplate,
2100       ServiceTemplate substitutionServiceTemplate,
2101       List<UnifiedCompositionData> unifiedCompositionDataList) {
2102     Map<String, Object> abstractSubstituteProperties = new LinkedHashMap<>();
2103     Map<String, ParameterDefinition> substitutionTemplateInputs = DataModelUtil
2104         .getInputParameters(substitutionServiceTemplate);
2105     if (substitutionTemplateInputs == null) {
2106       return Optional.empty();
2107     }
2108     //Since all the computes have the same type fetching the type from the first entry
2109     NodeTemplate firstComputeNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate,
2110         unifiedCompositionDataList.get(0)
2111             .getComputeTemplateConsolidationData().getNodeTemplateId());
2112     String computeType = getComputeTypeSuffix(firstComputeNodeTemplate.getType());
2113     for (Map.Entry<String, ParameterDefinition> input : substitutionTemplateInputs.entrySet()) {
2114       String substitutionTemplateInputName = input.getKey();
2115       ParameterDefinition inputParameterDefinition = input.getValue();
2116       String inputType = inputParameterDefinition.getType();
2117       if (!inputType.equalsIgnoreCase(PropertyType.LIST.getDisplayName())) {
2118         if (isIdenticalValueProperty(substitutionTemplateInputName)) {
2119           //Handle identical value properties
2120           Object abstractPropertyValue = getPropertyValueFromNodeTemplate(
2121               getIdenticalValuePropertyName(substitutionTemplateInputName),
2122               firstComputeNodeTemplate);
2123           abstractSubstituteProperties.put(substitutionTemplateInputName, abstractPropertyValue);
2124         }
2125         continue;
2126       }
2127
2128       //Check if the input is of type compute or port
2129       UnifiedCompositionEntity inputUnifiedCompositionEntity = getInputCompositionEntity(
2130           substitutionTemplateInputName);
2131       List<Object> abstractPropertyValue = new ArrayList<>();
2132       Object propertyValue = null;
2133       switch (inputUnifiedCompositionEntity) {
2134         case Compute:
2135           for (UnifiedCompositionData compositionData : unifiedCompositionDataList) {
2136             ComputeTemplateConsolidationData computeTemplateConsolidationData =
2137                 compositionData.getComputeTemplateConsolidationData();
2138             propertyValue = getComputePropertyValue(substitutionTemplateInputName,
2139                 serviceTemplate, computeTemplateConsolidationData);
2140             if (!(propertyValue instanceof Optional)) {
2141               abstractPropertyValue.add(propertyValue);
2142             }
2143           }
2144           break;
2145         case Port:
2146           for (UnifiedCompositionData compositionData : unifiedCompositionDataList) {
2147             ComputeTemplateConsolidationData computeTemplateConsolidationData = compositionData
2148                 .getComputeTemplateConsolidationData();
2149             List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
2150                 getPortTemplateConsolidationDataList(compositionData);
2151             //Get the input type for this input whether it is of type
2152             // port_<port_node_template_id>_<property_name> or port_<port_type>_<property_name>
2153             PortInputType portInputType = getPortInputType(substitutionTemplateInputName,
2154                 compositionData);
2155             for (PortTemplateConsolidationData portTemplateConsolidationData :
2156                 portTemplateConsolidationDataList) {
2157               //Get the port property value
2158               String portNodeTemplateId = portTemplateConsolidationData.getNodeTemplateId();
2159               propertyValue = getPortPropertyValue(substitutionTemplateInputName,
2160                   computeType, portInputType, serviceTemplate, computeTemplateConsolidationData,
2161                   portNodeTemplateId);
2162               //If the value object is Optional.empty it implies that the property name was not
2163               // found in the input name
2164               if (!(propertyValue instanceof Optional)) {
2165                 abstractPropertyValue.add(propertyValue);
2166               }
2167             }
2168           }
2169           break;
2170         default:
2171           break;
2172       }
2173       //Add the property only if it has at least one non-null value
2174       for (Object val : abstractPropertyValue) {
2175         if (Objects.nonNull(val)) {
2176           abstractSubstituteProperties.put(substitutionTemplateInputName, abstractPropertyValue);
2177           break;
2178         }
2179       }
2180     }
2181     return Optional.ofNullable(abstractSubstituteProperties);
2182   }
2183
2184   private PortInputType getPortInputType(String inputName,
2185                                          UnifiedCompositionData unifiedCompositionData) {
2186     String portInputPrefix = UnifiedCompositionEntity.Port.name().toLowerCase() + "_";
2187     ComputeTemplateConsolidationData computeTemplateConsolidationData = unifiedCompositionData
2188         .getComputeTemplateConsolidationData();
2189     List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
2190         getPortTemplateConsolidationDataList(unifiedCompositionData);
2191     //Scan the available port node template ids to check if the input is of the form
2192     // "port_<port_node_template_id>_<property_name>"
2193     for (PortTemplateConsolidationData portTemplateConsolidationData :
2194         portTemplateConsolidationDataList) {
2195       String portNodeTemplateId = portTemplateConsolidationData.getNodeTemplateId();
2196       String portNodeTemplateIdPrefix = portInputPrefix + portNodeTemplateId;
2197       if (inputName.startsWith(portNodeTemplateIdPrefix)) {
2198         return PortInputType.NodeTemplateId;
2199       }
2200     }
2201     //Check whether the input is of the form "port_<port_type>_<property_name>"
2202     Set<String> portTypes = computeTemplateConsolidationData.getPorts().keySet();
2203     for (String portType : portTypes) {
2204       String expectedPortTypeSusbtring = portInputPrefix + portType + "_";
2205       if (inputName.startsWith(expectedPortTypeSusbtring)) {
2206         return PortInputType.PortType;
2207       }
2208     }
2209     return PortInputType.Other;
2210   }
2211
2212   private void cleanServiceTemplate(ServiceTemplate serviceTemplate,
2213                                     EntityConsolidationData entity,
2214                                     TranslationContext context) {
2215     removeNodeTemplateFromServiceTemplate(serviceTemplate, entity, context);
2216     updateHeatStackGroup(serviceTemplate, entity, context);
2217   }
2218
2219   private void removeNodeTemplateFromServiceTemplate(ServiceTemplate serviceTemplate,
2220                                                      EntityConsolidationData entity,
2221                                                      TranslationContext context) {
2222     String nodeTemplateIdToRemove = entity.getNodeTemplateId();
2223     Map<String, NodeTemplate> nodeTemplates =
2224         serviceTemplate.getTopology_template().getNode_templates();
2225     NodeTemplate nodeTemplateToRemove =
2226         nodeTemplates.get(nodeTemplateIdToRemove);
2227     nodeTemplates.remove(nodeTemplateIdToRemove);
2228
2229     context.addCleanedNodeTemplate(ToscaUtil.getServiceTemplateFileName(serviceTemplate),
2230         nodeTemplateIdToRemove,
2231         entity.getClass() == ComputeTemplateConsolidationData.class
2232             ? UnifiedCompositionEntity.Compute
2233             : UnifiedCompositionEntity.Port,
2234         nodeTemplateToRemove);
2235
2236   }
2237
2238   private void removeCleanedNodeType(String cleanedNodeTemplateId,
2239                                      ServiceTemplate serviceTemplate,
2240                                      TranslationContext context) {
2241     NodeTemplate cleanedNodeTemplate =
2242         context
2243             .getCleanedNodeTemplate(ToscaUtil.getServiceTemplateFileName(serviceTemplate),
2244                 cleanedNodeTemplateId);
2245     String typeToRemove = cleanedNodeTemplate.getType();
2246
2247     if (Objects.nonNull(typeToRemove)
2248         && serviceTemplate.getNode_types().containsKey(typeToRemove)) {
2249       serviceTemplate.getNode_types().remove(typeToRemove);
2250     }
2251   }
2252
2253   private void updateHeatStackGroup(ServiceTemplate serviceTemplate,
2254                                     EntityConsolidationData entity,
2255                                     TranslationContext context) {
2256     Map<String, GroupDefinition> groups = serviceTemplate.getTopology_template()
2257         .getGroups() == null ? new HashMap<>()
2258         : serviceTemplate.getTopology_template().getGroups();
2259     String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
2260     String nodeRelatedAbstractNodeId =
2261         context.getUnifiedAbstractNodeTemplateId(serviceTemplate, entity.getNodeTemplateId());
2262
2263     for (Map.Entry<String, GroupDefinition> groupEntry : groups.entrySet()) {
2264       GroupDefinition groupDefinition = groupEntry.getValue();
2265       if (isHeatStackGroup(groupDefinition.getType())) {
2266         updateGroupMembersWithNewUnifiedNodeTemplateId(entity, nodeRelatedAbstractNodeId,
2267             groupEntry);
2268       }
2269     }
2270   }
2271
2272   private void updateGroupMembersWithNewUnifiedNodeTemplateId(
2273       EntityConsolidationData entity,
2274       String newNodetemplateId,
2275       Map.Entry<String, GroupDefinition> groupEntry) {
2276     List<String> members = groupEntry.getValue().getMembers();
2277     if (members.contains(entity.getNodeTemplateId())) {
2278       members.remove(entity.getNodeTemplateId());
2279       if (!members.contains(newNodetemplateId)) {
2280         members.add(newNodetemplateId);
2281       }
2282     }
2283     groupEntry.getValue().setMembers(members);
2284   }
2285
2286   private void updateHeatStackGroupNestedComposition(ServiceTemplate serviceTemplate,
2287                                                      EntityConsolidationData entity,
2288                                                      TranslationContext context) {
2289     Map<String, GroupDefinition> groups = serviceTemplate.getTopology_template()
2290         .getGroups() == null ? new HashMap<>() : serviceTemplate.getTopology_template().getGroups();
2291     String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
2292     Optional<String> nestedNodeTemplateId =
2293         context.getUnifiedNestedNodeTemplateId(serviceTemplateFileName, entity.getNodeTemplateId());
2294
2295     if (nestedNodeTemplateId.isPresent()) {
2296       for (Map.Entry<String, GroupDefinition> groupEntry : groups.entrySet()) {
2297         GroupDefinition groupDefinition = groupEntry.getValue();
2298         if (isHeatStackGroup(groupDefinition.getType())) {
2299           updateGroupMembersWithNewUnifiedNodeTemplateId(entity, nestedNodeTemplateId.get(),
2300               groupEntry);
2301         }
2302       }
2303     }
2304   }
2305
2306   private void handleNestedNodeTemplateInMainServiceTemplate(String nestedNodeTemplateId,
2307                                                              ServiceTemplate mainServiceTemplate,
2308                                                              ServiceTemplate nestedServiceTemplate,
2309                                                              TranslationContext context) {
2310     NodeTemplate nestedNodeTemplate = DataModelUtil.getNodeTemplate(mainServiceTemplate,
2311         nestedNodeTemplateId);
2312     if (Objects.isNull(nestedNodeTemplate)) {
2313       return;
2314     }
2315
2316     Optional<String> unifiedNestedNodeTypeId = context
2317         .getUnifiedNestedNodeTypeId(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
2318             nestedNodeTemplate.getType());
2319     unifiedNestedNodeTypeId
2320         .ifPresent(unifiedNestedNodeTypeIdVal -> updateNestedNodeTemplate(
2321             unifiedNestedNodeTypeIdVal, nestedNodeTemplateId, nestedNodeTemplate,
2322             mainServiceTemplate, nestedServiceTemplate, context));
2323   }
2324
2325   private void handleSubstitutionMappingInNestedServiceTemplate(
2326       String newNestedNodeType,
2327       ServiceTemplate nestedServiceTemplate) {
2328     if (Objects.isNull(newNestedNodeType)) {
2329       return;
2330     }
2331
2332     SubstitutionMapping substitutionMappings =
2333         nestedServiceTemplate.getTopology_template().getSubstitution_mappings();
2334     substitutionMappings.setNode_type(newNestedNodeType);
2335   }
2336
2337   private void updateNestedNodeTemplate(String newNestedNodeTypeId,
2338                                         String nestedNodeTemplateId,
2339                                         NodeTemplate nestedNodeTemplate,
2340                                         ServiceTemplate mainServiceTemplate,
2341                                         ServiceTemplate nestedServiceTemplate,
2342                                         TranslationContext context) {
2343     String mainServiceTemplateName = ToscaUtil.getServiceTemplateFileName(mainServiceTemplate);
2344     int index =
2345         context.getHandledNestedComputeNodeTemplateIndex(mainServiceTemplateName,
2346             newNestedNodeTypeId);
2347     String newNodeTemplateId =
2348         Constants.ABSTRACT_NODE_TEMPLATE_ID_PREFIX + getComputeTypeSuffix(newNestedNodeTypeId) +
2349             "_" + index;
2350
2351     nestedNodeTemplate.setType(newNestedNodeTypeId);
2352     mainServiceTemplate.getTopology_template().getNode_templates().remove(nestedNodeTemplateId);
2353     mainServiceTemplate.getTopology_template().getNode_templates()
2354         .put(newNodeTemplateId, nestedNodeTemplate);
2355
2356     context
2357         .addUnifiedNestedNodeTemplateId(mainServiceTemplateName,
2358             nestedNodeTemplateId, newNodeTemplateId);
2359   }
2360
2361   private void handleNestedNodeTypesInGlobalSubstituteServiceTemplate(
2362       String origNestedNodeTypeId,
2363       String newNestedNodeTypeId,
2364       ServiceTemplate globalSubstitutionServiceTemplate,
2365       TranslationContext context) {
2366     Map<String, NodeType> nodeTypes = globalSubstitutionServiceTemplate.getNode_types();
2367     NodeType nested = DataModelUtil.getNodeType(globalSubstitutionServiceTemplate,
2368         origNestedNodeTypeId);
2369     setNewValuesForNestedNodeType(origNestedNodeTypeId, newNestedNodeTypeId, nested, nodeTypes);
2370     context.addUnifiedNestedNodeTypeId(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
2371         origNestedNodeTypeId, newNestedNodeTypeId);
2372   }
2373
2374   private void setNewValuesForNestedNodeType(String origNestedNodeType,
2375                                              String newNestedNodeTypeId,
2376                                              NodeType nested,
2377                                              Map<String, NodeType> nodeTypes) {
2378     if (Objects.nonNull(nested)) {
2379       nested.setDerived_from(ToscaNodeType.VFC_ABSTRACT_SUBSTITUTE);
2380       nodeTypes.remove(origNestedNodeType);
2381       nodeTypes.put(newNestedNodeTypeId, nested);
2382     }
2383   }
2384
2385   private Optional<String> getNewNestedNodeTypeId(ServiceTemplate mainServiceTemplate,
2386                                                   ServiceTemplate nestedServiceTemplate,
2387                                                   TranslationContext context) {
2388     FileComputeConsolidationData fileComputeConsolidationData =
2389         context.getConsolidationData().getComputeConsolidationData()
2390             .getFileComputeConsolidationData(
2391                 ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate));
2392
2393     if (Objects.nonNull(fileComputeConsolidationData)) {
2394       String nestedNodeTypePrefix = ToscaNodeType.ABSTRACT_NODE_TYPE_PREFIX + "heat.";
2395       return Optional
2396           .of(nestedNodeTypePrefix + getComputeTypeInNestedFile(fileComputeConsolidationData));
2397     }
2398     return Optional.empty();
2399   }
2400
2401   private String getComputeTypeInNestedFile(
2402       FileComputeConsolidationData fileComputeConsolidationData) {
2403     List<TypeComputeConsolidationData> typeComputeConsolidationDatas =
2404         new ArrayList<>(fileComputeConsolidationData.getAllTypeComputeConsolidationData());
2405     if (typeComputeConsolidationDatas.size() == 0) {
2406       return null;
2407     } else {
2408       String computeNodeType = fileComputeConsolidationData.getAllComputeTypes().iterator().next();
2409       return getComputeTypeSuffix(computeNodeType);
2410     }
2411   }
2412
2413   private void handleGetAttrInAbstractNodeTemplate(ServiceTemplate serviceTemplate,
2414                                                    TranslationContext context,
2415                                                    String serviceTemplateFileName,
2416                                                    NodeTemplate abstractNodeTemplate) {
2417     Map<String, Object> properties =
2418         abstractNodeTemplate == null || abstractNodeTemplate.getProperties() == null
2419             ? new HashMap<>()
2420             : abstractNodeTemplate.getProperties();
2421     for (Object propertyValue : properties.values()) {
2422       List<List<Object>> getAttrList = extractGetAttrFunction(propertyValue);
2423       for (List<Object> getAttrFuncValue : getAttrList) {
2424         String origNodeTemplateId = (String) getAttrFuncValue.get(0);
2425         Optional<String> nestedNodeTemplateId = context.getUnifiedNestedNodeTemplateId(ToscaUtil
2426             .getServiceTemplateFileName(serviceTemplate), origNodeTemplateId);
2427         if (nestedNodeTemplateId.isPresent()) {
2428           getAttrFuncValue.set(0, nestedNodeTemplateId.get());
2429         } else {
2430           replaceGetAttrNodeIdAndAttrName(serviceTemplate, context, serviceTemplateFileName,
2431               getAttrFuncValue);
2432         }
2433       }
2434     }
2435   }
2436
2437   private void replaceGetAttrNodeIdAndAttrName(ServiceTemplate serviceTemplate,
2438                                                TranslationContext context,
2439                                                String serviceTemplateFileName,
2440                                                List<Object> getAttrFuncValue) {
2441     String origNodeTemplateId = (String) getAttrFuncValue.get(0);
2442     String attributeName = (String) getAttrFuncValue.get(1);
2443
2444     String unifiedAbstractNodeTemplateId =
2445         context.getUnifiedAbstractNodeTemplateId(serviceTemplate, origNodeTemplateId);
2446
2447     if (Objects.isNull(unifiedAbstractNodeTemplateId)) {
2448       return;
2449     }
2450
2451     String newNodeTemplateId =
2452         getNewNodeTemplateId(origNodeTemplateId, serviceTemplateFileName, serviceTemplate, context);
2453
2454     String newSubstitutionOutputParameterId =
2455         getNewSubstitutionOutputParameterId(newNodeTemplateId, attributeName);
2456
2457     getAttrFuncValue.set(0, unifiedAbstractNodeTemplateId);
2458     getAttrFuncValue.set(1, newSubstitutionOutputParameterId);
2459   }
2460
2461   private NodeTemplate getComputeNodeTemplate(String origNodeTemplateId,
2462                                               ServiceTemplate serviceTemplate,
2463                                               TranslationContext context) {
2464     NodeTemplate computeNodeTemplate =
2465         DataModelUtil.getNodeTemplate(serviceTemplate, origNodeTemplateId);
2466     if (computeNodeTemplate == null) {
2467       computeNodeTemplate =
2468           context.getCleanedNodeTemplate(ToscaUtil.getServiceTemplateFileName(serviceTemplate),
2469               origNodeTemplateId);
2470     }
2471     return computeNodeTemplate;
2472   }
2473
2474   private String handleIdOfPort(String origNodeTemplateId, String serviceTemplateFileName,
2475                                 ConsolidationData consolidationData) {
2476     Optional<Pair<String, ComputeTemplateConsolidationData>>
2477         computeTypeAndComputeTemplateByPortId =
2478         getComputeTypeAndComputeTemplateByPortId(origNodeTemplateId, serviceTemplateFileName,
2479             consolidationData);
2480     if (computeTypeAndComputeTemplateByPortId.isPresent()) {
2481       Pair<String, ComputeTemplateConsolidationData> computeIdToComputeData =
2482           computeTypeAndComputeTemplateByPortId.get();
2483       return getNewPortNodeTemplateId(origNodeTemplateId, computeIdToComputeData.getKey(),
2484           computeIdToComputeData.getValue());
2485     }
2486
2487     return null;
2488   }
2489
2490   private Optional<Pair<String, ComputeTemplateConsolidationData>>
2491   getComputeTypeAndComputeTemplateByPortId(String portId, String serviceTemplateFileName,
2492                                            ConsolidationData consolidationData) {
2493     FileComputeConsolidationData fileComputeConsolidationData =
2494         consolidationData.getComputeConsolidationData()
2495             .getFileComputeConsolidationData(serviceTemplateFileName);
2496     Set<String> computeTypes =
2497         fileComputeConsolidationData.getAllComputeTypes();
2498
2499     for (String computeType : computeTypes) {
2500       Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDatas =
2501           fileComputeConsolidationData.getTypeComputeConsolidationData(computeType)
2502               .getAllComputeTemplateConsolidationData();
2503
2504       for (ComputeTemplateConsolidationData compute : computeTemplateConsolidationDatas) {
2505         if (ConsolidationDataUtil.isComputeReferenceToPortId(compute, portId)) {
2506           return Optional.of(new ImmutablePair<>(computeType, compute));
2507         }
2508       }
2509     }
2510
2511     return Optional.empty();
2512   }
2513
2514   private boolean isIdIsOfExpectedType(String id,
2515                                        UnifiedCompositionEntity expectedUnifiedCompositionEntity,
2516                                        String serviceTemplateFileName,
2517                                        ConsolidationData consolidationData,
2518                                        TranslationContext context) {
2519     UnifiedSubstitutionData unifiedSubstitutionData =
2520         context.getUnifiedSubstitutionData().get(serviceTemplateFileName);
2521     if (Objects.isNull(unifiedSubstitutionData)) {
2522       return false;
2523     }
2524
2525     UnifiedCompositionEntity actualUnifiedCompositionEntity =
2526         unifiedSubstitutionData.getCleanedNodeTemplateCompositionEntity(id);
2527
2528     return actualUnifiedCompositionEntity == null ? false
2529         : actualUnifiedCompositionEntity.equals(expectedUnifiedCompositionEntity);
2530   }
2531
2532   private boolean isHeatStackGroup(String groupType) {
2533     return groupType.equals(ToscaGroupType.HEAT_STACK);
2534   }
2535
2536   private Object getPortPropertyValue(String inputName,
2537                                       String computeType,
2538                                       PortInputType portInputType,
2539                                       ServiceTemplate serviceTemplate,
2540                                       ComputeTemplateConsolidationData
2541                                           computeTemplateConsolidationData,
2542                                       String portNodeTemplateId) {
2543     //Get the input prefix to extract the property name from the input name
2544     String portInputPrefix = getPortInputPrefix(computeTemplateConsolidationData,
2545         portNodeTemplateId, portInputType);
2546     //Get the property name from the input
2547     Optional<String> propertyName = getPropertyNameFromInput(inputName,
2548         UnifiedCompositionEntity.Port, computeType, portInputPrefix);
2549     //Get the property value from the node template
2550     if (propertyName.isPresent()) {
2551       NodeTemplate portNodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate,
2552           portNodeTemplateId);
2553       if (Objects.nonNull(portNodeTemplate)) {
2554         return getPropertyValueFromNodeTemplate(propertyName.get(), portNodeTemplate);
2555       }
2556     }
2557     return Optional.empty();
2558   }
2559
2560   private Optional<String> getPortTypeFromInput(
2561       String inputName,
2562       String portNodeTemplateId,
2563       ComputeTemplateConsolidationData computeTemplateConsolidationData) {
2564     String portTypeFromInput = null;
2565     String portInputPrefix = UnifiedCompositionEntity.Port.name().toLowerCase() + "_";
2566     String portNodeTemplateIdPrefix = portInputPrefix + portNodeTemplateId;
2567     if (inputName.startsWith(portNodeTemplateIdPrefix)) {
2568       return Optional.empty();
2569     }
2570     Set<String> portTypes = computeTemplateConsolidationData.getPorts().keySet();
2571     for (String portType : portTypes) {
2572       String expectedPortTypeSusbtring = "_" + portType + "_";
2573       if (inputName.contains(expectedPortTypeSusbtring)) {
2574         portTypeFromInput = portType;
2575         break;
2576       }
2577     }
2578     return Optional.ofNullable(portTypeFromInput);
2579   }
2580
2581   private Object getComputePropertyValue(
2582       String inputName,
2583       ServiceTemplate serviceTemplate,
2584       ComputeTemplateConsolidationData computeTemplateConsolidationData) {
2585     NodeTemplate nodeTemplate = DataModelUtil.getNodeTemplate(serviceTemplate,
2586         computeTemplateConsolidationData.getNodeTemplateId());
2587     String nodeType = getComputeTypeSuffix(nodeTemplate.getType());
2588     Optional<String> propertyName =
2589         getPropertyNameFromInput(inputName, UnifiedCompositionEntity.Compute, nodeType, null);
2590     if (propertyName.isPresent()) {
2591       return getPropertyValueFromNodeTemplate(propertyName.get(), nodeTemplate);
2592     }
2593     return Optional.empty();
2594   }
2595
2596   private UnifiedCompositionEntity getInputCompositionEntity(String inputName) {
2597     UnifiedCompositionEntity inputCompositionEntity = UnifiedCompositionEntity.Other;
2598     String inputType = inputName.substring(0, inputName.indexOf('_'));
2599     if (inputType.equals(UnifiedCompositionEntity.Compute.name().toLowerCase())) {
2600       inputCompositionEntity = UnifiedCompositionEntity.Compute;
2601     } else if (inputType.equals(UnifiedCompositionEntity.Port.name().toLowerCase())) {
2602       inputCompositionEntity = UnifiedCompositionEntity.Port;
2603     }
2604     return inputCompositionEntity;
2605   }
2606
2607   private Optional<String> getPropertyNameFromInput(
2608       String inputName,
2609       UnifiedCompositionEntity compositionEntity,
2610       String computeType, String portInputPrefix) {
2611     String propertyName = null;
2612     switch (compositionEntity) {
2613       case Compute:
2614         propertyName = inputName.substring(inputName.lastIndexOf(computeType)
2615             + computeType.length() + 1);
2616         break;
2617       case Port:
2618         if (inputName.startsWith(portInputPrefix)) {
2619           propertyName = inputName.split(portInputPrefix)[1];
2620         }
2621         break;
2622       default:
2623         break;
2624     }
2625     return Optional.ofNullable(propertyName);
2626   }
2627
2628   private String getPortInputPrefix(
2629       ComputeTemplateConsolidationData computeTemplateConsolidationData,
2630       String portNodeTemplateId,
2631       PortInputType portInputType) {
2632     String portInputPrefix = UnifiedCompositionEntity.Port.name().toLowerCase() + "_";
2633     String portType = ConsolidationDataUtil.getPortType(portNodeTemplateId);
2634     if (portInputType == PortInputType.NodeTemplateId) {
2635       portInputPrefix += portNodeTemplateId + "_";
2636     } else if (portInputType == PortInputType.PortType) {
2637       portInputPrefix += portType + "_";
2638     }
2639     return portInputPrefix;
2640   }
2641
2642   private boolean isIdenticalValueProperty(String inputName) {
2643     StringBuilder builder = new StringBuilder(IDENTICAL_VALUE_PROPERTY_PREFIX);
2644     builder.append("[a-z]+");
2645     builder.append(IDENTICAL_VALUE_PROPERTY_SUFFIX);
2646     boolean isMatchingProperty = Pattern.matches(builder.toString(), inputName);
2647     List<String> identicalValuePropertyList = consolidationService.getPropertiesWithIdenticalVal();
2648     if (isMatchingProperty
2649         && identicalValuePropertyList.contains(getIdenticalValuePropertyName(inputName))) {
2650       return true;
2651     }
2652     return false;
2653   }
2654
2655   private String getIdenticalValuePropertyName(String input) {
2656     return input.split("_")[1];
2657   }
2658
2659   private Object getPropertyValueFromNodeTemplate(String propertyName, NodeTemplate nodeTemplate) {
2660     Map<String, Object> nodeTemplateProperties = nodeTemplate.getProperties();
2661     if (nodeTemplateProperties != null) {
2662       Object propertyValue = nodeTemplateProperties.get(propertyName);
2663       propertyValue = getClonedObject(propertyValue);
2664       return propertyValue;
2665     }
2666     return null;
2667   }
2668
2669   private <T> Object getClonedObject(Object objectValue, Class<T> clazz) {
2670     YamlUtil yamlUtil = new YamlUtil();
2671     Object clonedObjectValue;
2672     String objectToYaml = yamlUtil.objectToYaml(objectValue);
2673     clonedObjectValue = yamlUtil.yamlToObject(objectToYaml, clazz);
2674     return clonedObjectValue;
2675   }
2676
2677   private Object getClonedObject(Object objectValue) {
2678     Object clonedObjectValue;
2679     try {
2680       ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
2681       ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
2682       objectOutputStream.writeObject(objectValue);
2683
2684       ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream
2685           .toByteArray());
2686       ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
2687       clonedObjectValue = objectInputStream.readObject();
2688     } catch (NotSerializableException ex) {
2689       return getClonedObject(objectValue, objectValue.getClass());
2690     } catch (IOException ioe) {
2691       return null;
2692     } catch (ClassNotFoundException cnfe) {
2693       return null;
2694     }
2695     return clonedObjectValue;
2696   }
2697
2698   private Map<String, UnifiedCompositionEntity> getAllConsolidationNodeTemplateIdAndType(
2699       List<UnifiedCompositionData> unifiedCompositionDataList) {
2700
2701     Map<String, UnifiedCompositionEntity> consolidationNodeTemplateIdAndType = new HashMap<>();
2702     for (UnifiedCompositionData unifiedCompositionData : unifiedCompositionDataList) {
2703       ComputeTemplateConsolidationData computeTemplateConsolidationData =
2704           unifiedCompositionData.getComputeTemplateConsolidationData();
2705       if (Objects.nonNull(computeTemplateConsolidationData)) {
2706         consolidationNodeTemplateIdAndType
2707             .put(computeTemplateConsolidationData.getNodeTemplateId(),
2708                 UnifiedCompositionEntity.Compute);
2709       }
2710       List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
2711           getPortTemplateConsolidationDataList(unifiedCompositionData);
2712       for (PortTemplateConsolidationData portTemplateConsolidationData :
2713           portTemplateConsolidationDataList) {
2714         consolidationNodeTemplateIdAndType.put(portTemplateConsolidationData.getNodeTemplateId(),
2715             UnifiedCompositionEntity.Port);
2716       }
2717       NestedTemplateConsolidationData nestedTemplateConsolidationData =
2718           unifiedCompositionData.getNestedTemplateConsolidationData();
2719       if (Objects.nonNull(nestedTemplateConsolidationData)) {
2720         consolidationNodeTemplateIdAndType
2721             .put(nestedTemplateConsolidationData.getNodeTemplateId(),
2722                 UnifiedCompositionEntity.Nested);
2723       }
2724     }
2725     return consolidationNodeTemplateIdAndType;
2726   }
2727
2728   private enum PortInputType {
2729     NodeTemplateId,
2730     PortType,
2731     Other;
2732   }
2733
2734   private List<PortTemplateConsolidationData> getPortTemplateConsolidationDataList(
2735       UnifiedCompositionData unifiedCompositionData) {
2736     return unifiedCompositionData.getPortTemplateConsolidationDataList() == null ? new
2737         ArrayList<>() : unifiedCompositionData.getPortTemplateConsolidationDataList();
2738   }
2739 }