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