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