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