Add collaboration feature
[sdc.git] / openecomp-be / lib / openecomp-sdc-translator-lib / openecomp-sdc-translator-core / src / main / java / org / openecomp / sdc / translator / services / heattotosca / ConsolidationService.java
1 package org.openecomp.sdc.translator.services.heattotosca;
2
3 import org.apache.commons.collections4.CollectionUtils;
4 import org.apache.commons.collections4.MapUtils;
5 import org.openecomp.sdc.common.errors.CoreException;
6 import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage;
7 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
8 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
9 import org.openecomp.sdc.tosca.services.ToscaConstants;
10 import org.openecomp.sdc.tosca.services.ToscaUtil;
11 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
12 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedCompositionData;
13 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedCompositionEntity;
14 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedCompositionMode;
15 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.ComputeTemplateConsolidationData;
16 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.ConsolidationData;
17 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.EntityConsolidationData;
18 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.FileComputeConsolidationData;
19 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.FileNestedConsolidationData;
20 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.FilePortConsolidationData;
21 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.GetAttrFuncData;
22 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.NestedTemplateConsolidationData;
23 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.PortTemplateConsolidationData;
24 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.RequirementAssignmentData;
25 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.TypeComputeConsolidationData;
26 import org.openecomp.sdc.translator.services.heattotosca.errors.DuplicateResourceIdsInDifferentFilesErrorBuilder;
27
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.Collections;
31 import java.util.HashMap;
32 import java.util.HashSet;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Objects;
36 import java.util.Set;
37
38 public class ConsolidationService {
39
40   private MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
41   private UnifiedCompositionService unifiedCompositionService;
42
43   public ConsolidationService(UnifiedCompositionService unifiedCompositionService) {
44     this.unifiedCompositionService = unifiedCompositionService;
45   }
46
47   ConsolidationService() {
48
49   }
50
51   void serviceTemplateConsolidation(ServiceTemplate serviceTemplate,
52                                     TranslationContext translationContext) {
53
54     ConsolidationData consolidationData = translationContext.getConsolidationData();
55
56     FileComputeConsolidationData fileComputeConsolidationData =
57         consolidationData.getComputeConsolidationData()
58             .getFileComputeConsolidationData(ToscaUtil.getServiceTemplateFileName(serviceTemplate));
59
60     if (Objects.isNull(fileComputeConsolidationData)) {
61       return;
62     }
63     for (TypeComputeConsolidationData typeComputeConsolidationData :
64         fileComputeConsolidationData.getAllTypeComputeConsolidationData()) {
65       boolean preConditionResult =
66           consolidationPreCondition(
67               serviceTemplate, consolidationData, typeComputeConsolidationData);
68
69       List<UnifiedCompositionData> unifiedCompositionDataList =
70           createUnifiedCompositionDataList(
71               serviceTemplate, consolidationData, typeComputeConsolidationData);
72
73       if (preConditionResult) {
74         boolean consolidationRuleCheckResult =
75             checkConsolidationRules(serviceTemplate, typeComputeConsolidationData,
76                 consolidationData, translationContext);
77
78         unifiedCompositionService.createUnifiedComposition(
79             serviceTemplate, null, unifiedCompositionDataList,
80             consolidationRuleCheckResult ? UnifiedCompositionMode.ScalingInstances
81                 : UnifiedCompositionMode.CatalogInstance,
82             translationContext);
83       } else {
84         unifiedCompositionService.createUnifiedComposition(
85             serviceTemplate, null, unifiedCompositionDataList, UnifiedCompositionMode
86                 .SingleSubstitution,
87             translationContext);
88       }
89     }
90
91   }
92
93   public static Map<String, String> getConsolidationEntityIdToType(ServiceTemplate serviceTemplate,
94                                                              ConsolidationData consolidationData) {
95     Map<String, String> consolidationEntityIdToType = new HashMap<>();
96
97     String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
98     FileComputeConsolidationData fileComputeConsolidationData =
99         consolidationData.getComputeConsolidationData()
100             .getFileComputeConsolidationData(serviceTemplateFileName);
101     FilePortConsolidationData filePortConsolidationData =
102         consolidationData.getPortConsolidationData()
103             .getFilePortConsolidationData(serviceTemplateFileName);
104     if(Objects.nonNull(fileComputeConsolidationData)) {
105       for (String computeType : fileComputeConsolidationData.getAllComputeTypes()) {
106         TypeComputeConsolidationData typeComputeConsolidationData =
107             fileComputeConsolidationData.getTypeComputeConsolidationData(computeType);
108         Set<String> computeNodeTemplateIds =
109             typeComputeConsolidationData.getAllComputeNodeTemplateIds();
110         for (String computeNodeTemplateId : computeNodeTemplateIds) {
111           consolidationEntityIdToType.put(computeNodeTemplateId, computeType);
112         }
113       }
114     }
115
116     if(Objects.nonNull(filePortConsolidationData)) {
117       Set<String> portNodeTemplateIds = filePortConsolidationData.getAllPortNodeTemplateIds();
118       for (String portNodeTemplateId : portNodeTemplateIds) {
119         consolidationEntityIdToType
120             .put(portNodeTemplateId, ConsolidationDataUtil.getPortType(portNodeTemplateId));
121       }
122     }
123
124     return consolidationEntityIdToType;
125   }
126
127
128   private boolean checkConsolidationRules(ServiceTemplate serviceTemplate,
129                                           TypeComputeConsolidationData typeComputeConsolidationData,
130                                           ConsolidationData consolidationData,
131                                           TranslationContext context) {
132     return checkComputeConsolidation(serviceTemplate, typeComputeConsolidationData)
133         && checkPortConsolidation(serviceTemplate, typeComputeConsolidationData,
134         consolidationData, context)
135         && !checkGetAttrBetweenEntityConsolidationOfTheSameType(serviceTemplate,
136         typeComputeConsolidationData, consolidationData);
137   }
138
139   private boolean checkGetAttrBetweenConsolidationDataEntitiesNotFromSameType(
140       ServiceTemplate serviceTemplate,
141       TypeComputeConsolidationData typeComputeConsolidationData,
142       ConsolidationData consolidationData) {
143     List<ComputeTemplateConsolidationData> computeTemplateConsolidationDataList =
144         new ArrayList(typeComputeConsolidationData.getAllComputeTemplateConsolidationData());
145
146     Set<String> computeNodeTemplateIds =
147         typeComputeConsolidationData.getAllComputeNodeTemplateIds();
148
149     Map<String, Set<String>> portTypeToIds = UnifiedCompositionUtil
150         .collectAllPortsFromEachTypesFromComputes(computeTemplateConsolidationDataList);
151
152     return
153         checkGetAttrOutFromEntityToPortIsLegal(computeTemplateConsolidationDataList, portTypeToIds)
154             && checkGetAttrOutFromPortLegal(ToscaUtil.getServiceTemplateFileName(serviceTemplate),
155             computeNodeTemplateIds, portTypeToIds, consolidationData);
156
157   }
158
159   private boolean checkGetAttrInEntityConsolidationWithPortIsLegal(
160       List entityConsolidationDatas,
161       TypeComputeConsolidationData typeComputeConsolidationData) {
162     Map<String, Set<String>> portTypeToIds =
163         UnifiedCompositionUtil.collectAllPortsFromEachTypesFromComputes(
164             typeComputeConsolidationData.getAllComputeTemplateConsolidationData());
165
166     Set<String> startingPortTypesPointByGetAttr =
167         getPortTypesPointedByGetAttrFromEntity(
168             (EntityConsolidationData) entityConsolidationDatas.get(0), portTypeToIds);
169
170     for (int i = 1; i < entityConsolidationDatas.size(); i++) {
171       Set<String> currentPortTypesPointByGetAttr =
172           getPortTypesPointedByGetAttrFromEntity(
173               (EntityConsolidationData) entityConsolidationDatas.get(i), portTypeToIds);
174       if (!startingPortTypesPointByGetAttr.equals(currentPortTypesPointByGetAttr)) {
175         return false;
176       }
177     }
178
179     return true;
180   }
181
182   private Set<String> getPortTypesPointedByGetAttrFromEntity(
183       EntityConsolidationData entity,
184       Map<String, Set<String>> portTypeToIds) {
185     return getPortTypeToIdPointByGetAttrInOrOut(
186         entity.getNodesGetAttrIn(), portTypeToIds, entity).keySet();
187   }
188
189   private boolean checkGetAttrInToPortIsLegal(
190       ServiceTemplate serviceTemplate,
191       TypeComputeConsolidationData typeComputeConsolidationData,
192       ConsolidationData consolidationData) {
193
194     Map<String, Set<String>> portTypeToIds = UnifiedCompositionUtil
195         .collectAllPortsFromEachTypesFromComputes(
196             typeComputeConsolidationData.getAllComputeTemplateConsolidationData());
197
198     for (Set<String> portIdsFromSameType : portTypeToIds.values()) {
199       List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
200           collectAllPortsTemplateConsolidationData(
201               portIdsFromSameType, ToscaUtil.getServiceTemplateFileName(serviceTemplate),
202               consolidationData);
203
204       if (!checkGetAttrInEntityConsolidationWithPortIsLegal(
205           portTemplateConsolidationDataList, typeComputeConsolidationData)) {
206         return false;
207       }
208     }
209
210     return true;
211   }
212
213
214   private boolean checkGetAttrOutFromPortLegal(String serviceTemplateName,
215                                                Set<String> computeNodeTemplateIds,
216                                                Map<String, Set<String>> portTypeToIds,
217                                                ConsolidationData consolidationData) {
218     for (Set<String> portIdsFromSameType : portTypeToIds.values()) {
219       List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
220           collectAllPortsTemplateConsolidationData(portIdsFromSameType, serviceTemplateName,
221               consolidationData);
222
223       if (!(checkGetAttrOutFromEntityToPortIsLegal(portTemplateConsolidationDataList, portTypeToIds)
224           && checkGetAttrOutFromPortToComputeIsLegal(portTemplateConsolidationDataList,
225           computeNodeTemplateIds))) {
226         return false;
227       }
228     }
229
230     return true;
231   }
232
233   private boolean checkGetAttrOutFromEntityToPortIsLegal(List entityConsolidationDataList,
234                                                          Map<String, Set<String>> portTypeToIds) {
235
236     for (String portType : portTypeToIds.keySet()) {
237       Set<GetAttrFuncData> startingGetAttrFunc =
238           getEntityGetAttrFuncAsSet(portType,
239               (EntityConsolidationData) entityConsolidationDataList.get(0));
240       for (int i = 1; i < entityConsolidationDataList.size(); i++) {
241         Object entity = entityConsolidationDataList.get(i);
242         Set<GetAttrFuncData> currentGetAttrFuncData =
243             getEntityGetAttrFuncAsSet(portType,
244                 (EntityConsolidationData) entity);
245         if (!(startingGetAttrFunc.equals(currentGetAttrFuncData))) {
246           return false;
247         }
248       }
249     }
250
251     return true;
252   }
253
254   private boolean checkGetAttrOutFromPortToComputeIsLegal(
255       List<PortTemplateConsolidationData> portTemplateConsolidationDataList,
256       Set<String> computeNodeTemplateIds) {
257     PortTemplateConsolidationData startingPortTemplate =
258         portTemplateConsolidationDataList.get(0);
259     Map<String, Set<GetAttrFuncData>> startingComputeGetAttrOutFuncData =
260         getComputeGetAttrOutFuncData(startingPortTemplate.getNodesGetAttrOut(),
261             computeNodeTemplateIds);
262
263     for (int i = 1; i < portTemplateConsolidationDataList.size(); i++) {
264       PortTemplateConsolidationData currentPortTemplate =
265           portTemplateConsolidationDataList.get(i);
266       Map<String, Set<GetAttrFuncData>> currentComputeGetAttrOutFuncData =
267           getComputeGetAttrOutFuncData(currentPortTemplate.getNodesGetAttrOut(),
268               computeNodeTemplateIds);
269
270       if (!isGetAttrRelationToComputeSimilarBetweenEntities(startingComputeGetAttrOutFuncData,
271           currentComputeGetAttrOutFuncData)) {
272         return false;
273       }
274     }
275
276     return true;
277   }
278
279   private boolean isGetAttrRelationToComputeSimilarBetweenEntities(
280       Map<String, Set<GetAttrFuncData>> firstMap,
281       Map<String, Set<GetAttrFuncData>> secondMap) {
282     if (MapUtils.isEmpty(firstMap) != MapUtils.isEmpty(secondMap)) {
283       return false;
284     }
285
286     if (MapUtils.isEmpty(firstMap) && MapUtils.isEmpty(secondMap)) {
287       return true;
288     }
289
290     return new ArrayList<>(firstMap.values()).equals(new ArrayList<>(secondMap.values()));
291   }
292
293   private Set<GetAttrFuncData> getEntityGetAttrFuncAsSet(
294       String portType,
295       EntityConsolidationData entityConsolidationData) {
296
297     Set<GetAttrFuncData> getAttrFuncDataFromPortsWithSameType = new HashSet<>();
298     Map<String, List<GetAttrFuncData>> nodesGetAttrOut =
299         entityConsolidationData.getNodesGetAttrOut();
300
301     if (MapUtils.isEmpty(nodesGetAttrOut)) {
302       return getAttrFuncDataFromPortsWithSameType;
303     }
304
305     for (Map.Entry<String, List<GetAttrFuncData>> entry : nodesGetAttrOut.entrySet()) {
306       if (portType.equals(ConsolidationDataUtil.getPortType(entry.getKey()))) {
307         getAttrFuncDataFromPortsWithSameType.addAll(entry.getValue());
308       }
309     }
310
311     return getAttrFuncDataFromPortsWithSameType;
312   }
313
314   private Map<String, Set<GetAttrFuncData>> getComputeGetAttrOutFuncData(
315       Map<String, List<GetAttrFuncData>> nodesGetAttrOut,
316       Set<String> computeNodeTemplateIds) {
317     Map<String, Set<GetAttrFuncData>> computeGetAttrFuncData = new HashMap<>();
318
319     if (MapUtils.isEmpty(nodesGetAttrOut)) {
320       return computeGetAttrFuncData;
321     }
322
323     for (Map.Entry<String, List<GetAttrFuncData>> getAttrFuncEntry : nodesGetAttrOut.entrySet()) {
324       if (computeNodeTemplateIds.contains(getAttrFuncEntry.getKey())) {
325         computeGetAttrFuncData.put(getAttrFuncEntry.getKey(), new HashSet<>(getAttrFuncEntry
326             .getValue()));
327       }
328     }
329
330     return computeGetAttrFuncData;
331   }
332
333   private Map<String, List<String>> getPortTypeToIdPointByGetAttrInOrOut(
334       Map<String, List<GetAttrFuncData>> getAttr,
335       Map<String, Set<String>> portTypeToIds,
336       EntityConsolidationData entityConsolidationData) {
337     Map<String, List<String>> portIdToType = new HashMap<>();
338
339     if (MapUtils.isEmpty(getAttr)) {
340       return portIdToType;
341     }
342
343     for (String getAttrId : getAttr.keySet()) {
344       if (isNodeTemplateIdIsInComputeConsolidationData(getAttrId, portTypeToIds)) {
345         String portType = ConsolidationDataUtil.getPortType(getAttrId);
346         portIdToType.putIfAbsent(portType, new ArrayList<>());
347         portIdToType.get(portType).add(getAttrId);
348       }
349     }
350
351     return portIdToType;
352
353   }
354
355
356   private boolean isNodeTemplateIdIsInComputeConsolidationData(
357       String getAttrInId,
358       Map<String, Set<String>> portTypeToIds) {
359     return portTypeToIds.keySet().contains(ConsolidationDataUtil.getPortType(getAttrInId));
360   }
361
362   private boolean checkGetAttrBetweenEntityConsolidationOfTheSameType(
363       ServiceTemplate serviceTemplate,
364       TypeComputeConsolidationData typeComputeConsolidationData,
365       ConsolidationData consolidationData) {
366     return checkGetAttrRelationsBetweenComputesOfSameType(typeComputeConsolidationData)
367         || checkGetAttrRelationsBetweenPortsOfTheSameType(serviceTemplate,
368         typeComputeConsolidationData, consolidationData);
369
370   }
371
372   private boolean checkGetAttrRelationsBetweenComputesOfSameType(
373       TypeComputeConsolidationData typeComputeConsolidationData) {
374
375     Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDatas =
376         typeComputeConsolidationData.getAllComputeTemplateConsolidationData();
377     Set<String> computeNodeTemplateIds =
378         typeComputeConsolidationData.getAllComputeNodeTemplateIds();
379
380     return checkGetAttrRelationsForEntityConsolidationData(
381         computeTemplateConsolidationDatas, computeNodeTemplateIds);
382   }
383
384   private boolean checkGetAttrRelationsBetweenPortsOfTheSameType(
385       ServiceTemplate serviceTemplate,
386       TypeComputeConsolidationData typeComputeConsolidationData,
387       ConsolidationData consolidationData) {
388
389     Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDatas =
390         typeComputeConsolidationData.getAllComputeTemplateConsolidationData();
391     Map<String, Set<String>> portTypeToPortIds = UnifiedCompositionUtil
392         .collectAllPortsFromEachTypesFromComputes(computeTemplateConsolidationDatas);
393
394     FilePortConsolidationData filePortConsolidationData =
395         consolidationData.getPortConsolidationData().getFilePortConsolidationData(ToscaUtil
396             .getServiceTemplateFileName(serviceTemplate));
397
398     for (Set<String> portsOfTheSameTypeIds : portTypeToPortIds.values()) {
399       List<PortTemplateConsolidationData> portTemplateConsolidationDataOfSameType =
400           getAllPortTemplateConsolidationData(portsOfTheSameTypeIds, filePortConsolidationData);
401       if (!checkGetAttrRelationsForEntityConsolidationData(portTemplateConsolidationDataOfSameType,
402           portsOfTheSameTypeIds)) {
403         return false;
404       }
405     }
406
407     return true;
408   }
409
410   private List<PortTemplateConsolidationData> getAllPortTemplateConsolidationData(
411       Set<String> portsIds,
412       FilePortConsolidationData filePortConsolidationData) {
413     List<PortTemplateConsolidationData> portTemplateConsolidationDataOfSameType = new ArrayList<>();
414
415     for (String portId : portsIds) {
416       PortTemplateConsolidationData portTemplateConsolidationData =
417           filePortConsolidationData.getPortTemplateConsolidationData(portId);
418       if (Objects.nonNull(portTemplateConsolidationData)) {
419         portTemplateConsolidationDataOfSameType.add(portTemplateConsolidationData);
420       }
421     }
422
423     return portTemplateConsolidationDataOfSameType;
424   }
425
426   private boolean checkGetAttrRelationsForEntityConsolidationData(
427       Collection entities,
428       Set<String> nodeTemplateIdsOfTheSameType) {
429
430     List<EntityConsolidationData> entityConsolidationDataList =
431         new ArrayList(entities);
432
433     for (EntityConsolidationData entityConsolidationData : entityConsolidationDataList) {
434       Set<String> getAttrInNodeIds =
435           entityConsolidationData.getNodesGetAttrIn() == null ? new HashSet<>()
436               : entityConsolidationData.getNodesGetAttrIn().keySet();
437       for (String nodeId : getAttrInNodeIds) {
438         if (nodeTemplateIdsOfTheSameType.contains(nodeId)) {
439           return true;
440         }
441       }
442     }
443
444     return false;
445   }
446
447
448   private boolean checkComputeConsolidation(
449       ServiceTemplate serviceTemplate,
450       TypeComputeConsolidationData typeComputeConsolidationData) {
451     List<String> computeNodeTemplateIds =
452         new ArrayList(typeComputeConsolidationData.getAllComputeNodeTemplateIds());
453     List<String> propertiesWithIdenticalVal = getComputePropertiesWithIdenticalVal();
454
455     return arePropertiesSimilarBetweenComputeNodeTemplates(
456         serviceTemplate, computeNodeTemplateIds, propertiesWithIdenticalVal)
457         && checkComputeRelations(
458         typeComputeConsolidationData.getAllComputeTemplateConsolidationData());
459   }
460
461
462   private boolean checkComputeRelations(
463       Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDatas) {
464
465     return checkEntityConsolidationDataRelations(computeTemplateConsolidationDatas)
466         && checkComputesRelationsToVolume(computeTemplateConsolidationDatas);
467   }
468
469   private boolean checkEntityConsolidationDataRelations(Collection entities) {
470     List<EntityConsolidationData> entityConsolidationDataList =
471         new ArrayList(entities);
472     EntityConsolidationData startingEntity = entityConsolidationDataList.get(0);
473
474     for (int i = 1; i < entityConsolidationDataList.size(); i++) {
475       EntityConsolidationData currentEntity = entityConsolidationDataList.get(i);
476       if (!(checkNodesConnectedInRelations(startingEntity, currentEntity)
477           && (checkNodesConnectedOutRelations(startingEntity, currentEntity))
478           && (checkGroupIdsRelations(startingEntity, currentEntity)))) {
479         return false;
480       }
481     }
482     return true;
483   }
484
485   private boolean checkNodesConnectedInRelations(EntityConsolidationData firstEntity,
486                                                  EntityConsolidationData secondEntity) {
487     return compareNodeConnectivity(firstEntity.getNodesConnectedIn(),
488         secondEntity.getNodesConnectedIn());
489   }
490
491   private boolean checkNodesConnectedOutRelations(EntityConsolidationData firstEntity,
492                                                   EntityConsolidationData secondEntity) {
493     return compareNodeConnectivity(firstEntity.getNodesConnectedOut(),
494         secondEntity.getNodesConnectedOut());
495   }
496
497   private boolean compareNodeConnectivity(
498       Map<String, List<RequirementAssignmentData>> firstEntityMap,
499       Map<String, List<RequirementAssignmentData>> secondEntityMap) {
500     if (MapUtils.isEmpty(firstEntityMap)
501         && MapUtils.isEmpty(secondEntityMap)) {
502       return true;
503     }
504     if (!MapUtils.isEmpty(firstEntityMap)
505         && !MapUtils.isEmpty(secondEntityMap)) {
506       return firstEntityMap.keySet().equals(secondEntityMap.keySet());
507     }
508     return false;
509   }
510
511   private boolean checkGroupIdsRelations(EntityConsolidationData startingEntity,
512                                          EntityConsolidationData currentEntity) {
513     if (CollectionUtils.isEmpty(startingEntity.getGroupIds())
514         && CollectionUtils.isEmpty(currentEntity.getGroupIds())) {
515       return true;
516     }
517
518     return startingEntity.getGroupIds().equals(currentEntity.getGroupIds());
519   }
520
521   private boolean checkComputesRelationsToVolume(
522       Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDatas) {
523
524     Set<String> volumeRelationsFromComputes = new HashSet<>();
525     List<ComputeTemplateConsolidationData> computeTemplateConsolidationDataList =
526         new ArrayList(computeTemplateConsolidationDatas);
527
528     Map<String, List<RequirementAssignmentData>> startingVolumes =
529         computeTemplateConsolidationDataList.get(0).getVolumes();
530
531     for (int i = 1; i < computeTemplateConsolidationDataList.size(); i++) {
532       Map<String, List<RequirementAssignmentData>> currentVolumes =
533           computeTemplateConsolidationDataList.get(i).getVolumes();
534       if (!compareNodeConnectivity(startingVolumes, currentVolumes)) {
535         return false;
536       }
537     }
538     return true;
539   }
540
541
542   private boolean checkPortConsolidation(ServiceTemplate serviceTemplate,
543                                          TypeComputeConsolidationData typeComputeConsolidationData,
544                                          ConsolidationData consolidationData,
545                                          TranslationContext context) {
546     return isWantedPortPropertiesUsageIsSimilarInAllPorts(serviceTemplate,
547         typeComputeConsolidationData, context)
548         && checkPortRelations(ToscaUtil.getServiceTemplateFileName(serviceTemplate),
549         typeComputeConsolidationData, consolidationData);
550   }
551
552
553   private boolean isWantedPortPropertiesUsageIsSimilarInAllPorts(ServiceTemplate serviceTemplate,
554                                                                  TypeComputeConsolidationData typeComputeConsolidationData,
555                                                                  TranslationContext context) {
556
557     Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDataCollection =
558         typeComputeConsolidationData.getAllComputeTemplateConsolidationData();
559     List<String> propertiesThatNeedHaveUsage = getPortPropertiesWithIdenticalVal(context);
560     Map<String, Set<String>> portTypeToIds = UnifiedCompositionUtil
561         .collectAllPortsFromEachTypesFromComputes(computeTemplateConsolidationDataCollection);
562
563     for (Set<String> portsIds : portTypeToIds.values()) {
564       if (!areAllPortsFromSameTypeHaveIdenticalValForProperties(
565           serviceTemplate, portsIds, propertiesThatNeedHaveUsage)) {
566         return false;
567       }
568     }
569
570     return true;
571   }
572
573   private boolean checkPortRelations(String serviceTemplateName,
574                                      TypeComputeConsolidationData typeComputeConsolidationData,
575                                      ConsolidationData consolidationData) {
576     Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDataCollection =
577         typeComputeConsolidationData.getAllComputeTemplateConsolidationData();
578     Map<String, Set<String>> portTypeToIds = UnifiedCompositionUtil
579         .collectAllPortsFromEachTypesFromComputes(computeTemplateConsolidationDataCollection);
580
581     for (Set<String> portIds : portTypeToIds.values()) {
582       List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
583           collectAllPortsTemplateConsolidationData(
584               portIds, serviceTemplateName, consolidationData);
585
586       if (!checkEntityConsolidationDataRelations(portTemplateConsolidationDataList)) {
587         return false;
588       }
589     }
590
591     return true;
592   }
593
594   private List<PortTemplateConsolidationData>
595   collectAllPortsTemplateConsolidationData(Set<String> portIds,
596                                            String serviceTemplateName,
597                                            ConsolidationData consolidationData) {
598
599     FilePortConsolidationData filePortConsolidationData =
600         consolidationData.getPortConsolidationData()
601             .getFilePortConsolidationData(serviceTemplateName);
602     List<PortTemplateConsolidationData> portTemplateConsolidationDataList = new ArrayList<>();
603
604     for (String portId : portIds) {
605       PortTemplateConsolidationData portTemplateConsolidationData = filePortConsolidationData
606           .getPortTemplateConsolidationData(portId);
607       if (Objects.nonNull(portTemplateConsolidationData)) {
608         portTemplateConsolidationDataList.add(portTemplateConsolidationData);
609       }
610     }
611
612     return portTemplateConsolidationDataList;
613   }
614
615   private boolean areAllPortsFromSameTypeHaveIdenticalValForProperties(
616       ServiceTemplate serviceTemplate,
617       Set<String> portNodeTemplateIds,
618       List<String> propertiesThatNeedToHaveUsage) {
619     Map<String, NodeTemplate> nodeTemplates =
620         serviceTemplate.getTopology_template().getNode_templates();
621
622     for (String property : propertiesThatNeedToHaveUsage) {
623       if (!areAllPortsHaveIdenticalValForProperties(property, portNodeTemplateIds, nodeTemplates)) {
624         return false;
625       }
626     }
627
628     return true;
629   }
630
631   private boolean areAllPortsHaveIdenticalValForProperties(
632       String propertyToCheck,
633       Set<String> portNodeTemplateIds,
634       Map<String, NodeTemplate> nodeTemplates) {
635
636     List<String> portNodeTemplateIdList = new ArrayList(portNodeTemplateIds);
637     NodeTemplate startingPortNodeTemplate = nodeTemplates.get(portNodeTemplateIdList.get(0));
638
639     if (Objects.isNull(startingPortNodeTemplate)) {
640       throw new CoreException(
641           new DuplicateResourceIdsInDifferentFilesErrorBuilder(portNodeTemplateIdList.get(0)).build());
642     }
643
644     for (int i = 1; i < portNodeTemplateIdList.size(); i++) {
645       NodeTemplate portNodeTemplate = nodeTemplates.get(portNodeTemplateIdList.get(i));
646
647       if (Objects.isNull(portNodeTemplate)) {
648         throw new CoreException(
649             new DuplicateResourceIdsInDifferentFilesErrorBuilder(portNodeTemplateIdList.get(i)).build());
650       }
651
652       if (!isPropertySimilarBetweenNodeTemplates(propertyToCheck, portNodeTemplateIdList, nodeTemplates)) {
653         return false;
654       }
655     }
656
657     return true;
658   }
659
660
661   private boolean arePropertiesSimilarBetweenComputeNodeTemplates(
662       ServiceTemplate serviceTemplate,
663       List<String> computeNodeTemplateIds,
664       List<String> propertiesThatNeedToBeSimilar) {
665
666     Map<String, NodeTemplate> idToNodeTemplate =
667         serviceTemplate.getTopology_template().getNode_templates();
668
669     for (String property : propertiesThatNeedToBeSimilar) {
670       if (!isPropertySimilarBetweenNodeTemplates(property, computeNodeTemplateIds,
671           idToNodeTemplate)) {
672         return false;
673       }
674     }
675     return true;
676   }
677
678   private boolean isPropertySimilarBetweenNodeTemplates(
679       String propertyToCheck,
680       List<String> entityNodeTemplateIds,
681       Map<String, NodeTemplate> idToNodeTemplate) {
682
683     NodeTemplate startingNodeTemplate = idToNodeTemplate.get(entityNodeTemplateIds.get(0));
684     boolean propertyExistCondition =
685         isPropertyExistInNodeTemplate(propertyToCheck, startingNodeTemplate);
686
687     Set<Object> propertiesValues = new HashSet<>();
688     propertiesValues
689         .add(startingNodeTemplate.getProperties().get(propertyToCheck));
690
691     for (int i = 1; i < entityNodeTemplateIds.size(); i++) {
692       NodeTemplate currentNodeTemplate = idToNodeTemplate.get(entityNodeTemplateIds.get(i));
693       if (Objects.isNull(currentNodeTemplate)) {
694         throw new CoreException(
695             new DuplicateResourceIdsInDifferentFilesErrorBuilder(entityNodeTemplateIds.get(i)).build());
696       }
697       if(propertyExistCondition != isPropertyExistInNodeTemplate(propertyToCheck, currentNodeTemplate)){
698         return false;
699       }
700       propertiesValues
701           .add(currentNodeTemplate.getProperties().get(propertyToCheck));
702     }
703
704     return propertiesValues.size() == 1;
705   }
706
707   private boolean isPropertyExistInNodeTemplate(String propertyToCheck, NodeTemplate nodeTemplate){
708     return !(nodeTemplate.getProperties() == null || nodeTemplate.getProperties().get(propertyToCheck) == null);
709   }
710
711   public void substitutionServiceTemplateConsolidation(String substituteNodeTemplateId,
712                                                        ServiceTemplate serviceTemplate,
713                                                        ServiceTemplate substitutionServiceTemplate,
714                                                        TranslationContext translationContext) {
715
716     ConsolidationData consolidationData = translationContext.getConsolidationData();
717
718     FileComputeConsolidationData fileComputeConsolidationData =
719         translationContext.getConsolidationData().getComputeConsolidationData()
720             .getFileComputeConsolidationData(
721                 ToscaUtil.getServiceTemplateFileName(substitutionServiceTemplate));
722     boolean substitutionConsolidationRuleResult =
723         substitutionServiceTemplateConsolidationRule(substitutionServiceTemplate,
724             fileComputeConsolidationData, translationContext);
725
726     if (substitutionConsolidationRuleResult) {
727       List<UnifiedCompositionData> unifiedCompositionDataList =
728           createSubstitutionUnifiedCompositionDataList(substituteNodeTemplateId,
729               serviceTemplate, consolidationData);
730       unifiedCompositionService
731           .createUnifiedComposition(serviceTemplate, substitutionServiceTemplate,
732               unifiedCompositionDataList, UnifiedCompositionMode.NestedSingleCompute,
733               translationContext);
734     } else {
735       //The node template does not represent unified VFC but complexVFC
736       //Adding the id in the context for fixing connectivity from/to nested non-unified nodes
737       translationContext.addUnifiedNestedNodeTemplateId(ToscaUtil
738               .getServiceTemplateFileName(serviceTemplate),
739           substituteNodeTemplateId, substituteNodeTemplateId);
740
741       if (!translationContext.isUnifiedHandledServiceTemplate(substitutionServiceTemplate)) {
742         serviceTemplateConsolidation(substitutionServiceTemplate, translationContext);
743       }
744     }
745   }
746
747   private boolean substitutionServiceTemplateConsolidationRule(
748       ServiceTemplate nestedServiceTemplate,
749       FileComputeConsolidationData fileComputeConsolidationData,
750       TranslationContext context) {
751     if (Objects.isNull(fileComputeConsolidationData)) {
752       return false;
753     }
754     return isNumberOfComputeTypesLegal(fileComputeConsolidationData)
755         && isNumberOfComputeConsolidationDataPerTypeLegal(
756         fileComputeConsolidationData.getAllTypeComputeConsolidationData().iterator().next())
757         && !isThereMoreThanOneNestedLevel(nestedServiceTemplate, context.getConsolidationData());
758   }
759
760   private boolean isNumberOfComputeTypesLegal(
761       FileComputeConsolidationData fileComputeConsolidationData) {
762     return fileComputeConsolidationData.getAllTypeComputeConsolidationData().size() == 1;
763   }
764
765   private boolean isNumberOfComputeConsolidationDataPerTypeLegal(
766       TypeComputeConsolidationData typeComputeConsolidationData) {
767     return typeComputeConsolidationData.getAllComputeTemplateConsolidationData().size() == 1;
768   }
769
770   private boolean isThereMoreThanOneNestedLevel(ServiceTemplate nestedServiceTemplate,
771                                                 ConsolidationData consolidationData) {
772     String nestedServiceTemplateName = ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate);
773     if (Objects.isNull(nestedServiceTemplateName)) {
774       return false;
775     }
776
777     FileNestedConsolidationData fileNestedConsolidationData =
778         consolidationData.getNestedConsolidationData() == null ? new FileNestedConsolidationData()
779             : consolidationData.getNestedConsolidationData()
780                 .getFileNestedConsolidationData(nestedServiceTemplateName);
781
782     if (Objects.isNull(fileNestedConsolidationData)) {
783       return false;
784     }
785
786     return !CollectionUtils.isEmpty(fileNestedConsolidationData.getAllNestedNodeTemplateIds());
787   }
788
789
790   private List<UnifiedCompositionData> createUnifiedCompositionDataList(
791       ServiceTemplate serviceTemplate,
792       ConsolidationData consolidationData,
793       TypeComputeConsolidationData typeComputeConsolidationData) {
794
795     List<UnifiedCompositionData> unifiedCompositionDataList = new ArrayList<>();
796
797     for (ComputeTemplateConsolidationData computeTemplateConsolidationData : typeComputeConsolidationData
798         .getAllComputeTemplateConsolidationData()) {
799
800       UnifiedCompositionData unifiedCompositionData = new UnifiedCompositionData();
801       unifiedCompositionData.setComputeTemplateConsolidationData(computeTemplateConsolidationData);
802
803       Collection<List<String>> portCollection =
804           computeTemplateConsolidationData.getPorts() == null ? Collections.emptyList()
805               : computeTemplateConsolidationData.getPorts().values();
806
807       FilePortConsolidationData filePortConsolidationData =
808           consolidationData.getPortConsolidationData().getFilePortConsolidationData(ToscaUtil
809               .getServiceTemplateFileName(serviceTemplate));
810
811       for (List<String> portList : portCollection) {
812         for (String portId : portList) {
813           if (!Objects.isNull(filePortConsolidationData)) {
814             unifiedCompositionData.addPortTemplateConsolidationData(
815                 (filePortConsolidationData.getPortTemplateConsolidationData(portId)));
816           }
817         }
818       }
819       unifiedCompositionDataList.add(unifiedCompositionData);
820     }
821
822     return unifiedCompositionDataList;
823   }
824
825   private List<UnifiedCompositionData> createSubstitutionUnifiedCompositionDataList(
826       String substituteNodeTemplateId,
827       ServiceTemplate serviceTemplate,
828       ConsolidationData consolidationData) {
829     List<UnifiedCompositionData> unifiedCompositionDataList = new ArrayList<>();
830     FileNestedConsolidationData fileNestedConsolidationData =
831         consolidationData.getNestedConsolidationData()
832             .getFileNestedConsolidationData(ToscaUtil.getServiceTemplateFileName(serviceTemplate));
833
834     if (Objects.nonNull(fileNestedConsolidationData)) {
835       NestedTemplateConsolidationData nestedTemplateConsolidationData =
836           fileNestedConsolidationData.getNestedTemplateConsolidationData(substituteNodeTemplateId);
837       UnifiedCompositionData unifiedCompositionData = new UnifiedCompositionData();
838       unifiedCompositionData.setNestedTemplateConsolidationData(nestedTemplateConsolidationData);
839       unifiedCompositionDataList.add(unifiedCompositionData);
840       return unifiedCompositionDataList;
841     }
842
843     return unifiedCompositionDataList;
844   }
845
846   private boolean consolidationPreCondition(
847       ServiceTemplate serviceTemplate,
848       ConsolidationData consolidationData,
849       TypeComputeConsolidationData typeComputeConsolidationData) {
850
851     return (isThereMoreThanOneComputeTypeInstance(typeComputeConsolidationData)
852         && isNumberOfPortsEqualsBetweenComputeNodes(typeComputeConsolidationData)
853         && isNumberOfPortFromEachTypeLegal(typeComputeConsolidationData)
854         && isPortTypesEqualsBetweenComputeNodes(typeComputeConsolidationData)
855         && checkGetAttrBetweenConsolidationDataEntitiesNotFromSameType(serviceTemplate,
856         typeComputeConsolidationData, consolidationData));
857
858   }
859
860   private boolean isThereMoreThanOneComputeTypeInstance(
861       TypeComputeConsolidationData typeComputeConsolidationData) {
862     return typeComputeConsolidationData.getAllComputeNodeTemplateIds().size() > 1;
863   }
864
865   private boolean isNumberOfPortsEqualsBetweenComputeNodes(
866       TypeComputeConsolidationData typeComputeConsolidationData) {
867
868     ArrayList<ComputeTemplateConsolidationData> computeTemplateConsolidationDataList =
869         new ArrayList(typeComputeConsolidationData.getAllComputeTemplateConsolidationData());
870     int startingNumberOfPorts =
871         getNumberOfPortsPerCompute(computeTemplateConsolidationDataList.get(0));
872
873
874     for (int i = 1; i < computeTemplateConsolidationDataList.size(); i++) {
875       int currNumberOfPorts =
876           getNumberOfPortsPerCompute(computeTemplateConsolidationDataList.get(i));
877       if (currNumberOfPorts != startingNumberOfPorts) {
878         return false;
879       }
880     }
881
882     return true;
883   }
884
885
886   private boolean isNumberOfPortFromEachTypeLegal(
887       TypeComputeConsolidationData typeComputeConsolidationData) {
888
889     ArrayList<ComputeTemplateConsolidationData> computeTemplateConsolidationDataList =
890         new ArrayList(typeComputeConsolidationData.getAllComputeTemplateConsolidationData());
891
892     for (ComputeTemplateConsolidationData computeTemplate : computeTemplateConsolidationDataList) {
893       Map<String, List<String>> currPortsMap = computeTemplate.getPorts();
894       if (MapUtils.isEmpty(currPortsMap)) {
895         return true;
896       }
897       for (List<String> portList : currPortsMap.values()) {
898         if (portList.size() > 1) {
899           return false;
900         }
901       }
902     }
903
904     return true;
905   }
906
907   private boolean isPortTypesEqualsBetweenComputeNodes(
908       TypeComputeConsolidationData typeComputeConsolidationData) {
909
910     ArrayList<ComputeTemplateConsolidationData> computeTemplateConsolidationDataList =
911         new ArrayList(typeComputeConsolidationData.getAllComputeTemplateConsolidationData());
912     Set<String> staringPortIds = getPortsIds(computeTemplateConsolidationDataList.get(0));
913
914     for (int i = 1; i < computeTemplateConsolidationDataList.size(); i++) {
915       Set<String> currentPortIds = getPortsIds(computeTemplateConsolidationDataList.get(i));
916       if (!currentPortIds.equals(staringPortIds)) {
917         return false;
918       }
919     }
920
921     return true;
922   }
923
924   private int getNumberOfPortsPerCompute(
925       ComputeTemplateConsolidationData computeTemplateConsolidationData) {
926     return getPortsIds(computeTemplateConsolidationData) == null ? 0 :
927         getPortsIds(computeTemplateConsolidationData).size();
928   }
929
930   private Set<String> getPortsIds(
931       ComputeTemplateConsolidationData computeTemplateConsolidationData) {
932     return computeTemplateConsolidationData.getPorts() == null ? new HashSet<>()
933         : computeTemplateConsolidationData
934             .getPorts().keySet();
935   }
936
937   public List<String> getPropertiesWithIdenticalVal(UnifiedCompositionEntity entity,
938                                                     TranslationContext context){
939     switch (entity){
940       case Compute:
941         return getComputePropertiesWithIdenticalVal();
942
943       case Other:
944         return getComputePropertiesWithIdenticalVal();
945
946       case Port:
947         return getPortPropertiesWithIdenticalVal(context);
948
949       default:
950         return new ArrayList<>();
951     }
952   }
953
954   private List<String> getComputePropertiesWithIdenticalVal() {
955     List<String> propertyWithIdenticalValue = new ArrayList<>();
956     propertyWithIdenticalValue.add(ToscaConstants.COMPUTE_IMAGE);
957     propertyWithIdenticalValue.add(ToscaConstants.COMPUTE_FLAVOR);
958     return propertyWithIdenticalValue;
959   }
960
961   private List<String> getPortPropertiesWithIdenticalVal(TranslationContext context) {
962     List<String> propertiesThatNeedToHaveUsage = new ArrayList<>();
963     propertiesThatNeedToHaveUsage.add(ToscaConstants.PORT_FIXED_IPS);
964     propertiesThatNeedToHaveUsage.add(ToscaConstants.PORT_ALLOWED_ADDRESS_PAIRS);
965     propertiesThatNeedToHaveUsage.add(ToscaConstants.MAC_ADDRESS);
966
967     propertiesThatNeedToHaveUsage.addAll(context.getEnrichPortResourceProperties());
968
969     return propertiesThatNeedToHaveUsage;
970   }
971 }
972