Catalog alignment
[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.Collection;
42 import java.util.HashMap;
43 import java.util.HashSet;
44 import java.util.List;
45 import java.util.Map;
46 import java.util.Objects;
47 import java.util.Set;
48 import java.util.stream.Collectors;
49
50 public class ForwardingPathUtils {
51
52     public static final String FORWARDING_PATH_NODE_NAME = "Forwarding Path";
53     public static final String FORWARDER_CAPABILITY = "org.openecomp.capabilities.Forwarder";
54
55
56     public ServiceRelations convertServiceToServiceRelations(Service service) {
57         ServiceRelations serviceRelations = new ServiceRelations();
58         List<ComponentInstance> componentInstances = service.getComponentInstances();
59         if (componentInstances == null || componentInstances.isEmpty()) {
60             return serviceRelations;
61         }
62         Set<NameIdPairWrapper> relations = new HashSet<>();
63         //@todo get all capabilities and requirements.
64         SetMultimap<NameIdPair, NameIdPair> nodeToCP = HashMultimap.create();
65         componentInstances.forEach(ci -> initNodeToCP(ci, nodeToCP));
66         handleRelDef(relations, nodeToCP);
67         serviceRelations.setRelations(relations);
68         return serviceRelations;
69     }
70
71     private void initNodeToCP(ComponentInstance ci, SetMultimap<NameIdPair, NameIdPair> nodeToCP) {
72         if (ci.getCapabilities() == null){
73             return;
74         }
75         Set<CapabilityDefinition> capabilities = ci.getCapabilities().values().stream().flatMap(Collection::stream).collect(Collectors.toSet());
76         if (!CollectionUtils.isNotEmpty(capabilities)) {
77             return;
78         }
79         Set<CapabilityDefinition> forwarderCapabilities = capabilities.stream().filter(capabilityDefinition -> capabilityDefinition.getType().equals(FORWARDER_CAPABILITY)).collect(Collectors.toSet());
80         if (!CollectionUtils.isNotEmpty(forwarderCapabilities)) {
81             return;
82         }
83         NameIdPair node = new NameIdPair(ci.getName(), ci.getName());
84         forwarderCapabilities.forEach(fc -> {
85             NameIdPair capability = new NameIdPair(fc.getName(), fc.getName(), fc.getOwnerId());
86             nodeToCP.put(node, capability);
87          });
88
89     }
90
91
92     private void handleRelDef(Set<NameIdPairWrapper> relations, SetMultimap<NameIdPair, NameIdPair> nodeToCP) {
93         nodeToCP.keySet().forEach(fromNode -> {
94             NameIdPairWrapper nameIdPairWrapper = new NameIdPairWrapper();
95             nameIdPairWrapper.init(fromNode);
96             if (!relations.contains(nameIdPairWrapper)) {
97                 relations.add(nameIdPairWrapper);
98                 Collection<NameIdPair> fromCps = nodeToCP.get(fromNode);
99                 fromCps.forEach(fromCP -> handleFromCp(nodeToCP, nameIdPairWrapper));
100             }
101         });
102
103     }
104
105     private void handleFromCp(SetMultimap<NameIdPair, NameIdPair> nodeToCP, NameIdPairWrapper wrapper) {
106         Map<NameIdPair, Set<NameIdPair>> options = toMap(nodeToCP);
107
108         Set<NameIdPair> cpOptions = options.get(wrapper.getNameIdPair());
109         List<NameIdPairWrapper> wrappers = cpOptions.stream().map(this::createWrapper).collect(Collectors.toList());
110         wrappers.forEach(cpOptionWrapper -> {
111             org.openecomp.sdc.be.datamodel.NameIdPair data = wrapper.getData();
112             data.addWrappedData(cpOptionWrapper);
113         });
114     }
115
116     private NameIdPairWrapper createWrapper(NameIdPair cpOption) {
117         NameIdPairWrapper nameIdPairWrapper = new NameIdPairWrapper();
118         nameIdPairWrapper.init(new NameIdPair(cpOption));
119         return nameIdPairWrapper;
120     }
121
122
123     private Map<NameIdPair, Set<NameIdPair>> toMap(SetMultimap<NameIdPair, NameIdPair> nodeToCP) {
124         Map<NameIdPair, Set<NameIdPair>> retVal = new HashMap<>();
125         nodeToCP.asMap().forEach((nameIdPair, nameIdPairs) -> retVal.put(nameIdPair, new HashSet<>(nameIdPairs)));
126         return retVal;
127     }
128
129
130     protected ResponseFormatManager getResponseFormatManager() {
131         return ResponseFormatManager.getInstance();
132     }
133
134     public Set<String> findForwardingPathNamesToDeleteOnComponentInstanceDeletion(Service containerService,
135         String componentInstanceId) {
136         return findForwardingPathToDeleteOnCIDeletion(containerService, componentInstanceId).values().stream()
137             .map(ForwardingPathDataDefinition::getName).collect(Collectors.toSet());
138     }
139
140     private Map<String, ForwardingPathDataDefinition> findForwardingPathToDeleteOnCIDeletion(Service containerService,
141         String componentInstanceId) {
142         return containerService.getForwardingPaths().entrySet().stream()
143             .filter(entry -> elementContainsCI(entry, componentInstanceId))
144             .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
145     }
146
147     private boolean elementContainsCI(Map.Entry<String, ForwardingPathDataDefinition> fpEntry,
148         String componentInstanceId) {
149         return fpEntry.getValue().getPathElements()
150             .getListToscaDataDefinition().stream()
151             .anyMatch(element -> elementContainsCI(element, componentInstanceId));
152     }
153
154     private boolean elementContainsCI(ForwardingPathElementDataDefinition elementDataDefinitions,
155         String componentInstanceId) {
156         return elementDataDefinitions.getFromNode().equals(componentInstanceId)
157             || elementDataDefinitions.getToNode().equals(componentInstanceId);
158     }
159
160     public Pair<Map<String, ForwardingPathDataDefinition>, Map<String, ForwardingPathDataDefinition>> updateForwardingPathOnVersionChange(
161         Service containerService, DataForMergeHolder dataHolder,
162         Component updatedContainerComponent, String newInstanceId) {
163         Map<String, ForwardingPathDataDefinition> updated = containerService.getForwardingPaths().entrySet().stream()
164             .filter(entry -> elementContainsCIAndForwarder(entry.getValue(), dataHolder.getOrigComponentInstId(), updatedContainerComponent))
165             .collect(Collectors.toMap(Map.Entry::getKey,
166                 entry ->  updateCI(entry.getValue(), dataHolder.getOrigComponentInstId(),newInstanceId)));
167         Map<String, ForwardingPathDataDefinition> deleted = containerService.getForwardingPaths().entrySet().stream()
168             .filter(entry -> elementContainsCIAndDoesNotContainForwarder(entry.getValue(),  dataHolder.getOrigComponentInstId(), updatedContainerComponent))
169             .collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
170         return new Pair<>(updated, deleted);
171     }
172
173     public Set<String> getForwardingPathsToBeDeletedOnVersionChange(
174         Service containerService, DataForMergeHolder dataHolder, Component updatedContainerComponent) {
175         return containerService.getForwardingPaths().entrySet().stream()
176           .filter(entry -> elementContainsCIAndDoesNotContainForwarder(entry.getValue(),
177               dataHolder.getOrigComponentInstId(), updatedContainerComponent))
178            .map(entry -> entry.getValue().getUniqueId()).collect( Collectors.toSet());
179     }
180
181     private ForwardingPathDataDefinition updateCI(ForwardingPathDataDefinition inFP, String oldCI, String newCI) {
182         ForwardingPathDataDefinition retVal = new ForwardingPathDataDefinition(inFP);
183         List<ForwardingPathElementDataDefinition> fpList = retVal.getPathElements().getListToscaDataDefinition()
184             .stream().map(element -> updateElement(element, oldCI, newCI)).collect(Collectors.toList());
185         retVal.setPathElements(new ListDataDefinition<>(fpList));
186         return retVal;
187     }
188
189     private ForwardingPathElementDataDefinition updateElement(ForwardingPathElementDataDefinition element, String oldCI,
190         String newCI) {
191         ForwardingPathElementDataDefinition retVal = new ForwardingPathElementDataDefinition(element);
192         if (retVal.getFromNode().equals(oldCI)) {
193             retVal.setFromNode(newCI);
194         }
195         if (retVal.getToNode().equals(oldCI)) {
196             retVal.setToNode(newCI);
197         }
198         if (Objects.equals(retVal.getToCPOriginId(),oldCI )) {
199             retVal.setToCPOriginId(newCI);
200         }
201         if (Objects.equals(retVal.getFromCPOriginId(),oldCI)) {
202             retVal.setFromCPOriginId(newCI);
203         }
204         return retVal;
205     }
206
207     private boolean elementContainsCIAndForwarder(ForwardingPathDataDefinition forwardingPathDataDefinition,
208         String oldCIId, Component newCI) {
209         return forwardingPathDataDefinition.getPathElements()
210             .getListToscaDataDefinition().stream()
211             .anyMatch(element -> elementContainsCIAndForwarder(element, oldCIId, newCI));
212     }
213
214     private boolean elementContainsCIAndForwarder(ForwardingPathElementDataDefinition elementDataDefinitions,
215         String oldCIId, Component newCI) {
216         return (elementDataDefinitions.getFromNode().equals(oldCIId) && ciContainsForwarder(newCI,
217             elementDataDefinitions.getFromCP()))
218             || (elementDataDefinitions.getToNode().equals(oldCIId) && ciContainsForwarder(newCI,
219             elementDataDefinitions.getToCP()));
220     }
221
222     private boolean ciContainsForwarder(Component newCI, String capabilityID) {
223         if (newCI.getCapabilities() == null){
224             return false;
225         }
226         return newCI.getCapabilities().values()
227             .stream()
228             .flatMap(List::stream)
229             .anyMatch(c -> c.getName().equals(capabilityID));
230     }
231
232     private boolean elementContainsCIAndDoesNotContainForwarder(
233         ForwardingPathDataDefinition forwardingPathDataDefinition,
234         String oldCIId, Component newCI) {
235         return forwardingPathDataDefinition.getPathElements()
236             .getListToscaDataDefinition().stream()
237             .anyMatch(element -> elementContainsCIAndDoesNotContainForwarder(element, oldCIId, newCI));
238     }
239
240     private boolean elementContainsCIAndDoesNotContainForwarder(
241         ForwardingPathElementDataDefinition elementDataDefinitions,
242         String oldCIId, Component newCI) {
243         return (elementDataDefinitions.getFromNode().equals(oldCIId) && !ciContainsForwarder(newCI,
244             elementDataDefinitions.getFromCP()))
245             || (elementDataDefinitions.getToNode().equals(oldCIId) && !ciContainsForwarder(newCI,
246             elementDataDefinitions.getToCP()));
247     }
248
249
250     public Set<ForwardingPathDataDefinition> updateComponentInstanceName(Collection<ForwardingPathDataDefinition> forwardingPathDataDefinitions,
251         String oldName, String newName){
252         return  forwardingPathDataDefinitions.stream().filter(fp -> shouldRenameCI(fp,oldName)).
253             map(forwardingPathDataDefinition -> renamePathCI(forwardingPathDataDefinition,oldName,newName))
254             .collect(Collectors.toSet());
255
256     }
257
258     public boolean shouldRenameCI(ForwardingPathDataDefinition forwardingPathDataDefinitions,
259         String oldName){
260         return forwardingPathDataDefinitions.getPathElements().getListToscaDataDefinition().stream()
261             .anyMatch(pe -> pe.getToNode().equals(oldName) || pe.getFromNode().equals(oldName));
262     }
263
264     public ForwardingPathDataDefinition renamePathCI(ForwardingPathDataDefinition forwardingPathDataDefinitions,
265         String oldName, String newName){
266         forwardingPathDataDefinitions.getPathElements().getListToscaDataDefinition().stream()
267             .forEach(pe -> renamePathCI(pe,oldName, newName));
268         return forwardingPathDataDefinitions;
269     }
270
271     public void renamePathCI(ForwardingPathElementDataDefinition pathElementDataDefinition,
272         String oldName, String newName){
273         if (pathElementDataDefinition.getFromNode().equals(oldName)){
274             pathElementDataDefinition.setFromNode(newName);
275         }
276         if(pathElementDataDefinition.getToNode().equals(oldName)){
277             pathElementDataDefinition.setToNode(newName);
278         }
279
280     }
281 }