[sdc] update code of sdc
[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.common.errors.ErrorCode;
7 import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage;
8 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
9 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
10 import org.openecomp.sdc.tosca.services.ToscaConstants;
11 import org.openecomp.sdc.tosca.services.ToscaUtil;
12 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
13 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedCompositionData;
14 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedCompositionEntity;
15 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedCompositionMode;
16 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.ComputeTemplateConsolidationData;
17 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.ConsolidationData;
18 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.EntityConsolidationData;
19 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.FileComputeConsolidationData;
20 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.FileNestedConsolidationData;
21 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.FilePortConsolidationData;
22 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.GetAttrFuncData;
23 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.NestedTemplateConsolidationData;
24 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.PortTemplateConsolidationData;
25 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.RequirementAssignmentData;
26 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.TypeComputeConsolidationData;
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 mainServiceTemplateConsolidation(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   private 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
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     Set<String> portNodeTemplateIds = filePortConsolidationData.getAllPortNodeTemplateIds();
116     for (String portNodeTemplateId : portNodeTemplateIds) {
117       consolidationEntityIdToType
118           .put(portNodeTemplateId, ConsolidationDataUtil.getPortType(portNodeTemplateId));
119     }
120
121     return consolidationEntityIdToType;
122   }
123
124
125   private boolean checkConsolidationRules(ServiceTemplate serviceTemplate,
126                                           TypeComputeConsolidationData typeComputeConsolidationData,
127                                           ConsolidationData consolidationData,
128                                           TranslationContext context) {
129     return checkComputeConsolidation(serviceTemplate, typeComputeConsolidationData)
130         && checkPortConsolidation(serviceTemplate, typeComputeConsolidationData,
131         consolidationData, context)
132         && !checkGetAttrBetweenEntityConsolidationOfTheSameType(serviceTemplate,
133         typeComputeConsolidationData, consolidationData);
134   }
135
136   private boolean checkGetAttrBetweenConsolidationDataEntitiesNotFromSameType(
137       ServiceTemplate serviceTemplate,
138       TypeComputeConsolidationData typeComputeConsolidationData,
139       ConsolidationData consolidationData) {
140     List<ComputeTemplateConsolidationData> computeTemplateConsolidationDataList =
141         new ArrayList(typeComputeConsolidationData.getAllComputeTemplateConsolidationData());
142
143     Set<String> computeNodeTemplateIds =
144         typeComputeConsolidationData.getAllComputeNodeTemplateIds();
145
146     Map<String, Set<String>> portTypeToIds = UnifiedCompositionUtil
147         .collectAllPortsFromEachTypesFromComputes(computeTemplateConsolidationDataList);
148
149     return
150         checkGetAttrOutFromEntityToPortIsLegal(computeTemplateConsolidationDataList, portTypeToIds)
151             && checkGetAttrOutFromPortLegal(ToscaUtil.getServiceTemplateFileName(serviceTemplate),
152             computeNodeTemplateIds, portTypeToIds, consolidationData);
153
154   }
155
156   private boolean checkGetAttrInEntityConsolidationWithPortIsLegal(
157       List entityConsolidationDatas,
158       TypeComputeConsolidationData typeComputeConsolidationData) {
159     Map<String, Set<String>> portTypeToIds =
160         UnifiedCompositionUtil.collectAllPortsFromEachTypesFromComputes(
161             typeComputeConsolidationData.getAllComputeTemplateConsolidationData());
162
163     Set<String> startingPortTypesPointByGetAttr =
164         getPortTypesPointedByGetAttrFromEntity(
165             (EntityConsolidationData) entityConsolidationDatas.get(0), portTypeToIds);
166
167     for (int i = 1; i < entityConsolidationDatas.size(); i++) {
168       Set<String> currentPortTypesPointByGetAttr =
169           getPortTypesPointedByGetAttrFromEntity(
170               (EntityConsolidationData) entityConsolidationDatas.get(i), portTypeToIds);
171       if (!startingPortTypesPointByGetAttr.equals(currentPortTypesPointByGetAttr)) {
172         return false;
173       }
174     }
175
176     return true;
177   }
178
179   private Set<String> getPortTypesPointedByGetAttrFromEntity(
180       EntityConsolidationData entity,
181       Map<String, Set<String>> portTypeToIds) {
182     return getPortTypeToIdPointByGetAttrInOrOut(
183         entity.getNodesGetAttrIn(), portTypeToIds, entity).keySet();
184   }
185
186   private boolean checkGetAttrInToPortIsLegal(
187       ServiceTemplate serviceTemplate,
188       TypeComputeConsolidationData typeComputeConsolidationData,
189       ConsolidationData consolidationData) {
190
191     Map<String, Set<String>> portTypeToIds = UnifiedCompositionUtil
192         .collectAllPortsFromEachTypesFromComputes(
193             typeComputeConsolidationData.getAllComputeTemplateConsolidationData());
194
195     for (Set<String> portIdsFromSameType : portTypeToIds.values()) {
196       List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
197           collectAllPortsTemplateConsolidationData(
198               portIdsFromSameType, ToscaUtil.getServiceTemplateFileName(serviceTemplate),
199               consolidationData);
200
201       if (!checkGetAttrInEntityConsolidationWithPortIsLegal(
202           portTemplateConsolidationDataList, typeComputeConsolidationData)) {
203         return false;
204       }
205     }
206
207     return true;
208   }
209
210
211   private boolean checkGetAttrOutFromPortLegal(String serviceTemplateName,
212                                                Set<String> computeNodeTemplateIds,
213                                                Map<String, Set<String>> portTypeToIds,
214                                                ConsolidationData consolidationData) {
215     for (Set<String> portIdsFromSameType : portTypeToIds.values()) {
216       List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
217           collectAllPortsTemplateConsolidationData(portIdsFromSameType, serviceTemplateName,
218               consolidationData);
219
220       if (!(checkGetAttrOutFromEntityToPortIsLegal(portTemplateConsolidationDataList, portTypeToIds)
221           && checkGetAttrOutFromPortToComputeIsLegal(portTemplateConsolidationDataList,
222           computeNodeTemplateIds))) {
223         return false;
224       }
225     }
226
227     return true;
228   }
229
230   private boolean checkGetAttrOutFromEntityToPortIsLegal(List entityConsolidationDataList,
231                                                          Map<String, Set<String>> portTypeToIds) {
232
233     for (String portType : portTypeToIds.keySet()) {
234       Set<GetAttrFuncData> startingGetAttrFunc =
235           getEntityGetAttrFuncAsSet(portType,
236               (EntityConsolidationData) entityConsolidationDataList.get(0));
237       for (int i = 1; i < entityConsolidationDataList.size(); i++) {
238         Object entity = entityConsolidationDataList.get(i);
239         Set<GetAttrFuncData> currentGetAttrFuncData =
240             getEntityGetAttrFuncAsSet(portType,
241                 (EntityConsolidationData) entity);
242         if (!(startingGetAttrFunc.equals(currentGetAttrFuncData))) {
243           return false;
244         }
245       }
246     }
247
248     return true;
249   }
250
251   private boolean checkGetAttrOutFromPortToComputeIsLegal(
252       List<PortTemplateConsolidationData> portTemplateConsolidationDataList,
253       Set<String> computeNodeTemplateIds) {
254     PortTemplateConsolidationData startingPortTemplate =
255         portTemplateConsolidationDataList.get(0);
256     Map<String, Set<GetAttrFuncData>> startingComputeGetAttrOutFuncData =
257         getComputeGetAttrOutFuncData(startingPortTemplate.getNodesGetAttrOut(),
258             computeNodeTemplateIds);
259
260     for (int i = 1; i < portTemplateConsolidationDataList.size(); i++) {
261       PortTemplateConsolidationData currentPortTemplate =
262           portTemplateConsolidationDataList.get(i);
263       Map<String, Set<GetAttrFuncData>> currentComputeGetAttrOutFuncData =
264           getComputeGetAttrOutFuncData(currentPortTemplate.getNodesGetAttrOut(),
265               computeNodeTemplateIds);
266
267       if (!isGetAttrRelationToComputeSimilarBetweenEntities(startingComputeGetAttrOutFuncData,
268           currentComputeGetAttrOutFuncData)) {
269         return false;
270       }
271     }
272
273     return true;
274   }
275
276   private boolean isGetAttrRelationToComputeSimilarBetweenEntities(
277       Map<String, Set<GetAttrFuncData>> firstMap,
278       Map<String, Set<GetAttrFuncData>> secondMap) {
279     if (MapUtils.isEmpty(firstMap) != MapUtils.isEmpty(secondMap)) {
280       return false;
281     }
282
283     if (MapUtils.isEmpty(firstMap) && MapUtils.isEmpty(secondMap)) {
284       return true;
285     }
286
287     return new ArrayList<>(firstMap.values()).equals(new ArrayList<>(secondMap.values()));
288   }
289
290   private Set<GetAttrFuncData> getEntityGetAttrFuncAsSet(String portType,
291                                                          EntityConsolidationData entityConsolidationData) {
292
293     Set<GetAttrFuncData> getAttrFuncDataFromPortsWithSameType = new HashSet<>();
294     Map<String, List<GetAttrFuncData>> nodesGetAttrOut =
295         entityConsolidationData.getNodesGetAttrOut();
296
297     if (MapUtils.isEmpty(nodesGetAttrOut)) {
298       return getAttrFuncDataFromPortsWithSameType;
299     }
300
301     for (Map.Entry<String, List<GetAttrFuncData>> entry : nodesGetAttrOut.entrySet()) {
302       if (portType.equals(ConsolidationDataUtil.getPortType(entry.getKey()))) {
303         getAttrFuncDataFromPortsWithSameType.addAll(entry.getValue());
304       }
305     }
306
307     return getAttrFuncDataFromPortsWithSameType;
308   }
309
310   private Map<String, Set<GetAttrFuncData>> getComputeGetAttrOutFuncData(
311       Map<String, List<GetAttrFuncData>> nodesGetAttrOut,
312       Set<String> computeNodeTemplateIds) {
313     Map<String, Set<GetAttrFuncData>> computeGetAttrFuncData = new HashMap<>();
314
315     if (MapUtils.isEmpty(nodesGetAttrOut)) {
316       return computeGetAttrFuncData;
317     }
318
319     for (Map.Entry<String, List<GetAttrFuncData>> getAttrFuncEntry : nodesGetAttrOut.entrySet()) {
320       if (computeNodeTemplateIds.contains(getAttrFuncEntry.getKey())) {
321         computeGetAttrFuncData.put(getAttrFuncEntry.getKey(), new HashSet<>(getAttrFuncEntry
322             .getValue()));
323       }
324     }
325
326     return computeGetAttrFuncData;
327   }
328
329   private Map<String, List<String>> getPortTypeToIdPointByGetAttrInOrOut(
330       Map<String, List<GetAttrFuncData>> getAttr,
331       Map<String, Set<String>> portTypeToIds,
332       EntityConsolidationData entityConsolidationData) {
333     Map<String, List<String>> portIdToType = new HashMap<>();
334
335     if (MapUtils.isEmpty(getAttr)) {
336       return portIdToType;
337     }
338
339     for (String getAttrId : getAttr.keySet()) {
340       if (isNodeTemplateIdIsInComputeConsolidationData(getAttrId, portTypeToIds)) {
341         String portType = ConsolidationDataUtil.getPortType(getAttrId);
342         portIdToType.putIfAbsent(portType, new ArrayList<>());
343         portIdToType.get(portType).add(getAttrId);
344       }
345     }
346
347     return portIdToType;
348
349   }
350
351
352   private boolean isNodeTemplateIdIsInComputeConsolidationData(
353       String getAttrInId,
354       Map<String, Set<String>> portTypeToIds) {
355     return portTypeToIds.keySet().contains(ConsolidationDataUtil.getPortType(getAttrInId));
356   }
357
358   private boolean checkGetAttrBetweenEntityConsolidationOfTheSameType(
359       ServiceTemplate serviceTemplate,
360       TypeComputeConsolidationData typeComputeConsolidationData,
361       ConsolidationData consolidationData) {
362     return checkGetAttrRelationsBetweenComputesOfSameType(typeComputeConsolidationData)
363         || checkGetAttrRelationsBetweenPortsOfTheSameType(serviceTemplate,
364         typeComputeConsolidationData, consolidationData);
365
366   }
367
368   private boolean checkGetAttrRelationsBetweenComputesOfSameType(
369       TypeComputeConsolidationData typeComputeConsolidationData) {
370
371     Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDatas =
372         typeComputeConsolidationData.getAllComputeTemplateConsolidationData();
373     Set<String> computeNodeTemplateIds =
374         typeComputeConsolidationData.getAllComputeNodeTemplateIds();
375
376     return checkGetAttrRelationsForEntityConsolidationData(
377         computeTemplateConsolidationDatas, computeNodeTemplateIds);
378   }
379
380   private boolean checkGetAttrRelationsBetweenPortsOfTheSameType(
381       ServiceTemplate serviceTemplate,
382       TypeComputeConsolidationData typeComputeConsolidationData,
383       ConsolidationData consolidationData) {
384
385     Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDatas =
386         typeComputeConsolidationData.getAllComputeTemplateConsolidationData();
387     Map<String, Set<String>> portTypeToPortIds = UnifiedCompositionUtil
388         .collectAllPortsFromEachTypesFromComputes(computeTemplateConsolidationDatas);
389
390     FilePortConsolidationData filePortConsolidationData =
391         consolidationData.getPortConsolidationData().getFilePortConsolidationData(ToscaUtil
392             .getServiceTemplateFileName(serviceTemplate));
393
394     for (Set<String> portsOfTheSameTypeIds : portTypeToPortIds.values()) {
395       List<PortTemplateConsolidationData> portTemplateConsolidationDataOfSameType =
396           getAllPortTemplateConsolidationData(portsOfTheSameTypeIds, filePortConsolidationData);
397       if (!checkGetAttrRelationsForEntityConsolidationData(portTemplateConsolidationDataOfSameType,
398           portsOfTheSameTypeIds)) {
399         return false;
400       }
401     }
402
403     return true;
404   }
405
406   private List<PortTemplateConsolidationData> getAllPortTemplateConsolidationData(
407       Set<String> portsIds,
408       FilePortConsolidationData filePortConsolidationData) {
409     List<PortTemplateConsolidationData> portTemplateConsolidationDataOfSameType = new ArrayList<>();
410
411     for (String portId : portsIds) {
412       PortTemplateConsolidationData portTemplateConsolidationData =
413           filePortConsolidationData.getPortTemplateConsolidationData(portId);
414       if (Objects.nonNull(portTemplateConsolidationData)) {
415         portTemplateConsolidationDataOfSameType.add(portTemplateConsolidationData);
416       }
417     }
418
419     return portTemplateConsolidationDataOfSameType;
420   }
421
422   private boolean checkGetAttrRelationsForEntityConsolidationData(
423       Collection entities,
424       Set<String> nodeTemplateIdsOfTheSameType) {
425
426     List<EntityConsolidationData> entityConsolidationDataList =
427         new ArrayList(entities);
428
429     for (EntityConsolidationData entityConsolidationData : entityConsolidationDataList) {
430       Set<String> getAttrInNodeIds =
431           entityConsolidationData.getNodesGetAttrIn() == null ? new HashSet<>()
432               : entityConsolidationData.getNodesGetAttrIn().keySet();
433       for (String nodeId : getAttrInNodeIds) {
434         if (nodeTemplateIdsOfTheSameType.contains(nodeId)) {
435           return true;
436         }
437       }
438     }
439
440     return false;
441   }
442
443
444   private boolean checkComputeConsolidation(
445       ServiceTemplate serviceTemplate,
446       TypeComputeConsolidationData typeComputeConsolidationData) {
447     List<String> computeNodeTemplateIds =
448         new ArrayList(typeComputeConsolidationData.getAllComputeNodeTemplateIds());
449     List<String> propertiesWithIdenticalVal = getComputePropertiesWithIdenticalVal();
450
451     return arePropertiesSimilarBetweenComputeNodeTemplates(
452         serviceTemplate, computeNodeTemplateIds, propertiesWithIdenticalVal)
453         && checkComputeRelations(
454         typeComputeConsolidationData.getAllComputeTemplateConsolidationData());
455   }
456
457
458   private boolean checkComputeRelations(
459       Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDatas) {
460
461     return checkEntityConsolidationDataRelations(computeTemplateConsolidationDatas)
462         && checkComputesRelationsToVolume(computeTemplateConsolidationDatas);
463   }
464
465   private boolean checkEntityConsolidationDataRelations(Collection entities) {
466     List<EntityConsolidationData> entityConsolidationDataList =
467         new ArrayList(entities);
468     EntityConsolidationData startingEntity = entityConsolidationDataList.get(0);
469
470     for (int i = 1; i < entityConsolidationDataList.size(); i++) {
471       EntityConsolidationData currentEntity = entityConsolidationDataList.get(i);
472       if (!(checkNodesConnectedInRelations(startingEntity, currentEntity)
473           && (checkNodesConnectedOutRelations(startingEntity, currentEntity))
474           && (checkGroupIdsRelations(startingEntity, currentEntity)))) {
475         return false;
476       }
477     }
478     return true;
479   }
480
481   private boolean checkNodesConnectedInRelations(EntityConsolidationData firstEntity,
482                                                  EntityConsolidationData secondEntity) {
483     return compareNodeConnectivity(firstEntity.getNodesConnectedIn(),
484         secondEntity.getNodesConnectedIn());
485   }
486
487   private boolean checkNodesConnectedOutRelations(EntityConsolidationData firstEntity,
488                                                   EntityConsolidationData secondEntity) {
489     return compareNodeConnectivity(firstEntity.getNodesConnectedOut(),
490         secondEntity.getNodesConnectedOut());
491   }
492
493   private boolean compareNodeConnectivity(
494       Map<String, List<RequirementAssignmentData>> firstEntityMap,
495       Map<String, List<RequirementAssignmentData>> secondEntityMap) {
496     if (MapUtils.isEmpty(firstEntityMap)
497         && MapUtils.isEmpty(secondEntityMap)) {
498       return true;
499     }
500     if (!MapUtils.isEmpty(firstEntityMap)
501         && !MapUtils.isEmpty(secondEntityMap)) {
502       return firstEntityMap.keySet().equals(secondEntityMap.keySet());
503     }
504     return false;
505   }
506
507   private boolean checkGroupIdsRelations(EntityConsolidationData startingEntity,
508                                          EntityConsolidationData currentEntity) {
509     if (CollectionUtils.isEmpty(startingEntity.getGroupIds()) &&
510         CollectionUtils.isEmpty(currentEntity.getGroupIds())) {
511       return true;
512     }
513
514     return startingEntity.getGroupIds().equals(currentEntity.getGroupIds());
515   }
516
517   private boolean checkComputesRelationsToVolume(
518       Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDatas) {
519
520     Set<String> volumeRelationsFromComputes = new HashSet<>();
521     List<ComputeTemplateConsolidationData> computeTemplateConsolidationDataList =
522         new ArrayList(computeTemplateConsolidationDatas);
523
524     Map<String, List<RequirementAssignmentData>> startingVolumes =
525         computeTemplateConsolidationDataList.get(0).getVolumes();
526
527     for (int i = 1; i < computeTemplateConsolidationDataList.size(); i++) {
528       Map<String, List<RequirementAssignmentData>> currentVolumes =
529           computeTemplateConsolidationDataList.get(i).getVolumes();
530       if (!compareNodeConnectivity(startingVolumes, currentVolumes)) {
531         return false;
532       }
533     }
534     return true;
535   }
536
537
538   private boolean checkPortConsolidation(ServiceTemplate serviceTemplate,
539                                          TypeComputeConsolidationData typeComputeConsolidationData,
540                                          ConsolidationData consolidationData,
541                                          TranslationContext context) {
542     return isWantedPortPropertiesUsageIsSimilarInAllPorts(serviceTemplate,
543         typeComputeConsolidationData, context)
544         && checkPortRelations(ToscaUtil.getServiceTemplateFileName(serviceTemplate),
545         typeComputeConsolidationData, consolidationData);
546   }
547
548
549   private boolean isWantedPortPropertiesUsageIsSimilarInAllPorts(ServiceTemplate serviceTemplate,
550                                                                  TypeComputeConsolidationData typeComputeConsolidationData,
551                                                                  TranslationContext context) {
552
553     Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDataCollection =
554         typeComputeConsolidationData.getAllComputeTemplateConsolidationData();
555     List<String> propertiesThatNeedHaveUsage = getPortPropertiesWithIdenticalVal(context);
556     Map<String, Set<String>> portTypeToIds = UnifiedCompositionUtil
557         .collectAllPortsFromEachTypesFromComputes(computeTemplateConsolidationDataCollection);
558
559     for (Set<String> portsIds : portTypeToIds.values()) {
560       if (!areAllPortsFromSameTypeHaveIdenticalValForProperties(
561           serviceTemplate, portsIds, propertiesThatNeedHaveUsage)) {
562         return false;
563       }
564     }
565
566     return true;
567   }
568
569   private boolean checkPortRelations(String serviceTemplateName,
570                                      TypeComputeConsolidationData typeComputeConsolidationData,
571                                      ConsolidationData consolidationData) {
572     Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDataCollection =
573         typeComputeConsolidationData.getAllComputeTemplateConsolidationData();
574     Map<String, Set<String>> portTypeToIds = UnifiedCompositionUtil
575         .collectAllPortsFromEachTypesFromComputes(computeTemplateConsolidationDataCollection);
576
577     for (Set<String> portIds : portTypeToIds.values()) {
578       List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
579           collectAllPortsTemplateConsolidationData(
580               portIds, serviceTemplateName, consolidationData);
581
582       if (!checkEntityConsolidationDataRelations(portTemplateConsolidationDataList)) {
583         return false;
584       }
585     }
586
587     return true;
588   }
589
590   private List<PortTemplateConsolidationData>
591   collectAllPortsTemplateConsolidationData(Set<String> portIds,
592                                            String serviceTemplateName,
593                                            ConsolidationData consolidationData) {
594
595     FilePortConsolidationData filePortConsolidationData =
596         consolidationData.getPortConsolidationData()
597             .getFilePortConsolidationData(serviceTemplateName);
598     List<PortTemplateConsolidationData> portTemplateConsolidationDataList = new ArrayList<>();
599
600     for (String portId : portIds) {
601       PortTemplateConsolidationData portTemplateConsolidationData = filePortConsolidationData
602           .getPortTemplateConsolidationData(portId);
603       if (Objects.nonNull(portTemplateConsolidationData)) {
604         portTemplateConsolidationDataList.add(portTemplateConsolidationData);
605       }
606     }
607
608     return portTemplateConsolidationDataList;
609   }
610
611   private boolean areAllPortsFromSameTypeHaveIdenticalValForProperties(
612       ServiceTemplate serviceTemplate,
613       Set<String> portNodeTemplateIds,
614       List<String> propertiesThatNeedToHaveUsage) {
615     Map<String, NodeTemplate> nodeTemplates =
616         serviceTemplate.getTopology_template().getNode_templates();
617
618     for (String property : propertiesThatNeedToHaveUsage) {
619       if (!areAllPortsHaveIdenticalValForProperties(property, portNodeTemplateIds, nodeTemplates)) {
620         return false;
621       }
622     }
623
624     return true;
625   }
626
627   private boolean areAllPortsHaveIdenticalValForProperties(
628       String propertyToCheck,
629       Set<String> portNodeTemplateIds,
630       Map<String, NodeTemplate> nodeTemplates) {
631
632     List<String> portNodeTemplateIdList = new ArrayList(portNodeTemplateIds);
633     NodeTemplate startingPortNodeTemplate = nodeTemplates.get(portNodeTemplateIdList.get(0));
634
635     if (Objects.isNull(startingPortNodeTemplate)) {
636       throw new CoreException((new ErrorCode.ErrorCodeBuilder())
637           .withMessage("Resource with id "
638               + portNodeTemplateIdList.get(0) + " occures more than once in different addOn files")
639           .build());
640     }
641
642     for (int i = 1; i < portNodeTemplateIdList.size(); i++) {
643       NodeTemplate portNodeTemplate = nodeTemplates.get(portNodeTemplateIdList.get(i));
644
645       if (Objects.isNull(portNodeTemplate)) {
646         throw new CoreException((new ErrorCode.ErrorCodeBuilder())
647             .withMessage("Resource with id "
648                 + portNodeTemplateIdList.get(i) + " occures more than once in different addOn "
649                 + "files").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((new ErrorCode.ErrorCodeBuilder())
695             .withMessage("Resource with id "
696                 + entityNodeTemplateIds.get(i) + " occures more than once in different addOn files").build());
697       }
698       if(propertyExistCondition != isPropertyExistInNodeTemplate(propertyToCheck, currentNodeTemplate)){
699         return false;
700       }
701       propertiesValues
702           .add(currentNodeTemplate.getProperties().get(propertyToCheck));
703     }
704
705     return propertiesValues.size() == 1;
706   }
707
708   private boolean isPropertyExistInNodeTemplate(String propertyToCheck, NodeTemplate nodeTemplate){
709     return !(nodeTemplate.getProperties() == null || nodeTemplate.getProperties().get(propertyToCheck) == null);
710   }
711
712   public void substitutionServiceTemplateConsolidation(String substituteNodeTemplateId,
713                                                        ServiceTemplate mainServiceTemplate,
714                                                        ServiceTemplate substitutionServiceTemplate,
715                                                        TranslationContext translationContext) {
716
717     ConsolidationData consolidationData = translationContext.getConsolidationData();
718
719     FileComputeConsolidationData fileComputeConsolidationData =
720         translationContext.getConsolidationData().getComputeConsolidationData()
721             .getFileComputeConsolidationData(
722                 ToscaUtil.getServiceTemplateFileName(substitutionServiceTemplate));
723     boolean consolidationRuleResult =
724         substitutionServiceTemplateConsolidationRule(substitutionServiceTemplate,
725             fileComputeConsolidationData, translationContext);
726
727     if (consolidationRuleResult) {
728       List<UnifiedCompositionData> unifiedCompositionDataList =
729           createSubstitutionUnifiedCompositionDataList(substituteNodeTemplateId,
730               mainServiceTemplate, consolidationData);
731       unifiedCompositionService
732           .createUnifiedComposition(mainServiceTemplate, substitutionServiceTemplate,
733               unifiedCompositionDataList, UnifiedCompositionMode.NestedSingleCompute,
734               translationContext);
735     } else {
736       //The node template does not qualify for unified composition
737       //Adding the id in the context for fixing connectivity from/to nested non-unified nodes
738       translationContext.addUnifiedNestedNodeTemplateId(ToscaUtil
739               .getServiceTemplateFileName(mainServiceTemplate),
740           substituteNodeTemplateId, substituteNodeTemplateId);
741     }
742   }
743
744   private boolean substitutionServiceTemplateConsolidationRule(
745       ServiceTemplate nestedServiceTemplate,
746       FileComputeConsolidationData fileComputeConsolidationData,
747       TranslationContext context) {
748     if (Objects.isNull(fileComputeConsolidationData)) {
749       return false;
750     }
751     return isNumberOfComputeTypesLegal(fileComputeConsolidationData)
752         && isNumberOfComputeConsolidationDataPerTypeLegal(
753         fileComputeConsolidationData.getAllTypeComputeConsolidationData().iterator().next())
754         && !isThereMoreThanOneNestedLevel(nestedServiceTemplate, context.getConsolidationData());
755   }
756
757   private boolean isNumberOfComputeTypesLegal(
758       FileComputeConsolidationData fileComputeConsolidationData) {
759     return fileComputeConsolidationData.getAllTypeComputeConsolidationData().size() == 1;
760   }
761
762   private boolean isNumberOfComputeConsolidationDataPerTypeLegal(
763       TypeComputeConsolidationData typeComputeConsolidationData) {
764     return typeComputeConsolidationData.getAllComputeTemplateConsolidationData().size() == 1;
765   }
766
767   private boolean isThereMoreThanOneNestedLevel(ServiceTemplate nestedServiceTemplate,
768                                                 ConsolidationData consolidationData) {
769     String nestedServiceTemplateName = ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate);
770     if (Objects.isNull(nestedServiceTemplateName)) {
771       return false;
772     }
773
774     FileNestedConsolidationData fileNestedConsolidationData =
775         consolidationData.getNestedConsolidationData() == null ? new FileNestedConsolidationData()
776             : consolidationData.getNestedConsolidationData()
777                 .getFileNestedConsolidationData(nestedServiceTemplateName);
778
779     if (Objects.isNull(fileNestedConsolidationData)) {
780       return false;
781     }
782
783     return !CollectionUtils.isEmpty(fileNestedConsolidationData.getAllNestedNodeTemplateIds());
784   }
785
786
787   private List<UnifiedCompositionData> createUnifiedCompositionDataList(
788       ServiceTemplate serviceTemplate,
789       ConsolidationData consolidationData,
790       TypeComputeConsolidationData typeComputeConsolidationData) {
791
792     List<UnifiedCompositionData> unifiedCompositionDataList = new ArrayList<>();
793
794     for (ComputeTemplateConsolidationData computeTemplateConsolidationData : typeComputeConsolidationData
795         .getAllComputeTemplateConsolidationData()) {
796
797       UnifiedCompositionData unifiedCompositionData = new UnifiedCompositionData();
798       unifiedCompositionData.setComputeTemplateConsolidationData(computeTemplateConsolidationData);
799
800       Collection<List<String>> portCollection =
801           computeTemplateConsolidationData.getPorts() == null ? Collections.emptyList()
802               : computeTemplateConsolidationData.getPorts().values();
803
804       FilePortConsolidationData filePortConsolidationData =
805           consolidationData.getPortConsolidationData().getFilePortConsolidationData(ToscaUtil
806               .getServiceTemplateFileName(serviceTemplate));
807
808       for (List<String> portList : portCollection) {
809         for (String portId : portList) {
810           if (!Objects.isNull(filePortConsolidationData)) {
811             unifiedCompositionData.addPortTemplateConsolidationData(
812                 (filePortConsolidationData.getPortTemplateConsolidationData(portId)));
813           }
814         }
815       }
816       unifiedCompositionDataList.add(unifiedCompositionData);
817     }
818
819     return unifiedCompositionDataList;
820   }
821
822   private List<UnifiedCompositionData> createSubstitutionUnifiedCompositionDataList(
823       String substituteNodeTemplateId,
824       ServiceTemplate serviceTemplate,
825       ConsolidationData consolidationData) {
826     List<UnifiedCompositionData> unifiedCompositionDataList = new ArrayList<>();
827     FileNestedConsolidationData fileNestedConsolidationData =
828         consolidationData.getNestedConsolidationData()
829             .getFileNestedConsolidationData(ToscaUtil.getServiceTemplateFileName(serviceTemplate));
830
831     if (Objects.nonNull(fileNestedConsolidationData)) {
832       Collection<NestedTemplateConsolidationData> nestedConsolidationDatas =
833           fileNestedConsolidationData.getAllNestedConsolidationData();
834
835       for (NestedTemplateConsolidationData nested : nestedConsolidationDatas) {
836         if (nested.getNodeTemplateId().equals(substituteNodeTemplateId)) {
837           UnifiedCompositionData unifiedCompositionData = new UnifiedCompositionData();
838           unifiedCompositionData.setNestedTemplateConsolidationData(nested);
839           unifiedCompositionDataList.add(unifiedCompositionData);
840         }
841       }
842     }
843
844     return unifiedCompositionDataList;
845   }
846
847   private boolean consolidationPreCondition(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