re base code
[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.jsontitan.operations.ToscaOperationFacade;
12 import org.openecomp.sdc.be.model.jsontitan.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         }
126         else {
127             instanceBuildingBlocks = recursiveScanForAtomicBuildingBlocks(component);
128         }
129         return instanceBuildingBlocks;
130     }
131
132     public RelationMergeInfo mapRelationCapability(RequirementCapabilityRelDef relDef, List<CapabilityOwner> capsOwners) {
133         String ownerId = relDef.resolveSingleRelationship().getRelation().getCapabilityOwnerId();
134         return createCapabilityRelationMergeInfo(capsOwners, ownerId, relDef);
135     }
136
137     public RelationMergeInfo mapRelationRequirement(RequirementCapabilityRelDef relDef, List<ComponentInstance> vfcInstances) {
138         String ownerId = relDef.resolveSingleRelationship().getRelation().getRequirementOwnerId();
139         return createRequirementRelationMergeInfo(vfcInstances, ownerId, relDef);
140     }
141
142
143     public RequirementCapabilityRelDef restoreCapabilityRelation(RelationMergeInfo oldCapInfo,
144                                                                  String newInstanceId,
145                                                                  Map<String, CapabilityOwner> capOwnerByName,
146                                                                  Component updatedContainerComponent) {
147         String oldCapOwnerName = oldCapInfo.getCapOwnerName();
148
149         CapabilityOwner newCapOwner = capOwnerByName.get(oldCapOwnerName);
150         if (newCapOwner != null) {
151             // Append relation to updated container
152             RequirementCapabilityRelDef oldRelDef = oldCapInfo.getRelDef();
153             oldRelDef.setToNode(newInstanceId);
154             RelationshipInfo oldRelationshipInfo = oldRelDef.resolveSingleRelationship().getRelation();
155             oldRelationshipInfo.setCapabilityOwnerId(newCapOwner.getUniqueId());
156             oldRelationshipInfo.getRelationship().setType(oldCapInfo.getCapReqType());
157             String capabilityUid = retrieveCapabilityUid(oldCapInfo.getCapReqName(), newCapOwner);
158             oldRelationshipInfo.setCapabilityUid(capabilityUid);
159             if (updatedContainerComponent != null) {
160                 updatedContainerComponent.getComponentInstancesRelations().add(oldRelDef);
161             }
162             return oldRelDef;
163         } else {
164             log.debug("#restoreCapabilityRelation - Skip relation since it was not found VFC Instance with name {}", oldCapOwnerName);
165             return null;
166         }
167     }
168
169
170
171     public RequirementCapabilityRelDef restoreRequirementRelation(RelationMergeInfo oldReqInfo,
172                                                                   String newInstanceId,
173                                                                   Map<String, ComponentInstance> vfciMap,
174                                                                   Component updatedContainerComponent) {
175         String oldVfcInstanceName = oldReqInfo.getCapOwnerName();
176
177         ComponentInstance newVfcInstance = vfciMap.get(oldReqInfo.getCapOwnerName());
178         if (newVfcInstance != null) {
179             // Append relation to updated container
180             RequirementCapabilityRelDef oldRelDef = oldReqInfo.getRelDef();
181             oldRelDef.setFromNode(newInstanceId);
182
183             RelationshipInfo oldRelationshipInfo = oldRelDef.resolveSingleRelationship().getRelation();
184             oldRelationshipInfo.setRequirementOwnerId(newVfcInstance.getUniqueId());
185             oldRelationshipInfo.getRelationship().setType(oldReqInfo.getCapReqType());
186
187             String vfcUid = newVfcInstance.getComponentUid();
188             Either<Component, StorageOperationStatus> eitherComponent = toscaOperationFacade.getToscaElement(vfcUid);
189
190             if(eitherComponent.isLeft()) {
191                 String requirementUid = retrieveRequirementUid(oldReqInfo.getCapReqName() , eitherComponent.left().value());
192                 oldRelationshipInfo.setRequirementUid(requirementUid);
193             }
194             else {
195                 log.debug("#restoreRequirementCapabilityRelDef - Unexpected error: resource was not loaded for VF ID: {}", vfcUid);
196             }
197
198             if (updatedContainerComponent != null) {
199                 updatedContainerComponent.getComponentInstancesRelations().add(oldRelDef);
200             }
201             return oldRelDef;
202         }
203         else {
204             log.debug("#restoreRequirementCapabilityRelDef - Skip relation since it was not found VFC Instance with name {}", oldVfcInstanceName);
205             return null;
206         }
207     }
208
209     private List<ComponentInstance> getVfcInstances(ComponentInstance componentInstance) {
210         return getInstanceAtomicBuildingBlocks(componentInstance).getVfcInstances();
211     }
212
213     private Map<String, String> getCapabilitiesOwnerMapping(List<CapabilityOwner> oldCapOwners, List<CapabilityOwner> newCapOwners) {
214         Map<String, CapabilityOwner> newCapOwnerNameMap = toMap(newCapOwners, CapabilityOwner::getName, (p1, p2) -> p1);
215         return oldCapOwners.stream()
216                 .filter(oldCapOwner -> newCapOwnerNameMap.containsKey(oldCapOwner.getName()))
217                 .collect(Collectors.toMap(CapabilityOwner::getUniqueId, oldCapOwner -> newCapOwnerNameMap.get(oldCapOwner.getName()).getUniqueId(), (p1, p2) -> p1));
218     }
219
220     private static boolean isCVFC(Component component) {
221         ComponentTypeEnum componentType = component.getComponentType();
222         if (!componentType.equals(ComponentTypeEnum.RESOURCE)) {
223             return false;
224         }
225         Resource resource = (Resource) component;
226         ResourceTypeEnum resourceType = resource.getResourceType();
227         return resourceType == ResourceTypeEnum.CVFC;
228     }
229
230
231     private RequirementCapabilityRelDef mergeCapRelDefs(RequirementCapabilityRelDef capRelDefFrom, RequirementCapabilityRelDef capRelDefTo) {
232         if (capRelDefFrom == capRelDefTo) {
233             return capRelDefFrom;
234         }
235         else if (capRelDefFrom == null) {
236             return capRelDefTo;
237         }
238         else if (capRelDefTo == null) {
239             return capRelDefFrom;
240         }
241         
242         RelationshipInfo relationshipInfoFrom = capRelDefFrom.resolveSingleRelationship().getRelation();
243         RelationshipInfo relationshipInfoTo = capRelDefTo.resolveSingleRelationship().getRelation();
244         
245         relationshipInfoFrom.setCapabilityOwnerId(relationshipInfoTo.getCapabilityOwnerId());
246         relationshipInfoFrom.setCapabilityUid(relationshipInfoTo.getCapabilityUid());
247         
248         return capRelDefFrom;
249     }
250     
251
252
253     private Map<String, ComponentInstance> buildComponentInstanceMap(Resource oldRresource, Function<ComponentInstance, String> getKeyFunc) {
254         return oldRresource.getComponentInstances().stream()
255                 .collect(Collectors.toMap(getKeyFunc, Function.identity(), (p1, p2) -> p1));
256     }
257
258     private List<RequirementCapabilityRelDef> getUpdatedCapReqDefs(Resource oldResource,
259                                                                    Map<String, ComponentInstance> mapOldComponentInstances,
260                                                                    Map<String, ComponentInstance> mapNewComponentInstances,
261                                                                    Predicate<? super RequirementCapabilityRelDef> filter) {
262         return oldResource.getComponentInstancesRelations().stream()
263                         .filter(filter)
264                         .map(rel -> createRelationMergeInfoPair(rel, mapOldComponentInstances))
265                         .map(infoPair -> restoreRequirementCapabilityRelDef(infoPair, mapNewComponentInstances))
266                         .filter(Objects::nonNull)
267                         .collect(Collectors.toList());
268     }
269
270     private ImmutablePair<RelationMergeInfo, RelationMergeInfo> createRelationMergeInfoPair(RequirementCapabilityRelDef reqCapDef,
271                                                                                             Map<String, ComponentInstance> mapOldComponentInstances) {
272         
273         ComponentInstance oldComponentInstanceFrom = mapOldComponentInstances.get(reqCapDef.getFromNode());
274         RelationMergeInfo fromRelationMergeInfo = createRequirmentRelationMergeInfo(oldComponentInstanceFrom, reqCapDef);
275         
276         ComponentInstance oldComponentInstanceTo = mapOldComponentInstances.get(reqCapDef.getToNode());
277         RelationMergeInfo toRelationMergeInfo = createCapabilityRelationMergeInfo(oldComponentInstanceTo, reqCapDef);
278         return new ImmutablePair<>(fromRelationMergeInfo, toRelationMergeInfo);
279     }
280
281     private RelationMergeInfo createRequirmentRelationMergeInfo(ComponentInstance componentInstance, RequirementCapabilityRelDef reqCapDef ) {
282         
283         List<ComponentInstance> vfcInstances = getVfcInstances(componentInstance);
284         if  (vfcInstances != null) { 
285             return mapRelationRequirement(reqCapDef, vfcInstances);
286         }
287         else {
288             log.debug("#createRelationMergeInfo - It's unexpected that vfc instnaces were not found for {}", componentInstance);
289             return null;
290         }
291     }
292
293     private RelationMergeInfo createCapabilityRelationMergeInfo(ComponentInstance componentInstance,
294                                                       RequirementCapabilityRelDef reqCapDef) {
295         List<CapabilityOwner> capabilityOwners = getInstanceAtomicBuildingBlocks(componentInstance).getCapabilitiesOwners();
296         return mapRelationCapability(reqCapDef, capabilityOwners);
297     }
298
299     
300     private RequirementCapabilityRelDef restoreRequirementCapabilityRelDef(ImmutablePair<RelationMergeInfo, RelationMergeInfo> mergeInfoPair, Map<String, ComponentInstance> mapNewComponentInstances) {
301         RequirementCapabilityRelDef capRelDefFrom = restoreRequirementRelDef(mergeInfoPair, mapNewComponentInstances);
302         RequirementCapabilityRelDef capRelDefTo = restoreCapabilityRelDef(mergeInfoPair, mapNewComponentInstances);
303
304         return mergeCapRelDefs(capRelDefFrom, capRelDefTo);
305     }
306
307     private RequirementCapabilityRelDef restoreRequirementRelDef(ImmutablePair<RelationMergeInfo, RelationMergeInfo> mergeInfoPair, Map<String, ComponentInstance> mapNewComponentInstances) {
308         RequirementCapabilityRelDef capRelDefFrom;
309         RelationMergeInfo mergeInfoFrom = mergeInfoPair.getLeft();
310         if (mergeInfoFrom != null) {
311             ComponentInstance newComponentInstanceFrom = mapNewComponentInstances.get(mergeInfoFrom.getCapOwnerName());
312             capRelDefFrom = restoreRequirementRelDef(newComponentInstanceFrom, mergeInfoFrom,  newComponentInstanceFrom.getUniqueId());
313         }
314         else {
315             capRelDefFrom = null;
316         }
317         return capRelDefFrom;
318     }
319
320     private RequirementCapabilityRelDef restoreCapabilityRelDef(ImmutablePair<RelationMergeInfo, RelationMergeInfo> mergeInfoPair, Map<String, ComponentInstance> mapNewComponentInstances) {
321         RequirementCapabilityRelDef capRelDefTo;
322         RelationMergeInfo mergeInfoTo = mergeInfoPair.getRight();
323         if (mergeInfoTo != null) {
324             ComponentInstance newComponentInstanceTo = mapNewComponentInstances.get(mergeInfoTo.getCapOwnerName());
325             capRelDefTo = restoreCapabilityRelDef(newComponentInstanceTo, mergeInfoTo, newComponentInstanceTo.getUniqueId());
326         }
327         else {
328             capRelDefTo = null;
329         }
330         return capRelDefTo;
331     }
332
333     private RequirementCapabilityRelDef  restoreRequirementRelDef(ComponentInstance newComponentInstance, RelationMergeInfo mergeInfoFrom, String newComponentInstanceFromId) {
334         if (newComponentInstance != null) {
335             List<ComponentInstance> vfcInstances = getVfcInstances(newComponentInstance);
336             if(vfcInstances != null) {
337                 Map<String, ComponentInstance> vfciMap = toMap(vfcInstances, ComponentInstance::getName, (p1, p2) -> p1);
338                 return restoreRequirementRelation(mergeInfoFrom, newComponentInstanceFromId, vfciMap, null);
339             }
340             else {
341                 log.debug("#restoreRequirementCapabilityRelDef - It was not found VFC instances for component instance {}", newComponentInstance);
342             }
343         }
344         return null;
345     }
346
347     private RequirementCapabilityRelDef restoreCapabilityRelDef(ComponentInstance newComponentInstance, RelationMergeInfo mergeInfoTo, String newComponentInstanceToId) {
348         if (newComponentInstance != null) {
349             List<CapabilityOwner> capsOwners = getInstanceAtomicBuildingBlocks(newComponentInstance).getCapabilitiesOwners();
350             if(capsOwners != null) {
351                 Map<String, CapabilityOwner> vfciMap = toMap(capsOwners, CapabilityOwner::getName, (p1, p2) -> p1);
352                 return restoreCapabilityRelation(mergeInfoTo, newComponentInstanceToId, vfciMap, null);
353             }
354             else {
355                 log.debug("#restoreRequirementCapabilityRelDef - It was not found VFC instances for component instance {}", newComponentInstance);
356             }
357         }
358         return null;
359     }
360
361
362     private ComponentInstanceBuildingBlocks recursiveScanForAtomicBuildingBlocks(Component component) {
363         ComponentInstanceBuildingBlocks capsOwners = ComponentInstanceBuildingBlocks.of(component.getGroups(), null);
364         List<ComponentInstance> componentInstances = component.safeGetComponentInstances();
365         // Go recursively to collect atomic components only
366         ComponentInstanceBuildingBlocks propsOwnersRec = componentInstances.stream()
367                 .map(this::getInstanceAtomicBuildingBlocks)
368                 .reduce(ComponentInstanceBuildingBlocks::merge)
369                 .orElse(ComponentInstanceBuildingBlocks.empty());
370         return ComponentInstanceBuildingBlocks.merge(capsOwners, propsOwnersRec);
371     }
372
373
374     private Map<String, String> prepareMapForAtomicComponent(String newInstanceId, List<String> oldCapabilitiesOwnerIds) {
375         Map<String, String> resultMap;
376
377         int oldCapabilityOwnerIdsSize = oldCapabilitiesOwnerIds.size();
378         if (oldCapabilityOwnerIdsSize == 1) {
379             resultMap = new HashMap<>();
380             resultMap.put(oldCapabilitiesOwnerIds.get(0), newInstanceId);
381         }
382         else {
383             log.debug("#prepareMapForAtomicComponent - For atomic component the list of old capabilities owner Ids should contains one element while actual size is {},", oldCapabilityOwnerIdsSize);
384             resultMap = emptyMap();
385         }
386
387         return resultMap;
388     }
389
390     private Map<String, String> prepareMapForNonAtomicComponent(Component container, Component origInstanceNode,
391                                                                     String newInstanceId, List<String> oldCapabilitiesOwnerIds) {
392         ComponentInstance newInstance = container.getComponentInstanceById(newInstanceId).orElse(null);
393         if (newInstance == null) {
394             log.debug("#prepareMapForNonAtomicComponent - Failed to get component instance by newInstanceId: {}.", newInstanceId);
395             return emptyMap();
396         }
397         List<CapabilityOwner> prevCapOwners = recursiveScanForAtomicBuildingBlocks(origInstanceNode).getCapabilitiesOwners();
398         Component origNewCmpt = toscaOperationFacade.getToscaElement(newInstance.getActualComponentUid()).left().on(err -> exceptionUtils.rollBackAndThrow(err, newInstance.getActualComponentUid()));
399         return mapOldOwnerIdsToNewOnes(oldCapabilitiesOwnerIds, prevCapOwners, newInstance, origNewCmpt);
400     }
401
402     private Map<String, String> mapOldOwnerIdsToNewOnes(List<String> oldCapabilitiesOwnerIds,
403                                                         List<CapabilityOwner> prevCapOwners, ComponentInstance newInstance, Component origNewInstanceType) {
404         List<CapabilityOwner> newCapOwners = getInstanceAtomicBuildingBlocks(newInstance, origNewInstanceType).getCapabilitiesOwners();
405         return getCapabilitiesOwnerMapping(oldCapabilitiesOwnerIds, prevCapOwners, newCapOwners);
406     }
407
408     private Map<String, String> getCapabilitiesOwnerMapping(List<String> oldCapabilitiesOwnerIds, List<CapabilityOwner> prevCapOwners, List<CapabilityOwner> newCapOwners) {
409         Map<String, CapabilityOwner> capOwnersByName = toMap(newCapOwners, CapabilityOwner::getName, (p1, p2) -> p1);
410         return prevCapOwners
411                 .stream()
412                 .filter(oldCapOwner -> oldCapabilitiesOwnerIds.contains(oldCapOwner.getUniqueId()))
413                 .filter(oldCapOwner -> capOwnersByName.containsKey(oldCapOwner.getName()))
414                 .collect(Collectors.toMap(CapabilityOwner::getUniqueId, oldCapOwner -> capOwnersByName.get(oldCapOwner.getName()).getUniqueId(), (p1, p2) -> p1));
415     }
416
417
418     private RelationMergeInfo createCapabilityRelationMergeInfo(List<CapabilityOwner> vfcInstances, String ownerId, RequirementCapabilityRelDef relation) {
419         return vfcInstances.stream()
420                             .filter(inst -> StringUtils.equals(inst.getUniqueId(), ownerId))
421                             .map(capabilityOwner -> getCapabilityMergeInfo(capabilityOwner, relation))
422                             .findAny()
423                             .orElse(null);
424     }
425
426
427     private RelationMergeInfo createRequirementRelationMergeInfo(List<ComponentInstance> vfcInstances, String ownerId, RequirementCapabilityRelDef relation) {
428         return vfcInstances.stream()
429                 .filter(inst -> StringUtils.equals(inst.getUniqueId(), ownerId))
430                 .map(currVfcInst -> mapVfcInstanceRequirement(currVfcInst, relation))
431                 .filter(Objects::nonNull)
432                 .findAny()
433                 .orElse(null);
434     }
435
436     private RelationMergeInfo getCapabilityMergeInfo(CapabilityOwner capabilityOwner, RequirementCapabilityRelDef relDef) {
437         String capabilityUniqueId = relDef.resolveSingleRelationship().getRelation().getCapabilityUid();
438         String capOwnerName = capabilityOwner.getName();
439         CapabilityDefinition capabilityDef = retrieveCapabilityDefinition(capabilityUniqueId, capabilityOwner);
440         String capabilityType;
441         String capabilityName;
442         if (capabilityDef != null) {
443             capabilityType = capabilityDef.getType();
444             capabilityName = capabilityDef.getName();
445         } else {
446             log.debug("#getCapabilityMergeInfo - Failed to retrieve capability type for relation with name: {} and uniqueId {}", relDef.resolveSingleRelationship().getRelation().getCapability(), capabilityUniqueId);
447             capabilityType = null;
448             capabilityName = null;
449         }
450         return new RelationMergeInfo(capabilityType, capabilityName, capOwnerName, relDef);
451     }
452     
453     private RelationMergeInfo mapVfcInstanceRequirement(ComponentInstance vfcInstance, RequirementCapabilityRelDef relDef) {
454         String requirementUniqueId = relDef.resolveSingleRelationship().getRelation().getRequirementUid();
455         
456         String vfcInstanceName = vfcInstance.getName();
457         String vfcUid = vfcInstance.getComponentUid();
458         
459         Either<Resource, StorageOperationStatus> vfcResource = toscaOperationFacade.getToscaElement(vfcUid);
460         if(vfcResource.isLeft()) {
461             Resource vfc = vfcResource.left().value();
462             
463             RequirementDefinition requirementDef = retrieveRequirementDefinition(requirementUniqueId, vfc);
464             String requirementType;
465             String requirementName;
466             if (requirementDef != null) {
467                 requirementType = requirementDef.getCapability();
468                 requirementName = requirementDef.getName();
469             }
470             else {
471                 log.debug("#mapVfcInstanceRequirement - Failed to retrieve requirement type for relation with name: {} and uniqueId {}", relDef.resolveSingleRelationship().getRelation().getRequirement(), requirementUniqueId);
472                 requirementType = null;
473                 requirementName = null;                
474             }
475             
476             return new RelationMergeInfo(requirementType, requirementName, vfcInstanceName, relDef);
477         }
478         else {
479             log.debug("#mapVfcInstanceRequirement - Failed to load VFC by uid {}", vfcUid); 
480             return null;
481         }
482     }
483
484     private CapabilityDefinition retrieveCapabilityDefinition(String uniqueId, CapabilityOwner capabilityOwner) {
485         return capabilityOwner.getCapabilities().values().stream()
486                                                 .flatMap(List::stream)
487                                                 .filter(Objects::nonNull)
488                                                 .filter(def -> uniqueId.equals(def.getUniqueId()))
489                                                 .findFirst()
490                                                 .orElse(null);
491     }
492     
493     private RequirementDefinition retrieveRequirementDefinition(String uniqueId, Resource vfc) {
494         return vfc.getRequirements().values().stream()
495                 .flatMap(List::stream)
496                 .filter(Objects::nonNull)
497                 .filter(def -> uniqueId.equals(def.getUniqueId()))
498                 .findFirst()
499                 .orElse(null);
500     }
501     
502     private String retrieveCapabilityUid(String name, CapabilityOwner capabilityOwner) {
503         return capabilityOwner.getCapabilities().values()
504                                                 .stream()
505                                                 .flatMap(List::stream)
506                                                 .filter(Objects::nonNull)
507                                                 .filter(def -> name.equals(def.getName()))
508                                                 .findFirst()
509                                                 .map(CapabilityDefinition::getUniqueId)
510                                                 .orElse(null);
511     }
512
513     private String retrieveRequirementUid(String name, Component vfc) {
514         return vfc.getRequirements().values().stream()
515                                                 .flatMap(List::stream)
516                                                 .filter(Objects::nonNull)
517                                                 .filter(def -> name.equals(def.getName()))
518                                                 .findFirst()
519                                                 .map(RequirementDefinition::getUniqueId)
520                                                 .orElse(null);
521     }
522 }