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