Upgrade SDC from Titan to Janus Graph
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / merge / utils / MergeInstanceUtils.java
1 package org.openecomp.sdc.be.components.merge.utils;
2
3 import fj.data.Either;
4 import org.apache.commons.lang3.StringUtils;
5 import org.apache.commons.lang3.tuple.ImmutablePair;
6 import org.openecomp.sdc.be.components.impl.utils.ExceptionUtils;
7 import org.openecomp.sdc.be.components.merge.instance.RelationMergeInfo;
8 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
9 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
10 import org.openecomp.sdc.be.model.*;
11 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
12 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
13 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
14 import org.openecomp.sdc.common.log.wrappers.Logger;
15
16 import java.util.*;
17 import java.util.function.Function;
18 import java.util.function.Predicate;
19 import java.util.stream.Collectors;
20
21 import static java.util.Collections.emptyMap;
22 import static java.util.Collections.singletonList;
23 import static org.openecomp.sdc.be.dao.utils.MapUtil.toMap;
24
25 /**
26  * This class is Utils class but it should be bean
27  * @author dr2032
28  *
29  */
30 @org.springframework.stereotype.Component
31 public class MergeInstanceUtils {
32     private static final Logger log = Logger.getLogger(MergeInstanceUtils.class);
33     
34     private final ToscaOperationFacade toscaOperationFacade;
35     private final ExceptionUtils exceptionUtils;
36
37     public MergeInstanceUtils(ToscaOperationFacade toscaOperationFacade, ExceptionUtils exceptionUtils) {
38         this.toscaOperationFacade = toscaOperationFacade;
39         this.exceptionUtils = exceptionUtils;
40     }
41
42     /**
43      * @param container containing new component instance
44      * @param origInstanceNode old component (in case of PROXY it should be actual service)
45      * @param newInstanceId - ID of new instance of the component
46      * @param oldCapabilitiesOwnerIds the old capabilities owner ids
47      * @return a map of capability owner IDs of old component instance to capability owner IDs of the new component instance
48      */
49     public Map<String, String> mapOldToNewCapabilitiesOwnerIds(Component container,
50                                                                Component origInstanceNode,
51                                                                String newInstanceId,
52                                                                List<String> oldCapabilitiesOwnerIds) {
53
54         Map<String, String> resultMap;
55
56         if (ModelConverter.isAtomicComponent(origInstanceNode) || isCVFC(origInstanceNode)) {
57             resultMap = prepareMapForAtomicComponent(newInstanceId, oldCapabilitiesOwnerIds);
58         }
59         else {
60             resultMap = prepareMapForNonAtomicComponent(container, origInstanceNode, newInstanceId, oldCapabilitiesOwnerIds);
61         }
62
63         return resultMap;
64     }
65
66     /**
67      * @param oldInstance the old instance to find its capabilities owner ids
68      * @param newInstance the new instance to find its capabilities owner ids
69      * @return a map between capability owner IDs of old component instance to capability owner IDs of the new component instance
70      */
71     public Map<String, String> mapOldToNewCapabilitiesOwnerIds(ComponentInstance oldInstance, ComponentInstance newInstance) {
72         List<CapabilityOwner> prevCapabilityOwners  = getInstanceAtomicBuildingBlocks(oldInstance).getCapabilitiesOwners();
73         List<CapabilityOwner> newCapOwners  = getInstanceAtomicBuildingBlocks(newInstance).getCapabilitiesOwners();
74         return getCapabilitiesOwnerMapping(prevCapabilityOwners, newCapOwners);
75     }
76
77     /**
78      * @param oldResource - old version of the Resource
79      * @param newResource - new version of the same Resource
80      * @return list of updated Relations created in UI
81      */
82     public List<RequirementCapabilityRelDef> updateUiRelationsInResource(Resource oldResource, Resource newResource) {
83         Map<String, ComponentInstance> mapOldComponentInstances = buildComponentInstanceMap(oldResource, ComponentInstance::getUniqueId);
84         Map<String, ComponentInstance> mapNewComponentInstances = buildComponentInstanceMap(newResource, ComponentInstance::getName);
85
86         return getUpdatedCapReqDefs(oldResource,
87                 mapOldComponentInstances,
88                 mapNewComponentInstances,
89                 RequirementCapabilityRelDef::isOriginUI);
90     }
91
92     /**
93      *
94      * @param componentInstance the instance which its building blocks are to be returned
95      * @return the atomic building (groups and instances) blocks which the given component instance is a composition of
96      */
97     public ComponentInstanceBuildingBlocks getInstanceAtomicBuildingBlocks(ComponentInstance componentInstance) {
98         if (componentInstance == null) {
99             return ComponentInstanceBuildingBlocks.empty();
100         }
101         String componentId = componentInstance.getActualComponentUid();
102         Component component = toscaOperationFacade.getToscaElement(componentId).left().on(err -> exceptionUtils.rollBackAndThrow(err, componentId));
103         return getInstanceAtomicBuildingBlocks(componentInstance, component);
104     }
105
106     /**
107      *
108      * @param componentInstance the instance which its building blocks are to be returned
109      * @param component the type thar the given component instance was created from
110      * @return the atomic building blocks (groups and instances) which the given component instance is a composition of
111      */
112     public ComponentInstanceBuildingBlocks getInstanceAtomicBuildingBlocks(ComponentInstance componentInstance, Component component) {
113         if (componentInstance == null || component == null) {
114             return ComponentInstanceBuildingBlocks.empty();
115         }
116         ComponentInstanceBuildingBlocks instanceBuildingBlocks;
117         if (ModelConverter.isAtomicComponent(component) || isCVFC(component)) {
118             if (componentInstance.getIsProxy()) {
119                 // Component is proxy and it doesn't contain required data
120                 instanceBuildingBlocks = getInstanceAtomicBuildingBlocks(componentInstance);
121             }
122             else {
123                 instanceBuildingBlocks = ComponentInstanceBuildingBlocks.of(new ArrayList<>(), singletonList(componentInstance));
124             }
125             return instanceBuildingBlocks;
126         }
127         else {
128             instanceBuildingBlocks = recursiveScanForAtomicBuildingBlocks(component);
129             if(org.apache.commons.collections.MapUtils.isNotEmpty(component.getCapabilities()) || org.apache.commons.collections.MapUtils.isNotEmpty(component.getRequirements())) {
130                 ComponentInstanceBuildingBlocks nonAtomicBlocks = ComponentInstanceBuildingBlocks.of(new ArrayList<>(), singletonList(componentInstance));
131                 return ComponentInstanceBuildingBlocks.merge(instanceBuildingBlocks, nonAtomicBlocks);
132             }
133             return instanceBuildingBlocks;
134         
135         }
136     }
137
138     public RelationMergeInfo mapRelationCapability(RequirementCapabilityRelDef relDef, List<CapabilityOwner> capsOwners) {
139         String ownerId = relDef.resolveSingleRelationship().getRelation().getCapabilityOwnerId();
140         return createCapabilityRelationMergeInfo(capsOwners, ownerId, relDef);
141     }
142
143     public RelationMergeInfo mapRelationRequirement(RequirementCapabilityRelDef relDef, List<ComponentInstance> vfcInstances) {
144         String ownerId = relDef.resolveSingleRelationship().getRelation().getRequirementOwnerId();
145         return createRequirementRelationMergeInfo(vfcInstances, ownerId, relDef);
146     }
147
148
149     public RequirementCapabilityRelDef restoreCapabilityRelation(RelationMergeInfo oldCapInfo,
150                                                                  String newInstanceId,
151                                                                  Map<String, CapabilityOwner> capOwnerByName,
152                                                                  Component updatedContainerComponent) {
153         String oldCapOwnerName = oldCapInfo.getCapOwnerName();
154
155         CapabilityOwner newCapOwner = capOwnerByName.get(oldCapOwnerName);
156         if (newCapOwner != null) {
157             // Append relation to updated container
158             RequirementCapabilityRelDef oldRelDef = oldCapInfo.getRelDef();
159             oldRelDef.setToNode(newInstanceId);
160             RelationshipInfo oldRelationshipInfo = oldRelDef.resolveSingleRelationship().getRelation();
161             oldRelationshipInfo.setCapabilityOwnerId(newCapOwner.getUniqueId());
162             oldRelationshipInfo.getRelationship().setType(oldCapInfo.getCapReqType());
163             String capabilityUid = retrieveCapabilityUid(oldCapInfo.getCapReqName(), newCapOwner);
164             oldRelationshipInfo.setCapabilityUid(capabilityUid);
165             if (updatedContainerComponent != null) {
166                 updatedContainerComponent.getComponentInstancesRelations().add(oldRelDef);
167             }
168             return oldRelDef;
169         } else {
170             log.debug("#restoreCapabilityRelation - Skip relation since it was not found VFC Instance with name {}", oldCapOwnerName);
171             return null;
172         }
173     }
174
175
176
177     public RequirementCapabilityRelDef restoreRequirementRelation(RelationMergeInfo oldReqInfo,
178                                                                   String newInstanceId,
179                                                                   Map<String, ComponentInstance> vfciMap,
180                                                                   Component updatedContainerComponent) {
181         String oldVfcInstanceName = oldReqInfo.getCapOwnerName();
182
183         ComponentInstance newVfcInstance = vfciMap.get(oldReqInfo.getCapOwnerName());
184         if (newVfcInstance != null) {
185             // Append relation to updated container
186             RequirementCapabilityRelDef oldRelDef = oldReqInfo.getRelDef();
187             oldRelDef.setFromNode(newInstanceId);
188
189             RelationshipInfo oldRelationshipInfo = oldRelDef.resolveSingleRelationship().getRelation();
190             oldRelationshipInfo.setRequirementOwnerId(newVfcInstance.getUniqueId());
191             oldRelationshipInfo.getRelationship().setType(oldReqInfo.getCapReqType());
192
193             String vfcUid = newVfcInstance.getComponentUid();
194             Either<Component, StorageOperationStatus> eitherComponent = toscaOperationFacade.getToscaElement(vfcUid);
195
196             if(eitherComponent.isLeft()) {
197                 String requirementUid = retrieveRequirementUid(oldReqInfo.getCapReqName() , eitherComponent.left().value());
198                 oldRelationshipInfo.setRequirementUid(requirementUid);
199             }
200             else {
201                 log.debug("#restoreRequirementCapabilityRelDef - Unexpected error: resource was not loaded for VF ID: {}", vfcUid);
202             }
203
204             if (updatedContainerComponent != null) {
205                 updatedContainerComponent.getComponentInstancesRelations().add(oldRelDef);
206             }
207             return oldRelDef;
208         }
209         else {
210             log.debug("#restoreRequirementCapabilityRelDef - Skip relation since it was not found VFC Instance with name {}", oldVfcInstanceName);
211             return null;
212         }
213     }
214
215     private List<ComponentInstance> getVfcInstances(ComponentInstance componentInstance) {
216         return getInstanceAtomicBuildingBlocks(componentInstance).getVfcInstances();
217     }
218
219     private Map<String, String> getCapabilitiesOwnerMapping(List<CapabilityOwner> oldCapOwners, List<CapabilityOwner> newCapOwners) {
220         Map<String, CapabilityOwner> newCapOwnerNameMap = toMap(newCapOwners, CapabilityOwner::getName, (p1, p2) -> p1);
221         return oldCapOwners.stream()
222                 .filter(oldCapOwner -> newCapOwnerNameMap.containsKey(oldCapOwner.getName()))
223                 .collect(Collectors.toMap(CapabilityOwner::getUniqueId, oldCapOwner -> newCapOwnerNameMap.get(oldCapOwner.getName()).getUniqueId(), (p1, p2) -> p1));
224     }
225
226     private static boolean isCVFC(Component component) {
227         ComponentTypeEnum componentType = component.getComponentType();
228         if (!componentType.equals(ComponentTypeEnum.RESOURCE)) {
229             return false;
230         }
231         Resource resource = (Resource) component;
232         ResourceTypeEnum resourceType = resource.getResourceType();
233         return resourceType == ResourceTypeEnum.CVFC;
234     }
235
236
237     private RequirementCapabilityRelDef mergeCapRelDefs(RequirementCapabilityRelDef capRelDefFrom, RequirementCapabilityRelDef capRelDefTo) {
238         if (capRelDefFrom == capRelDefTo) {
239             return capRelDefFrom;
240         }
241         else if (capRelDefFrom == null) {
242             return capRelDefTo;
243         }
244         else if (capRelDefTo == null) {
245             return capRelDefFrom;
246         }
247         
248         RelationshipInfo relationshipInfoFrom = capRelDefFrom.resolveSingleRelationship().getRelation();
249         RelationshipInfo relationshipInfoTo = capRelDefTo.resolveSingleRelationship().getRelation();
250         
251         relationshipInfoFrom.setCapabilityOwnerId(relationshipInfoTo.getCapabilityOwnerId());
252         relationshipInfoFrom.setCapabilityUid(relationshipInfoTo.getCapabilityUid());
253         
254         return capRelDefFrom;
255     }
256     
257
258
259     private Map<String, ComponentInstance> buildComponentInstanceMap(Resource oldRresource, Function<ComponentInstance, String> getKeyFunc) {
260         return oldRresource.getComponentInstances().stream()
261                 .collect(Collectors.toMap(getKeyFunc, Function.identity(), (p1, p2) -> p1));
262     }
263
264     private List<RequirementCapabilityRelDef> getUpdatedCapReqDefs(Resource oldResource,
265                                                                    Map<String, ComponentInstance> mapOldComponentInstances,
266                                                                    Map<String, ComponentInstance> mapNewComponentInstances,
267                                                                    Predicate<? super RequirementCapabilityRelDef> filter) {
268         return oldResource.getComponentInstancesRelations().stream()
269                         .filter(filter)
270                         .map(rel -> createRelationMergeInfoPair(rel, mapOldComponentInstances))
271                         .map(infoPair -> restoreRequirementCapabilityRelDef(infoPair, mapNewComponentInstances))
272                         .filter(Objects::nonNull)
273                         .collect(Collectors.toList());
274     }
275
276     private ImmutablePair<RelationMergeInfo, RelationMergeInfo> createRelationMergeInfoPair(RequirementCapabilityRelDef reqCapDef,
277                                                                                             Map<String, ComponentInstance> mapOldComponentInstances) {
278         
279         ComponentInstance oldComponentInstanceFrom = mapOldComponentInstances.get(reqCapDef.getFromNode());
280         RelationMergeInfo fromRelationMergeInfo = createRequirmentRelationMergeInfo(oldComponentInstanceFrom, reqCapDef);
281         
282         ComponentInstance oldComponentInstanceTo = mapOldComponentInstances.get(reqCapDef.getToNode());
283         RelationMergeInfo toRelationMergeInfo = createCapabilityRelationMergeInfo(oldComponentInstanceTo, reqCapDef);
284         return new ImmutablePair<>(fromRelationMergeInfo, toRelationMergeInfo);
285     }
286
287     private RelationMergeInfo createRequirmentRelationMergeInfo(ComponentInstance componentInstance, RequirementCapabilityRelDef reqCapDef ) {
288         
289         List<ComponentInstance> vfcInstances = getVfcInstances(componentInstance);
290         if  (vfcInstances != null) { 
291             return mapRelationRequirement(reqCapDef, vfcInstances);
292         }
293         else {
294             log.debug("#createRelationMergeInfo - It's unexpected that vfc instnaces were not found for {}", componentInstance);
295             return null;
296         }
297     }
298
299     private RelationMergeInfo createCapabilityRelationMergeInfo(ComponentInstance componentInstance,
300                                                       RequirementCapabilityRelDef reqCapDef) {
301         List<CapabilityOwner> capabilityOwners = getInstanceAtomicBuildingBlocks(componentInstance).getCapabilitiesOwners();
302         return mapRelationCapability(reqCapDef, capabilityOwners);
303     }
304
305     
306     private RequirementCapabilityRelDef restoreRequirementCapabilityRelDef(ImmutablePair<RelationMergeInfo, RelationMergeInfo> mergeInfoPair, Map<String, ComponentInstance> mapNewComponentInstances) {
307         RequirementCapabilityRelDef capRelDefFrom = restoreRequirementRelDef(mergeInfoPair, mapNewComponentInstances);
308         RequirementCapabilityRelDef capRelDefTo = restoreCapabilityRelDef(mergeInfoPair, mapNewComponentInstances);
309
310         return mergeCapRelDefs(capRelDefFrom, capRelDefTo);
311     }
312
313     private RequirementCapabilityRelDef restoreRequirementRelDef(ImmutablePair<RelationMergeInfo, RelationMergeInfo> mergeInfoPair, Map<String, ComponentInstance> mapNewComponentInstances) {
314         RequirementCapabilityRelDef capRelDefFrom;
315         RelationMergeInfo mergeInfoFrom = mergeInfoPair.getLeft();
316         if (mergeInfoFrom != null) {
317             ComponentInstance newComponentInstanceFrom = mapNewComponentInstances.get(mergeInfoFrom.getCapOwnerName());
318             capRelDefFrom = restoreRequirementRelDef(newComponentInstanceFrom, mergeInfoFrom,  newComponentInstanceFrom.getUniqueId());
319         }
320         else {
321             capRelDefFrom = null;
322         }
323         return capRelDefFrom;
324     }
325
326     private RequirementCapabilityRelDef restoreCapabilityRelDef(ImmutablePair<RelationMergeInfo, RelationMergeInfo> mergeInfoPair, Map<String, ComponentInstance> mapNewComponentInstances) {
327         RequirementCapabilityRelDef capRelDefTo;
328         RelationMergeInfo mergeInfoTo = mergeInfoPair.getRight();
329         if (mergeInfoTo != null) {
330             ComponentInstance newComponentInstanceTo = mapNewComponentInstances.get(mergeInfoTo.getCapOwnerName());
331             capRelDefTo = restoreCapabilityRelDef(newComponentInstanceTo, mergeInfoTo, newComponentInstanceTo.getUniqueId());
332         }
333         else {
334             capRelDefTo = null;
335         }
336         return capRelDefTo;
337     }
338
339     private RequirementCapabilityRelDef  restoreRequirementRelDef(ComponentInstance newComponentInstance, RelationMergeInfo mergeInfoFrom, String newComponentInstanceFromId) {
340         if (newComponentInstance != null) {
341             List<ComponentInstance> vfcInstances = getVfcInstances(newComponentInstance);
342             if(vfcInstances != null) {
343                 Map<String, ComponentInstance> vfciMap = toMap(vfcInstances, ComponentInstance::getName, (p1, p2) -> p1);
344                 return restoreRequirementRelation(mergeInfoFrom, newComponentInstanceFromId, vfciMap, null);
345             }
346             else {
347                 log.debug("#restoreRequirementCapabilityRelDef - It was not found VFC instances for component instance {}", newComponentInstance);
348             }
349         }
350         return null;
351     }
352
353     private RequirementCapabilityRelDef restoreCapabilityRelDef(ComponentInstance newComponentInstance, RelationMergeInfo mergeInfoTo, String newComponentInstanceToId) {
354         if (newComponentInstance != null) {
355             List<CapabilityOwner> capsOwners = getInstanceAtomicBuildingBlocks(newComponentInstance).getCapabilitiesOwners();
356             if(capsOwners != null) {
357                 Map<String, CapabilityOwner> vfciMap = toMap(capsOwners, CapabilityOwner::getName, (p1, p2) -> p1);
358                 return restoreCapabilityRelation(mergeInfoTo, newComponentInstanceToId, vfciMap, null);
359             }
360             else {
361                 log.debug("#restoreRequirementCapabilityRelDef - It was not found VFC instances for component instance {}", newComponentInstance);
362             }
363         }
364         return null;
365     }
366
367
368     private ComponentInstanceBuildingBlocks recursiveScanForAtomicBuildingBlocks(Component component) {
369         ComponentInstanceBuildingBlocks capsOwners = ComponentInstanceBuildingBlocks.of(component.getGroups(), null);
370         List<ComponentInstance> componentInstances = component.safeGetComponentInstances();
371         // Go recursively to collect atomic components only
372         ComponentInstanceBuildingBlocks propsOwnersRec = componentInstances.stream()
373                 .map(this::getInstanceAtomicBuildingBlocks)
374                 .reduce(ComponentInstanceBuildingBlocks::merge)
375                 .orElse(ComponentInstanceBuildingBlocks.empty());
376         return ComponentInstanceBuildingBlocks.merge(capsOwners, propsOwnersRec);
377     }
378
379
380     private Map<String, String> prepareMapForAtomicComponent(String newInstanceId, List<String> oldCapabilitiesOwnerIds) {
381         Map<String, String> resultMap;
382
383         int oldCapabilityOwnerIdsSize = oldCapabilitiesOwnerIds.size();
384         if (oldCapabilityOwnerIdsSize == 1) {
385             resultMap = new HashMap<>();
386             resultMap.put(oldCapabilitiesOwnerIds.get(0), newInstanceId);
387         }
388         else {
389             log.debug("#prepareMapForAtomicComponent - For atomic component the list of old capabilities owner Ids should contains one element while actual size is {},", oldCapabilityOwnerIdsSize);
390             resultMap = emptyMap();
391         }
392
393         return resultMap;
394     }
395
396     private Map<String, String> prepareMapForNonAtomicComponent(Component container, Component origInstanceNode,
397                                                                     String newInstanceId, List<String> oldCapabilitiesOwnerIds) {
398         ComponentInstance newInstance = container.getComponentInstanceById(newInstanceId).orElse(null);
399         if (newInstance == null) {
400             log.debug("#prepareMapForNonAtomicComponent - Failed to get component instance by newInstanceId: {}.", newInstanceId);
401             return emptyMap();
402         }
403         List<CapabilityOwner> prevCapOwners = recursiveScanForAtomicBuildingBlocks(origInstanceNode).getCapabilitiesOwners();
404         Component origNewCmpt = toscaOperationFacade.getToscaElement(newInstance.getActualComponentUid()).left().on(err -> exceptionUtils.rollBackAndThrow(err, newInstance.getActualComponentUid()));
405         return mapOldOwnerIdsToNewOnes(oldCapabilitiesOwnerIds, prevCapOwners, newInstance, origNewCmpt);
406     }
407
408     private Map<String, String> mapOldOwnerIdsToNewOnes(List<String> oldCapabilitiesOwnerIds,
409                                                         List<CapabilityOwner> prevCapOwners, ComponentInstance newInstance, Component origNewInstanceType) {
410         List<CapabilityOwner> newCapOwners = getInstanceAtomicBuildingBlocks(newInstance, origNewInstanceType).getCapabilitiesOwners();
411         return getCapabilitiesOwnerMapping(oldCapabilitiesOwnerIds, prevCapOwners, newCapOwners);
412     }
413
414     private Map<String, String> getCapabilitiesOwnerMapping(List<String> oldCapabilitiesOwnerIds, List<CapabilityOwner> prevCapOwners, List<CapabilityOwner> newCapOwners) {
415         Map<String, CapabilityOwner> capOwnersByName = toMap(newCapOwners, CapabilityOwner::getName, (p1, p2) -> p1);
416         return prevCapOwners
417                 .stream()
418                 .filter(oldCapOwner -> oldCapabilitiesOwnerIds.contains(oldCapOwner.getUniqueId()))
419                 .filter(oldCapOwner -> capOwnersByName.containsKey(oldCapOwner.getName()))
420                 .collect(Collectors.toMap(CapabilityOwner::getUniqueId, oldCapOwner -> capOwnersByName.get(oldCapOwner.getName()).getUniqueId(), (p1, p2) -> p1));
421     }
422
423
424     private RelationMergeInfo createCapabilityRelationMergeInfo(List<CapabilityOwner> vfcInstances, String ownerId, RequirementCapabilityRelDef relation) {
425         return vfcInstances.stream()
426                             .filter(inst -> StringUtils.equals(inst.getUniqueId(), ownerId))
427                             .map(capabilityOwner -> getCapabilityMergeInfo(capabilityOwner, relation))
428                             .findAny()
429                             .orElse(null);
430     }
431
432
433     private RelationMergeInfo createRequirementRelationMergeInfo(List<ComponentInstance> vfcInstances, String ownerId, RequirementCapabilityRelDef relation) {
434         return vfcInstances.stream()
435                 .filter(inst -> StringUtils.equals(inst.getUniqueId(), ownerId))
436                 .map(currVfcInst -> mapVfcInstanceRequirement(currVfcInst, relation))
437                 .filter(Objects::nonNull)
438                 .findAny()
439                 .orElse(null);
440     }
441
442     private RelationMergeInfo getCapabilityMergeInfo(CapabilityOwner capabilityOwner, RequirementCapabilityRelDef relDef) {
443         String capabilityUniqueId = relDef.resolveSingleRelationship().getRelation().getCapabilityUid();
444         String capOwnerName = capabilityOwner.getName();
445         CapabilityDefinition capabilityDef = retrieveCapabilityDefinition(capabilityUniqueId, capabilityOwner);
446         String capabilityType;
447         String capabilityName;
448         if (capabilityDef != null) {
449             capabilityType = capabilityDef.getType();
450             capabilityName = capabilityDef.getName();
451         } else {
452             log.debug("#getCapabilityMergeInfo - Failed to retrieve capability type for relation with name: {} and uniqueId {}", relDef.resolveSingleRelationship().getRelation().getCapability(), capabilityUniqueId);
453             capabilityType = null;
454             capabilityName = null;
455         }
456         return new RelationMergeInfo(capabilityType, capabilityName, capOwnerName, relDef);
457     }
458     
459     private RelationMergeInfo mapVfcInstanceRequirement(ComponentInstance vfcInstance, RequirementCapabilityRelDef relDef) {
460         String requirementUniqueId = relDef.resolveSingleRelationship().getRelation().getRequirementUid();
461         
462         String vfcInstanceName = vfcInstance.getName();
463         String vfcUid = vfcInstance.getComponentUid();
464         
465         Either<Resource, StorageOperationStatus> vfcResource = toscaOperationFacade.getToscaElement(vfcUid);
466         if(vfcResource.isLeft()) {
467             Resource vfc = vfcResource.left().value();
468             
469             RequirementDefinition requirementDef = retrieveRequirementDefinition(requirementUniqueId, vfc);
470             String requirementType;
471             String requirementName;
472             if (requirementDef != null) {
473                 requirementType = requirementDef.getCapability();
474                 requirementName = requirementDef.getName();
475             }
476             else {
477                 log.debug("#mapVfcInstanceRequirement - Failed to retrieve requirement type for relation with name: {} and uniqueId {}", relDef.resolveSingleRelationship().getRelation().getRequirement(), requirementUniqueId);
478                 requirementType = null;
479                 requirementName = null;                
480             }
481             
482             return new RelationMergeInfo(requirementType, requirementName, vfcInstanceName, relDef);
483         }
484         else {
485             log.debug("#mapVfcInstanceRequirement - Failed to load VFC by uid {}", vfcUid); 
486             return null;
487         }
488     }
489
490     private CapabilityDefinition retrieveCapabilityDefinition(String uniqueId, CapabilityOwner capabilityOwner) {
491         return capabilityOwner.getCapabilities().values().stream()
492                                                 .flatMap(List::stream)
493                                                 .filter(Objects::nonNull)
494                                                 .filter(def -> uniqueId.equals(def.getUniqueId()))
495                                                 .findFirst()
496                                                 .orElse(null);
497     }
498     
499     private RequirementDefinition retrieveRequirementDefinition(String uniqueId, Resource vfc) {
500         return vfc.getRequirements().values().stream()
501                 .flatMap(List::stream)
502                 .filter(Objects::nonNull)
503                 .filter(def -> uniqueId.equals(def.getUniqueId()))
504                 .findFirst()
505                 .orElse(null);
506     }
507     
508     private String retrieveCapabilityUid(String name, CapabilityOwner capabilityOwner) {
509         return capabilityOwner.getCapabilities().values()
510                                                 .stream()
511                                                 .flatMap(List::stream)
512                                                 .filter(Objects::nonNull)
513                                                 .filter(def -> name.equals(def.getName()))
514                                                 .findFirst()
515                                                 .map(CapabilityDefinition::getUniqueId)
516                                                 .orElse(null);
517     }
518
519     private String retrieveRequirementUid(String name, Component vfc) {
520         return vfc.getRequirements().values().stream()
521                                                 .flatMap(List::stream)
522                                                 .filter(Objects::nonNull)
523                                                 .filter(def -> name.equals(def.getName()))
524                                                 .findFirst()
525                                                 .map(RequirementDefinition::getUniqueId)
526                                                 .orElse(null);
527     }
528 }