Merge "Fix ControllerExecutionBB flow."
[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  * Modifications Copyright (c) 2021 Orange
14  * ================================================================================
15  * Licensed under the Apache License, Version 2.0 (the "License");
16  * you may not use this file except in compliance with the License.
17  * You may obtain a copy of the License at
18  *
19  *      http://www.apache.org/licenses/LICENSE-2.0
20  *
21  * Unless required by applicable law or agreed to in writing, software
22  * distributed under the License is distributed on an "AS IS" BASIS,
23  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24  * See the License for the specific language governing permissions and
25  * limitations under the License.
26  * ============LICENSE_END=========================================================
27  */
28
29 package org.onap.so.bpmn.infrastructure.workflow.tasks;
30
31 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.ASSIGN_INSTANCE;
32 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.CONTROLLER;
33 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.CREATE_INSTANCE;
34 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.DELETE_INSTANCE;
35 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.FABRIC_CONFIGURATION;
36 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.RECREATE_INSTANCE;
37 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.REPLACEINSTANCE;
38 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.REPLACEINSTANCERETAINASSIGNMENTS;
39 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.SERVICE;
40 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.UPDATE_INSTANCE;
41 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.WORKFLOW_ACTION_ERROR_MESSAGE;
42 import java.io.IOException;
43 import java.util.ArrayList;
44 import java.util.Arrays;
45 import java.util.Comparator;
46 import java.util.List;
47 import java.util.Map;
48 import java.util.Optional;
49 import java.util.UUID;
50 import java.util.regex.Matcher;
51 import java.util.regex.Pattern;
52 import java.util.stream.Collectors;
53 import org.apache.commons.lang3.SerializationUtils;
54 import org.camunda.bpm.engine.delegate.DelegateExecution;
55 import org.javatuples.Pair;
56 import org.onap.aai.domain.yang.Vnfc;
57 import org.onap.aai.domain.yang.VolumeGroup;
58 import org.onap.aaiclient.client.aai.AAIObjectName;
59 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper;
60 import org.onap.aaiclient.client.aai.entities.Relationships;
61 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri;
62 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory;
63 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder;
64 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types;
65 import org.onap.so.bpmn.common.BBConstants;
66 import org.onap.so.bpmn.infrastructure.workflow.tasks.ebb.loader.ServiceEBBLoader;
67 import org.onap.so.bpmn.infrastructure.workflow.tasks.ebb.loader.VnfEBBLoader;
68 import org.onap.so.bpmn.infrastructure.workflow.tasks.excpetion.VnfcMultipleRelationshipException;
69 import org.onap.so.bpmn.infrastructure.workflow.tasks.utils.WorkflowResourceIdsUtils;
70 import org.onap.so.bpmn.servicedecomposition.entities.ExecuteBuildingBlock;
71 import org.onap.so.bpmn.servicedecomposition.entities.WorkflowResourceIds;
72 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetup;
73 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetupUtils;
74 import org.onap.so.client.exception.ExceptionBuilder;
75 import org.onap.so.client.orchestration.AAIEntityNotFoundException;
76 import org.onap.so.db.catalog.beans.VfModuleCustomization;
77 import org.onap.so.db.catalog.beans.macro.NorthBoundRequest;
78 import org.onap.so.db.catalog.beans.macro.OrchestrationFlow;
79 import org.onap.so.db.catalog.client.CatalogDbClient;
80 import org.onap.so.serviceinstancebeans.CloudConfiguration;
81 import org.onap.so.serviceinstancebeans.ModelInfo;
82 import org.onap.so.serviceinstancebeans.ModelType;
83 import org.onap.so.serviceinstancebeans.RelatedInstance;
84 import org.onap.so.serviceinstancebeans.RelatedInstanceList;
85 import org.onap.so.serviceinstancebeans.RequestDetails;
86 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
87 import org.slf4j.Logger;
88 import org.slf4j.LoggerFactory;
89 import org.springframework.beans.factory.annotation.Autowired;
90 import org.springframework.core.env.Environment;
91 import org.springframework.stereotype.Component;
92 import org.springframework.util.CollectionUtils;
93 import com.fasterxml.jackson.databind.ObjectMapper;
94
95 @Component
96 public class WorkflowAction {
97
98     private static final Logger logger = LoggerFactory.getLogger(WorkflowAction.class);
99
100     private static final String SERVICE_INSTANCES = "serviceInstances";
101     private static final String VF_MODULES = "vfModules";
102     private static final String VNF_TYPE = "vnfType";
103     private static final String CONFIGURATION = "Configuration";
104     private static final String SUPPORTEDTYPES =
105             "vnfs|vfModules|networks|networkCollections|volumeGroups|serviceInstances|instanceGroups";
106     private static final String HOMINGSOLUTION = "Homing_Solution";
107     private static final String SERVICE_TYPE_TRANSPORT = "TRANSPORT";
108     private static final String SERVICE_TYPE_BONDING = "BONDING";
109     private static final String CLOUD_OWNER = "DEFAULT";
110     private static final String CREATENETWORKBB = "CreateNetworkBB";
111     private static final String ACTIVATENETWORKBB = "ActivateNetworkBB";
112     private static final String VOLUMEGROUP_DELETE_PATTERN = "(Un|De)(.*)Volume(.*)";
113     private static final String VOLUMEGROUP_CREATE_PATTERN = "(A|C)(.*)Volume(.*)";
114     private static final String DEFAULT_CLOUD_OWNER = "org.onap.so.cloud-owner";
115     private static final String HOMING = "homing";
116
117     @Autowired
118     protected BBInputSetup bbInputSetup;
119     @Autowired
120     protected BBInputSetupUtils bbInputSetupUtils;
121     @Autowired
122     private ExceptionBuilder exceptionBuilder;
123     @Autowired
124     private CatalogDbClient catalogDbClient;
125     @Autowired
126     private Environment environment;
127     @Autowired
128     private AaiResourceIdValidator aaiResourceIdValidator;
129     @Autowired
130     private ExecuteBuildingBlockBuilder executeBuildingBlockBuilder;
131     @Autowired
132     private VnfEBBLoader vnfEBBLoader;
133     @Autowired
134     private ServiceEBBLoader serviceEBBLoader;
135
136     public void setBbInputSetupUtils(BBInputSetupUtils bbInputSetupUtils) {
137         this.bbInputSetupUtils = bbInputSetupUtils;
138     }
139
140     public void setBbInputSetup(BBInputSetup bbInputSetup) {
141         this.bbInputSetup = bbInputSetup;
142     }
143
144     public void selectExecutionList(DelegateExecution execution) throws Exception {
145         try {
146             fillExecutionDefault(execution);
147             final String bpmnRequest = (String) execution.getVariable(BBConstants.G_BPMN_REQUEST);
148             ServiceInstancesRequest sIRequest =
149                     new ObjectMapper().readValue(bpmnRequest, ServiceInstancesRequest.class);
150
151             final String requestId = (String) execution.getVariable(BBConstants.G_REQUEST_ID);
152
153             String uri = (String) execution.getVariable(BBConstants.G_URI);
154             boolean isResume = isUriResume(uri);
155
156             final boolean isALaCarte = (boolean) execution.getVariable(BBConstants.G_ALACARTE);
157             Resource resource = getResource(bbInputSetupUtils, isResume, isALaCarte, uri, requestId);
158
159             WorkflowResourceIds workflowResourceIds = populateResourceIdsFromApiHandler(execution);
160             RequestDetails requestDetails = sIRequest.getRequestDetails();
161             String requestAction = (String) execution.getVariable(BBConstants.G_ACTION);
162             String resourceId = getResourceId(resource, requestAction, requestDetails, workflowResourceIds);
163             WorkflowType resourceType = resource.getResourceType();
164
165             String serviceInstanceId = getServiceInstanceId(execution, resourceId, resourceType);
166
167             fillExecution(execution, requestDetails.getRequestInfo().getSuppressRollback(), resourceId, resourceType);
168             List<ExecuteBuildingBlock> flowsToExecute;
169             if (isRequestMacroServiceResume(isALaCarte, resourceType, requestAction, serviceInstanceId)) {
170                 String errorMessage = "Could not resume Macro flow. Error loading execution path.";
171                 flowsToExecute = loadExecuteBuildingBlocks(execution, requestId, errorMessage);
172             } else if (isALaCarte && isResume) {
173                 String errorMessage =
174                         "Could not resume request with request Id: " + requestId + ". No flowsToExecute was found";
175                 flowsToExecute = loadExecuteBuildingBlocks(execution, requestId, errorMessage);
176             } else {
177                 String vnfType = (String) execution.getVariable(VNF_TYPE);
178                 String cloudOwner = getCloudOwner(requestDetails.getCloudConfiguration());
179                 List<OrchestrationFlow> orchFlows =
180                         (List<OrchestrationFlow>) execution.getVariable(BBConstants.G_ORCHESTRATION_FLOW);
181                 final String apiVersion = (String) execution.getVariable(BBConstants.G_APIVERSION);
182                 final String serviceType =
183                         Optional.ofNullable((String) execution.getVariable(BBConstants.G_SERVICE_TYPE)).orElse("");
184                 if (isALaCarte) {
185                     flowsToExecute = loadExecuteBuildingBlocksForAlaCarte(orchFlows, execution, requestAction,
186                             resourceType, cloudOwner, serviceType, sIRequest, requestId, workflowResourceIds,
187                             requestDetails, resourceId, vnfType, apiVersion);
188                 } else {
189                     flowsToExecute = loadExecuteBuildingBlocksForMacro(sIRequest, resourceType, requestAction,
190                             execution, serviceInstanceId, resourceId, workflowResourceIds, orchFlows, cloudOwner,
191                             serviceType, requestId, apiVersion, vnfType, requestDetails);
192                 }
193             }
194             // If the user set "Homing_Solution" to "none", disable homing, else if "Homing_Solution" is specified,
195             // enable it.
196             if (sIRequest.getRequestDetails().getRequestParameters() != null
197                     && sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
198                 List<Map<String, Object>> userParams =
199                         sIRequest.getRequestDetails().getRequestParameters().getUserParams();
200                 for (Map<String, Object> params : userParams) {
201                     if (params.containsKey(HOMINGSOLUTION)) {
202                         execution.setVariable(HOMING, !"none".equals(params.get(HOMINGSOLUTION)));
203                     }
204                 }
205             }
206
207             if (CollectionUtils.isEmpty(flowsToExecute)) {
208                 throw new IllegalStateException("Macro did not come up with a valid execution path.");
209             }
210
211             List<String> flowNames = new ArrayList<>();
212             logger.info("List of BuildingBlocks to execute:");
213
214             flowsToExecute.forEach(ebb -> {
215                 logger.info(ebb.getBuildingBlock().getBpmnFlowName());
216                 flowNames.add(ebb.getBuildingBlock().getBpmnFlowName());
217             });
218
219             if (!isResume) {
220                 bbInputSetupUtils.persistFlowExecutionPath(requestId, flowsToExecute);
221             }
222             setExecutionVariables(execution, flowsToExecute, flowNames);
223
224         } catch (Exception ex) {
225             if (!(execution.hasVariable("WorkflowException")
226                     || execution.hasVariable("WorkflowExceptionExceptionMessage"))) {
227                 buildAndThrowException(execution, "Exception while setting execution list. ", ex);
228             } else {
229                 throw ex;
230             }
231         }
232     }
233
234     private List<ExecuteBuildingBlock> loadExecuteBuildingBlocksForAlaCarte(List<OrchestrationFlow> orchFlows,
235             DelegateExecution execution, String requestAction, WorkflowType resourceType, String cloudOwner,
236             String serviceType, ServiceInstancesRequest sIRequest, String requestId,
237             WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails, String resourceId, String vnfType,
238             String apiVersion) throws Exception {
239         List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
240         if (orchFlows == null || orchFlows.isEmpty()) {
241             orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, true, cloudOwner,
242                     serviceType);
243         }
244         Resource resourceKey = getResourceKey(sIRequest, resourceType);
245
246         ReplaceInstanceRelatedInformation replaceInfo = new ReplaceInstanceRelatedInformation();
247         if ((requestAction.equalsIgnoreCase(REPLACEINSTANCE)
248                 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS))
249                 && resourceType.equals(WorkflowType.VFMODULE)) {
250             logger.debug("Build a BB list for replacing BB modules");
251             ConfigBuildingBlocksDataObject cbbdo = createConfigBuildingBlocksDataObject(execution, sIRequest, requestId,
252                     workflowResourceIds, requestDetails, requestAction, resourceId, vnfType, orchFlows, apiVersion,
253                     resourceKey, replaceInfo);
254             orchFlows = getVfModuleReplaceBuildingBlocks(cbbdo);
255
256             createBuildingBlocksForOrchFlows(execution, sIRequest, requestId, workflowResourceIds, requestDetails,
257                     requestAction, resourceId, flowsToExecute, vnfType, orchFlows, apiVersion, resourceKey,
258                     replaceInfo);
259         } else {
260             if (isConfiguration(orchFlows) && !requestAction.equalsIgnoreCase(CREATE_INSTANCE)) {
261                 addConfigBuildingBlocksToFlowsToExecuteList(execution, sIRequest, requestId, workflowResourceIds,
262                         requestDetails, requestAction, resourceId, flowsToExecute, vnfType, apiVersion, resourceKey,
263                         replaceInfo, orchFlows);
264             }
265             orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().contains(FABRIC_CONFIGURATION))
266                     .collect(Collectors.toList());
267
268             for (OrchestrationFlow orchFlow : orchFlows) {
269                 ExecuteBuildingBlock ebb = executeBuildingBlockBuilder.buildExecuteBuildingBlock(orchFlow, requestId,
270                         resourceKey, apiVersion, resourceId, requestAction, true, vnfType, workflowResourceIds,
271                         requestDetails, false, null, null, false, replaceInfo);
272                 flowsToExecute.add(ebb);
273             }
274         }
275         return flowsToExecute;
276     }
277
278     private List<ExecuteBuildingBlock> loadExecuteBuildingBlocksForMacro(ServiceInstancesRequest sIRequest,
279             WorkflowType resourceType, String requestAction, DelegateExecution execution, String serviceInstanceId,
280             String resourceId, WorkflowResourceIds workflowResourceIds, List<OrchestrationFlow> orchFlows,
281             String cloudOwner, String serviceType, String requestId, String apiVersion, String vnfType,
282             RequestDetails requestDetails) throws IOException, VrfBondingServiceException {
283         List<ExecuteBuildingBlock> flowsToExecute;
284         List<Resource> resourceList = new ArrayList<>();
285         List<Pair<WorkflowType, String>> aaiResourceIds = new ArrayList<>();
286
287         if (resourceType == WorkflowType.SERVICE || isVNFCreateOrDelete(resourceType, requestAction)) {
288             resourceList = serviceEBBLoader.getResourceListForService(sIRequest, requestAction, execution,
289                     serviceInstanceId, resourceId, aaiResourceIds);
290         } else if (resourceType == WorkflowType.VNF && (REPLACEINSTANCE.equalsIgnoreCase(requestAction)
291                 || (RECREATE_INSTANCE.equalsIgnoreCase(requestAction)))) {
292             vnfEBBLoader.traverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
293                     workflowResourceIds.getVnfId(), aaiResourceIds);
294         } else if (resourceType == WorkflowType.VNF && UPDATE_INSTANCE.equalsIgnoreCase(requestAction)) {
295             vnfEBBLoader.customTraverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
296                     workflowResourceIds.getVnfId(), aaiResourceIds);
297         } else {
298             buildAndThrowException(execution, "Current Macro Request is not supported");
299         }
300         StringBuilder foundObjects = new StringBuilder();
301         for (WorkflowType type : WorkflowType.values()) {
302             foundObjects.append(type).append(" - ")
303                     .append((int) resourceList.stream().filter(x -> type.equals(x.getResourceType())).count())
304                     .append("    ");
305         }
306         logger.info("Found {}", foundObjects);
307
308         if (orchFlows == null || orchFlows.isEmpty()) {
309             orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, false, cloudOwner,
310                     serviceType);
311         }
312         boolean vnfReplace = false;
313         if (resourceType.equals(WorkflowType.VNF) && (REPLACEINSTANCE.equalsIgnoreCase(requestAction)
314                 || REPLACEINSTANCERETAINASSIGNMENTS.equalsIgnoreCase(requestAction))) {
315             vnfReplace = true;
316         }
317         flowsToExecute = executeBuildingBlockBuilder.buildExecuteBuildingBlockList(orchFlows, resourceList, requestId,
318                 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, vnfReplace);
319         if (serviceEBBLoader.isNetworkCollectionInTheResourceList(resourceList)) {
320             logger.info("Sorting for Vlan Tagging");
321             flowsToExecute = sortExecutionPathByObjectForVlanTagging(flowsToExecute, requestAction);
322         }
323         logger.info("Building Block Execution Order");
324         for (ExecuteBuildingBlock block : flowsToExecute) {
325             Resource res = resourceList.stream()
326                     .filter(resource -> resource.getResourceId() == block.getBuildingBlock().getKey()).findAny()
327                     .orElse(null);
328             String log = "Block: " + block.getBuildingBlock().getBpmnFlowName();
329             if (res != null) {
330                 log += ", Resource: " + res.getResourceType() + "[" + res.getResourceId() + "]";
331                 log += ", Priority: " + res.getProcessingPriority();
332                 if (res.getResourceType() == WorkflowType.VFMODULE)
333                     log += ", Base: " + res.isBaseVfModule();
334             }
335             if (block.getBuildingBlock().getBpmnScope() != null)
336                 log += ", Scope: " + block.getBuildingBlock().getBpmnScope();
337             if (block.getBuildingBlock().getBpmnAction() != null)
338                 log += ", Action: " + block.getBuildingBlock().getBpmnAction();
339             logger.info(log);
340         }
341         // By default, enable homing at VNF level for CREATE_INSTANCE and ASSIGNINSTANCE
342         if (resourceType == WorkflowType.SERVICE
343                 && (requestAction.equals(CREATE_INSTANCE) || requestAction.equals(ASSIGN_INSTANCE))
344                 && resourceList.stream().anyMatch(x -> WorkflowType.VNF.equals(x.getResourceType()))) {
345             execution.setVariable(HOMING, true);
346             execution.setVariable("calledHoming", false);
347         }
348         if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGN_INSTANCE)
349                 || requestAction.equalsIgnoreCase(CREATE_INSTANCE))) {
350             generateResourceIds(flowsToExecute, resourceList, serviceInstanceId);
351         } else {
352             updateResourceIdsFromAAITraversal(flowsToExecute, resourceList, aaiResourceIds, serviceInstanceId);
353         }
354         return flowsToExecute;
355     }
356
357     private boolean isVNFCreateOrDelete(WorkflowType resourceType, String requestAction) {
358         return resourceType == WorkflowType.VNF
359                 && (CREATE_INSTANCE.equalsIgnoreCase(requestAction) || DELETE_INSTANCE.equalsIgnoreCase(requestAction));
360     }
361
362     private void setExecutionVariables(DelegateExecution execution, List<ExecuteBuildingBlock> flowsToExecute,
363             List<String> flowNames) {
364         execution.setVariable("flowNames", flowNames);
365         execution.setVariable(BBConstants.G_CURRENT_SEQUENCE, 0);
366         execution.setVariable("retryCount", 0);
367         execution.setVariable("isRollback", false);
368         execution.setVariable("flowsToExecute", flowsToExecute);
369         execution.setVariable("isRollbackComplete", false);
370     }
371
372     private List<ExecuteBuildingBlock> loadExecuteBuildingBlocks(DelegateExecution execution, String requestId,
373             String errorMessage) {
374         List<ExecuteBuildingBlock> flowsToExecute;
375         flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
376         if (flowsToExecute == null) {
377             buildAndThrowException(execution, errorMessage);
378         }
379         return flowsToExecute;
380     }
381
382     private ConfigBuildingBlocksDataObject createConfigBuildingBlocksDataObject(DelegateExecution execution,
383             ServiceInstancesRequest sIRequest, String requestId, WorkflowResourceIds workflowResourceIds,
384             RequestDetails requestDetails, String requestAction, String resourceId, String vnfType,
385             List<OrchestrationFlow> orchFlows, String apiVersion, Resource resourceKey,
386             ReplaceInstanceRelatedInformation replaceInfo) {
387
388         return new ConfigBuildingBlocksDataObject().setsIRequest(sIRequest).setOrchFlows(orchFlows)
389                 .setRequestId(requestId).setResourceKey(resourceKey).setApiVersion(apiVersion).setResourceId(resourceId)
390                 .setRequestAction(requestAction).setaLaCarte(true).setVnfType(vnfType)
391                 .setWorkflowResourceIds(workflowResourceIds).setRequestDetails(requestDetails).setExecution(execution)
392                 .setReplaceInformation(replaceInfo);
393     }
394
395     private void createBuildingBlocksForOrchFlows(DelegateExecution execution, ServiceInstancesRequest sIRequest,
396             String requestId, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
397             String requestAction, String resourceId, List<ExecuteBuildingBlock> flowsToExecute, String vnfType,
398             List<OrchestrationFlow> orchFlows, String apiVersion, Resource resourceKey,
399             ReplaceInstanceRelatedInformation replaceInfo) throws Exception {
400
401         for (OrchestrationFlow orchFlow : orchFlows) {
402             if (orchFlow.getFlowName().contains(CONFIGURATION)) {
403                 List<OrchestrationFlow> configOrchFlows = new ArrayList<>();
404                 configOrchFlows.add(orchFlow);
405                 addConfigBuildingBlocksToFlowsToExecuteList(execution, sIRequest, requestId, workflowResourceIds,
406                         requestDetails, requestAction, resourceId, flowsToExecute, vnfType, apiVersion, resourceKey,
407                         replaceInfo, configOrchFlows);
408             } else {
409                 ExecuteBuildingBlock ebb = executeBuildingBlockBuilder.buildExecuteBuildingBlock(orchFlow, requestId,
410                         resourceKey, apiVersion, resourceId, requestAction, true, vnfType, workflowResourceIds,
411                         requestDetails, false, null, null, false, replaceInfo);
412                 flowsToExecute.add(ebb);
413             }
414         }
415     }
416
417     private void addConfigBuildingBlocksToFlowsToExecuteList(DelegateExecution execution,
418             ServiceInstancesRequest sIRequest, String requestId, WorkflowResourceIds workflowResourceIds,
419             RequestDetails requestDetails, String requestAction, String resourceId,
420             List<ExecuteBuildingBlock> flowsToExecute, String vnfType, String apiVersion, Resource resourceKey,
421             ReplaceInstanceRelatedInformation replaceInfo, List<OrchestrationFlow> configOrchFlows) throws Exception {
422
423         ConfigBuildingBlocksDataObject cbbdo = createConfigBuildingBlocksDataObject(execution, sIRequest, requestId,
424                 workflowResourceIds, requestDetails, requestAction, resourceId, vnfType, configOrchFlows, apiVersion,
425                 resourceKey, replaceInfo);
426         List<ExecuteBuildingBlock> configBuildingBlocks = getConfigBuildingBlocks(cbbdo);
427         flowsToExecute.addAll(configBuildingBlocks);
428     }
429
430     private Resource getResourceKey(ServiceInstancesRequest sIRequest, WorkflowType resourceType) {
431         String resourceId = "";
432         ModelInfo modelInfo = sIRequest.getRequestDetails().getModelInfo();
433         if (modelInfo != null) {
434             if (modelInfo.getModelType().equals(ModelType.service)) {
435                 resourceId = modelInfo.getModelVersionId();
436             } else {
437                 resourceId = modelInfo.getModelCustomizationId();
438             }
439         }
440         return new Resource(resourceType, resourceId, true, null);
441     }
442
443     private String getCloudOwner(CloudConfiguration cloudConfiguration) {
444         if (cloudConfiguration != null && cloudConfiguration.getCloudOwner() != null) {
445             return cloudConfiguration.getCloudOwner();
446         }
447         logger.warn("cloud owner value not found in request details, it will be set as default");
448         return environment.getProperty(DEFAULT_CLOUD_OWNER);
449     }
450
451     protected <T> List<T> getRelatedResourcesInVfModule(String vnfId, String vfModuleId, Class<T> resultClass,
452             AAIObjectName name) {
453         List<T> vnfcs = new ArrayList<>();
454         AAIResourceUri uri =
455                 AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId).vfModule(vfModuleId));
456         AAIResultWrapper vfModuleResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
457         Optional<Relationships> relationshipsOp = vfModuleResultsWrapper.getRelationships();
458         if (relationshipsOp.isEmpty()) {
459             logger.debug("No relationships were found for vfModule in AAI");
460         } else {
461             Relationships relationships = relationshipsOp.get();
462             List<AAIResultWrapper> vnfcResultWrappers = relationships.getByType(name);
463             for (AAIResultWrapper vnfcResultWrapper : vnfcResultWrappers) {
464                 Optional<T> vnfcOp = vnfcResultWrapper.asBean(resultClass);
465                 vnfcOp.ifPresent(vnfcs::add);
466             }
467         }
468         return vnfcs;
469     }
470
471     protected <T> T getRelatedResourcesInVnfc(Vnfc vnfc, Class<T> resultClass, AAIObjectName name)
472             throws VnfcMultipleRelationshipException {
473         T configuration = null;
474         AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().vnfc(vnfc.getVnfcName()));
475         AAIResultWrapper vnfcResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
476         Optional<Relationships> relationshipsOp = vnfcResultsWrapper.getRelationships();
477         if (relationshipsOp.isEmpty()) {
478             logger.debug("No relationships were found for VNFC in AAI");
479         } else {
480             Relationships relationships = relationshipsOp.get();
481             List<AAIResultWrapper> configurationResultWrappers =
482                     this.getResultWrappersFromRelationships(relationships, name);
483             if (configurationResultWrappers.size() > 1) {
484                 throw new VnfcMultipleRelationshipException(vnfc.getVnfcName());
485             }
486             if (!configurationResultWrappers.isEmpty()) {
487                 Optional<T> configurationOp = configurationResultWrappers.get(0).asBean(resultClass);
488                 if (configurationOp.isPresent()) {
489                     configuration = configurationOp.get();
490                 }
491             }
492         }
493         return configuration;
494     }
495
496     protected List<AAIResultWrapper> getResultWrappersFromRelationships(Relationships relationships,
497             AAIObjectName name) {
498         return relationships.getByType(name);
499     }
500
501     protected boolean isConfiguration(List<OrchestrationFlow> orchFlows) {
502         for (OrchestrationFlow flow : orchFlows) {
503             if (flow.getFlowName().contains(CONFIGURATION) && !"ConfigurationScaleOutBB".equals(flow.getFlowName())) {
504                 return true;
505             }
506         }
507         return false;
508     }
509
510     protected List<ExecuteBuildingBlock> getConfigBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
511             throws AAIEntityNotFoundException, VnfcMultipleRelationshipException {
512
513         List<ExecuteBuildingBlock> flowsToExecuteConfigs = new ArrayList<>();
514         List<OrchestrationFlow> result = dataObj.getOrchFlows().stream()
515                 .filter(item -> item.getFlowName().contains(FABRIC_CONFIGURATION)).collect(Collectors.toList());
516         String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
517         String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
518
519         String vnfCustomizationUUID = bbInputSetupUtils.getAAIGenericVnf(vnfId).getModelCustomizationId();
520         String vfModuleCustomizationUUID;
521         org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
522
523         if (aaiVfModule == null) {
524             logger.error("No matching VfModule is found in Generic-Vnf in AAI for vnfId: {} and vfModuleId : {}", vnfId,
525                     vfModuleId);
526             throw new AAIEntityNotFoundException("No matching VfModule is found in Generic-Vnf in AAI for vnfId: "
527                     + vnfId + " and vfModuleId : " + vfModuleId);
528         } else {
529             vfModuleCustomizationUUID = aaiVfModule.getModelCustomizationId();
530         }
531         String replaceVfModuleCustomizationUUID = "";
532         String replaceVnfModuleCustomizationUUID = "";
533         boolean isReplace = false;
534         if (dataObj.getRequestAction().equalsIgnoreCase("replaceInstance")
535                 || dataObj.getRequestAction().equalsIgnoreCase("replaceInstanceRetainAssignments")) {
536             for (RelatedInstanceList relatedInstList : dataObj.getRequestDetails().getRelatedInstanceList()) {
537                 RelatedInstance relatedInstance = relatedInstList.getRelatedInstance();
538                 if (relatedInstance.getModelInfo().getModelType().equals(ModelType.vnf)) {
539                     replaceVnfModuleCustomizationUUID = relatedInstance.getModelInfo().getModelCustomizationId();
540                 }
541             }
542             replaceVfModuleCustomizationUUID = dataObj.getRequestDetails().getModelInfo().getModelCustomizationId();
543             isReplace = true;
544         }
545
546         List<org.onap.aai.domain.yang.Vnfc> vnfcs =
547                 getRelatedResourcesInVfModule(vnfId, vfModuleId, org.onap.aai.domain.yang.Vnfc.class, Types.VNFC);
548         for (org.onap.aai.domain.yang.Vnfc vnfc : vnfcs) {
549             WorkflowResourceIds workflowIdsCopy = SerializationUtils.clone(dataObj.getWorkflowResourceIds());
550             org.onap.aai.domain.yang.Configuration configuration =
551                     getRelatedResourcesInVnfc(vnfc, org.onap.aai.domain.yang.Configuration.class, Types.CONFIGURATION);
552             if (configuration == null) {
553                 logger.warn(String.format("No configuration found for VNFC %s in AAI", vnfc.getVnfcName()));
554                 continue;
555             }
556             workflowIdsCopy.setConfigurationId(configuration.getConfigurationId());
557             for (OrchestrationFlow orchFlow : result) {
558                 if (!isReplace || (isReplace && (orchFlow.getFlowName().contains("Delete")))) {
559                     if (!isReplace) {
560                         dataObj.getResourceKey().setVfModuleCustomizationId(vfModuleCustomizationUUID);
561                         dataObj.getResourceKey().setVnfCustomizationId(vnfCustomizationUUID);
562                     } else {
563                         if (orchFlow.getFlowName().contains("Delete")) {
564                             dataObj.getResourceKey().setVfModuleCustomizationId(vfModuleCustomizationUUID);
565                             dataObj.getResourceKey().setVnfCustomizationId(vnfCustomizationUUID);
566                         } else {
567                             dataObj.getResourceKey().setVfModuleCustomizationId(replaceVfModuleCustomizationUUID);
568                             dataObj.getResourceKey().setVnfCustomizationId(replaceVnfModuleCustomizationUUID);
569                         }
570                     }
571                     dataObj.getResourceKey().setCvnfModuleCustomizationId(vnfc.getModelCustomizationId());
572                     String vnfcName = vnfc.getVnfcName();
573                     if (vnfcName == null || vnfcName.isEmpty()) {
574                         buildAndThrowException(dataObj.getExecution(), "Exception in create execution list "
575                                 + ": VnfcName does not exist or is null while there is a configuration for the vfModule",
576                                 new Exception("Vnfc and Configuration do not match"));
577                     }
578                     ExecuteBuildingBlock ebb =
579                             executeBuildingBlockBuilder.buildExecuteBuildingBlock(orchFlow, dataObj.getRequestId(),
580                                     dataObj.getResourceKey(), dataObj.getApiVersion(), dataObj.getResourceId(),
581                                     dataObj.getRequestAction(), dataObj.isaLaCarte(), dataObj.getVnfType(),
582                                     workflowIdsCopy, dataObj.getRequestDetails(), false, null, vnfcName, true, null);
583                     flowsToExecuteConfigs.add(ebb);
584                 }
585             }
586         }
587         return flowsToExecuteConfigs;
588     }
589
590     protected void buildAndThrowException(DelegateExecution execution, String msg) {
591         logger.error(msg);
592         execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg);
593         exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
594     }
595
596     protected void buildAndThrowException(DelegateExecution execution, String msg, Exception ex) {
597         logger.error(msg, ex);
598         execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg + ex.getMessage());
599         exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg + ex.getMessage());
600     }
601
602     protected List<OrchestrationFlow> getVfModuleReplaceBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
603             throws Exception {
604
605         String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
606         String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
607
608         logger.debug("BUILDING REPLACE LIST");
609
610         boolean volumeGroupExisted = false;
611         boolean volumeGroupWillExist = false;
612         boolean keepVolumeGroup = false;
613
614         boolean rebuildVolumeGroups = false;
615         if (dataObj.getRequestDetails().getRequestParameters() != null
616                 && dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups() != null) {
617             rebuildVolumeGroups = dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups();
618         }
619         String volumeGroupName = "";
620         Optional<VolumeGroup> volumeGroupFromVfModule =
621                 bbInputSetupUtils.getRelatedVolumeGroupFromVfModule(vnfId, vfModuleId);
622         if (volumeGroupFromVfModule.isPresent()) {
623             String volumeGroupId = volumeGroupFromVfModule.get().getVolumeGroupId();
624             volumeGroupName = volumeGroupFromVfModule.get().getVolumeGroupName();
625             logger.debug("Volume group id of the existing volume group is: {}", volumeGroupId);
626             volumeGroupExisted = true;
627             dataObj.getWorkflowResourceIds().setVolumeGroupId(volumeGroupId);
628             dataObj.getReplaceInformation().setOldVolumeGroupName(volumeGroupName);
629         }
630
631         List<OrchestrationFlow> orchFlows = dataObj.getOrchFlows();
632         VfModuleCustomization vfModuleCustomization = catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
633                 dataObj.getRequestDetails().getModelInfo().getModelCustomizationUuid());
634         if (vfModuleCustomization != null && vfModuleCustomization.getVfModule() != null
635                 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
636                 && vfModuleCustomization.getVolumeHeatEnv() != null) {
637             volumeGroupWillExist = true;
638             if (!volumeGroupExisted) {
639                 String newVolumeGroupId = UUID.randomUUID().toString();
640                 dataObj.getWorkflowResourceIds().setVolumeGroupId(newVolumeGroupId);
641                 dataObj.getReplaceInformation().setOldVolumeGroupName(volumeGroupName);
642                 logger.debug("newVolumeGroupId: {}", newVolumeGroupId);
643             }
644         }
645
646         if (volumeGroupExisted && volumeGroupWillExist && !rebuildVolumeGroups) {
647             keepVolumeGroup = true;
648         }
649
650         if (!volumeGroupExisted || keepVolumeGroup) {
651             logger.debug("Filtering out deletion of volume groups");
652             orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_DELETE_PATTERN))
653                     .collect(Collectors.toList());
654         }
655         if (!volumeGroupWillExist || keepVolumeGroup) {
656             logger.debug("Filtering out creation of volume groups");
657             orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_CREATE_PATTERN))
658                     .collect(Collectors.toList());
659         }
660
661         return orchFlows;
662     }
663
664     private void updateResourceIdsFromAAITraversal(List<ExecuteBuildingBlock> flowsToExecute,
665             List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds, String serviceInstanceId) {
666         for (Pair<WorkflowType, String> pair : aaiResourceIds) {
667             logger.debug("{}, {}", pair.getValue0(), pair.getValue1());
668         }
669
670         Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
671                 .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
672                         .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
673                                 retrieveAAIResourceId(aaiResourceIds, type), null, serviceInstanceId)));
674     }
675
676     private String retrieveAAIResourceId(List<Pair<WorkflowType, String>> aaiResourceIds, WorkflowType resource) {
677         String id = null;
678         for (int i = 0; i < aaiResourceIds.size(); i++) {
679             if (aaiResourceIds.get(i).getValue0() == resource) {
680                 id = aaiResourceIds.get(i).getValue1();
681                 aaiResourceIds.remove(i);
682                 break;
683             }
684         }
685         return id;
686     }
687
688     private void generateResourceIds(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
689             String serviceInstanceId) {
690         Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
691                 .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
692                         .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
693                                 null, resource.getVirtualLinkKey(), serviceInstanceId)));
694     }
695
696     protected void updateWorkflowResourceIds(List<ExecuteBuildingBlock> flowsToExecute, WorkflowType resourceType,
697             String key, String id, String virtualLinkKey, String serviceInstanceId) {
698         String resourceId = id;
699         if (resourceId == null) {
700             resourceId = UUID.randomUUID().toString();
701         }
702         for (ExecuteBuildingBlock ebb : flowsToExecute) {
703             if (key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey()) && (ebb.getBuildingBlock()
704                     .getBpmnFlowName().contains(resourceType.toString())
705                     || (ebb.getBuildingBlock().getBpmnFlowName().contains(CONTROLLER)
706                             && ebb.getBuildingBlock().getBpmnScope().equalsIgnoreCase(resourceType.toString())))) {
707                 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
708                 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
709                 WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, resourceType, resourceId);
710                 ebb.setWorkflowResourceIds(workflowResourceIds);
711             }
712             if (virtualLinkKey != null && ebb.getBuildingBlock().isVirtualLink()
713                     && virtualLinkKey.equalsIgnoreCase(ebb.getBuildingBlock().getVirtualLinkKey())) {
714                 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
715                 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
716                 workflowResourceIds.setNetworkId(resourceId);
717                 ebb.setWorkflowResourceIds(workflowResourceIds);
718             }
719         }
720     }
721
722     protected WorkflowResourceIds populateResourceIdsFromApiHandler(DelegateExecution execution) {
723         return WorkflowResourceIdsUtils.getWorkflowResourceIdsFromExecution(execution);
724     }
725
726     protected Resource extractResourceIdAndTypeFromUri(String uri) {
727         Pattern patt = Pattern.compile("[vV]\\d+.*?(?:(?:/(?<type>" + SUPPORTEDTYPES
728                 + ")(?:/(?<id>[^/]+))?)(?:/(?<action>[^/]+))?(?:/resume)?)?$");
729         Matcher m = patt.matcher(uri);
730         boolean generated = false;
731
732         if (m.find()) {
733             logger.debug("found match on {} : {} ", uri, m);
734             String type = m.group("type");
735             String id = m.group("id");
736             String action = m.group("action");
737             if (type == null) {
738                 throw new IllegalArgumentException("Uri could not be parsed. No type found. " + uri);
739             }
740             if (action == null) {
741                 if (type.equals(SERVICE_INSTANCES) && (id == null || "assign".equals(id))) {
742                     id = UUID.randomUUID().toString();
743                     generated = true;
744                 } else if (type.equals(VF_MODULES) && "scaleOut".equals(id)) {
745                     id = UUID.randomUUID().toString();
746                     generated = true;
747                 }
748             } else {
749                 if (action.matches(SUPPORTEDTYPES)) {
750                     id = UUID.randomUUID().toString();
751                     generated = true;
752                     type = action;
753                 }
754             }
755             return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated, null);
756         } else {
757             throw new IllegalArgumentException("Uri could not be parsed: " + uri);
758         }
759     }
760
761     protected String convertTypeFromPlural(String type) {
762         if (!type.matches(SUPPORTEDTYPES)) {
763             return type;
764         } else {
765             if (type.equals(SERVICE_INSTANCES)) {
766                 return SERVICE;
767             } else {
768                 return type.substring(0, 1).toUpperCase() + type.substring(1, type.length() - 1);
769             }
770         }
771     }
772
773     protected List<ExecuteBuildingBlock> sortExecutionPathByObjectForVlanTagging(List<ExecuteBuildingBlock> orchFlows,
774             String requestAction) {
775         List<ExecuteBuildingBlock> sortedOrchFlows = new ArrayList<>();
776         if (requestAction.equals(CREATE_INSTANCE)) {
777             for (ExecuteBuildingBlock ebb : orchFlows) {
778                 if (ebb.getBuildingBlock().getBpmnFlowName().equals("AssignNetworkBB")) {
779                     String key = ebb.getBuildingBlock().getKey();
780                     boolean isVirtualLink = Boolean.TRUE.equals(ebb.getBuildingBlock().isVirtualLink());
781                     String virtualLinkKey = ebb.getBuildingBlock().getVirtualLinkKey();
782                     sortedOrchFlows.add(ebb);
783                     for (ExecuteBuildingBlock ebb2 : orchFlows) {
784                         if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
785                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
786                             sortedOrchFlows.add(ebb2);
787                             break;
788                         }
789                         if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
790                                 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
791                             sortedOrchFlows.add(ebb2);
792                             break;
793                         }
794                     }
795                     for (ExecuteBuildingBlock ebb2 : orchFlows) {
796                         if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
797                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
798                             sortedOrchFlows.add(ebb2);
799                             break;
800                         }
801                         if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
802                                 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
803                             sortedOrchFlows.add(ebb2);
804                             break;
805                         }
806                     }
807                 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
808                         || ebb.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)) {
809                     continue;
810                 } else if (!"".equals(ebb.getBuildingBlock().getBpmnFlowName())) {
811                     sortedOrchFlows.add(ebb);
812                 }
813             }
814         } else if (requestAction.equals("deleteInstance")) {
815             for (ExecuteBuildingBlock ebb : orchFlows) {
816                 if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeactivateNetworkBB")) {
817                     sortedOrchFlows.add(ebb);
818                     String key = ebb.getBuildingBlock().getKey();
819                     for (ExecuteBuildingBlock ebb2 : orchFlows) {
820                         if (ebb2.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
821                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
822                             sortedOrchFlows.add(ebb2);
823                             break;
824                         }
825                     }
826                     for (ExecuteBuildingBlock ebb2 : orchFlows) {
827                         if (ebb2.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")
828                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
829                             sortedOrchFlows.add(ebb2);
830                             break;
831                         }
832                     }
833                 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
834                         || ebb.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")) {
835                     continue;
836                 } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) {
837                     sortedOrchFlows.add(ebb);
838                 }
839             }
840         }
841         return sortedOrchFlows;
842     }
843
844     protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
845             WorkflowType resourceName, boolean aLaCarte, String cloudOwner) {
846         return this.queryNorthBoundRequestCatalogDb(execution, requestAction, resourceName, aLaCarte, cloudOwner, "");
847     }
848
849     protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
850             WorkflowType resourceName, boolean aLaCarte, String cloudOwner, String serviceType) {
851         List<OrchestrationFlow> listToExecute = new ArrayList<>();
852         NorthBoundRequest northBoundRequest;
853         if (serviceType.equalsIgnoreCase(SERVICE_TYPE_TRANSPORT)
854                 || serviceType.equalsIgnoreCase(SERVICE_TYPE_BONDING)) {
855             northBoundRequest =
856                     catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwnerAndServiceType(
857                             requestAction, resourceName.toString(), aLaCarte, cloudOwner, serviceType);
858         } else {
859             northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
860                     requestAction, resourceName.toString(), aLaCarte, cloudOwner);
861         }
862         if (northBoundRequest == null) {
863             northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
864                     requestAction, resourceName.toString(), aLaCarte, CLOUD_OWNER);
865         }
866         if (northBoundRequest == null) {
867             buildAndThrowException(execution, String.format("The request: %s %s %s is not supported by GR_API.",
868                     (aLaCarte ? "AlaCarte" : "Macro"), resourceName, requestAction));
869         } else {
870             if (northBoundRequest.getIsToplevelflow() != null) {
871                 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, northBoundRequest.getIsToplevelflow());
872             }
873             List<OrchestrationFlow> flows = northBoundRequest.getOrchestrationFlowList();
874             if (flows == null) {
875                 flows = new ArrayList<>();
876             } else {
877                 flows.sort(Comparator.comparingInt(OrchestrationFlow::getSequenceNumber));
878             }
879             for (OrchestrationFlow flow : flows) {
880                 if (!flow.getFlowName().contains("BB") && !flow.getFlowName().contains("Activity")) {
881                     List<OrchestrationFlow> macroQueryFlows =
882                             catalogDbClient.getOrchestrationFlowByAction(flow.getFlowName());
883                     listToExecute.addAll(macroQueryFlows);
884                 } else {
885                     listToExecute.add(flow);
886                 }
887             }
888         }
889         return listToExecute;
890     }
891
892     public void handleRuntimeException(DelegateExecution execution) {
893         StringBuilder wfeExpMsg = new StringBuilder("Runtime error ");
894         String runtimeErrorMessage;
895         try {
896             String javaExpMsg = (String) execution.getVariable("BPMN_javaExpMsg");
897             if (javaExpMsg != null && !javaExpMsg.isEmpty()) {
898                 wfeExpMsg.append(": ").append(javaExpMsg);
899             }
900             runtimeErrorMessage = wfeExpMsg.toString();
901             logger.error(runtimeErrorMessage);
902             execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, runtimeErrorMessage);
903         } catch (Exception e) {
904             logger.error("Runtime error", e);
905             // if runtime message was mulformed
906             runtimeErrorMessage = "Runtime error";
907         }
908         exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, runtimeErrorMessage);
909     }
910
911     protected boolean isUriResume(String uri) {
912         return uri.endsWith("/resume");
913     }
914
915     protected boolean isRequestMacroServiceResume(boolean aLaCarte, WorkflowType resourceType, String requestAction,
916             String serviceInstanceId) {
917         return (!aLaCarte && resourceType == WorkflowType.SERVICE
918                 && (requestAction.equalsIgnoreCase(ASSIGN_INSTANCE) || requestAction.equalsIgnoreCase(CREATE_INSTANCE))
919                 && (serviceInstanceId != null && serviceInstanceId.trim().length() > 1)
920                 && (bbInputSetupUtils.getAAIServiceInstanceById(serviceInstanceId) != null));
921     }
922
923     private void fillExecutionDefault(DelegateExecution execution) {
924         execution.setVariable("sentSyncResponse", false);
925         execution.setVariable(HOMING, false);
926         execution.setVariable("calledHoming", false);
927         execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, true);
928     }
929
930     private void fillExecution(DelegateExecution execution, boolean suppressRollback, String resourceId,
931             WorkflowType resourceType) {
932         execution.setVariable("suppressRollback", suppressRollback);
933         execution.setVariable("resourceId", resourceId);
934         execution.setVariable("resourceType", resourceType);
935         execution.setVariable("resourceName", resourceType.toString());
936     }
937
938     private Resource getResource(BBInputSetupUtils bbInputSetupUtils, boolean isResume, boolean alaCarte, String uri,
939             String requestId) {
940         if (!alaCarte && isResume) {
941             logger.debug("replacing URI {}", uri);
942             uri = bbInputSetupUtils.loadOriginalInfraActiveRequestById(requestId).getRequestUrl();
943             logger.debug("for RESUME with original value {}", uri);
944         }
945         return extractResourceIdAndTypeFromUri(uri);
946     }
947
948     private String getResourceId(Resource resource, String requestAction, RequestDetails requestDetails,
949             WorkflowResourceIds workflowResourceIds) throws Exception {
950         if (resource.isGenerated() && requestAction.equalsIgnoreCase("createInstance")
951                 && requestDetails.getRequestInfo().getInstanceName() != null) {
952             return aaiResourceIdValidator.validateResourceIdInAAI(resource.getResourceId(), resource.getResourceType(),
953                     requestDetails.getRequestInfo().getInstanceName(), requestDetails, workflowResourceIds);
954         } else {
955             return resource.getResourceId();
956         }
957     }
958
959     private String getServiceInstanceId(DelegateExecution execution, String resourceId, WorkflowType resourceType) {
960         String serviceInstanceId = (String) execution.getVariable("serviceInstanceId");
961         if ((serviceInstanceId == null || serviceInstanceId.isEmpty()) && WorkflowType.SERVICE.equals(resourceType)) {
962             serviceInstanceId = resourceId;
963         }
964         return serviceInstanceId;
965     }
966
967 }