Added oparent to sdc main
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / impl / ForwardingPathUtils.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.be.impl;
22
23
24 import com.google.common.collect.HashMultimap;
25 import com.google.common.collect.SetMultimap;
26 import org.apache.commons.collections.CollectionUtils;
27 import org.javatuples.Pair;
28 import org.openecomp.sdc.be.components.impl.ResponseFormatManager;
29 import org.openecomp.sdc.be.components.merge.instance.DataForMergeHolder;
30 import org.openecomp.sdc.be.datamodel.NameIdPair;
31 import org.openecomp.sdc.be.datamodel.NameIdPairWrapper;
32 import org.openecomp.sdc.be.datamodel.ServiceRelations;
33 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
34 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathElementDataDefinition;
35 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
36 import org.openecomp.sdc.be.model.CapabilityDefinition;
37 import org.openecomp.sdc.be.model.Component;
38 import org.openecomp.sdc.be.model.ComponentInstance;
39 import org.openecomp.sdc.be.model.Service;
40
41 import java.util.*;
42 import java.util.stream.Collectors;
43
44 public class ForwardingPathUtils {
45
46     public static final String FORWARDING_PATH_NODE_NAME = "Forwarding Path";
47     public static final String FORWARDER_CAPABILITY = "org.openecomp.capabilities.Forwarder";
48
49
50     public ServiceRelations convertServiceToServiceRelations(Service service) {
51         ServiceRelations serviceRelations = new ServiceRelations();
52         List<ComponentInstance> componentInstances = service.getComponentInstances();
53         if (componentInstances == null || componentInstances.isEmpty()) {
54             return serviceRelations;
55         }
56         Set<NameIdPairWrapper> relations = new HashSet<>();
57         //@todo get all capabilities and requirements.
58         SetMultimap<NameIdPair, NameIdPair> nodeToCP = HashMultimap.create();
59         componentInstances.forEach(ci -> initNodeToCP(ci, nodeToCP));
60         handleRelDef(relations, nodeToCP);
61         serviceRelations.setRelations(relations);
62         return serviceRelations;
63     }
64
65     private void initNodeToCP(ComponentInstance ci, SetMultimap<NameIdPair, NameIdPair> nodeToCP) {
66         if (ci.getCapabilities() == null){
67             return;
68         }
69         Set<CapabilityDefinition> capabilities = ci.getCapabilities().values().stream().flatMap(Collection::stream).collect(Collectors.toSet());
70         if (!CollectionUtils.isNotEmpty(capabilities)) {
71             return;
72         }
73         Set<CapabilityDefinition> forwarderCapabilities = capabilities.stream().filter(capabilityDefinition -> capabilityDefinition.getType().equals(FORWARDER_CAPABILITY)).collect(Collectors.toSet());
74         if (!CollectionUtils.isNotEmpty(forwarderCapabilities)) {
75             return;
76         }
77         NameIdPair node = new NameIdPair(ci.getName(), ci.getName());
78         forwarderCapabilities.forEach(fc -> {
79             NameIdPair capability = new NameIdPair(fc.getName(), fc.getName(), fc.getOwnerId());
80             nodeToCP.put(node, capability);
81          });
82
83     }
84
85
86     private void handleRelDef(Set<NameIdPairWrapper> relations, SetMultimap<NameIdPair, NameIdPair> nodeToCP) {
87         nodeToCP.keySet().forEach(fromNode -> {
88             NameIdPairWrapper nameIdPairWrapper = new NameIdPairWrapper();
89             nameIdPairWrapper.init(fromNode);
90             if (!relations.contains(nameIdPairWrapper)) {
91                 relations.add(nameIdPairWrapper);
92                 Collection<NameIdPair> fromCps = nodeToCP.get(fromNode);
93                 fromCps.forEach(fromCP -> handleFromCp(nodeToCP, nameIdPairWrapper));
94             }
95         });
96
97     }
98
99     private void handleFromCp(SetMultimap<NameIdPair, NameIdPair> nodeToCP, NameIdPairWrapper wrapper) {
100         Map<NameIdPair, Set<NameIdPair>> options = toMap(nodeToCP);
101
102         Set<NameIdPair> cpOptions = options.get(wrapper.getNameIdPair());
103         List<NameIdPairWrapper> wrappers = cpOptions.stream().map(this::createWrapper).collect(Collectors.toList());
104         wrappers.forEach(cpOptionWrapper -> {
105             org.openecomp.sdc.be.datamodel.NameIdPair data = wrapper.getData();
106             data.addWrappedData(cpOptionWrapper);
107         });
108     }
109
110     private NameIdPairWrapper createWrapper(NameIdPair cpOption) {
111         NameIdPairWrapper nameIdPairWrapper = new NameIdPairWrapper();
112         nameIdPairWrapper.init(new NameIdPair(cpOption));
113         return nameIdPairWrapper;
114     }
115
116
117     private Map<NameIdPair, Set<NameIdPair>> toMap(SetMultimap<NameIdPair, NameIdPair> nodeToCP) {
118         Map<NameIdPair, Set<NameIdPair>> retVal = new HashMap<>();
119         nodeToCP.asMap().forEach((nameIdPair, nameIdPairs) -> retVal.put(nameIdPair, new HashSet<>(nameIdPairs)));
120         return retVal;
121     }
122
123
124     protected ResponseFormatManager getResponseFormatManager() {
125         return ResponseFormatManager.getInstance();
126     }
127
128     public Set<String> findForwardingPathNamesToDeleteOnComponentInstanceDeletion(Service containerService,
129         String componentInstanceId) {
130         return findForwardingPathToDeleteOnCIDeletion(containerService, componentInstanceId).values().stream()
131             .map(ForwardingPathDataDefinition::getName).collect(Collectors.toSet());
132     }
133
134     private Map<String, ForwardingPathDataDefinition> findForwardingPathToDeleteOnCIDeletion(Service containerService,
135         String componentInstanceId) {
136         return containerService.getForwardingPaths().entrySet().stream()
137             .filter(entry -> elementContainsCI(entry, componentInstanceId))
138             .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
139     }
140
141     private boolean elementContainsCI(Map.Entry<String, ForwardingPathDataDefinition> fpEntry,
142         String componentInstanceId) {
143         return fpEntry.getValue().getPathElements()
144             .getListToscaDataDefinition().stream()
145             .anyMatch(element -> elementContainsCI(element, componentInstanceId));
146     }
147
148     private boolean elementContainsCI(ForwardingPathElementDataDefinition elementDataDefinitions,
149         String componentInstanceId) {
150         return elementDataDefinitions.getFromNode().equals(componentInstanceId)
151             || elementDataDefinitions.getToNode().equals(componentInstanceId);
152     }
153
154     public Pair<Map<String, ForwardingPathDataDefinition>, Map<String, ForwardingPathDataDefinition>> updateForwardingPathOnVersionChange(
155         Service containerService, DataForMergeHolder dataHolder,
156         Component updatedContainerComponent, String newInstanceId) {
157         Map<String, ForwardingPathDataDefinition> updated = containerService.getForwardingPaths().entrySet().stream()
158             .filter(entry -> elementContainsCIAndForwarder(entry.getValue(), dataHolder.getOrigComponentInstId(), updatedContainerComponent))
159             .collect(Collectors.toMap(Map.Entry::getKey,
160                 entry ->  updateCI(entry.getValue(), dataHolder.getOrigComponentInstId(),newInstanceId)));
161         Map<String, ForwardingPathDataDefinition> deleted = containerService.getForwardingPaths().entrySet().stream()
162             .filter(entry -> elementContainsCIAndDoesNotContainForwarder(entry.getValue(),  dataHolder.getOrigComponentInstId(), updatedContainerComponent))
163             .collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
164         return new Pair<>(updated, deleted);
165     }
166
167     public Set<String> getForwardingPathsToBeDeletedOnVersionChange(
168         Service containerService, DataForMergeHolder dataHolder, Component updatedContainerComponent) {
169         return containerService.getForwardingPaths().entrySet().stream()
170           .filter(entry -> elementContainsCIAndDoesNotContainForwarder(entry.getValue(),
171               dataHolder.getOrigComponentInstId(), updatedContainerComponent))
172            .map(entry -> entry.getValue().getUniqueId()).collect( Collectors.toSet());
173     }
174
175     private ForwardingPathDataDefinition updateCI(ForwardingPathDataDefinition inFP, String oldCI, String newCI) {
176         ForwardingPathDataDefinition retVal = new ForwardingPathDataDefinition(inFP);
177         List<ForwardingPathElementDataDefinition> fpList = retVal.getPathElements().getListToscaDataDefinition()
178             .stream().map(element -> updateElement(element, oldCI, newCI)).collect(Collectors.toList());
179         retVal.setPathElements(new ListDataDefinition<>(fpList));
180         return retVal;
181     }
182
183     private ForwardingPathElementDataDefinition updateElement(ForwardingPathElementDataDefinition element, String oldCI,
184         String newCI) {
185         ForwardingPathElementDataDefinition retVal = new ForwardingPathElementDataDefinition(element);
186         if (retVal.getFromNode().equals(oldCI)) {
187             retVal.setFromNode(newCI);
188         }
189         if (retVal.getToNode().equals(oldCI)) {
190             retVal.setToNode(newCI);
191         }
192         if (Objects.equals(retVal.getToCPOriginId(),oldCI )) {
193             retVal.setToCPOriginId(newCI);
194         }
195         if (Objects.equals(retVal.getFromCPOriginId(),oldCI)) {
196             retVal.setFromCPOriginId(newCI);
197         }
198         return retVal;
199     }
200
201     private boolean elementContainsCIAndForwarder(ForwardingPathDataDefinition forwardingPathDataDefinition,
202         String oldCIId, Component newCI) {
203         return forwardingPathDataDefinition.getPathElements()
204             .getListToscaDataDefinition().stream()
205             .anyMatch(element -> elementContainsCIAndForwarder(element, oldCIId, newCI));
206     }
207
208     private boolean elementContainsCIAndForwarder(ForwardingPathElementDataDefinition elementDataDefinitions,
209         String oldCIId, Component newCI) {
210         return (elementDataDefinitions.getFromNode().equals(oldCIId) && ciContainsForwarder(newCI,
211             elementDataDefinitions.getFromCP()))
212             || (elementDataDefinitions.getToNode().equals(oldCIId) && ciContainsForwarder(newCI,
213             elementDataDefinitions.getToCP()));
214     }
215
216     private boolean ciContainsForwarder(Component newCI, String capabilityID) {
217         if (newCI.getCapabilities() == null){
218             return false;
219         }
220         return newCI.getCapabilities().values()
221             .stream()
222             .flatMap(List::stream)
223             .anyMatch(c -> c.getName().equals(capabilityID));
224     }
225
226     private boolean elementContainsCIAndDoesNotContainForwarder(
227         ForwardingPathDataDefinition forwardingPathDataDefinition,
228         String oldCIId, Component newCI) {
229         return forwardingPathDataDefinition.getPathElements()
230             .getListToscaDataDefinition().stream()
231             .anyMatch(element -> elementContainsCIAndDoesNotContainForwarder(element, oldCIId, newCI));
232     }
233
234     private boolean elementContainsCIAndDoesNotContainForwarder(
235         ForwardingPathElementDataDefinition elementDataDefinitions,
236         String oldCIId, Component newCI) {
237         return (elementDataDefinitions.getFromNode().equals(oldCIId) && !ciContainsForwarder(newCI,
238             elementDataDefinitions.getFromCP()))
239             || (elementDataDefinitions.getToNode().equals(oldCIId) && !ciContainsForwarder(newCI,
240             elementDataDefinitions.getToCP()));
241     }
242
243
244     public Set<ForwardingPathDataDefinition> updateComponentInstanceName(Collection<ForwardingPathDataDefinition> forwardingPathDataDefinitions,
245         String oldName, String newName){
246         return  forwardingPathDataDefinitions.stream().filter(fp -> shouldRenameCI(fp,oldName)).
247             map(forwardingPathDataDefinition -> renamePathCI(forwardingPathDataDefinition,oldName,newName))
248             .collect(Collectors.toSet());
249
250     }
251
252     public boolean shouldRenameCI(ForwardingPathDataDefinition forwardingPathDataDefinitions,
253         String oldName){
254         return forwardingPathDataDefinitions.getPathElements().getListToscaDataDefinition().stream()
255             .anyMatch(pe -> pe.getToNode().equals(oldName) || pe.getFromNode().equals(oldName));
256     }
257
258     public ForwardingPathDataDefinition renamePathCI(ForwardingPathDataDefinition forwardingPathDataDefinitions,
259         String oldName, String newName){
260         forwardingPathDataDefinitions.getPathElements().getListToscaDataDefinition().stream()
261             .forEach(pe -> renamePathCI(pe,oldName, newName));
262         return forwardingPathDataDefinitions;
263     }
264
265     public void renamePathCI(ForwardingPathElementDataDefinition pathElementDataDefinition,
266         String oldName, String newName){
267         if (pathElementDataDefinition.getFromNode().equals(oldName)){
268             pathElementDataDefinition.setFromNode(newName);
269         }
270         if(pathElementDataDefinition.getToNode().equals(oldName)){
271             pathElementDataDefinition.setToNode(newName);
272         }
273
274     }
275 }