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