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