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