1 package org.openecomp.sdc.be.components.merge.utils;
4 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
5 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
6 import org.openecomp.sdc.be.model.Component;
7 import org.openecomp.sdc.be.model.ComponentInstance;
8 import org.openecomp.sdc.be.model.Resource;
9 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
10 import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter;
11 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
12 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory;
14 import org.springframework.beans.factory.annotation.Autowired;
16 import com.google.common.annotations.VisibleForTesting;
18 import java.util.stream.Collectors;
20 import static java.util.function.Function.identity;
23 * This class is Utils class but it should be bean
27 @org.springframework.stereotype.Component("MergeInstanceUtils")
28 public class MergeInstanceUtils {
29 private Logger log = LoggerFactory.getLogger(MergeInstanceUtils.class);
32 private ToscaOperationFacade toscaOperationFacade;
35 * Maps capability owner IDs of old component instance to capability owner IDs of the new component instance
36 * @param container containing new component instance
37 * @param origInstanceNode old component (in case of PROXY it should be actual service)
38 * @param newInstanceId - ID of new instance of the component
39 * @param oldCapabilitiesOwnerIds
42 public Map<String, String> mapOldToNewCapabilitiesOwnerIds(Component container,
43 Component origInstanceNode,
45 List<String> oldCapabilitiesOwnerIds) {
47 Map<String, String> resultMap;
49 if (ModelConverter.isAtomicComponent(origInstanceNode) || isCVFC(origInstanceNode)) {
50 resultMap = prepareMapForAtomicComponent(newInstanceId, oldCapabilitiesOwnerIds);
53 resultMap = prepareMapForNonAtomicComponent(container, origInstanceNode, newInstanceId, oldCapabilitiesOwnerIds);
60 private static boolean isCVFC(Component component) {
61 ComponentTypeEnum componentType = component.getComponentType();
62 if (!componentType.equals(ComponentTypeEnum.RESOURCE)) {
66 Resource resource = (Resource) component;
67 ResourceTypeEnum resourceType = resource.getResourceType();
68 return resourceType == ResourceTypeEnum.CVFC;
73 * Maps capability owner IDs of old component instance to capability owner IDs of the new component instance
78 public Map<String, String> mapOldToNewCapabilitiesOwnerIds(ComponentInstance oldInstance, ComponentInstance newInstance) {
79 List<ComponentInstance> oldVfcInstances = getVfcInstances(oldInstance);
80 List<ComponentInstance> newVfcInstances = getVfcInstances(newInstance);
82 Map<String, ComponentInstance> newVfciNameMap = convertToVfciNameMap(newVfcInstances);
84 return oldVfcInstances.stream()
85 .filter(oldVfci -> newVfciNameMap.containsKey(oldVfci.getName()))
86 .collect(Collectors.toMap(ComponentInstance::getUniqueId, oldVfci -> newVfciNameMap.get(oldVfci.getName()).getUniqueId()));
91 * Method converts list of Component Instances to map of the instances where the key is their name
92 * @param componentInstances
95 public Map<String, ComponentInstance> convertToVfciNameMap(List<ComponentInstance> componentInstances) {
96 return componentInstances != null ?
97 componentInstances.stream()
98 .collect(Collectors.toMap(ComponentInstance::getName, identity())): Collections.emptyMap();
104 * Returns List of componentInstances by specified componentInstance
105 * If componentInstance is for atomic component the returned list will contain the specified componentInstance only.
106 * @param componentInstance
109 public List<ComponentInstance> getVfcInstances(ComponentInstance componentInstance) {
110 if (componentInstance == null) {
111 return Collections.emptyList();
115 List<ComponentInstance> vfcInstances;
117 String componentId = componentInstance.getActualComponentUid();
118 Either<Component, StorageOperationStatus> eitherComponent = toscaOperationFacade.getToscaElement(componentId);
120 if(eitherComponent.isLeft()) {
121 Component component = eitherComponent.left().value();
122 vfcInstances = getVfcInstances(componentInstance, component);
125 log.debug("Unexpected error: resource was not loaded for VF ID: {}", componentId);
126 vfcInstances = Collections.emptyList();
134 * Returns List of componentInstances by specified componentInstance and component
135 * If componentInstance is for atomic component the returned list will contain the specified componentInstance only.
136 * @param componentInstance
137 * @param eitherComponent
140 public List<ComponentInstance> getVfcInstances(ComponentInstance componentInstance, Component component) {
141 if (componentInstance == null || component == null) {
142 return Collections.emptyList();
146 List<ComponentInstance> vfcInstances;
148 if (ModelConverter.isAtomicComponent(component) || isCVFC(component)) {
149 if (componentInstance.getIsProxy()) {
150 // Component is proxy and it doesn't contain required data
151 vfcInstances = getVfcInstances(componentInstance);
154 vfcInstances = Arrays.asList(componentInstance);
158 vfcInstances = recursiveScanForAtomicComponentInstances(component);
166 public void setToscaOperationFacade(ToscaOperationFacade toscaOperationFacade) {
167 this.toscaOperationFacade = toscaOperationFacade;
176 private List<ComponentInstance> recursiveScanForAtomicComponentInstances(Component component) {
177 List<ComponentInstance> vfcInstances;
179 List<ComponentInstance> componentInstances = component.getComponentInstances();
180 if (componentInstances != null) {
181 // Go recursively to collect atomic components only
182 vfcInstances = componentInstances.stream()
183 .map(this::getVfcInstances)
184 .flatMap(List::stream)
185 .collect(Collectors.toList());
188 vfcInstances = Collections.emptyList();
197 * @param newInstanceId
198 * @param oldCapabilitiesOwnerIds
201 private Map<String, String> prepareMapForAtomicComponent(String newInstanceId, List<String> oldCapabilitiesOwnerIds) {
202 Map<String, String> resultMap;
204 int oldCapabilityOwnerIdsSize = oldCapabilitiesOwnerIds.size();
205 if (oldCapabilityOwnerIdsSize == 1) {
206 resultMap = new HashMap<>();
207 resultMap.put(oldCapabilitiesOwnerIds.get(0), newInstanceId);
210 log.debug("For automic component the list of old capabilities owner Ids should contains one element while actual size is {},", oldCapabilityOwnerIdsSize);
211 resultMap = Collections.emptyMap();
219 * @param origInstanceNode
220 * @param newInstanceId
221 * @param oldCapabilitiesOwnerIds
224 private Map<String, String> prepareMapForNonAtomicComponent(Component container, Component origInstanceNode,
225 String newInstanceId, List<String> oldCapabilitiesOwnerIds) {
226 Map<String, String> resultMap;
227 List<ComponentInstance> oldVfcInstances = recursiveScanForAtomicComponentInstances(origInstanceNode);
229 ComponentInstance newInstance = container.getComponentInstanceById(newInstanceId).orElse(null);
230 if (newInstance == null) {
231 log.debug("Failed to get component instance by newInstanceId: {}.", newInstanceId);
232 resultMap = Collections.emptyMap();
235 resultMap = mapOldVfcIdsToNewOnes(oldCapabilitiesOwnerIds, oldVfcInstances, newInstance);
241 * @param oldCapabilitiesOwnerIds
242 * @param oldVfcInstances
246 private Map<String, String> mapOldVfcIdsToNewOnes(List<String> oldCapabilitiesOwnerIds,
247 List<ComponentInstance> oldVfcInstances, ComponentInstance newInstance) {
248 List<ComponentInstance> newVfcInstances = getVfcInstances(newInstance);
249 Map<String, ComponentInstance> newVfciNameMap = convertToVfciNameMap(newVfcInstances);
251 return oldVfcInstances.stream()
252 .filter(oldVfc -> oldCapabilitiesOwnerIds.contains(oldVfc.getUniqueId()))
253 .filter(oldVfci -> newVfciNameMap.containsKey(oldVfci.getName()))
254 .collect(Collectors.toMap(ComponentInstance::getUniqueId, oldVfci -> newVfciNameMap.get(oldVfci.getName()).getUniqueId()));