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