Sync Integ to Master
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / impl / ForwardingPathUtils.java
1 package org.openecomp.sdc.be.impl;
2
3 import com.google.common.collect.HashMultimap;
4 import com.google.common.collect.SetMultimap;
5 import java.util.Collection;
6 import java.util.HashMap;
7 import java.util.HashSet;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.Objects;
11 import java.util.Set;
12 import java.util.stream.Collectors;
13 import org.apache.commons.collections.CollectionUtils;
14 import org.javatuples.Pair;
15 import org.openecomp.sdc.be.components.impl.ResponseFormatManager;
16 import org.openecomp.sdc.be.components.merge.instance.DataForMergeHolder;
17 import org.openecomp.sdc.be.datamodel.NameIdPair;
18 import org.openecomp.sdc.be.datamodel.NameIdPairWrapper;
19 import org.openecomp.sdc.be.datamodel.ServiceRelations;
20 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
21 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathElementDataDefinition;
22 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
23 import org.openecomp.sdc.be.model.CapabilityDefinition;
24 import org.openecomp.sdc.be.model.Component;
25 import org.openecomp.sdc.be.model.ComponentInstance;
26 import org.openecomp.sdc.be.model.Service;
27
28 public class ForwardingPathUtils {
29
30     public static final String FORWARDING_PATH_NODE_NAME = "Forwarding Path";
31     public static final String FORWARDER_CAPABILITY = "org.openecomp.capabilities.Forwarder";
32
33
34     public ServiceRelations convertServiceToServiceRelations(Service service) {
35         ServiceRelations serviceRelations = new ServiceRelations();
36         List<ComponentInstance> componentInstances = service.getComponentInstances();
37         if (componentInstances == null || componentInstances.isEmpty()) {
38             return serviceRelations;
39         }
40         Set<NameIdPairWrapper> relations = new HashSet<>();
41         //@todo get all capabilities and requirements.
42         SetMultimap<NameIdPair, NameIdPair> nodeToCP = HashMultimap.create();
43         componentInstances.forEach(ci -> initNodeToCP(ci, nodeToCP));
44         handleRelDef(relations, nodeToCP);
45         serviceRelations.setRelations(relations);
46         return serviceRelations;
47     }
48
49     private void initNodeToCP(ComponentInstance ci, SetMultimap<NameIdPair, NameIdPair> nodeToCP) {
50         Set<CapabilityDefinition> capabilities = ci.getCapabilities().values().stream().flatMap(capabilityDefinitions -> capabilityDefinitions.stream()).collect(Collectors.toSet());
51         if (!CollectionUtils.isNotEmpty(capabilities)) {
52             return;
53         }
54         Set<CapabilityDefinition> forwarderCapabilities = capabilities.stream().filter(capabilityDefinition -> capabilityDefinition.getType().equals(FORWARDER_CAPABILITY)).collect(Collectors.toSet());
55         if (!CollectionUtils.isNotEmpty(forwarderCapabilities)) {
56             return;
57         }
58         NameIdPair node = new NameIdPair(ci.getName(), ci.getUniqueId());
59         forwarderCapabilities.forEach(fc -> {
60             NameIdPair capability = new NameIdPair(fc.getName(), fc.getUniqueId(), fc.getOwnerId());
61             nodeToCP.put(node, capability);
62
63         });
64
65     }
66
67
68     private void handleRelDef(Set<NameIdPairWrapper> relations, SetMultimap<NameIdPair, NameIdPair> nodeToCP) {
69         nodeToCP.keySet().forEach(fromNode -> {
70             NameIdPairWrapper nameIdPairWrapper = new NameIdPairWrapper();
71             nameIdPairWrapper.init(fromNode);
72             if (!relations.contains(nameIdPairWrapper)) {
73                 relations.add(nameIdPairWrapper);
74                 Collection<NameIdPair> fromCps = nodeToCP.get(fromNode);
75                 fromCps.forEach(fromCP -> handleFromCp(nodeToCP, nameIdPairWrapper));
76             }
77         });
78
79     }
80
81     private void handleFromCp(SetMultimap<NameIdPair, NameIdPair> nodeToCP, NameIdPairWrapper wrapper) {
82         Map<NameIdPair, Set<NameIdPair>> options = toMap(nodeToCP);
83
84         Set<NameIdPair> cpOptions = options.get(wrapper.getNameIdPair());
85         List<NameIdPairWrapper> wrappers = cpOptions.stream().map(cpOption -> createWrapper(cpOption)).collect(Collectors.toList());
86         wrappers.forEach(cpOptionWrapper -> {
87             org.openecomp.sdc.be.datamodel.NameIdPair data = wrapper.getData();
88             data.addWrappedData(cpOptionWrapper);
89         });
90         addNodes(wrappers, options);
91     }
92
93     private void addNodes(List<NameIdPairWrapper> cpOptions, Map<NameIdPair, Set<NameIdPair>> options) {
94
95         cpOptions.forEach(cpOption -> {
96             Set<NameIdPairWrapper> wrappers = options.keySet().stream().map(option -> createWrapper(option)).collect(Collectors.toSet());
97             wrappers.forEach(wrapper -> {
98                 cpOption.getData().addWrappedData(wrapper);
99                 Collection<NameIdPair> cps = options.get(wrapper.getNameIdPair());
100                 Set<NameIdPairWrapper> cpsWrappers = cps.stream().map(cp -> new NameIdPairWrapper(cp)).collect(Collectors.toSet());
101                 cpsWrappers.forEach(cpw -> {
102                     NameIdPair data = wrapper.getData();
103                     if (!data.containsKey(cpw)) {
104                         data.addWrappedData(cpw);
105                     }
106                 });
107             });
108
109         });
110     }
111
112     private NameIdPairWrapper createWrapper(NameIdPair cpOption) {
113         NameIdPairWrapper nameIdPairWrapper = new NameIdPairWrapper();
114         nameIdPairWrapper.init(new NameIdPair(cpOption));
115         return nameIdPairWrapper;
116     }
117
118
119     private Map<NameIdPair, Set<NameIdPair>> toMap(SetMultimap<NameIdPair, NameIdPair> nodeToCP) {
120         Map<NameIdPair, Set<NameIdPair>> retVal = new HashMap<>();
121         nodeToCP.asMap().forEach((nameIdPair, nameIdPairs) -> retVal.put(nameIdPair, new HashSet<>(nameIdPairs)));
122         return retVal;
123     }
124
125
126     protected ResponseFormatManager getResponseFormatManager() {
127         return ResponseFormatManager.getInstance();
128     }
129
130     public Set<String> findForwardingPathNamesToDeleteOnComponentInstanceDeletion(Service containerService,
131         String componentInstanceId) {
132         return findForwardingPathToDeleteOnCIDeletion(containerService, componentInstanceId).values().stream()
133             .map(ForwardingPathDataDefinition::getName).collect(Collectors.toSet());
134     }
135
136     private Map<String, ForwardingPathDataDefinition> findForwardingPathToDeleteOnCIDeletion(Service containerService,
137         String componentInstanceId) {
138         return containerService.getForwardingPaths().entrySet().stream()
139             .filter(entry -> elementContainsCI(entry, componentInstanceId))
140             .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
141     }
142
143     private boolean elementContainsCI(Map.Entry<String, ForwardingPathDataDefinition> fpEntry,
144         String componentInstanceId) {
145         return fpEntry.getValue().getPathElements()
146             .getListToscaDataDefinition().stream()
147             .anyMatch(element -> elementContainsCI(element, componentInstanceId));
148     }
149
150     private boolean elementContainsCI(ForwardingPathElementDataDefinition elementDataDefinitions,
151         String componentInstanceId) {
152         return elementDataDefinitions.getFromNode().equals(componentInstanceId)
153             || elementDataDefinitions.getToNode().equals(componentInstanceId);
154     }
155
156     public Pair<Map<String, ForwardingPathDataDefinition>, Map<String, ForwardingPathDataDefinition>> updateForwardingPathOnVersionChange(
157         Service containerService, DataForMergeHolder dataHolder,
158         Component updatedContainerComponent, String newInstanceId) {
159         Map<String, ForwardingPathDataDefinition> updated = containerService.getForwardingPaths().entrySet().stream()
160             .filter(entry -> elementContainsCIAndForwarder(entry.getValue(), dataHolder.getOrigComponentInstId(), updatedContainerComponent))
161             .collect(Collectors.toMap(Map.Entry::getKey,
162                 entry ->  updateCI(entry.getValue(), dataHolder.getOrigComponentInstId(),newInstanceId)));
163         Map<String, ForwardingPathDataDefinition> deleted = containerService.getForwardingPaths().entrySet().stream()
164             .filter(entry -> elementContainsCIAndDoesNotContainForwarder(entry.getValue(),  dataHolder.getOrigComponentInstId(), updatedContainerComponent))
165             .collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
166         return new Pair<>(updated, deleted);
167     }
168
169     public Set<String> getForwardingPathsToBeDeletedOnVersionChange(
170         Service containerService, DataForMergeHolder dataHolder, Component updatedContainerComponent) {
171         return containerService.getForwardingPaths().entrySet().stream()
172           .filter(entry -> elementContainsCIAndDoesNotContainForwarder(entry.getValue(),
173               dataHolder.getOrigComponentInstId(), updatedContainerComponent))
174            .map(entry -> entry.getValue().getUniqueId()).collect( Collectors.toSet());
175     }
176
177     private ForwardingPathDataDefinition updateCI(ForwardingPathDataDefinition inFP, String oldCI, String newCI) {
178         ForwardingPathDataDefinition retVal = new ForwardingPathDataDefinition(inFP);
179         List<ForwardingPathElementDataDefinition> fpList = retVal.getPathElements().getListToscaDataDefinition()
180             .stream().map(element -> updateElement(element, oldCI, newCI)).collect(Collectors.toList());
181         retVal.setPathElements(new ListDataDefinition<>(fpList));
182         return retVal;
183     }
184
185     private ForwardingPathElementDataDefinition updateElement(ForwardingPathElementDataDefinition element, String oldCI,
186         String newCI) {
187         ForwardingPathElementDataDefinition retVal = new ForwardingPathElementDataDefinition(element);
188         if (retVal.getFromNode().equals(oldCI)) {
189             retVal.setFromNode(newCI);
190         }
191         if (retVal.getToNode().equals(oldCI)) {
192             retVal.setToNode(newCI);
193         }
194         if (Objects.equals(retVal.getToCPOriginId(),oldCI )) {
195             retVal.setToCPOriginId(newCI);
196         }
197         if (Objects.equals(retVal.getFromCPOriginId(),oldCI)) {
198             retVal.setFromCPOriginId(newCI);
199         }
200         return retVal;
201     }
202
203     private boolean elementContainsCIAndForwarder(ForwardingPathDataDefinition forwardingPathDataDefinition,
204         String oldCIId, Component newCI) {
205         return forwardingPathDataDefinition.getPathElements()
206             .getListToscaDataDefinition().stream()
207             .anyMatch(element -> elementContainsCIAndForwarder(element, oldCIId, newCI));
208     }
209
210     private boolean elementContainsCIAndForwarder(ForwardingPathElementDataDefinition elementDataDefinitions,
211         String oldCIId, Component newCI) {
212         return (elementDataDefinitions.getFromNode().equals(oldCIId) && ciContainsForwarder(newCI,
213             elementDataDefinitions.getFromCP()))
214             || (elementDataDefinitions.getToNode().equals(oldCIId) && ciContainsForwarder(newCI,
215             elementDataDefinitions.getToCP()));
216     }
217
218     private boolean ciContainsForwarder(Component newCI, String capabilityID) {
219         if (newCI.getCapabilities() == null){
220             return false;
221         }
222         return newCI.getCapabilities().values()
223             .stream()
224             .flatMap(List::stream)
225             .anyMatch(c -> c.getUniqueId().equals(capabilityID));
226     }
227
228     private boolean elementContainsCIAndDoesNotContainForwarder(
229         ForwardingPathDataDefinition forwardingPathDataDefinition,
230         String oldCIId, Component newCI) {
231         return forwardingPathDataDefinition.getPathElements()
232             .getListToscaDataDefinition().stream()
233             .anyMatch(element -> elementContainsCIAndDoesNotContainForwarder(element, oldCIId, newCI));
234     }
235
236     private boolean elementContainsCIAndDoesNotContainForwarder(
237         ForwardingPathElementDataDefinition elementDataDefinitions,
238         String oldCIId, Component newCI) {
239         return (elementDataDefinitions.getFromNode().equals(oldCIId) && !ciContainsForwarder(newCI,
240             elementDataDefinitions.getFromCP()))
241             || (elementDataDefinitions.getToNode().equals(oldCIId) && !ciContainsForwarder(newCI,
242             elementDataDefinitions.getToCP()));
243     }
244 }