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