Merge "SO WorkflowAction refactor II"
[so.git] / bpmn / so-bpmn-tasks / src / main / java / org / onap / so / bpmn / infrastructure / workflow / tasks / WorkflowAction.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (c) 2019 Samsung
8  * ================================================================================
9  * Modifications Copyright (c) 2021 Nokia
10  * ================================================================================
11  * Modifications Copyright (c) 2020 Tech Mahindra
12  * ================================================================================
13  * Licensed under the Apache License, Version 2.0 (the "License");
14  * you may not use this file except in compliance with the License.
15  * You may obtain a copy of the License at
16  *
17  *      http://www.apache.org/licenses/LICENSE-2.0
18  *
19  * Unless required by applicable law or agreed to in writing, software
20  * distributed under the License is distributed on an "AS IS" BASIS,
21  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22  * See the License for the specific language governing permissions and
23  * limitations under the License.
24  * ============LICENSE_END=========================================================
25  */
26
27 package org.onap.so.bpmn.infrastructure.workflow.tasks;
28
29 import com.fasterxml.jackson.core.JsonProcessingException;
30 import com.fasterxml.jackson.databind.ObjectMapper;
31 import org.apache.commons.lang3.SerializationUtils;
32 import org.camunda.bpm.engine.delegate.DelegateExecution;
33 import org.javatuples.Pair;
34 import org.onap.aai.domain.yang.Relationship;
35 import org.onap.aai.domain.yang.ServiceInstance;
36 import org.onap.aai.domain.yang.Vnfc;
37 import org.onap.aai.domain.yang.VolumeGroup;
38 import org.onap.aai.domain.yang.VpnBinding;
39 import org.onap.aaiclient.client.aai.AAICommonObjectMapperProvider;
40 import org.onap.aaiclient.client.aai.AAIObjectName;
41 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper;
42 import org.onap.aaiclient.client.aai.entities.Relationships;
43 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri;
44 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory;
45 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder;
46 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types;
47 import org.onap.so.bpmn.common.BBConstants;
48 import org.onap.so.bpmn.infrastructure.workflow.tasks.utils.WorkflowResourceIdsUtils;
49 import org.onap.so.bpmn.servicedecomposition.bbobjects.Configuration;
50 import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule;
51 import org.onap.so.bpmn.servicedecomposition.entities.ConfigurationResourceKeys;
52 import org.onap.so.bpmn.servicedecomposition.entities.ExecuteBuildingBlock;
53 import org.onap.so.bpmn.servicedecomposition.entities.WorkflowResourceIds;
54 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetup;
55 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetupUtils;
56 import org.onap.so.client.exception.ExceptionBuilder;
57 import org.onap.so.client.orchestration.AAIConfigurationResources;
58 import org.onap.so.client.orchestration.AAIEntityNotFoundException;
59 import org.onap.so.db.catalog.beans.CollectionNetworkResourceCustomization;
60 import org.onap.so.db.catalog.beans.CollectionResourceCustomization;
61 import org.onap.so.db.catalog.beans.CollectionResourceInstanceGroupCustomization;
62 import org.onap.so.db.catalog.beans.InstanceGroup;
63 import org.onap.so.db.catalog.beans.VfModuleCustomization;
64 import org.onap.so.db.catalog.beans.macro.NorthBoundRequest;
65 import org.onap.so.db.catalog.beans.macro.OrchestrationFlow;
66 import org.onap.so.db.catalog.client.CatalogDbClient;
67 import org.onap.so.serviceinstancebeans.CloudConfiguration;
68 import org.onap.so.serviceinstancebeans.ModelInfo;
69 import org.onap.so.serviceinstancebeans.ModelType;
70 import org.onap.so.serviceinstancebeans.RelatedInstance;
71 import org.onap.so.serviceinstancebeans.RelatedInstanceList;
72 import org.onap.so.serviceinstancebeans.RequestDetails;
73 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
74 import org.slf4j.Logger;
75 import org.slf4j.LoggerFactory;
76 import org.springframework.beans.factory.annotation.Autowired;
77 import org.springframework.core.env.Environment;
78 import org.springframework.stereotype.Component;
79 import org.springframework.util.CollectionUtils;
80 import java.util.ArrayList;
81 import java.util.Arrays;
82 import java.util.Comparator;
83 import java.util.List;
84 import java.util.Map;
85 import java.util.Optional;
86 import java.util.UUID;
87 import java.util.regex.Matcher;
88 import java.util.regex.Pattern;
89 import java.util.stream.Collectors;
90 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.ASSIGNINSTANCE;
91 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.CONTROLLER;
92 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.CREATE_INSTANCE;
93 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.FABRIC_CONFIGURATION;
94 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.NETWORKCOLLECTION;
95 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.REPLACEINSTANCE;
96 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.REPLACEINSTANCERETAINASSIGNMENTS;
97 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.SERVICE;
98 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.USER_PARAM_SERVICE;
99 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.WORKFLOW_ACTION_ERROR_MESSAGE;
100
101 @Component
102 public class WorkflowAction {
103
104     private static final Logger logger = LoggerFactory.getLogger(WorkflowAction.class);
105
106     private static final String SERVICE_INSTANCES = "serviceInstances";
107     private static final String VF_MODULES = "vfModules";
108     private static final String VNF_TYPE = "vnfType";
109     private static final String CONFIGURATION = "Configuration";
110     private static final String SUPPORTEDTYPES =
111             "vnfs|vfModules|networks|networkCollections|volumeGroups|serviceInstances|instanceGroups";
112     private static final String HOMINGSOLUTION = "Homing_Solution";
113     private static final String SERVICE_TYPE_TRANSPORT = "TRANSPORT";
114     private static final String SERVICE_TYPE_BONDING = "BONDING";
115     private static final String CLOUD_OWNER = "DEFAULT";
116     private static final String CREATENETWORKBB = "CreateNetworkBB";
117     private static final String ACTIVATENETWORKBB = "ActivateNetworkBB";
118     private static final String VOLUMEGROUP_DELETE_PATTERN = "(Un|De)(.*)Volume(.*)";
119     private static final String VOLUMEGROUP_CREATE_PATTERN = "(A|C)(.*)Volume(.*)";
120     private static final String DEFAULT_CLOUD_OWNER = "org.onap.so.cloud-owner";
121     private static final String HOMING = "homing";
122
123     @Autowired
124     protected BBInputSetup bbInputSetup;
125     @Autowired
126     protected BBInputSetupUtils bbInputSetupUtils;
127     @Autowired
128     private ExceptionBuilder exceptionBuilder;
129     @Autowired
130     private CatalogDbClient catalogDbClient;
131     @Autowired
132     private AAIConfigurationResources aaiConfigurationResources;
133     @Autowired
134     private WorkflowActionExtractResourcesAAI workflowActionUtils;
135     @Autowired
136     private VrfValidation vrfValidation;
137     @Autowired
138     private Environment environment;
139     @Autowired
140     private UserParamsServiceTraversal userParamsServiceTraversal;
141     @Autowired
142     private AaiResourceIdValidator aaiResourceIdValidator;
143     @Autowired
144     private ExecuteBuildingBlockBuilder executeBuildingBlockBuilder;
145
146     public void setBbInputSetupUtils(BBInputSetupUtils bbInputSetupUtils) {
147         this.bbInputSetupUtils = bbInputSetupUtils;
148     }
149
150     public void setBbInputSetup(BBInputSetup bbInputSetup) {
151         this.bbInputSetup = bbInputSetup;
152     }
153
154     public void selectExecutionList(DelegateExecution execution) throws Exception {
155         try {
156             fillExecutionDefault(execution);
157             final String bpmnRequest = (String) execution.getVariable(BBConstants.G_BPMN_REQUEST);
158             ServiceInstancesRequest sIRequest =
159                     new ObjectMapper().readValue(bpmnRequest, ServiceInstancesRequest.class);
160
161             final String requestId = (String) execution.getVariable(BBConstants.G_REQUEST_ID);
162
163             String uri = (String) execution.getVariable(BBConstants.G_URI);
164             boolean isResume = isUriResume(uri);
165
166             final boolean isALaCarte = (boolean) execution.getVariable(BBConstants.G_ALACARTE);
167             Resource resource = getResource(bbInputSetupUtils, isResume, isALaCarte, uri, requestId);
168
169             WorkflowResourceIds workflowResourceIds = populateResourceIdsFromApiHandler(execution);
170             RequestDetails requestDetails = sIRequest.getRequestDetails();
171             String requestAction = (String) execution.getVariable(BBConstants.G_ACTION);
172             String resourceId = getResourceId(resource, requestAction, requestDetails, workflowResourceIds);
173             WorkflowType resourceType = resource.getResourceType();
174
175             String serviceInstanceId = getServiceInstanceId(execution, resourceId, resourceType);
176
177             fillExecution(execution, requestDetails.getRequestInfo().getSuppressRollback(), resourceId, resourceType);
178             List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
179
180             if (isRequestMacroServiceResume(isALaCarte, resourceType, requestAction, serviceInstanceId)) {
181                 String errorMessage = "Could not resume Macro flow. Error loading execution path.";
182                 flowsToExecute = loadExecuteBuildingBlocks(execution, requestId, errorMessage);
183             } else if (isALaCarte && isResume) {
184                 String errorMessage =
185                         "Could not resume request with request Id: " + requestId + ". No flowsToExecute was found";
186                 flowsToExecute = loadExecuteBuildingBlocks(execution, requestId, errorMessage);
187             } else {
188                 String vnfType = (String) execution.getVariable(VNF_TYPE);
189                 String cloudOwner = getCloudOwner(requestDetails.getCloudConfiguration());
190                 List<OrchestrationFlow> orchFlows =
191                         (List<OrchestrationFlow>) execution.getVariable(BBConstants.G_ORCHESTRATION_FLOW);
192                 final String apiVersion = (String) execution.getVariable(BBConstants.G_APIVERSION);
193                 final String serviceType =
194                         Optional.ofNullable((String) execution.getVariable(BBConstants.G_SERVICE_TYPE)).orElse("");
195                 if (isALaCarte) {
196                     if (orchFlows == null || orchFlows.isEmpty()) {
197                         orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, true,
198                                 cloudOwner, serviceType);
199                     }
200                     Resource resourceKey = getResourceKey(sIRequest, resourceType);
201
202                     ReplaceInstanceRelatedInformation replaceInfo = new ReplaceInstanceRelatedInformation();
203                     if ((requestAction.equalsIgnoreCase(REPLACEINSTANCE)
204                             || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS))
205                             && resourceType.equals(WorkflowType.VFMODULE)) {
206                         logger.debug("Build a BB list for replacing BB modules");
207                         ConfigBuildingBlocksDataObject cbbdo = createConfigBuildingBlocksDataObject(execution,
208                                 sIRequest, requestId, workflowResourceIds, requestDetails, requestAction, resourceId,
209                                 vnfType, orchFlows, apiVersion, resourceKey, replaceInfo);
210                         orchFlows = getVfModuleReplaceBuildingBlocks(cbbdo);
211
212                         createBuildingBlocksForOrchFlows(execution, sIRequest, requestId, workflowResourceIds,
213                                 requestDetails, requestAction, resourceId, flowsToExecute, vnfType, orchFlows,
214                                 apiVersion, resourceKey, replaceInfo);
215                     } else {
216                         if (isConfiguration(orchFlows) && !requestAction.equalsIgnoreCase(CREATE_INSTANCE)) {
217                             addConfigBuildingBlocksToFlowsToExecuteList(execution, sIRequest, requestId,
218                                     workflowResourceIds, requestDetails, requestAction, resourceId, flowsToExecute,
219                                     vnfType, apiVersion, resourceKey, replaceInfo, orchFlows);
220                         }
221                         orchFlows =
222                                 orchFlows.stream().filter(item -> !item.getFlowName().contains(FABRIC_CONFIGURATION))
223                                         .collect(Collectors.toList());
224
225                         for (OrchestrationFlow orchFlow : orchFlows) {
226                             ExecuteBuildingBlock ebb = executeBuildingBlockBuilder.buildExecuteBuildingBlock(orchFlow,
227                                     requestId, resourceKey, apiVersion, resourceId, requestAction, true, vnfType,
228                                     workflowResourceIds, requestDetails, false, null, null, false, replaceInfo);
229                             flowsToExecute.add(ebb);
230                         }
231                     }
232                 } else {
233                     boolean containsService = false;
234                     List<Resource> resourceList = new ArrayList<>();
235                     List<Pair<WorkflowType, String>> aaiResourceIds = new ArrayList<>();
236                     List<Map<String, Object>> userParams =
237                             sIRequest.getRequestDetails().getRequestParameters().getUserParams();
238                     if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(ASSIGNINSTANCE)) {
239                         // SERVICE-MACRO-ASSIGN will always get user params with a
240                         // service.
241
242                         if (userParams != null) {
243                             containsService = isContainsService(sIRequest);
244                             if (containsService) {
245                                 resourceList = userParamsServiceTraversal.getResourceListFromUserParams(execution,
246                                         userParams, serviceInstanceId, requestAction);
247                             }
248                         } else {
249                             buildAndThrowException(execution,
250                                     "Service-Macro-Assign request details must contain user params with a service");
251                         }
252                     } else if (resourceType == WorkflowType.SERVICE
253                             && requestAction.equalsIgnoreCase(CREATE_INSTANCE)) {
254                         // SERVICE-MACRO-CREATE will get user params with a service,
255                         // a service with a network, a service with a
256                         // network collection, OR an empty service.
257                         // If user params is just a service or null and macro
258                         // queries the SI and finds a VNF, macro fails.
259
260                         if (userParams != null) {
261                             containsService = isContainsService(sIRequest);
262                         }
263                         if (containsService) {
264                             resourceList = userParamsServiceTraversal.getResourceListFromUserParams(execution,
265                                     userParams, serviceInstanceId, requestAction);
266                         }
267                         if (!foundRelated(resourceList)) {
268                             traverseCatalogDbService(execution, sIRequest, resourceList, aaiResourceIds);
269                         }
270                     } else if (resourceType == WorkflowType.SERVICE
271                             && ("activateInstance".equalsIgnoreCase(requestAction)
272                                     || "unassignInstance".equalsIgnoreCase(requestAction)
273                                     || "deleteInstance".equalsIgnoreCase(requestAction)
274                                     || requestAction.equalsIgnoreCase("activate" + FABRIC_CONFIGURATION))) {
275                         // SERVICE-MACRO-ACTIVATE, SERVICE-MACRO-UNASSIGN, and
276                         // SERVICE-MACRO-DELETE
277                         // Will never get user params with service, macro will have
278                         // to query the SI in AAI to find related instances.
279                         traverseAAIService(execution, resourceList, resourceId, aaiResourceIds);
280                     } else if (resourceType == WorkflowType.SERVICE
281                             && "deactivateInstance".equalsIgnoreCase(requestAction)) {
282                         resourceList.add(new Resource(WorkflowType.SERVICE, "", false));
283                     } else if (resourceType == WorkflowType.VNF && (REPLACEINSTANCE.equalsIgnoreCase(requestAction)
284                             || ("recreateInstance".equalsIgnoreCase(requestAction)))) {
285                         traverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
286                                 workflowResourceIds.getVnfId(), aaiResourceIds);
287                     } else if (resourceType == WorkflowType.VNF && "updateInstance".equalsIgnoreCase(requestAction)) {
288                         customTraverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
289                                 workflowResourceIds.getVnfId(), aaiResourceIds);
290                     } else {
291                         buildAndThrowException(execution, "Current Macro Request is not supported");
292                     }
293                     StringBuilder foundObjects = new StringBuilder();
294                     for (WorkflowType type : WorkflowType.values()) {
295                         foundObjects.append(type).append(" - ").append(
296                                 (int) resourceList.stream().filter(x -> type.equals(x.getResourceType())).count())
297                                 .append("    ");
298                     }
299                     logger.info("Found {}", foundObjects);
300
301                     if (orchFlows == null || orchFlows.isEmpty()) {
302                         orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, isALaCarte,
303                                 cloudOwner, serviceType);
304                     }
305                     boolean vnfReplace = false;
306                     if (resourceType.equals(WorkflowType.VNF) && (REPLACEINSTANCE.equalsIgnoreCase(requestAction)
307                             || REPLACEINSTANCERETAINASSIGNMENTS.equalsIgnoreCase(requestAction))) {
308                         vnfReplace = true;
309                     }
310                     flowsToExecute = executeBuildingBlockBuilder.buildExecuteBuildingBlockList(orchFlows, resourceList,
311                             requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds,
312                             requestDetails, vnfReplace);
313                     if (isNetworkCollectionInTheResourceList(resourceList)) {
314                         logger.info("Sorting for Vlan Tagging");
315                         flowsToExecute = sortExecutionPathByObjectForVlanTagging(flowsToExecute, requestAction);
316                     }
317                     // By default, enable homing at VNF level for CREATE_INSTANCE and ASSIGNINSTANCE
318                     if (resourceType == WorkflowType.SERVICE
319                             && (requestAction.equals(CREATE_INSTANCE) || requestAction.equals(ASSIGNINSTANCE))
320                             && resourceList.stream().anyMatch(x -> WorkflowType.VNF.equals(x.getResourceType()))) {
321                         execution.setVariable(HOMING, true);
322                         execution.setVariable("calledHoming", false);
323                     }
324                     if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE)
325                             || requestAction.equalsIgnoreCase(CREATE_INSTANCE))) {
326                         generateResourceIds(flowsToExecute, resourceList, serviceInstanceId);
327                     } else {
328                         updateResourceIdsFromAAITraversal(flowsToExecute, resourceList, aaiResourceIds,
329                                 serviceInstanceId);
330                     }
331                 }
332             }
333             // If the user set "Homing_Solution" to "none", disable homing, else if "Homing_Solution" is specified,
334             // enable it.
335             List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
336             if (sIRequest.getRequestDetails().getRequestParameters() != null && userParams != null) {
337                 for (Map<String, Object> params : userParams) {
338                     if (params.containsKey(HOMINGSOLUTION)) {
339                         execution.setVariable(HOMING, !"none".equals(params.get(HOMINGSOLUTION)));
340                     }
341                 }
342             }
343
344             if (CollectionUtils.isEmpty(flowsToExecute)) {
345                 throw new IllegalStateException("Macro did not come up with a valid execution path.");
346             }
347
348             List<String> flowNames = new ArrayList<>();
349             logger.info("List of BuildingBlocks to execute:");
350
351             flowsToExecute.forEach(ebb -> {
352                 logger.info(ebb.getBuildingBlock().getBpmnFlowName());
353                 flowNames.add(ebb.getBuildingBlock().getBpmnFlowName());
354             });
355
356             if (!isResume) {
357                 bbInputSetupUtils.persistFlowExecutionPath(requestId, flowsToExecute);
358             }
359             setExecutionVariables(execution, flowsToExecute, flowNames);
360
361         } catch (Exception ex) {
362             if (!(execution.hasVariable("WorkflowException")
363                     || execution.hasVariable("WorkflowExceptionExceptionMessage"))) {
364                 buildAndThrowException(execution, "Exception while setting execution list. ", ex);
365             } else {
366                 throw ex;
367             }
368         }
369     }
370
371     private void setExecutionVariables(DelegateExecution execution, List<ExecuteBuildingBlock> flowsToExecute,
372             List<String> flowNames) {
373         execution.setVariable("flowNames", flowNames);
374         execution.setVariable(BBConstants.G_CURRENT_SEQUENCE, 0);
375         execution.setVariable("retryCount", 0);
376         execution.setVariable("isRollback", false);
377         execution.setVariable("flowsToExecute", flowsToExecute);
378         execution.setVariable("isRollbackComplete", false);
379     }
380
381     private boolean isContainsService(ServiceInstancesRequest sIRequest) {
382         boolean containsService;
383         List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
384         containsService = userParams.stream().anyMatch(param -> param.containsKey(USER_PARAM_SERVICE));
385         return containsService;
386     }
387
388
389
390     private List<ExecuteBuildingBlock> loadExecuteBuildingBlocks(DelegateExecution execution, String requestId,
391             String errorMessage) {
392         List<ExecuteBuildingBlock> flowsToExecute;
393         flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
394         if (flowsToExecute == null) {
395             buildAndThrowException(execution, errorMessage);
396         }
397         return flowsToExecute;
398     }
399
400     private ConfigBuildingBlocksDataObject createConfigBuildingBlocksDataObject(DelegateExecution execution,
401             ServiceInstancesRequest sIRequest, String requestId, WorkflowResourceIds workflowResourceIds,
402             RequestDetails requestDetails, String requestAction, String resourceId, String vnfType,
403             List<OrchestrationFlow> orchFlows, String apiVersion, Resource resourceKey,
404             ReplaceInstanceRelatedInformation replaceInfo) {
405
406         return new ConfigBuildingBlocksDataObject().setsIRequest(sIRequest).setOrchFlows(orchFlows)
407                 .setRequestId(requestId).setResourceKey(resourceKey).setApiVersion(apiVersion).setResourceId(resourceId)
408                 .setRequestAction(requestAction).setaLaCarte(true).setVnfType(vnfType)
409                 .setWorkflowResourceIds(workflowResourceIds).setRequestDetails(requestDetails).setExecution(execution)
410                 .setReplaceInformation(replaceInfo);
411     }
412
413     private void createBuildingBlocksForOrchFlows(DelegateExecution execution, ServiceInstancesRequest sIRequest,
414             String requestId, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
415             String requestAction, String resourceId, List<ExecuteBuildingBlock> flowsToExecute, String vnfType,
416             List<OrchestrationFlow> orchFlows, String apiVersion, Resource resourceKey,
417             ReplaceInstanceRelatedInformation replaceInfo) throws Exception {
418
419         for (OrchestrationFlow orchFlow : orchFlows) {
420             if (orchFlow.getFlowName().contains(CONFIGURATION)) {
421                 List<OrchestrationFlow> configOrchFlows = new ArrayList<>();
422                 configOrchFlows.add(orchFlow);
423                 addConfigBuildingBlocksToFlowsToExecuteList(execution, sIRequest, requestId, workflowResourceIds,
424                         requestDetails, requestAction, resourceId, flowsToExecute, vnfType, apiVersion, resourceKey,
425                         replaceInfo, configOrchFlows);
426             } else {
427                 ExecuteBuildingBlock ebb = executeBuildingBlockBuilder.buildExecuteBuildingBlock(orchFlow, requestId,
428                         resourceKey, apiVersion, resourceId, requestAction, true, vnfType, workflowResourceIds,
429                         requestDetails, false, null, null, false, replaceInfo);
430                 flowsToExecute.add(ebb);
431             }
432         }
433     }
434
435     private void addConfigBuildingBlocksToFlowsToExecuteList(DelegateExecution execution,
436             ServiceInstancesRequest sIRequest, String requestId, WorkflowResourceIds workflowResourceIds,
437             RequestDetails requestDetails, String requestAction, String resourceId,
438             List<ExecuteBuildingBlock> flowsToExecute, String vnfType, String apiVersion, Resource resourceKey,
439             ReplaceInstanceRelatedInformation replaceInfo, List<OrchestrationFlow> configOrchFlows) throws Exception {
440
441         ConfigBuildingBlocksDataObject cbbdo = createConfigBuildingBlocksDataObject(execution, sIRequest, requestId,
442                 workflowResourceIds, requestDetails, requestAction, resourceId, vnfType, configOrchFlows, apiVersion,
443                 resourceKey, replaceInfo);
444         List<ExecuteBuildingBlock> configBuildingBlocks = getConfigBuildingBlocks(cbbdo);
445         flowsToExecute.addAll(configBuildingBlocks);
446     }
447
448     private Resource getResourceKey(ServiceInstancesRequest sIRequest, WorkflowType resourceType) {
449         String resourceId = "";
450         ModelInfo modelInfo = sIRequest.getRequestDetails().getModelInfo();
451         if (modelInfo != null) {
452             if (modelInfo.getModelType().equals(ModelType.service)) {
453                 resourceId = modelInfo.getModelVersionId();
454             } else {
455                 resourceId = modelInfo.getModelCustomizationId();
456             }
457         }
458         return new Resource(resourceType, resourceId, true);
459     }
460
461     private String getCloudOwner(CloudConfiguration cloudConfiguration) {
462         if (cloudConfiguration != null && cloudConfiguration.getCloudOwner() != null) {
463             return cloudConfiguration.getCloudOwner();
464         }
465         logger.warn("cloud owner value not found in request details, it will be set as default");
466         return environment.getProperty(DEFAULT_CLOUD_OWNER);
467     }
468
469     protected <T> List<T> getRelatedResourcesInVfModule(String vnfId, String vfModuleId, Class<T> resultClass,
470             AAIObjectName name) {
471         List<T> vnfcs = new ArrayList<>();
472         AAIResourceUri uri =
473                 AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId).vfModule(vfModuleId));
474         AAIResultWrapper vfModuleResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
475         Optional<Relationships> relationshipsOp = vfModuleResultsWrapper.getRelationships();
476         if (!relationshipsOp.isPresent()) {
477             logger.debug("No relationships were found for vfModule in AAI");
478         } else {
479             Relationships relationships = relationshipsOp.get();
480             List<AAIResultWrapper> vnfcResultWrappers = relationships.getByType(name);
481             for (AAIResultWrapper vnfcResultWrapper : vnfcResultWrappers) {
482                 Optional<T> vnfcOp = vnfcResultWrapper.asBean(resultClass);
483                 vnfcOp.ifPresent(vnfcs::add);
484             }
485         }
486         return vnfcs;
487     }
488
489     protected <T> T getRelatedResourcesInVnfc(Vnfc vnfc, Class<T> resultClass, AAIObjectName name) throws Exception {
490         T configuration = null;
491         AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().vnfc(vnfc.getVnfcName()));
492         AAIResultWrapper vnfcResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
493         Optional<Relationships> relationshipsOp = vnfcResultsWrapper.getRelationships();
494         if (!relationshipsOp.isPresent()) {
495             logger.debug("No relationships were found for VNFC in AAI");
496         } else {
497             Relationships relationships = relationshipsOp.get();
498             List<AAIResultWrapper> configurationResultWrappers =
499                     this.getResultWrappersFromRelationships(relationships, name);
500             if (configurationResultWrappers.size() > 1) {
501                 String multipleRelationshipsError =
502                         "Multiple relationships exist from VNFC " + vnfc.getVnfcName() + " to Configurations";
503                 throw new Exception(multipleRelationshipsError);
504             }
505             if (!configurationResultWrappers.isEmpty()) {
506                 Optional<T> configurationOp = configurationResultWrappers.get(0).asBean(resultClass);
507                 if (configurationOp.isPresent()) {
508                     configuration = configurationOp.get();
509                 }
510             }
511         }
512         return configuration;
513     }
514
515     protected List<AAIResultWrapper> getResultWrappersFromRelationships(Relationships relationships,
516             AAIObjectName name) {
517         return relationships.getByType(name);
518     }
519
520     protected boolean isConfiguration(List<OrchestrationFlow> orchFlows) {
521         for (OrchestrationFlow flow : orchFlows) {
522             if (flow.getFlowName().contains(CONFIGURATION) && !"ConfigurationScaleOutBB".equals(flow.getFlowName())) {
523                 return true;
524             }
525         }
526         return false;
527     }
528
529     protected List<ExecuteBuildingBlock> getConfigBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
530             throws Exception {
531
532         List<ExecuteBuildingBlock> flowsToExecuteConfigs = new ArrayList<>();
533         List<OrchestrationFlow> result = dataObj.getOrchFlows().stream()
534                 .filter(item -> item.getFlowName().contains(FABRIC_CONFIGURATION)).collect(Collectors.toList());
535         String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
536         String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
537
538         String vnfCustomizationUUID = bbInputSetupUtils.getAAIGenericVnf(vnfId).getModelCustomizationId();
539         String vfModuleCustomizationUUID;
540         org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
541
542         if (aaiVfModule == null) {
543             logger.error("No matching VfModule is found in Generic-Vnf in AAI for vnfId: {} and vfModuleId : {}", vnfId,
544                     vfModuleId);
545             throw new AAIEntityNotFoundException("No matching VfModule is found in Generic-Vnf in AAI for vnfId: "
546                     + vnfId + " and vfModuleId : " + vfModuleId);
547         } else {
548             vfModuleCustomizationUUID = aaiVfModule.getModelCustomizationId();
549         }
550         String replaceVfModuleCustomizationUUID = "";
551         String replaceVnfModuleCustomizationUUID = "";
552         boolean isReplace = false;
553         if (dataObj.getRequestAction().equalsIgnoreCase("replaceInstance")
554                 || dataObj.getRequestAction().equalsIgnoreCase("replaceInstanceRetainAssignments")) {
555             for (RelatedInstanceList relatedInstList : dataObj.getRequestDetails().getRelatedInstanceList()) {
556                 RelatedInstance relatedInstance = relatedInstList.getRelatedInstance();
557                 if (relatedInstance.getModelInfo().getModelType().equals(ModelType.vnf)) {
558                     replaceVnfModuleCustomizationUUID = relatedInstance.getModelInfo().getModelCustomizationId();
559                 }
560             }
561             replaceVfModuleCustomizationUUID = dataObj.getRequestDetails().getModelInfo().getModelCustomizationId();
562             isReplace = true;
563         }
564
565         List<org.onap.aai.domain.yang.Vnfc> vnfcs =
566                 getRelatedResourcesInVfModule(vnfId, vfModuleId, org.onap.aai.domain.yang.Vnfc.class, Types.VNFC);
567         for (org.onap.aai.domain.yang.Vnfc vnfc : vnfcs) {
568             WorkflowResourceIds workflowIdsCopy = SerializationUtils.clone(dataObj.getWorkflowResourceIds());
569             org.onap.aai.domain.yang.Configuration configuration =
570                     getRelatedResourcesInVnfc(vnfc, org.onap.aai.domain.yang.Configuration.class, Types.CONFIGURATION);
571             if (configuration == null) {
572                 logger.warn(String.format("No configuration found for VNFC %s in AAI", vnfc.getVnfcName()));
573                 continue;
574             }
575             workflowIdsCopy.setConfigurationId(configuration.getConfigurationId());
576             for (OrchestrationFlow orchFlow : result) {
577                 if (!isReplace || (isReplace && (orchFlow.getFlowName().contains("Delete")))) {
578                     if (!isReplace) {
579                         dataObj.getResourceKey().setVfModuleCustomizationId(vfModuleCustomizationUUID);
580                         dataObj.getResourceKey().setVnfCustomizationId(vnfCustomizationUUID);
581                     } else {
582                         if (orchFlow.getFlowName().contains("Delete")) {
583                             dataObj.getResourceKey().setVfModuleCustomizationId(vfModuleCustomizationUUID);
584                             dataObj.getResourceKey().setVnfCustomizationId(vnfCustomizationUUID);
585                         } else {
586                             dataObj.getResourceKey().setVfModuleCustomizationId(replaceVfModuleCustomizationUUID);
587                             dataObj.getResourceKey().setVnfCustomizationId(replaceVnfModuleCustomizationUUID);
588                         }
589                     }
590                     dataObj.getResourceKey().setCvnfModuleCustomizationId(vnfc.getModelCustomizationId());
591                     String vnfcName = vnfc.getVnfcName();
592                     if (vnfcName == null || vnfcName.isEmpty()) {
593                         buildAndThrowException(dataObj.getExecution(), "Exception in create execution list "
594                                 + ": VnfcName does not exist or is null while there is a configuration for the vfModule",
595                                 new Exception("Vnfc and Configuration do not match"));
596                     }
597                     ExecuteBuildingBlock ebb =
598                             executeBuildingBlockBuilder.buildExecuteBuildingBlock(orchFlow, dataObj.getRequestId(),
599                                     dataObj.getResourceKey(), dataObj.getApiVersion(), dataObj.getResourceId(),
600                                     dataObj.getRequestAction(), dataObj.isaLaCarte(), dataObj.getVnfType(),
601                                     workflowIdsCopy, dataObj.getRequestDetails(), false, null, vnfcName, true, null);
602                     flowsToExecuteConfigs.add(ebb);
603                 }
604             }
605         }
606         return flowsToExecuteConfigs;
607     }
608
609     protected void buildAndThrowException(DelegateExecution execution, String msg) {
610         logger.error(msg);
611         execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg);
612         exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
613     }
614
615     protected void buildAndThrowException(DelegateExecution execution, String msg, Exception ex) {
616         logger.error(msg, ex);
617         execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg + ex.getMessage());
618         exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg + ex.getMessage());
619     }
620
621     protected List<OrchestrationFlow> getVfModuleReplaceBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
622             throws Exception {
623
624         String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
625         String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
626
627         logger.debug("BUILDING REPLACE LIST");
628
629         boolean volumeGroupExisted = false;
630         boolean volumeGroupWillExist = false;
631         boolean keepVolumeGroup = false;
632
633         boolean rebuildVolumeGroups = false;
634         if (dataObj.getRequestDetails().getRequestParameters() != null
635                 && dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups() != null) {
636             rebuildVolumeGroups = dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups();
637         }
638         String volumeGroupName = "";
639         Optional<VolumeGroup> volumeGroupFromVfModule =
640                 bbInputSetupUtils.getRelatedVolumeGroupFromVfModule(vnfId, vfModuleId);
641         if (volumeGroupFromVfModule.isPresent()) {
642             String volumeGroupId = volumeGroupFromVfModule.get().getVolumeGroupId();
643             volumeGroupName = volumeGroupFromVfModule.get().getVolumeGroupName();
644             logger.debug("Volume group id of the existing volume group is: " + volumeGroupId);
645             volumeGroupExisted = true;
646             dataObj.getWorkflowResourceIds().setVolumeGroupId(volumeGroupId);
647             dataObj.getReplaceInformation().setOldVolumeGroupName(volumeGroupName);
648         }
649
650         List<OrchestrationFlow> orchFlows = dataObj.getOrchFlows();
651         VfModuleCustomization vfModuleCustomization = catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
652                 dataObj.getRequestDetails().getModelInfo().getModelCustomizationUuid());
653         if (vfModuleCustomization != null && vfModuleCustomization.getVfModule() != null
654                 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
655                 && vfModuleCustomization.getVolumeHeatEnv() != null) {
656             volumeGroupWillExist = true;
657             if (!volumeGroupExisted) {
658                 String newVolumeGroupId = UUID.randomUUID().toString();
659                 dataObj.getWorkflowResourceIds().setVolumeGroupId(newVolumeGroupId);
660                 dataObj.getReplaceInformation().setOldVolumeGroupName(volumeGroupName);
661                 logger.debug("newVolumeGroupId: " + newVolumeGroupId);
662             }
663         }
664
665         if (volumeGroupExisted && volumeGroupWillExist && !rebuildVolumeGroups) {
666             keepVolumeGroup = true;
667         }
668
669         if (!volumeGroupExisted || keepVolumeGroup) {
670             logger.debug("Filtering out deletion of volume groups");
671             orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_DELETE_PATTERN))
672                     .collect(Collectors.toList());
673         }
674         if (!volumeGroupWillExist || keepVolumeGroup) {
675             logger.debug("Filtering out creation of volume groups");
676             orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_CREATE_PATTERN))
677                     .collect(Collectors.toList());
678         }
679
680         return orchFlows;
681     }
682
683
684
685     private void updateResourceIdsFromAAITraversal(List<ExecuteBuildingBlock> flowsToExecute,
686             List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds, String serviceInstanceId) {
687         for (Pair<WorkflowType, String> pair : aaiResourceIds) {
688             logger.debug(pair.getValue0() + ", " + pair.getValue1());
689         }
690
691         Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
692                 .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
693                         .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
694                                 retrieveAAIResourceId(aaiResourceIds, type), null, serviceInstanceId)));
695     }
696
697     private String retrieveAAIResourceId(List<Pair<WorkflowType, String>> aaiResourceIds, WorkflowType resource) {
698         String id = null;
699         for (int i = 0; i < aaiResourceIds.size(); i++) {
700             if (aaiResourceIds.get(i).getValue0() == resource) {
701                 id = aaiResourceIds.get(i).getValue1();
702                 aaiResourceIds.remove(i);
703                 break;
704             }
705         }
706         return id;
707     }
708
709     private void generateResourceIds(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
710             String serviceInstanceId) {
711         Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
712                 .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
713                         .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
714                                 null, resource.getVirtualLinkKey(), serviceInstanceId)));
715     }
716
717     protected void updateWorkflowResourceIds(List<ExecuteBuildingBlock> flowsToExecute, WorkflowType resourceType,
718             String key, String id, String virtualLinkKey, String serviceInstanceId) {
719         String resourceId = id;
720         if (resourceId == null) {
721             resourceId = UUID.randomUUID().toString();
722         }
723         for (ExecuteBuildingBlock ebb : flowsToExecute) {
724             if (key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey()) && (ebb.getBuildingBlock()
725                     .getBpmnFlowName().contains(resourceType.toString())
726                     || (ebb.getBuildingBlock().getBpmnFlowName().contains(CONTROLLER)
727                             && ebb.getBuildingBlock().getBpmnScope().equalsIgnoreCase(resourceType.toString())))) {
728                 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
729                 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
730                 WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, resourceType, resourceId);
731                 ebb.setWorkflowResourceIds(workflowResourceIds);
732             }
733             if (virtualLinkKey != null && ebb.getBuildingBlock().isVirtualLink()
734                     && virtualLinkKey.equalsIgnoreCase(ebb.getBuildingBlock().getVirtualLinkKey())) {
735                 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
736                 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
737                 workflowResourceIds.setNetworkId(resourceId);
738                 ebb.setWorkflowResourceIds(workflowResourceIds);
739             }
740         }
741     }
742
743     protected CollectionResourceCustomization findCatalogNetworkCollection(DelegateExecution execution,
744             org.onap.so.db.catalog.beans.Service service) {
745         CollectionResourceCustomization networkCollection = null;
746         int count = 0;
747         for (CollectionResourceCustomization collectionCust : service.getCollectionResourceCustomizations()) {
748             if (catalogDbClient.getNetworkCollectionResourceCustomizationByID(
749                     collectionCust.getModelCustomizationUUID()) != null) {
750                 networkCollection = collectionCust;
751                 count++;
752             }
753         }
754         if (count == 0) {
755             return null;
756         } else if (count > 1) {
757             buildAndThrowException(execution,
758                     "Found multiple Network Collections in the Service model, only one per Service is supported.");
759         }
760         return networkCollection;
761     }
762
763     protected void traverseCatalogDbService(DelegateExecution execution, ServiceInstancesRequest sIRequest,
764             List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds)
765             throws JsonProcessingException, VrfBondingServiceException {
766         String modelUUID = sIRequest.getRequestDetails().getModelInfo().getModelVersionId();
767         org.onap.so.db.catalog.beans.Service service = catalogDbClient.getServiceByID(modelUUID);
768
769         if (service == null) {
770             buildAndThrowException(execution, "Could not find the service model in catalog db.");
771         } else {
772             resourceList.add(new Resource(WorkflowType.SERVICE, service.getModelUUID(), false));
773             RelatedInstance relatedVpnBinding =
774                     bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.vpnBinding);
775             RelatedInstance relatedLocalNetwork =
776                     bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.network);
777
778             if (relatedVpnBinding != null && relatedLocalNetwork != null) {
779                 traverseVrfConfiguration(aaiResourceIds, resourceList, service, relatedVpnBinding, relatedLocalNetwork);
780             } else {
781                 traverseNetworkCollection(execution, resourceList, service);
782             }
783         }
784     }
785
786     protected void traverseVrfConfiguration(List<Pair<WorkflowType, String>> aaiResourceIds,
787             List<Resource> resourceList, org.onap.so.db.catalog.beans.Service service,
788             RelatedInstance relatedVpnBinding, RelatedInstance relatedLocalNetwork)
789             throws VrfBondingServiceException, JsonProcessingException {
790         org.onap.aai.domain.yang.L3Network aaiLocalNetwork =
791                 bbInputSetupUtils.getAAIL3Network(relatedLocalNetwork.getInstanceId());
792         vrfValidation.vrfServiceValidation(service);
793         vrfValidation.vrfCatalogDbChecks(service);
794         vrfValidation.aaiVpnBindingValidation(relatedVpnBinding.getInstanceId(),
795                 bbInputSetupUtils.getAAIVpnBinding(relatedVpnBinding.getInstanceId()));
796         vrfValidation.aaiNetworkValidation(relatedLocalNetwork.getInstanceId(), aaiLocalNetwork);
797         vrfValidation.aaiSubnetValidation(aaiLocalNetwork);
798         vrfValidation.aaiAggregateRouteValidation(aaiLocalNetwork);
799         vrfValidation.aaiRouteTargetValidation(aaiLocalNetwork);
800         String existingAAIVrfConfiguration = getExistingAAIVrfConfiguration(relatedVpnBinding, aaiLocalNetwork);
801         if (existingAAIVrfConfiguration != null) {
802             aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, existingAAIVrfConfiguration));
803         }
804         resourceList.add(new Resource(WorkflowType.CONFIGURATION,
805                 service.getConfigurationCustomizations().get(0).getModelCustomizationUUID(), false));
806
807     }
808
809     protected String getExistingAAIVrfConfiguration(RelatedInstance relatedVpnBinding,
810             org.onap.aai.domain.yang.L3Network aaiLocalNetwork)
811             throws JsonProcessingException, VrfBondingServiceException {
812         Optional<Relationships> relationshipsOp = new AAIResultWrapper(
813                 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiLocalNetwork)).getRelationships();
814         if (relationshipsOp.isPresent()) {
815             List<AAIResultWrapper> configurationsRelatedToLocalNetwork =
816                     relationshipsOp.get().getByType(Types.CONFIGURATION);
817             if (configurationsRelatedToLocalNetwork.size() > 1) {
818                 throw new VrfBondingServiceException(
819                         "Network: " + aaiLocalNetwork.getNetworkId() + " has more than 1 configuration related to it");
820             }
821             if (configurationsRelatedToLocalNetwork.size() == 1) {
822                 AAIResultWrapper configWrapper = configurationsRelatedToLocalNetwork.get(0);
823                 Optional<Configuration> relatedConfiguration = configWrapper.asBean(Configuration.class);
824                 if (relatedConfiguration.isPresent() && vrfConfigurationAlreadyExists(relatedVpnBinding,
825                         relatedConfiguration.get(), configWrapper)) {
826                     return relatedConfiguration.get().getConfigurationId();
827                 }
828             }
829         }
830         return null;
831     }
832
833     protected boolean vrfConfigurationAlreadyExists(RelatedInstance relatedVpnBinding, Configuration vrfConfiguration,
834             AAIResultWrapper configWrapper) throws VrfBondingServiceException {
835         if ("VRF-ENTRY".equalsIgnoreCase(vrfConfiguration.getConfigurationType())) {
836             Optional<Relationships> relationshipsConfigOp = configWrapper.getRelationships();
837             if (relationshipsConfigOp.isPresent()) {
838                 Optional<VpnBinding> relatedInfraVpnBindingOp =
839                         workflowActionUtils.extractRelationshipsVpnBinding(relationshipsConfigOp.get());
840                 if (relatedInfraVpnBindingOp.isPresent()) {
841                     VpnBinding relatedInfraVpnBinding = relatedInfraVpnBindingOp.get();
842                     if (!relatedInfraVpnBinding.getVpnId().equalsIgnoreCase(relatedVpnBinding.getInstanceId())) {
843                         throw new VrfBondingServiceException("Configuration: " + vrfConfiguration.getConfigurationId()
844                                 + " is not connected to the same vpn binding id provided in request: "
845                                 + relatedVpnBinding.getInstanceId());
846                     } else {
847                         return true;
848                     }
849                 }
850             }
851         }
852         return false;
853     }
854
855     protected void traverseNetworkCollection(DelegateExecution execution, List<Resource> resourceList,
856             org.onap.so.db.catalog.beans.Service service) {
857         if (isVnfCustomizationsInTheService(service)) {
858             buildAndThrowException(execution,
859                     "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");
860         }
861         if (isPnfCustomizationsInTheService(service)) {
862             buildAndThrowException(execution,
863                     "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");
864         }
865         List<CollectionResourceCustomization> customizations = service.getCollectionResourceCustomizations();
866         if (customizations.isEmpty()) {
867             logger.debug("No Collections found. CollectionResourceCustomization list is empty.");
868         } else {
869             CollectionResourceCustomization collectionResourceCustomization =
870                     findCatalogNetworkCollection(execution, service);
871             traverseNetworkCollectionResourceCustomization(resourceList, collectionResourceCustomization);
872         }
873         traverseNetworkCollectionCustomization(resourceList, service);
874     }
875
876     private void traverseNetworkCollectionResourceCustomization(List<Resource> resourceList,
877             CollectionResourceCustomization collectionResourceCustomization) {
878         if (collectionResourceCustomizationShouldNotBeProcessed(resourceList, collectionResourceCustomization))
879             return;
880         int minNetworks = 0;
881         org.onap.so.db.catalog.beans.InstanceGroup instanceGroup =
882                 collectionResourceCustomization.getCollectionResource().getInstanceGroup();
883         CollectionResourceInstanceGroupCustomization collectionInstCust = null;
884         if (!instanceGroup.getCollectionInstanceGroupCustomizations().isEmpty()) {
885             for (CollectionResourceInstanceGroupCustomization collectionInstanceGroupTemp : instanceGroup
886                     .getCollectionInstanceGroupCustomizations()) {
887                 if (collectionInstanceGroupTemp.getModelCustomizationUUID()
888                         .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
889                     collectionInstCust = collectionInstanceGroupTemp;
890                     break;
891                 }
892             }
893             if (interfaceNetworkQuantityIsAvailableInCollection(collectionInstCust)) {
894                 minNetworks = collectionInstCust.getSubInterfaceNetworkQuantity();
895             }
896         }
897         logger.debug("minNetworks: {}", minNetworks);
898         CollectionNetworkResourceCustomization collectionNetworkResourceCust =
899                 getCollectionNetworkResourceCustomization(collectionResourceCustomization, instanceGroup);
900         for (int i = 0; i < minNetworks; i++) {
901             if (collectionNetworkResourceCust != null) {
902                 Resource resource = new Resource(WorkflowType.VIRTUAL_LINK,
903                         collectionNetworkResourceCust.getModelCustomizationUUID(), false);
904                 resource.setVirtualLinkKey(Integer.toString(i));
905                 resourceList.add(resource);
906             }
907         }
908     }
909
910     private CollectionNetworkResourceCustomization getCollectionNetworkResourceCustomization(
911             CollectionResourceCustomization collectionResourceCustomization, InstanceGroup instanceGroup) {
912         CollectionNetworkResourceCustomization collectionNetworkResourceCust = null;
913         for (CollectionNetworkResourceCustomization collectionNetworkTemp : instanceGroup
914                 .getCollectionNetworkResourceCustomizations()) {
915             if (collectionNetworkTemp.getNetworkResourceCustomization().getModelCustomizationUUID()
916                     .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
917                 collectionNetworkResourceCust = collectionNetworkTemp;
918                 break;
919             }
920         }
921         return collectionNetworkResourceCust;
922     }
923
924     private boolean collectionResourceCustomizationShouldNotBeProcessed(List<Resource> resourceList,
925             CollectionResourceCustomization collectionResourceCustomization) {
926         if (collectionResourceCustomization == null) {
927             logger.debug("No Network Collection Customization found");
928             return true;
929         }
930         resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
931                 collectionResourceCustomization.getModelCustomizationUUID(), false));
932         logger.debug("Found a network collection");
933         if (collectionResourceCustomization.getCollectionResource() == null) {
934             logger.debug("No Network Collection found. collectionResource is null");
935             return true;
936         }
937         if (collectionResourceCustomization.getCollectionResource().getInstanceGroup() == null) {
938             logger.debug("No Instance Group found for network collection.");
939             return true;
940         }
941         String toscaNodeType =
942                 collectionResourceCustomization.getCollectionResource().getInstanceGroup().getToscaNodeType();
943         if (!toscaNodeTypeHasNetworkCollection(toscaNodeType)) {
944             logger.debug("Instance Group tosca node type does not contain NetworkCollection:  {}", toscaNodeType);
945             return true;
946         }
947         return false;
948     }
949
950     private boolean interfaceNetworkQuantityIsAvailableInCollection(
951             CollectionResourceInstanceGroupCustomization collectionInstCust) {
952         return collectionInstCust != null && collectionInstCust.getSubInterfaceNetworkQuantity() != null;
953     }
954
955     private boolean toscaNodeTypeHasNetworkCollection(String toscaNodeType) {
956         return toscaNodeType != null && toscaNodeType.contains(NETWORKCOLLECTION);
957     }
958
959     private void traverseNetworkCollectionCustomization(List<Resource> resourceList,
960             org.onap.so.db.catalog.beans.Service service) {
961         if (isNetworkCollectionInTheResourceList(resourceList)) {
962             return;
963         }
964         if (service.getNetworkCustomizations() == null) {
965             logger.debug("No networks were found on this service model");
966             return;
967         }
968         for (int i = 0; i < service.getNetworkCustomizations().size(); i++) {
969             resourceList.add(new Resource(WorkflowType.NETWORK,
970                     service.getNetworkCustomizations().get(i).getModelCustomizationUUID(), false));
971         }
972     }
973
974     private boolean isNetworkCollectionInTheResourceList(List<Resource> resourceList) {
975         return resourceList.stream().anyMatch(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType());
976     }
977
978     private boolean isVnfCustomizationsInTheService(org.onap.so.db.catalog.beans.Service service) {
979         return !(service.getVnfCustomizations() == null || service.getVnfCustomizations().isEmpty());
980     }
981
982     private boolean isPnfCustomizationsInTheService(org.onap.so.db.catalog.beans.Service service) {
983         return !(service.getPnfCustomizations() == null || service.getPnfCustomizations().isEmpty());
984     }
985
986     protected void traverseAAIService(DelegateExecution execution, List<Resource> resourceList, String resourceId,
987             List<Pair<WorkflowType, String>> aaiResourceIds) {
988         try {
989             ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(resourceId);
990             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
991                     bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
992             resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
993             traverseServiceInstanceMSOVnfs(resourceList, aaiResourceIds, serviceInstanceMSO);
994             traverseServiceInstanceMSOPnfs(resourceList, aaiResourceIds, serviceInstanceMSO);
995             if (serviceInstanceMSO.getNetworks() != null) {
996                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network network : serviceInstanceMSO
997                         .getNetworks()) {
998                     aaiResourceIds.add(new Pair<>(WorkflowType.NETWORK, network.getNetworkId()));
999                     resourceList.add(new Resource(WorkflowType.NETWORK, network.getNetworkId(), false));
1000                 }
1001             }
1002             if (serviceInstanceMSO.getCollection() != null) {
1003                 logger.debug("found networkcollection");
1004                 aaiResourceIds
1005                         .add(new Pair<>(WorkflowType.NETWORKCOLLECTION, serviceInstanceMSO.getCollection().getId()));
1006                 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
1007                         serviceInstanceMSO.getCollection().getId(), false));
1008             }
1009             if (serviceInstanceMSO.getConfigurations() != null) {
1010                 for (Configuration config : serviceInstanceMSO.getConfigurations()) {
1011                     Optional<org.onap.aai.domain.yang.Configuration> aaiConfig =
1012                             aaiConfigurationResources.getConfiguration(config.getConfigurationId());
1013                     if (aaiConfig.isPresent() && aaiConfig.get().getRelationshipList() != null) {
1014                         for (Relationship relationship : aaiConfig.get().getRelationshipList().getRelationship()) {
1015                             if (relationship.getRelatedTo().contains("vnfc")
1016                                     || relationship.getRelatedTo().contains("vpn-binding")) {
1017                                 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.getConfigurationId()));
1018                                 resourceList.add(
1019                                         new Resource(WorkflowType.CONFIGURATION, config.getConfigurationId(), false));
1020                                 break;
1021                             }
1022                         }
1023                     }
1024                 }
1025             }
1026         } catch (Exception ex) {
1027             logger.error("Exception in traverseAAIService", ex);
1028             buildAndThrowException(execution,
1029                     "Could not find existing Service Instance or related Instances to execute the request on.");
1030         }
1031     }
1032
1033     private void traverseServiceInstanceMSOVnfs(List<Resource> resourceList,
1034             List<Pair<WorkflowType, String>> aaiResourceIds,
1035             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO) {
1036         if (serviceInstanceMSO.getVnfs() == null) {
1037             return;
1038         }
1039         for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
1040             aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
1041             resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
1042             traverseVnfModules(resourceList, aaiResourceIds, vnf);
1043             if (vnf.getVolumeGroups() != null) {
1044                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf.getVolumeGroups()) {
1045                     aaiResourceIds.add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1046                     resourceList.add(new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1047                 }
1048             }
1049         }
1050     }
1051
1052     private void traverseServiceInstanceMSOPnfs(List<Resource> resourceList,
1053             List<Pair<WorkflowType, String>> aaiResourceIds,
1054             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO) {
1055         if (serviceInstanceMSO.getPnfs() == null) {
1056             return;
1057         }
1058         for (org.onap.so.bpmn.servicedecomposition.bbobjects.Pnf pnf : serviceInstanceMSO.getPnfs()) {
1059             aaiResourceIds.add(new Pair<>(WorkflowType.PNF, pnf.getPnfId()));
1060             resourceList.add(new Resource(WorkflowType.PNF, pnf.getPnfId(), false));
1061         }
1062     }
1063
1064     private void traverseVnfModules(List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds,
1065             org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf) {
1066         if (vnf.getVfModules() == null) {
1067             return;
1068         }
1069         for (VfModule vfModule : vnf.getVfModules()) {
1070             aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1071             Resource resource = new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false);
1072             resource.setBaseVfModule(vfModule.getModelInfoVfModule().getIsBaseBoolean());
1073             resourceList.add(resource);
1074         }
1075     }
1076
1077     private void traverseAAIVnf(DelegateExecution execution, List<Resource> resourceList, String serviceId,
1078             String vnfId, List<Pair<WorkflowType, String>> aaiResourceIds) {
1079         try {
1080             ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(serviceId);
1081             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
1082                     bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
1083             resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
1084             if (serviceInstanceMSO.getVnfs() != null) {
1085                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
1086                     if (vnf.getVnfId().equals(vnfId)) {
1087                         aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
1088                         resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
1089                         if (vnf.getVfModules() != null) {
1090                             for (VfModule vfModule : vnf.getVfModules()) {
1091                                 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1092                                 resourceList.add(new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false));
1093                                 findConfigurationsInsideVfModule(execution, vnf.getVnfId(), vfModule.getVfModuleId(),
1094                                         resourceList, aaiResourceIds);
1095                             }
1096                         }
1097                         if (vnf.getVolumeGroups() != null) {
1098                             for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
1099                                     .getVolumeGroups()) {
1100                                 aaiResourceIds
1101                                         .add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1102                                 resourceList.add(
1103                                         new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1104                             }
1105                         }
1106                         break;
1107                     }
1108                 }
1109             }
1110         } catch (Exception ex) {
1111             logger.error("Exception in traverseAAIVnf", ex);
1112             buildAndThrowException(execution,
1113                     "Could not find existing Vnf or related Instances to execute the request on.");
1114         }
1115     }
1116
1117     private void customTraverseAAIVnf(DelegateExecution execution, List<Resource> resourceList, String serviceId,
1118             String vnfId, List<Pair<WorkflowType, String>> aaiResourceIds) {
1119         try {
1120             ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(serviceId);
1121             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
1122                     bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
1123             resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
1124             if (serviceInstanceMSO.getVnfs() != null) {
1125                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
1126                     if (vnf.getVnfId().equals(vnfId)) {
1127                         aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
1128
1129                         String vnfCustomizationUUID =
1130                                 bbInputSetupUtils.getAAIGenericVnf(vnfId).getModelCustomizationId();
1131                         resourceList.add(new Resource(WorkflowType.VNF, vnfCustomizationUUID, false));
1132
1133                         if (vnf.getVfModules() != null) {
1134                             for (VfModule vfModule : vnf.getVfModules()) {
1135                                 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1136                                 resourceList.add(new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false));
1137                                 findConfigurationsInsideVfModule(execution, vnf.getVnfId(), vfModule.getVfModuleId(),
1138                                         resourceList, aaiResourceIds);
1139                             }
1140                         }
1141                         if (vnf.getVolumeGroups() != null) {
1142                             for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
1143                                     .getVolumeGroups()) {
1144                                 aaiResourceIds
1145                                         .add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1146                                 resourceList.add(
1147                                         new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1148                             }
1149                         }
1150                         break;
1151                     }
1152                 }
1153             }
1154         } catch (Exception ex) {
1155             logger.error("Exception in customTraverseAAIVnf", ex);
1156             buildAndThrowException(execution,
1157                     "Could not find existing Vnf or related Instances to execute the request on.");
1158         }
1159
1160     }
1161
1162     private void findConfigurationsInsideVfModule(DelegateExecution execution, String vnfId, String vfModuleId,
1163             List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds) {
1164         try {
1165             org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
1166             AAIResultWrapper vfModuleWrapper = new AAIResultWrapper(
1167                     new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiVfModule));
1168             Optional<Relationships> relationshipsOp;
1169             relationshipsOp = vfModuleWrapper.getRelationships();
1170             if (relationshipsOp.isPresent()) {
1171                 relationshipsOp = workflowActionUtils.extractRelationshipsVnfc(relationshipsOp.get());
1172                 if (relationshipsOp.isPresent()) {
1173                     Optional<Configuration> config =
1174                             workflowActionUtils.extractRelationshipsConfiguration(relationshipsOp.get());
1175                     if (config.isPresent()) {
1176                         aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.get().getConfigurationId()));
1177                         resourceList.add(
1178                                 new Resource(WorkflowType.CONFIGURATION, config.get().getConfigurationId(), false));
1179                     }
1180                 }
1181             }
1182         } catch (Exception ex) {
1183             logger.error("Exception in findConfigurationsInsideVfModule", ex);
1184             buildAndThrowException(execution, "Failed to find Configuration object from the vfModule.");
1185         }
1186     }
1187
1188     protected WorkflowResourceIds populateResourceIdsFromApiHandler(DelegateExecution execution) {
1189         return WorkflowResourceIdsUtils.getWorkflowResourceIdsFromExecution(execution);
1190     }
1191
1192     protected Resource extractResourceIdAndTypeFromUri(String uri) {
1193         Pattern patt = Pattern.compile("[vV]\\d+.*?(?:(?:/(?<type>" + SUPPORTEDTYPES
1194                 + ")(?:/(?<id>[^/]+))?)(?:/(?<action>[^/]+))?(?:/resume)?)?$");
1195         Matcher m = patt.matcher(uri);
1196         boolean generated = false;
1197
1198         if (m.find()) {
1199             logger.debug("found match on {} : {} ", uri, m);
1200             String type = m.group("type");
1201             String id = m.group("id");
1202             String action = m.group("action");
1203             if (type == null) {
1204                 throw new IllegalArgumentException("Uri could not be parsed. No type found. " + uri);
1205             }
1206             if (action == null) {
1207                 if (type.equals(SERVICE_INSTANCES) && (id == null || "assign".equals(id))) {
1208                     id = UUID.randomUUID().toString();
1209                     generated = true;
1210                 } else if (type.equals(VF_MODULES) && "scaleOut".equals(id)) {
1211                     id = UUID.randomUUID().toString();
1212                     generated = true;
1213                 }
1214             } else {
1215                 if (action.matches(SUPPORTEDTYPES)) {
1216                     id = UUID.randomUUID().toString();
1217                     generated = true;
1218                     type = action;
1219                 }
1220             }
1221             return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated);
1222         } else {
1223             throw new IllegalArgumentException("Uri could not be parsed: " + uri);
1224         }
1225     }
1226
1227     protected String convertTypeFromPlural(String type) {
1228         if (!type.matches(SUPPORTEDTYPES)) {
1229             return type;
1230         } else {
1231             if (type.equals(SERVICE_INSTANCES)) {
1232                 return SERVICE;
1233             } else {
1234                 return type.substring(0, 1).toUpperCase() + type.substring(1, type.length() - 1);
1235             }
1236         }
1237     }
1238
1239     protected List<ExecuteBuildingBlock> sortExecutionPathByObjectForVlanTagging(List<ExecuteBuildingBlock> orchFlows,
1240             String requestAction) {
1241         List<ExecuteBuildingBlock> sortedOrchFlows = new ArrayList<>();
1242         if (requestAction.equals(CREATE_INSTANCE)) {
1243             for (ExecuteBuildingBlock ebb : orchFlows) {
1244                 if (ebb.getBuildingBlock().getBpmnFlowName().equals("AssignNetworkBB")) {
1245                     String key = ebb.getBuildingBlock().getKey();
1246                     boolean isVirtualLink = Boolean.TRUE.equals(ebb.getBuildingBlock().isVirtualLink());
1247                     String virtualLinkKey = ebb.getBuildingBlock().getVirtualLinkKey();
1248                     sortedOrchFlows.add(ebb);
1249                     for (ExecuteBuildingBlock ebb2 : orchFlows) {
1250                         if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1251                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1252                             sortedOrchFlows.add(ebb2);
1253                             break;
1254                         }
1255                         if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1256                                 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1257                             sortedOrchFlows.add(ebb2);
1258                             break;
1259                         }
1260                     }
1261                     for (ExecuteBuildingBlock ebb2 : orchFlows) {
1262                         if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1263                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1264                             sortedOrchFlows.add(ebb2);
1265                             break;
1266                         }
1267                         if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1268                                 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1269                             sortedOrchFlows.add(ebb2);
1270                             break;
1271                         }
1272                     }
1273                 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1274                         || ebb.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)) {
1275                     continue;
1276                 } else if (!"".equals(ebb.getBuildingBlock().getBpmnFlowName())) {
1277                     sortedOrchFlows.add(ebb);
1278                 }
1279             }
1280         } else if (requestAction.equals("deleteInstance")) {
1281             for (ExecuteBuildingBlock ebb : orchFlows) {
1282                 if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeactivateNetworkBB")) {
1283                     sortedOrchFlows.add(ebb);
1284                     String key = ebb.getBuildingBlock().getKey();
1285                     for (ExecuteBuildingBlock ebb2 : orchFlows) {
1286                         if (ebb2.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1287                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1288                             sortedOrchFlows.add(ebb2);
1289                             break;
1290                         }
1291                     }
1292                     for (ExecuteBuildingBlock ebb2 : orchFlows) {
1293                         if (ebb2.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")
1294                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1295                             sortedOrchFlows.add(ebb2);
1296                             break;
1297                         }
1298                     }
1299                 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1300                         || ebb.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")) {
1301                     continue;
1302                 } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) {
1303                     sortedOrchFlows.add(ebb);
1304                 }
1305             }
1306         }
1307         return sortedOrchFlows;
1308     }
1309
1310     private ConfigurationResourceKeys getConfigurationResourceKeys(Resource resource, String vnfcName) {
1311         ConfigurationResourceKeys configurationResourceKeys = new ConfigurationResourceKeys();
1312         Optional.ofNullable(vnfcName).ifPresent(configurationResourceKeys::setVnfcName);
1313         configurationResourceKeys.setCvnfcCustomizationUUID(resource.getCvnfModuleCustomizationId());
1314         configurationResourceKeys.setVfModuleCustomizationUUID(resource.getVfModuleCustomizationId());
1315         configurationResourceKeys.setVnfResourceCustomizationUUID(resource.getVnfCustomizationId());
1316         return configurationResourceKeys;
1317     }
1318
1319     protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1320             WorkflowType resourceName, boolean aLaCarte, String cloudOwner) {
1321         return this.queryNorthBoundRequestCatalogDb(execution, requestAction, resourceName, aLaCarte, cloudOwner, "");
1322     }
1323
1324     protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1325             WorkflowType resourceName, boolean aLaCarte, String cloudOwner, String serviceType) {
1326         List<OrchestrationFlow> listToExecute = new ArrayList<>();
1327         NorthBoundRequest northBoundRequest;
1328         if (serviceType.equalsIgnoreCase(SERVICE_TYPE_TRANSPORT)
1329                 || serviceType.equalsIgnoreCase(SERVICE_TYPE_BONDING)) {
1330             northBoundRequest =
1331                     catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwnerAndServiceType(
1332                             requestAction, resourceName.toString(), aLaCarte, cloudOwner, serviceType);
1333         } else {
1334             northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1335                     requestAction, resourceName.toString(), aLaCarte, cloudOwner);
1336         }
1337         if (northBoundRequest == null) {
1338             northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1339                     requestAction, resourceName.toString(), aLaCarte, CLOUD_OWNER);
1340         }
1341         if (northBoundRequest == null) {
1342             buildAndThrowException(execution, String.format("The request: %s %s %s is not supported by GR_API.",
1343                     (aLaCarte ? "AlaCarte" : "Macro"), resourceName, requestAction));
1344         } else {
1345             if (northBoundRequest.getIsToplevelflow() != null) {
1346                 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, northBoundRequest.getIsToplevelflow());
1347             }
1348             List<OrchestrationFlow> flows = northBoundRequest.getOrchestrationFlowList();
1349             if (flows == null) {
1350                 flows = new ArrayList<>();
1351             } else {
1352                 flows.sort(Comparator.comparingInt(OrchestrationFlow::getSequenceNumber));
1353             }
1354             for (OrchestrationFlow flow : flows) {
1355                 if (!flow.getFlowName().contains("BB") && !flow.getFlowName().contains("Activity")) {
1356                     List<OrchestrationFlow> macroQueryFlows =
1357                             catalogDbClient.getOrchestrationFlowByAction(flow.getFlowName());
1358                     listToExecute.addAll(macroQueryFlows);
1359                 } else {
1360                     listToExecute.add(flow);
1361                 }
1362             }
1363         }
1364         return listToExecute;
1365     }
1366
1367     public void handleRuntimeException(DelegateExecution execution) {
1368         StringBuilder wfeExpMsg = new StringBuilder("Runtime error ");
1369         String runtimeErrorMessage;
1370         try {
1371             String javaExpMsg = (String) execution.getVariable("BPMN_javaExpMsg");
1372             if (javaExpMsg != null && !javaExpMsg.isEmpty()) {
1373                 wfeExpMsg.append(": ").append(javaExpMsg);
1374             }
1375             runtimeErrorMessage = wfeExpMsg.toString();
1376             logger.error(runtimeErrorMessage);
1377             execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, runtimeErrorMessage);
1378         } catch (Exception e) {
1379             logger.error("Runtime error", e);
1380             // if runtime message was mulformed
1381             runtimeErrorMessage = "Runtime error";
1382         }
1383         exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, runtimeErrorMessage);
1384     }
1385
1386     protected boolean isUriResume(String uri) {
1387         return uri.endsWith("/resume");
1388     }
1389
1390     protected boolean isRequestMacroServiceResume(boolean aLaCarte, WorkflowType resourceType, String requestAction,
1391             String serviceInstanceId) {
1392         return (!aLaCarte && resourceType == WorkflowType.SERVICE
1393                 && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE) || requestAction.equalsIgnoreCase(CREATE_INSTANCE))
1394                 && (serviceInstanceId != null && serviceInstanceId.trim().length() > 1)
1395                 && (bbInputSetupUtils.getAAIServiceInstanceById(serviceInstanceId) != null));
1396     }
1397
1398     protected boolean foundRelated(List<Resource> resourceList) {
1399         return (containsWorkflowType(resourceList, WorkflowType.VNF)
1400                 || containsWorkflowType(resourceList, WorkflowType.PNF)
1401                 || containsWorkflowType(resourceList, WorkflowType.NETWORK)
1402                 || containsWorkflowType(resourceList, WorkflowType.NETWORKCOLLECTION));
1403     }
1404
1405     protected boolean containsWorkflowType(List<Resource> resourceList, WorkflowType workflowType) {
1406         return resourceList.stream().anyMatch(resource -> resource.getResourceType().equals(workflowType));
1407     }
1408
1409     private void fillExecutionDefault(DelegateExecution execution) {
1410         execution.setVariable("sentSyncResponse", false);
1411         execution.setVariable(HOMING, false);
1412         execution.setVariable("calledHoming", false);
1413         execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, true);
1414     }
1415
1416     private void fillExecution(DelegateExecution execution, boolean suppressRollback, String resourceId,
1417             WorkflowType resourceType) {
1418         execution.setVariable("suppressRollback", suppressRollback);
1419         execution.setVariable("resourceId", resourceId);
1420         execution.setVariable("resourceType", resourceType);
1421         execution.setVariable("resourceName", resourceType.toString());
1422     }
1423
1424     private Resource getResource(BBInputSetupUtils bbInputSetupUtils, boolean isResume, boolean alaCarte, String uri,
1425             String requestId) {
1426         if (!alaCarte && isResume) {
1427             logger.debug("replacing URI {}", uri);
1428             uri = bbInputSetupUtils.loadOriginalInfraActiveRequestById(requestId).getRequestUrl();
1429             logger.debug("for RESUME with original value {}", uri);
1430         }
1431         return extractResourceIdAndTypeFromUri(uri);
1432     }
1433
1434     private String getResourceId(Resource resource, String requestAction, RequestDetails requestDetails,
1435             WorkflowResourceIds workflowResourceIds) throws Exception {
1436         if (resource.isGenerated() && requestAction.equalsIgnoreCase("createInstance")
1437                 && requestDetails.getRequestInfo().getInstanceName() != null) {
1438             return aaiResourceIdValidator.validateResourceIdInAAI(resource.getResourceId(), resource.getResourceType(),
1439                     requestDetails.getRequestInfo().getInstanceName(), requestDetails, workflowResourceIds);
1440         } else {
1441             return resource.getResourceId();
1442         }
1443     }
1444
1445     private String getServiceInstanceId(DelegateExecution execution, String resourceId, WorkflowType resourceType) {
1446         String serviceInstanceId = (String) execution.getVariable("serviceInstanceId");
1447         if ((serviceInstanceId == null || serviceInstanceId.isEmpty()) && WorkflowType.SERVICE.equals(resourceType)) {
1448             serviceInstanceId = resourceId;
1449         }
1450         return serviceInstanceId;
1451     }
1452
1453 }