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