Merge "Fix Relationship update b/w core NSSI and its Sliceprofile"
[so.git] / bpmn / so-bpmn-tasks / src / main / java / org / onap / so / bpmn / infrastructure / workflow / tasks / ebb / loader / ServiceEBBLoader.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (c) 2020 Nokia
6  * ================================================================================
7  * Modifications Copyright (c) 2021 Orange
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.bpmn.infrastructure.workflow.tasks.ebb.loader;
24
25 import com.fasterxml.jackson.core.JsonProcessingException;
26 import org.camunda.bpm.engine.delegate.DelegateExecution;
27 import org.javatuples.Pair;
28 import org.onap.aai.domain.yang.Relationship;
29 import org.onap.aai.domain.yang.ServiceInstance;
30 import org.onap.aai.domain.yang.VpnBinding;
31 import org.onap.aaiclient.client.aai.AAICommonObjectMapperProvider;
32 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper;
33 import org.onap.aaiclient.client.aai.entities.Relationships;
34 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder;
35 import org.onap.so.bpmn.infrastructure.workflow.tasks.Resource;
36 import org.onap.so.bpmn.infrastructure.workflow.tasks.VrfBondingServiceException;
37 import org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowType;
38 import org.onap.so.bpmn.servicedecomposition.bbobjects.Configuration;
39 import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule;
40 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetup;
41 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetupUtils;
42 import org.onap.so.client.exception.ExceptionBuilder;
43 import org.onap.so.client.orchestration.AAIConfigurationResources;
44 import org.onap.so.db.catalog.beans.CollectionNetworkResourceCustomization;
45 import org.onap.so.db.catalog.beans.CollectionResourceCustomization;
46 import org.onap.so.db.catalog.beans.CollectionResourceInstanceGroupCustomization;
47 import org.onap.so.db.catalog.beans.InstanceGroup;
48 import org.onap.so.db.catalog.client.CatalogDbClient;
49 import org.onap.so.serviceinstancebeans.ModelType;
50 import org.onap.so.serviceinstancebeans.RelatedInstance;
51 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54 import org.springframework.stereotype.Component;
55 import java.io.IOException;
56 import java.util.ArrayList;
57 import java.util.List;
58 import java.util.Map;
59 import java.util.Optional;
60 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.ACTIVATE_INSTANCE;
61 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.DEACTIVATE_INSTANCE;
62 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.DELETE_INSTANCE;
63 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.UNASSIGN_INSTANCE;
64 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.UPGRADE_INSTANCE;
65 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.WORKFLOW_ACTION_ERROR_MESSAGE;
66 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.CREATE_INSTANCE;
67 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.FABRIC_CONFIGURATION;
68 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.NETWORKCOLLECTION;
69 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.USER_PARAM_SERVICE;
70 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.ASSIGN_INSTANCE;
71
72
73 @Component
74 public class ServiceEBBLoader {
75
76     private static final Logger logger = LoggerFactory.getLogger(ServiceEBBLoader.class);
77
78     private final UserParamsServiceTraversal userParamsServiceTraversal;
79     private final CatalogDbClient catalogDbClient;
80     private final VrfValidation vrfValidation;
81     private final AAIConfigurationResources aaiConfigurationResources;
82     private final WorkflowActionExtractResourcesAAI workflowActionUtils;
83     private final BBInputSetupUtils bbInputSetupUtils;
84     private final BBInputSetup bbInputSetup;
85     private final ExceptionBuilder exceptionBuilder;
86
87     public ServiceEBBLoader(UserParamsServiceTraversal userParamsServiceTraversal, CatalogDbClient catalogDbClient,
88             VrfValidation vrfValidation, AAIConfigurationResources aaiConfigurationResources,
89             WorkflowActionExtractResourcesAAI workflowActionUtils, BBInputSetupUtils bbInputSetupUtils,
90             BBInputSetup bbInputSetup, ExceptionBuilder exceptionBuilder) {
91         this.userParamsServiceTraversal = userParamsServiceTraversal;
92         this.catalogDbClient = catalogDbClient;
93         this.vrfValidation = vrfValidation;
94         this.aaiConfigurationResources = aaiConfigurationResources;
95         this.workflowActionUtils = workflowActionUtils;
96         this.bbInputSetupUtils = bbInputSetupUtils;
97         this.bbInputSetup = bbInputSetup;
98         this.exceptionBuilder = exceptionBuilder;
99     }
100
101     public List<Resource> getResourceListForService(ServiceInstancesRequest sIRequest, String requestAction,
102             DelegateExecution execution, String serviceInstanceId, String resourceId,
103             List<Pair<WorkflowType, String>> aaiResourceIds) throws IOException, VrfBondingServiceException {
104         boolean containsService = false;
105         List<Resource> resourceList = new ArrayList<>();
106         List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
107         if (requestAction.equalsIgnoreCase(ASSIGN_INSTANCE)) {
108             // SERVICE-MACRO-ASSIGN will always get user params with a
109             // service.
110
111             if (userParams != null) {
112                 containsService = isContainsService(sIRequest);
113                 if (containsService) {
114                     resourceList = userParamsServiceTraversal.getResourceListFromUserParams(execution, userParams,
115                             serviceInstanceId, requestAction);
116                 }
117             } else {
118                 buildAndThrowException(execution,
119                         "Service-Macro-Assign request details must contain user params with a service");
120             }
121         } else if (requestAction.equalsIgnoreCase(CREATE_INSTANCE)) {
122             // SERVICE-MACRO-CREATE will get user params with a service,
123             // a service with a network, a service with a
124             // network collection, OR an empty service.
125             // If user params is just a service or null and macro
126             // queries the SI and finds a VNF, macro fails.
127
128             if (userParams != null) {
129                 containsService = isContainsService(sIRequest);
130             }
131             if (containsService) {
132                 resourceList = userParamsServiceTraversal.getResourceListFromUserParams(execution, userParams,
133                         serviceInstanceId, requestAction);
134             }
135             if (!foundRelated(resourceList)) {
136                 traverseCatalogDbService(execution, sIRequest, resourceList, aaiResourceIds);
137             }
138         } else if ((ACTIVATE_INSTANCE.equalsIgnoreCase(requestAction)
139                 || UNASSIGN_INSTANCE.equalsIgnoreCase(requestAction) || DELETE_INSTANCE.equalsIgnoreCase(requestAction)
140                 || UPGRADE_INSTANCE.equalsIgnoreCase(requestAction)
141                 || requestAction.equalsIgnoreCase("activate" + FABRIC_CONFIGURATION))) {
142             // SERVICE-MACRO-ACTIVATE, SERVICE-MACRO-UNASSIGN, and
143             // SERVICE-MACRO-DELETE
144             // Will never get user params with service, macro will have
145             // to query the SI in AAI to find related instances.
146             traverseAAIService(execution, resourceList, resourceId, aaiResourceIds);
147         } else if (DEACTIVATE_INSTANCE.equalsIgnoreCase(requestAction)) {
148             resourceList.add(new Resource(WorkflowType.SERVICE, "", false, null));
149         }
150         return resourceList;
151     }
152
153     private boolean isContainsService(ServiceInstancesRequest sIRequest) {
154         boolean containsService;
155         List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
156         containsService = userParams.stream().anyMatch(param -> param.containsKey(USER_PARAM_SERVICE));
157         return containsService;
158     }
159
160     public void traverseCatalogDbService(DelegateExecution execution, ServiceInstancesRequest sIRequest,
161             List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds)
162             throws JsonProcessingException, VrfBondingServiceException {
163         String modelUUID = sIRequest.getRequestDetails().getModelInfo().getModelVersionId();
164         org.onap.so.db.catalog.beans.Service service = catalogDbClient.getServiceByID(modelUUID);
165
166         if (service == null) {
167             buildAndThrowException(execution, "Could not find the service model in catalog db.");
168         } else {
169             Resource serviceResource = new Resource(WorkflowType.SERVICE, service.getModelUUID(), false, null);
170             resourceList.add(serviceResource);
171             RelatedInstance relatedVpnBinding =
172                     bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.vpnBinding);
173             RelatedInstance relatedLocalNetwork =
174                     bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.network);
175
176             if (relatedVpnBinding != null && relatedLocalNetwork != null) {
177                 traverseVrfConfiguration(aaiResourceIds, resourceList, serviceResource, service, relatedVpnBinding,
178                         relatedLocalNetwork);
179             } else {
180                 traverseNetworkCollection(execution, resourceList, serviceResource, service);
181             }
182         }
183     }
184
185     public boolean foundRelated(List<Resource> resourceList) {
186         return (containsWorkflowType(resourceList, WorkflowType.VNF)
187                 || containsWorkflowType(resourceList, WorkflowType.PNF)
188                 || containsWorkflowType(resourceList, WorkflowType.NETWORK)
189                 || containsWorkflowType(resourceList, WorkflowType.NETWORKCOLLECTION));
190     }
191
192     public void traverseAAIService(DelegateExecution execution, List<Resource> resourceList, String resourceId,
193             List<Pair<WorkflowType, String>> aaiResourceIds) {
194         try {
195             ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(resourceId);
196             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
197                     bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
198             var serviceResource =
199                     new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false, null);
200             serviceResource.setModelInvariantId(serviceInstanceAAI.getModelInvariantId());
201             resourceList.add(serviceResource);
202             traverseServiceInstanceMSOVnfs(resourceList, serviceResource, aaiResourceIds, serviceInstanceMSO);
203             traverseServiceInstanceMSOPnfs(resourceList, serviceResource, aaiResourceIds, serviceInstanceMSO);
204             if (serviceInstanceMSO.getNetworks() != null) {
205                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network network : serviceInstanceMSO
206                         .getNetworks()) {
207                     aaiResourceIds.add(new Pair<>(WorkflowType.NETWORK, network.getNetworkId()));
208                     resourceList
209                             .add(new Resource(WorkflowType.NETWORK, network.getNetworkId(), false, serviceResource));
210                 }
211             }
212             if (serviceInstanceMSO.getCollection() != null) {
213                 logger.debug("found networkcollection");
214                 aaiResourceIds
215                         .add(new Pair<>(WorkflowType.NETWORKCOLLECTION, serviceInstanceMSO.getCollection().getId()));
216                 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
217                         serviceInstanceMSO.getCollection().getId(), false, serviceResource));
218             }
219             if (serviceInstanceMSO.getConfigurations() != null) {
220                 for (Configuration config : serviceInstanceMSO.getConfigurations()) {
221                     Optional<org.onap.aai.domain.yang.Configuration> aaiConfig =
222                             aaiConfigurationResources.getConfiguration(config.getConfigurationId());
223                     if (aaiConfig.isPresent() && aaiConfig.get().getRelationshipList() != null) {
224                         for (Relationship relationship : aaiConfig.get().getRelationshipList().getRelationship()) {
225                             if (relationship.getRelatedTo().contains("vnfc")
226                                     || relationship.getRelatedTo().contains("vpn-binding")) {
227                                 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.getConfigurationId()));
228                                 resourceList.add(new Resource(WorkflowType.CONFIGURATION, config.getConfigurationId(),
229                                         false, serviceResource));
230                                 break;
231                             }
232                         }
233                     }
234                 }
235             }
236         } catch (Exception ex) {
237             logger.error("Exception in traverseAAIService", ex);
238             buildAndThrowException(execution,
239                     "Could not find existing Service Instance or related Instances to execute the request on.");
240         }
241     }
242
243     private void traverseServiceInstanceMSOVnfs(List<Resource> resourceList, Resource serviceResource,
244             List<Pair<WorkflowType, String>> aaiResourceIds,
245             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO) {
246         if (serviceInstanceMSO.getVnfs() == null) {
247             return;
248         }
249         for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
250             aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
251             Resource vnfResource = new Resource(WorkflowType.VNF, vnf.getVnfId(), false, serviceResource);
252             resourceList.add(vnfResource);
253             traverseVnfModules(resourceList, vnfResource, aaiResourceIds, vnf);
254             if (vnf.getVolumeGroups() != null) {
255                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf.getVolumeGroups()) {
256                     aaiResourceIds.add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
257                     resourceList.add(
258                             new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false, vnfResource));
259                 }
260             }
261         }
262     }
263
264     private void traverseServiceInstanceMSOPnfs(List<Resource> resourceList, Resource serviceResource,
265             List<Pair<WorkflowType, String>> aaiResourceIds,
266             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO) {
267         if (serviceInstanceMSO.getPnfs() == null) {
268             return;
269         }
270         for (org.onap.so.bpmn.servicedecomposition.bbobjects.Pnf pnf : serviceInstanceMSO.getPnfs()) {
271             aaiResourceIds.add(new Pair<>(WorkflowType.PNF, pnf.getPnfId()));
272             resourceList.add(new Resource(WorkflowType.PNF, pnf.getPnfId(), false, serviceResource));
273         }
274     }
275
276     protected void traverseVrfConfiguration(List<Pair<WorkflowType, String>> aaiResourceIds,
277             List<Resource> resourceList, Resource serviceResource, org.onap.so.db.catalog.beans.Service service,
278             RelatedInstance relatedVpnBinding, RelatedInstance relatedLocalNetwork)
279             throws VrfBondingServiceException, JsonProcessingException {
280         org.onap.aai.domain.yang.L3Network aaiLocalNetwork =
281                 bbInputSetupUtils.getAAIL3Network(relatedLocalNetwork.getInstanceId());
282         vrfValidation.vrfServiceValidation(service);
283         vrfValidation.vrfCatalogDbChecks(service);
284         vrfValidation.aaiVpnBindingValidation(relatedVpnBinding.getInstanceId(),
285                 bbInputSetupUtils.getAAIVpnBinding(relatedVpnBinding.getInstanceId()));
286         vrfValidation.aaiNetworkValidation(relatedLocalNetwork.getInstanceId(), aaiLocalNetwork);
287         vrfValidation.aaiSubnetValidation(aaiLocalNetwork);
288         vrfValidation.aaiAggregateRouteValidation(aaiLocalNetwork);
289         vrfValidation.aaiRouteTargetValidation(aaiLocalNetwork);
290         String existingAAIVrfConfiguration = getExistingAAIVrfConfiguration(relatedVpnBinding, aaiLocalNetwork);
291         if (existingAAIVrfConfiguration != null) {
292             aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, existingAAIVrfConfiguration));
293         }
294         resourceList.add(new Resource(WorkflowType.CONFIGURATION,
295                 service.getConfigurationCustomizations().get(0).getModelCustomizationUUID(), false, serviceResource));
296
297     }
298
299     protected void traverseNetworkCollection(DelegateExecution execution, List<Resource> resourceList,
300             Resource serviceResource, org.onap.so.db.catalog.beans.Service service) {
301         if (isVnfCustomizationsInTheService(service)) {
302             buildAndThrowException(execution,
303                     "Cannot orchestrate Service-Macro-Create without user params with a vnf. Please update ASDC model for new macro orchestration support or add service_recipe records to route to old macro flows");
304         }
305         if (isPnfCustomizationsInTheService(service)) {
306             buildAndThrowException(execution,
307                     "Cannot orchestrate Service-Macro-Create without user params with a pnf. Please update ASDC model for new macro orchestration support or add service_recipe records to route to old macro flows");
308         }
309         List<CollectionResourceCustomization> customizations = service.getCollectionResourceCustomizations();
310         if (customizations.isEmpty()) {
311             logger.debug("No Collections found. CollectionResourceCustomization list is empty.");
312         } else {
313             CollectionResourceCustomization collectionResourceCustomization =
314                     findCatalogNetworkCollection(execution, service);
315             traverseNetworkCollectionResourceCustomization(resourceList, serviceResource,
316                     collectionResourceCustomization);
317         }
318         traverseNetworkCollectionCustomization(resourceList, serviceResource, service);
319     }
320
321     private void traverseNetworkCollectionResourceCustomization(List<Resource> resourceList, Resource serviceResource,
322             CollectionResourceCustomization collectionResourceCustomization) {
323         if (collectionResourceCustomizationShouldNotBeProcessed(resourceList, serviceResource,
324                 collectionResourceCustomization))
325             return;
326         int minNetworks = 0;
327         org.onap.so.db.catalog.beans.InstanceGroup instanceGroup =
328                 collectionResourceCustomization.getCollectionResource().getInstanceGroup();
329         CollectionResourceInstanceGroupCustomization collectionInstCust = null;
330         if (!instanceGroup.getCollectionInstanceGroupCustomizations().isEmpty()) {
331             for (CollectionResourceInstanceGroupCustomization collectionInstanceGroupTemp : instanceGroup
332                     .getCollectionInstanceGroupCustomizations()) {
333                 if (collectionInstanceGroupTemp.getModelCustomizationUUID()
334                         .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
335                     collectionInstCust = collectionInstanceGroupTemp;
336                     break;
337                 }
338             }
339             if (interfaceNetworkQuantityIsAvailableInCollection(collectionInstCust)) {
340                 minNetworks = collectionInstCust.getSubInterfaceNetworkQuantity();
341             }
342         }
343         logger.debug("minNetworks: {}", minNetworks);
344         CollectionNetworkResourceCustomization collectionNetworkResourceCust =
345                 getCollectionNetworkResourceCustomization(collectionResourceCustomization, instanceGroup);
346         for (int i = 0; i < minNetworks; i++) {
347             if (collectionNetworkResourceCust != null) {
348                 Resource resource = new Resource(WorkflowType.VIRTUAL_LINK,
349                         collectionNetworkResourceCust.getModelCustomizationUUID(), false, serviceResource);
350                 resource.setVirtualLinkKey(Integer.toString(i));
351                 resourceList.add(resource);
352             }
353         }
354     }
355
356     private CollectionNetworkResourceCustomization getCollectionNetworkResourceCustomization(
357             CollectionResourceCustomization collectionResourceCustomization, InstanceGroup instanceGroup) {
358         CollectionNetworkResourceCustomization collectionNetworkResourceCust = null;
359         for (CollectionNetworkResourceCustomization collectionNetworkTemp : instanceGroup
360                 .getCollectionNetworkResourceCustomizations()) {
361             if (collectionNetworkTemp.getNetworkResourceCustomization().getModelCustomizationUUID()
362                     .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
363                 collectionNetworkResourceCust = collectionNetworkTemp;
364                 break;
365             }
366         }
367         return collectionNetworkResourceCust;
368     }
369
370     private boolean collectionResourceCustomizationShouldNotBeProcessed(List<Resource> resourceList,
371             Resource serviceResource, CollectionResourceCustomization collectionResourceCustomization) {
372         if (collectionResourceCustomization == null) {
373             logger.debug("No Network Collection Customization found");
374             return true;
375         }
376         resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
377                 collectionResourceCustomization.getModelCustomizationUUID(), false, serviceResource));
378         logger.debug("Found a network collection");
379         if (collectionResourceCustomization.getCollectionResource() == null) {
380             logger.debug("No Network Collection found. collectionResource is null");
381             return true;
382         }
383         if (collectionResourceCustomization.getCollectionResource().getInstanceGroup() == null) {
384             logger.debug("No Instance Group found for network collection.");
385             return true;
386         }
387         String toscaNodeType =
388                 collectionResourceCustomization.getCollectionResource().getInstanceGroup().getToscaNodeType();
389         if (!toscaNodeTypeHasNetworkCollection(toscaNodeType)) {
390             logger.debug("Instance Group tosca node type does not contain NetworkCollection:  {}", toscaNodeType);
391             return true;
392         }
393         return false;
394     }
395
396     private boolean interfaceNetworkQuantityIsAvailableInCollection(
397             CollectionResourceInstanceGroupCustomization collectionInstCust) {
398         return collectionInstCust != null && collectionInstCust.getSubInterfaceNetworkQuantity() != null;
399     }
400
401     private boolean toscaNodeTypeHasNetworkCollection(String toscaNodeType) {
402         return toscaNodeType != null && toscaNodeType.contains(NETWORKCOLLECTION);
403     }
404
405     private void traverseNetworkCollectionCustomization(List<Resource> resourceList, Resource serviceResource,
406             org.onap.so.db.catalog.beans.Service service) {
407         if (isNetworkCollectionInTheResourceList(resourceList)) {
408             return;
409         }
410         if (service.getNetworkCustomizations() == null) {
411             logger.debug("No networks were found on this service model");
412             return;
413         }
414         for (int i = 0; i < service.getNetworkCustomizations().size(); i++) {
415             resourceList.add(new Resource(WorkflowType.NETWORK,
416                     service.getNetworkCustomizations().get(i).getModelCustomizationUUID(), false, serviceResource));
417         }
418     }
419
420     private boolean isVnfCustomizationsInTheService(org.onap.so.db.catalog.beans.Service service) {
421         return !(service.getVnfCustomizations() == null || service.getVnfCustomizations().isEmpty());
422     }
423
424     private boolean isPnfCustomizationsInTheService(org.onap.so.db.catalog.beans.Service service) {
425         return !(service.getPnfCustomizations() == null || service.getPnfCustomizations().isEmpty());
426     }
427
428     private void traverseVnfModules(List<Resource> resourceList, Resource vnfResource,
429             List<Pair<WorkflowType, String>> aaiResourceIds,
430             org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf) {
431         if (vnf.getVfModules() == null) {
432             return;
433         }
434         for (VfModule vfModule : vnf.getVfModules()) {
435             aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
436             Resource resource = new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false, vnfResource);
437             resource.setBaseVfModule(vfModule.getModelInfoVfModule().getIsBaseBoolean());
438             resourceList.add(resource);
439         }
440     }
441
442
443     protected String getExistingAAIVrfConfiguration(RelatedInstance relatedVpnBinding,
444             org.onap.aai.domain.yang.L3Network aaiLocalNetwork)
445             throws JsonProcessingException, VrfBondingServiceException {
446         Optional<Relationships> relationshipsOp = new AAIResultWrapper(
447                 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiLocalNetwork)).getRelationships();
448         if (relationshipsOp.isPresent()) {
449             List<AAIResultWrapper> configurationsRelatedToLocalNetwork =
450                     relationshipsOp.get().getByType(AAIFluentTypeBuilder.Types.CONFIGURATION);
451             if (configurationsRelatedToLocalNetwork.size() > 1) {
452                 throw new VrfBondingServiceException(
453                         "Network: " + aaiLocalNetwork.getNetworkId() + " has more than 1 configuration related to it");
454             }
455             if (configurationsRelatedToLocalNetwork.size() == 1) {
456                 AAIResultWrapper configWrapper = configurationsRelatedToLocalNetwork.get(0);
457                 Optional<Configuration> relatedConfiguration = configWrapper.asBean(Configuration.class);
458                 if (relatedConfiguration.isPresent() && vrfConfigurationAlreadyExists(relatedVpnBinding,
459                         relatedConfiguration.get(), configWrapper)) {
460                     return relatedConfiguration.get().getConfigurationId();
461                 }
462             }
463         }
464         return null;
465     }
466
467     protected boolean vrfConfigurationAlreadyExists(RelatedInstance relatedVpnBinding, Configuration vrfConfiguration,
468             AAIResultWrapper configWrapper) throws VrfBondingServiceException {
469         if ("VRF-ENTRY".equalsIgnoreCase(vrfConfiguration.getConfigurationType())) {
470             Optional<Relationships> relationshipsConfigOp = configWrapper.getRelationships();
471             if (relationshipsConfigOp.isPresent()) {
472                 Optional<VpnBinding> relatedInfraVpnBindingOp =
473                         workflowActionUtils.extractRelationshipsVpnBinding(relationshipsConfigOp.get());
474                 if (relatedInfraVpnBindingOp.isPresent()) {
475                     VpnBinding relatedInfraVpnBinding = relatedInfraVpnBindingOp.get();
476                     if (!relatedInfraVpnBinding.getVpnId().equalsIgnoreCase(relatedVpnBinding.getInstanceId())) {
477                         throw new VrfBondingServiceException("Configuration: " + vrfConfiguration.getConfigurationId()
478                                 + " is not connected to the same vpn binding id provided in request: "
479                                 + relatedVpnBinding.getInstanceId());
480                     } else {
481                         return true;
482                     }
483                 }
484             }
485         }
486         return false;
487     }
488
489     public boolean containsWorkflowType(List<Resource> resourceList, WorkflowType workflowType) {
490         return resourceList.stream().anyMatch(resource -> resource.getResourceType().equals(workflowType));
491     }
492
493     public boolean isNetworkCollectionInTheResourceList(List<Resource> resourceList) {
494         return resourceList.stream().anyMatch(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType());
495     }
496
497     public CollectionResourceCustomization findCatalogNetworkCollection(DelegateExecution execution,
498             org.onap.so.db.catalog.beans.Service service) {
499         CollectionResourceCustomization networkCollection = null;
500         int count = 0;
501         for (CollectionResourceCustomization collectionCust : service.getCollectionResourceCustomizations()) {
502             if (catalogDbClient.getNetworkCollectionResourceCustomizationByID(
503                     collectionCust.getModelCustomizationUUID()) != null) {
504                 networkCollection = collectionCust;
505                 count++;
506             }
507         }
508         if (count == 0) {
509             return null;
510         } else if (count > 1) {
511             buildAndThrowException(execution,
512                     "Found multiple Network Collections in the Service model, only one per Service is supported.");
513         }
514         return networkCollection;
515     }
516
517     protected void buildAndThrowException(DelegateExecution execution, String msg) {
518         logger.error(msg);
519         execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg);
520         exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
521     }
522 }