d9ad245e76a12799978f1b405440d566bc95cf8d
[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) 2020 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 java.io.IOException;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Collections;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Optional;
36 import java.util.UUID;
37 import java.util.regex.Matcher;
38 import java.util.regex.Pattern;
39 import java.util.stream.Collectors;
40 import org.apache.commons.lang3.SerializationUtils;
41 import org.camunda.bpm.engine.delegate.DelegateExecution;
42 import org.javatuples.Pair;
43 import org.onap.aai.domain.yang.GenericVnf;
44 import org.onap.aai.domain.yang.GenericVnfs;
45 import org.onap.aai.domain.yang.L3Network;
46 import org.onap.aai.domain.yang.Relationship;
47 import org.onap.aai.domain.yang.ServiceInstance;
48 import org.onap.aai.domain.yang.ServiceInstances;
49 import org.onap.aai.domain.yang.Vnfc;
50 import org.onap.aai.domain.yang.VolumeGroup;
51 import org.onap.aai.domain.yang.VpnBinding;
52 import org.onap.aaiclient.client.aai.AAICommonObjectMapperProvider;
53 import org.onap.aaiclient.client.aai.AAIObjectName;
54 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper;
55 import org.onap.aaiclient.client.aai.entities.Relationships;
56 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri;
57 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory;
58 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder;
59 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types;
60 import org.onap.so.bpmn.common.BBConstants;
61 import org.onap.so.bpmn.infrastructure.workflow.tasks.utils.WorkflowResourceIdsUtils;
62 import org.onap.so.bpmn.servicedecomposition.bbobjects.Configuration;
63 import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule;
64 import org.onap.so.bpmn.servicedecomposition.entities.BuildingBlock;
65 import org.onap.so.bpmn.servicedecomposition.entities.ConfigurationResourceKeys;
66 import org.onap.so.bpmn.servicedecomposition.entities.ExecuteBuildingBlock;
67 import org.onap.so.bpmn.servicedecomposition.entities.WorkflowResourceIds;
68 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetup;
69 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetupUtils;
70 import org.onap.so.bpmn.servicedecomposition.tasks.exceptions.DuplicateNameException;
71 import org.onap.so.bpmn.servicedecomposition.tasks.exceptions.MultipleObjectsFoundException;
72 import org.onap.so.client.exception.ExceptionBuilder;
73 import org.onap.so.client.orchestration.AAIConfigurationResources;
74 import org.onap.so.client.orchestration.AAIEntityNotFoundException;
75 import org.onap.so.db.catalog.beans.CollectionNetworkResourceCustomization;
76 import org.onap.so.db.catalog.beans.CollectionResourceCustomization;
77 import org.onap.so.db.catalog.beans.CollectionResourceInstanceGroupCustomization;
78 import org.onap.so.db.catalog.beans.CvnfcConfigurationCustomization;
79 import org.onap.so.db.catalog.beans.CvnfcCustomization;
80 import org.onap.so.db.catalog.beans.InstanceGroup;
81 import org.onap.so.db.catalog.beans.VfModuleCustomization;
82 import org.onap.so.db.catalog.beans.macro.NorthBoundRequest;
83 import org.onap.so.db.catalog.beans.macro.OrchestrationFlow;
84 import org.onap.so.db.catalog.client.CatalogDbClient;
85 import org.onap.so.serviceinstancebeans.CloudConfiguration;
86 import org.onap.so.serviceinstancebeans.ModelInfo;
87 import org.onap.so.serviceinstancebeans.ModelType;
88 import org.onap.so.serviceinstancebeans.Networks;
89 import org.onap.so.serviceinstancebeans.Pnfs;
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.Service;
94 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
95 import org.onap.so.serviceinstancebeans.VfModules;
96 import org.onap.so.serviceinstancebeans.Vnfs;
97 import org.slf4j.Logger;
98 import org.slf4j.LoggerFactory;
99 import org.springframework.beans.factory.annotation.Autowired;
100 import org.springframework.core.env.Environment;
101 import org.springframework.stereotype.Component;
102 import org.springframework.util.CollectionUtils;
103 import com.fasterxml.jackson.core.JsonProcessingException;
104 import com.fasterxml.jackson.databind.ObjectMapper;
105
106 @Component
107 public class WorkflowAction {
108
109     private static final String WORKFLOW_ACTION_ERROR_MESSAGE = "WorkflowActionErrorMessage";
110     private static final String SERVICE_INSTANCES = "serviceInstances";
111     private static final String SERVICE_INSTANCE = "serviceInstance";
112     private static final String VF_MODULES = "vfModules";
113     private static final String WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI =
114             "WorkflowAction was unable to verify if the instance name already exist in AAI.";
115     private static final String VNF_TYPE = "vnfType";
116     private static final String SERVICE = "Service";
117     private static final String VNF = "Vnf";
118     private static final String PNF = "Pnf";
119     private static final String VFMODULE = "VfModule";
120     private static final String VOLUMEGROUP = "VolumeGroup";
121     private static final String NETWORK = "Network";
122     private static final String NETWORKCOLLECTION = "NetworkCollection";
123     private static final String CONFIGURATION = "Configuration";
124     private static final String ASSIGNINSTANCE = "assignInstance";
125     private static final String CREATEINSTANCE = "createInstance";
126     private static final String REPLACEINSTANCE = "replaceInstance";
127     private static final String REPLACEINSTANCERETAINASSIGNMENTS = "replaceInstanceRetainAssignments";
128     private static final String USERPARAMSERVICE = "service";
129     private static final String SUPPORTEDTYPES =
130             "vnfs|vfModules|networks|networkCollections|volumeGroups|serviceInstances|instanceGroups";
131     private static final String HOMINGSOLUTION = "Homing_Solution";
132     private static final String FABRIC_CONFIGURATION = "FabricConfiguration";
133     private static final String SERVICE_TYPE_TRANSPORT = "TRANSPORT";
134     private static final String SERVICE_TYPE_BONDING = "BONDING";
135     private static final String CLOUD_OWNER = "DEFAULT";
136     private static final Logger logger = LoggerFactory.getLogger(WorkflowAction.class);
137     private static final String NAME_EXISTS_WITH_DIFF_VERSION_ID = "(%s) and different version id (%s)";
138     private static final String NAME_EXISTS_MULTIPLE =
139             "(%s) and multiple combination of model-version-id + service-type + global-customer-id";
140     private static final String NAME_EXISTS_WITH_DIFF_COMBINATION =
141             "(%s) and global-customer-id (%s), service-type (%s), model-version-id (%s)";
142     private static final String NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID =
143             "(%s), same parent and different customization id (%s)";
144     private static final String NAME_EXISTS_WITH_DIFF_PARENT = "(%s) id (%s) and different parent relationship";
145     private static final String CREATENETWORKBB = "CreateNetworkBB";
146     private static final String ACTIVATENETWORKBB = "ActivateNetworkBB";
147     private static final String VOLUMEGROUP_DELETE_PATTERN = "(Un|De)(.*)Volume(.*)";
148     private static final String VOLUMEGROUP_CREATE_PATTERN = "(A|C)(.*)Volume(.*)";
149     private static final String CONTROLLER = "Controller";
150     private static final String DEFAULT_CLOUD_OWNER = "org.onap.so.cloud-owner";
151     private static final String HOMING = "homing";
152
153     @Autowired
154     protected BBInputSetup bbInputSetup;
155     @Autowired
156     protected BBInputSetupUtils bbInputSetupUtils;
157     @Autowired
158     private ExceptionBuilder exceptionBuilder;
159     @Autowired
160     private CatalogDbClient catalogDbClient;
161     @Autowired
162     private AAIConfigurationResources aaiConfigurationResources;
163     @Autowired
164     private WorkflowActionExtractResourcesAAI workflowActionUtils;
165     @Autowired
166     private VrfValidation vrfValidation;
167     @Autowired
168     private Environment environment;
169
170     public void setBbInputSetupUtils(BBInputSetupUtils bbInputSetupUtils) {
171         this.bbInputSetupUtils = bbInputSetupUtils;
172     }
173
174     public void setBbInputSetup(BBInputSetup bbInputSetup) {
175         this.bbInputSetup = bbInputSetup;
176     }
177
178     public void selectExecutionList(DelegateExecution execution) throws Exception {
179         try {
180             final String bpmnRequest = (String) execution.getVariable(BBConstants.G_BPMN_REQUEST);
181             ServiceInstancesRequest sIRequest =
182                     new ObjectMapper().readValue(bpmnRequest, ServiceInstancesRequest.class);
183
184             final String requestId = (String) execution.getVariable(BBConstants.G_REQUEST_ID);
185
186             String uri = (String) execution.getVariable(BBConstants.G_URI);
187             boolean isResume = isUriResume(uri);
188
189             final boolean isALaCarte = (boolean) execution.getVariable(BBConstants.G_ALACARTE);
190             Resource resource = getResource(bbInputSetupUtils, isResume, isALaCarte, uri, requestId);
191
192             WorkflowResourceIds workflowResourceIds = populateResourceIdsFromApiHandler(execution);
193             RequestDetails requestDetails = sIRequest.getRequestDetails();
194             String requestAction = (String) execution.getVariable(BBConstants.G_ACTION);
195             String resourceId = getResourceId(resource, requestAction, requestDetails, workflowResourceIds);
196             WorkflowType resourceType = resource.getResourceType();
197
198             String serviceInstanceId = getServiceInstanceId(execution, resourceId, resourceType);
199
200             fillExecution(execution, requestDetails.getRequestInfo().getSuppressRollback(), resourceId, resourceType);
201             List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
202
203             if (isRequestMacroServiceResume(isALaCarte, resourceType, requestAction, serviceInstanceId)) {
204                 String errorMessage = "Could not resume Macro flow. Error loading execution path.";
205                 flowsToExecute = loadExecuteBuildingBlocks(execution, requestId, errorMessage);
206             } else if (isALaCarte && isResume) {
207                 String errorMessage =
208                         "Could not resume request with request Id: " + requestId + ". No flowsToExecute was found";
209                 flowsToExecute = loadExecuteBuildingBlocks(execution, requestId, errorMessage);
210             } else {
211                 String vnfType = (String) execution.getVariable(VNF_TYPE);
212                 String cloudOwner = getCloudOwner(requestDetails.getCloudConfiguration());
213                 List<OrchestrationFlow> orchFlows =
214                         (List<OrchestrationFlow>) execution.getVariable(BBConstants.G_ORCHESTRATION_FLOW);
215                 final String apiVersion = (String) execution.getVariable(BBConstants.G_APIVERSION);
216                 final String serviceType =
217                         Optional.ofNullable((String) execution.getVariable(BBConstants.G_SERVICE_TYPE)).orElse("");
218                 if (isALaCarte) {
219                     if (orchFlows == null || orchFlows.isEmpty()) {
220                         orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, true,
221                                 cloudOwner, serviceType);
222                     }
223                     Resource resourceKey = getResourceKey(sIRequest, resourceType);
224
225                     ReplaceInstanceRelatedInformation replaceInfo = new ReplaceInstanceRelatedInformation();
226                     if ((requestAction.equalsIgnoreCase(REPLACEINSTANCE)
227                             || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS))
228                             && resourceType.equals(WorkflowType.VFMODULE)) {
229                         logger.debug("Build a BB list for replacing BB modules");
230                         ConfigBuildingBlocksDataObject cbbdo = createConfigBuildingBlocksDataObject(execution,
231                                 sIRequest, requestId, workflowResourceIds, requestDetails, requestAction, resourceId,
232                                 vnfType, orchFlows, apiVersion, resourceKey, replaceInfo);
233                         orchFlows = getVfModuleReplaceBuildingBlocks(cbbdo);
234
235                         createBuildingBlocksForOrchFlows(execution, sIRequest, requestId, workflowResourceIds,
236                                 requestDetails, requestAction, resourceId, flowsToExecute, vnfType, orchFlows,
237                                 apiVersion, resourceKey, replaceInfo);
238                     } else {
239                         if (isConfiguration(orchFlows) && !requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
240                             addConfigBuildingBlocksToFlowsToExecuteList(execution, sIRequest, requestId,
241                                     workflowResourceIds, requestDetails, requestAction, resourceId, flowsToExecute,
242                                     vnfType, apiVersion, resourceKey, replaceInfo, orchFlows);
243                         }
244                         orchFlows =
245                                 orchFlows.stream().filter(item -> !item.getFlowName().contains(FABRIC_CONFIGURATION))
246                                         .collect(Collectors.toList());
247
248                         for (OrchestrationFlow orchFlow : orchFlows) {
249                             ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, resourceKey,
250                                     apiVersion, resourceId, requestAction, true, vnfType, workflowResourceIds,
251                                     requestDetails, false, null, null, false, replaceInfo);
252                             flowsToExecute.add(ebb);
253                         }
254                     }
255                 } else {
256                     boolean foundRelated = false;
257                     boolean containsService = false;
258                     List<Resource> resourceList = new ArrayList<>();
259                     List<Pair<WorkflowType, String>> aaiResourceIds = new ArrayList<>();
260                     if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(ASSIGNINSTANCE)) {
261                         // SERVICE-MACRO-ASSIGN will always get user params with a
262                         // service.
263                         if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
264                             containsService = isContainsService(sIRequest);
265                             if (containsService) {
266                                 traverseUserParamsService(execution, resourceList, sIRequest, requestAction);
267                             }
268                         } else {
269                             buildAndThrowException(execution,
270                                     "Service-Macro-Assign request details must contain user params with a service");
271                         }
272                     } else if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
273                         // SERVICE-MACRO-CREATE will get user params with a service,
274                         // a service with a network, a service with a
275                         // networkcollection, OR an empty service.
276                         // If user params is just a service or null and macro
277                         // queries the SI and finds a VNF, macro fails.
278
279                         if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
280                             containsService = isContainsService(sIRequest);
281                         }
282                         if (containsService) {
283                             foundRelated = traverseUserParamsService(execution, resourceList, sIRequest, requestAction);
284                         }
285                         if (!foundRelated) {
286                             traverseCatalogDbService(execution, sIRequest, resourceList, aaiResourceIds);
287                         }
288                     } else if (resourceType == WorkflowType.SERVICE
289                             && ("activateInstance".equalsIgnoreCase(requestAction)
290                                     || "unassignInstance".equalsIgnoreCase(requestAction)
291                                     || "deleteInstance".equalsIgnoreCase(requestAction)
292                                     || requestAction.equalsIgnoreCase("activate" + FABRIC_CONFIGURATION))) {
293                         // SERVICE-MACRO-ACTIVATE, SERVICE-MACRO-UNASSIGN, and
294                         // SERVICE-MACRO-DELETE
295                         // Will never get user params with service, macro will have
296                         // to query the SI in AAI to find related instances.
297                         traverseAAIService(execution, resourceList, resourceId, aaiResourceIds);
298                     } else if (resourceType == WorkflowType.SERVICE
299                             && "deactivateInstance".equalsIgnoreCase(requestAction)) {
300                         resourceList.add(new Resource(WorkflowType.SERVICE, "", false));
301                     } else if (resourceType == WorkflowType.VNF && (REPLACEINSTANCE.equalsIgnoreCase(requestAction)
302                             || ("recreateInstance".equalsIgnoreCase(requestAction)))) {
303                         traverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
304                                 workflowResourceIds.getVnfId(), aaiResourceIds);
305                     } else if (resourceType == WorkflowType.VNF && "updateInstance".equalsIgnoreCase(requestAction)) {
306                         customTraverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
307                                 workflowResourceIds.getVnfId(), aaiResourceIds);
308                     } else {
309                         buildAndThrowException(execution, "Current Macro Request is not supported");
310                     }
311                     StringBuilder foundObjects = new StringBuilder();
312                     for (WorkflowType type : WorkflowType.values()) {
313                         foundObjects.append(type).append(" - ").append(
314                                 (int) resourceList.stream().filter(x -> type.equals(x.getResourceType())).count())
315                                 .append("    ");
316                     }
317                     logger.info("Found {}", foundObjects);
318
319                     if (orchFlows == null || orchFlows.isEmpty()) {
320                         orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, isALaCarte,
321                                 cloudOwner, serviceType);
322                     }
323                     boolean vnfReplace = false;
324                     if (resourceType.equals(WorkflowType.VNF) && (REPLACEINSTANCE.equalsIgnoreCase(requestAction)
325                             || REPLACEINSTANCERETAINASSIGNMENTS.equalsIgnoreCase(requestAction))) {
326                         vnfReplace = true;
327                     }
328                     flowsToExecute = buildExecuteBuildingBlockList(orchFlows, resourceList, requestId, apiVersion,
329                             resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, vnfReplace);
330                     if (isNetworkCollectionInTheResourceList(resourceList)) {
331                         logger.info("Sorting for Vlan Tagging");
332                         flowsToExecute = sortExecutionPathByObjectForVlanTagging(flowsToExecute, requestAction);
333                     }
334                     // By default, enable homing at VNF level for CREATEINSTANCE and ASSIGNINSTANCE
335                     if (resourceType == WorkflowType.SERVICE
336                             && (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE))
337                             && resourceList.stream().anyMatch(x -> WorkflowType.VNF.equals(x.getResourceType()))) {
338                         execution.setVariable(HOMING, true);
339                         execution.setVariable("calledHoming", false);
340                     }
341                     if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE)
342                             || requestAction.equalsIgnoreCase(CREATEINSTANCE))) {
343                         generateResourceIds(flowsToExecute, resourceList, serviceInstanceId);
344                     } else {
345                         updateResourceIdsFromAAITraversal(flowsToExecute, resourceList, aaiResourceIds,
346                                 serviceInstanceId);
347                     }
348                 }
349             }
350             // If the user set "Homing_Solution" to "none", disable homing, else if "Homing_Solution" is specified,
351             // enable it.
352             if (sIRequest.getRequestDetails().getRequestParameters() != null
353                     && sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
354                 List<Map<String, Object>> userParams = getListOfUserParams(sIRequest);
355                 for (Map<String, Object> params : userParams) {
356                     if (params.containsKey(HOMINGSOLUTION)) {
357                         execution.setVariable(HOMING, !"none".equals(params.get(HOMINGSOLUTION)));
358                     }
359                 }
360             }
361
362             if (CollectionUtils.isEmpty(flowsToExecute)) {
363                 throw new IllegalStateException("Macro did not come up with a valid execution path.");
364             }
365
366             List<String> flowNames = new ArrayList<>();
367             logger.info("List of BuildingBlocks to execute:");
368
369             flowsToExecute.forEach(ebb -> {
370                 logger.info(ebb.getBuildingBlock().getBpmnFlowName());
371                 flowNames.add(ebb.getBuildingBlock().getBpmnFlowName());
372             });
373
374             if (!isResume) {
375                 bbInputSetupUtils.persistFlowExecutionPath(requestId, flowsToExecute);
376             }
377             setExecutionVariables(execution, flowsToExecute, flowNames);
378
379         } catch (Exception ex) {
380             if (!(execution.hasVariable("WorkflowException")
381                     || execution.hasVariable("WorkflowExceptionExceptionMessage"))) {
382                 buildAndThrowException(execution, "Exception while setting execution list. ", ex);
383             } else {
384                 throw ex;
385             }
386         }
387     }
388
389     private void setExecutionVariables(DelegateExecution execution, List<ExecuteBuildingBlock> flowsToExecute,
390             List<String> flowNames) {
391         execution.setVariable("flowNames", flowNames);
392         execution.setVariable(BBConstants.G_CURRENT_SEQUENCE, 0);
393         execution.setVariable("retryCount", 0);
394         execution.setVariable("isRollback", false);
395         execution.setVariable("flowsToExecute", flowsToExecute);
396         execution.setVariable("isRollbackComplete", false);
397     }
398
399     private boolean isContainsService(ServiceInstancesRequest sIRequest) {
400         boolean containsService;
401         List<Map<String, Object>> userParams = getListOfUserParams(sIRequest);
402         containsService = userParams.stream().anyMatch(param -> param.containsKey(USERPARAMSERVICE));
403         return containsService;
404     }
405
406     private List<Map<String, Object>> getListOfUserParams(ServiceInstancesRequest sIRequest) {
407         return sIRequest.getRequestDetails().getRequestParameters().getUserParams();
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 = buildExecuteBuildingBlock(orchFlow, requestId, resourceKey, apiVersion,
448                         resourceId, requestAction, true, vnfType, workflowResourceIds, requestDetails, false, null,
449                         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.isPresent()) {
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) throws Exception {
510         T configuration = null;
511         AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().vnfc(vnfc.getVnfcName()));
512         AAIResultWrapper vnfcResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
513         Optional<Relationships> relationshipsOp = vnfcResultsWrapper.getRelationships();
514         if (!relationshipsOp.isPresent()) {
515             logger.debug("No relationships were found for VNFC in AAI");
516         } else {
517             Relationships relationships = relationshipsOp.get();
518             List<AAIResultWrapper> configurationResultWrappers =
519                     this.getResultWrappersFromRelationships(relationships, name);
520             if (configurationResultWrappers.size() > 1) {
521                 String multipleRelationshipsError =
522                         "Multiple relationships exist from VNFC " + vnfc.getVnfcName() + " to Configurations";
523                 throw new Exception(multipleRelationshipsError);
524             }
525             if (!configurationResultWrappers.isEmpty()) {
526                 Optional<T> configurationOp = configurationResultWrappers.get(0).asBean(resultClass);
527                 if (configurationOp.isPresent()) {
528                     configuration = configurationOp.get();
529                 }
530             }
531         }
532         return configuration;
533     }
534
535     protected List<AAIResultWrapper> getResultWrappersFromRelationships(Relationships relationships,
536             AAIObjectName name) {
537         return relationships.getByType(name);
538     }
539
540     protected boolean isConfiguration(List<OrchestrationFlow> orchFlows) {
541         for (OrchestrationFlow flow : orchFlows) {
542             if (flow.getFlowName().contains(CONFIGURATION) && !"ConfigurationScaleOutBB".equals(flow.getFlowName())) {
543                 return true;
544             }
545         }
546         return false;
547     }
548
549     protected List<ExecuteBuildingBlock> getConfigBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
550             throws Exception {
551
552         List<ExecuteBuildingBlock> flowsToExecuteConfigs = new ArrayList<>();
553         List<OrchestrationFlow> result = dataObj.getOrchFlows().stream()
554                 .filter(item -> item.getFlowName().contains(FABRIC_CONFIGURATION)).collect(Collectors.toList());
555         String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
556         String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
557
558         String vnfCustomizationUUID = bbInputSetupUtils.getAAIGenericVnf(vnfId).getModelCustomizationId();
559         String vfModuleCustomizationUUID;
560         org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
561
562         if (aaiVfModule == null) {
563             logger.error("No matching VfModule is found in Generic-Vnf in AAI for vnfId: {} and vfModuleId : {}", vnfId,
564                     vfModuleId);
565             throw new AAIEntityNotFoundException("No matching VfModule is found in Generic-Vnf in AAI for vnfId: "
566                     + vnfId + " and vfModuleId : " + vfModuleId);
567         } else {
568             vfModuleCustomizationUUID = aaiVfModule.getModelCustomizationId();
569         }
570         String replaceVfModuleCustomizationUUID = "";
571         String replaceVnfModuleCustomizationUUID = "";
572         boolean isReplace = false;
573         if (dataObj.getRequestAction().equalsIgnoreCase("replaceInstance")
574                 || dataObj.getRequestAction().equalsIgnoreCase("replaceInstanceRetainAssignments")) {
575             for (RelatedInstanceList relatedInstList : dataObj.getRequestDetails().getRelatedInstanceList()) {
576                 RelatedInstance relatedInstance = relatedInstList.getRelatedInstance();
577                 if (relatedInstance.getModelInfo().getModelType().equals(ModelType.vnf)) {
578                     replaceVnfModuleCustomizationUUID = relatedInstance.getModelInfo().getModelCustomizationId();
579                 }
580             }
581             replaceVfModuleCustomizationUUID = dataObj.getRequestDetails().getModelInfo().getModelCustomizationId();
582             isReplace = true;
583         }
584
585         List<org.onap.aai.domain.yang.Vnfc> vnfcs =
586                 getRelatedResourcesInVfModule(vnfId, vfModuleId, org.onap.aai.domain.yang.Vnfc.class, Types.VNFC);
587         for (org.onap.aai.domain.yang.Vnfc vnfc : vnfcs) {
588             WorkflowResourceIds workflowIdsCopy = SerializationUtils.clone(dataObj.getWorkflowResourceIds());
589             org.onap.aai.domain.yang.Configuration configuration =
590                     getRelatedResourcesInVnfc(vnfc, org.onap.aai.domain.yang.Configuration.class, Types.CONFIGURATION);
591             if (configuration == null) {
592                 logger.warn(String.format("No configuration found for VNFC %s in AAI", vnfc.getVnfcName()));
593                 continue;
594             }
595             workflowIdsCopy.setConfigurationId(configuration.getConfigurationId());
596             for (OrchestrationFlow orchFlow : result) {
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 = buildExecuteBuildingBlock(orchFlow, dataObj.getRequestId(),
617                         dataObj.getResourceKey(), dataObj.getApiVersion(), dataObj.getResourceId(),
618                         dataObj.getRequestAction(), dataObj.isaLaCarte(), dataObj.getVnfType(), workflowIdsCopy,
619                         dataObj.getRequestDetails(), false, null, vnfcName, true, null);
620                 flowsToExecuteConfigs.add(ebb);
621             }
622         }
623         return flowsToExecuteConfigs;
624     }
625
626     protected List<OrchestrationFlow> getVfModuleReplaceBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
627             throws Exception {
628
629         String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
630         String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
631
632         logger.debug("BUILDING REPLACE LIST");
633
634         boolean volumeGroupExisted = false;
635         boolean volumeGroupWillExist = false;
636         boolean keepVolumeGroup = false;
637
638         boolean rebuildVolumeGroups = false;
639         if (dataObj.getRequestDetails().getRequestParameters() != null
640                 && dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups() != null) {
641             rebuildVolumeGroups = dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups();
642         }
643         String volumeGroupName = "";
644         Optional<VolumeGroup> volumeGroupFromVfModule =
645                 bbInputSetupUtils.getRelatedVolumeGroupFromVfModule(vnfId, vfModuleId);
646         if (volumeGroupFromVfModule.isPresent()) {
647             String volumeGroupId = volumeGroupFromVfModule.get().getVolumeGroupId();
648             volumeGroupName = volumeGroupFromVfModule.get().getVolumeGroupName();
649             logger.debug("Volume group id of the existing volume group is: " + volumeGroupId);
650             volumeGroupExisted = true;
651             dataObj.getWorkflowResourceIds().setVolumeGroupId(volumeGroupId);
652             dataObj.getReplaceInformation().setOldVolumeGroupName(volumeGroupName);
653         }
654
655         List<OrchestrationFlow> orchFlows = dataObj.getOrchFlows();
656         VfModuleCustomization vfModuleCustomization = catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
657                 dataObj.getRequestDetails().getModelInfo().getModelCustomizationUuid());
658         if (vfModuleCustomization != null && vfModuleCustomization.getVfModule() != null
659                 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
660                 && vfModuleCustomization.getVolumeHeatEnv() != null) {
661             volumeGroupWillExist = true;
662             if (!volumeGroupExisted) {
663                 String newVolumeGroupId = UUID.randomUUID().toString();
664                 dataObj.getWorkflowResourceIds().setVolumeGroupId(newVolumeGroupId);
665                 dataObj.getReplaceInformation().setOldVolumeGroupName(volumeGroupName);
666                 logger.debug("newVolumeGroupId: " + newVolumeGroupId);
667             }
668         }
669
670         if (volumeGroupExisted && volumeGroupWillExist && !rebuildVolumeGroups) {
671             keepVolumeGroup = true;
672         }
673
674         if (!volumeGroupExisted || keepVolumeGroup) {
675             logger.debug("Filtering out deletion of volume groups");
676             orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_DELETE_PATTERN))
677                     .collect(Collectors.toList());
678         }
679         if (!volumeGroupWillExist || keepVolumeGroup) {
680             logger.debug("Filtering out creation of volume groups");
681             orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_CREATE_PATTERN))
682                     .collect(Collectors.toList());
683         }
684
685         return orchFlows;
686     }
687
688     protected List<Resource> sortVfModulesByBaseFirst(List<Resource> vfModuleResources) {
689         int count = 0;
690         for (Resource resource : vfModuleResources) {
691             if (resource.isBaseVfModule()) {
692                 Collections.swap(vfModuleResources, 0, count);
693                 break;
694             }
695             count++;
696         }
697         return vfModuleResources;
698     }
699
700     protected List<Resource> sortVfModulesByBaseLast(List<Resource> vfModuleResources) {
701         int count = 0;
702         for (Resource resource : vfModuleResources) {
703             if (resource.isBaseVfModule()) {
704                 Collections.swap(vfModuleResources, vfModuleResources.size() - 1, count);
705                 break;
706             }
707             count++;
708         }
709         return vfModuleResources;
710     }
711
712     private void updateResourceIdsFromAAITraversal(List<ExecuteBuildingBlock> flowsToExecute,
713             List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds, String serviceInstanceId) {
714         for (Pair<WorkflowType, String> pair : aaiResourceIds) {
715             logger.debug(pair.getValue0() + ", " + pair.getValue1());
716         }
717
718         Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
719                 .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
720                         .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
721                                 retrieveAAIResourceId(aaiResourceIds, type), null, serviceInstanceId)));
722     }
723
724     private String retrieveAAIResourceId(List<Pair<WorkflowType, String>> aaiResourceIds, WorkflowType resource) {
725         String id = null;
726         for (int i = 0; i < aaiResourceIds.size(); i++) {
727             if (aaiResourceIds.get(i).getValue0() == resource) {
728                 id = aaiResourceIds.get(i).getValue1();
729                 aaiResourceIds.remove(i);
730                 break;
731             }
732         }
733         return id;
734     }
735
736     private void generateResourceIds(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
737             String serviceInstanceId) {
738         Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
739                 .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
740                         .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
741                                 null, resource.getVirtualLinkKey(), serviceInstanceId)));
742     }
743
744     protected void updateWorkflowResourceIds(List<ExecuteBuildingBlock> flowsToExecute, WorkflowType resourceType,
745             String key, String id, String virtualLinkKey, String serviceInstanceId) {
746         String resourceId = id;
747         if (resourceId == null) {
748             resourceId = UUID.randomUUID().toString();
749         }
750         for (ExecuteBuildingBlock ebb : flowsToExecute) {
751             if (key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey()) && (ebb.getBuildingBlock()
752                     .getBpmnFlowName().contains(resourceType.toString())
753                     || (ebb.getBuildingBlock().getBpmnFlowName().contains(CONTROLLER)
754                             && ebb.getBuildingBlock().getBpmnScope().equalsIgnoreCase(resourceType.toString())))) {
755                 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
756                 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
757                 WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, resourceType, resourceId);
758                 ebb.setWorkflowResourceIds(workflowResourceIds);
759             }
760             if (virtualLinkKey != null && ebb.getBuildingBlock().isVirtualLink()
761                     && virtualLinkKey.equalsIgnoreCase(ebb.getBuildingBlock().getVirtualLinkKey())) {
762                 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
763                 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
764                 workflowResourceIds.setNetworkId(resourceId);
765                 ebb.setWorkflowResourceIds(workflowResourceIds);
766             }
767         }
768     }
769
770     protected CollectionResourceCustomization findCatalogNetworkCollection(DelegateExecution execution,
771             org.onap.so.db.catalog.beans.Service service) {
772         CollectionResourceCustomization networkCollection = null;
773         int count = 0;
774         for (CollectionResourceCustomization collectionCust : service.getCollectionResourceCustomizations()) {
775             if (catalogDbClient.getNetworkCollectionResourceCustomizationByID(
776                     collectionCust.getModelCustomizationUUID()) != null) {
777                 networkCollection = collectionCust;
778                 count++;
779             }
780         }
781         if (count == 0) {
782             return null;
783         } else if (count > 1) {
784             buildAndThrowException(execution,
785                     "Found multiple Network Collections in the Service model, only one per Service is supported.");
786         }
787         return networkCollection;
788     }
789
790     protected void traverseCatalogDbService(DelegateExecution execution, ServiceInstancesRequest sIRequest,
791             List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds)
792             throws JsonProcessingException, VrfBondingServiceException {
793         String modelUUID = sIRequest.getRequestDetails().getModelInfo().getModelVersionId();
794         org.onap.so.db.catalog.beans.Service service = catalogDbClient.getServiceByID(modelUUID);
795
796         if (service == null) {
797             buildAndThrowException(execution, "Could not find the service model in catalog db.");
798         } else {
799             resourceList.add(new Resource(WorkflowType.SERVICE, service.getModelUUID(), false));
800             RelatedInstance relatedVpnBinding =
801                     bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.vpnBinding);
802             RelatedInstance relatedLocalNetwork =
803                     bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.network);
804
805             if (relatedVpnBinding != null && relatedLocalNetwork != null) {
806                 traverseVrfConfiguration(aaiResourceIds, resourceList, service, relatedVpnBinding, relatedLocalNetwork);
807             } else {
808                 traverseNetworkCollection(execution, resourceList, service);
809             }
810         }
811     }
812
813     protected void traverseVrfConfiguration(List<Pair<WorkflowType, String>> aaiResourceIds,
814             List<Resource> resourceList, org.onap.so.db.catalog.beans.Service service,
815             RelatedInstance relatedVpnBinding, RelatedInstance relatedLocalNetwork)
816             throws VrfBondingServiceException, JsonProcessingException {
817         org.onap.aai.domain.yang.L3Network aaiLocalNetwork =
818                 bbInputSetupUtils.getAAIL3Network(relatedLocalNetwork.getInstanceId());
819         vrfValidation.vrfServiceValidation(service);
820         vrfValidation.vrfCatalogDbChecks(service);
821         vrfValidation.aaiVpnBindingValidation(relatedVpnBinding.getInstanceId(),
822                 bbInputSetupUtils.getAAIVpnBinding(relatedVpnBinding.getInstanceId()));
823         vrfValidation.aaiNetworkValidation(relatedLocalNetwork.getInstanceId(), aaiLocalNetwork);
824         vrfValidation.aaiSubnetValidation(aaiLocalNetwork);
825         vrfValidation.aaiAggregateRouteValidation(aaiLocalNetwork);
826         vrfValidation.aaiRouteTargetValidation(aaiLocalNetwork);
827         String existingAAIVrfConfiguration = getExistingAAIVrfConfiguration(relatedVpnBinding, aaiLocalNetwork);
828         if (existingAAIVrfConfiguration != null) {
829             aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, existingAAIVrfConfiguration));
830         }
831         resourceList.add(new Resource(WorkflowType.CONFIGURATION,
832                 service.getConfigurationCustomizations().get(0).getModelCustomizationUUID(), false));
833
834     }
835
836     protected String getExistingAAIVrfConfiguration(RelatedInstance relatedVpnBinding,
837             org.onap.aai.domain.yang.L3Network aaiLocalNetwork)
838             throws JsonProcessingException, VrfBondingServiceException {
839         Optional<Relationships> relationshipsOp = new AAIResultWrapper(
840                 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiLocalNetwork)).getRelationships();
841         if (relationshipsOp.isPresent()) {
842             List<AAIResultWrapper> configurationsRelatedToLocalNetwork =
843                     relationshipsOp.get().getByType(Types.CONFIGURATION);
844             if (configurationsRelatedToLocalNetwork.size() > 1) {
845                 throw new VrfBondingServiceException(
846                         "Network: " + aaiLocalNetwork.getNetworkId() + " has more than 1 configuration related to it");
847             }
848             if (configurationsRelatedToLocalNetwork.size() == 1) {
849                 AAIResultWrapper configWrapper = configurationsRelatedToLocalNetwork.get(0);
850                 Optional<Configuration> relatedConfiguration = configWrapper.asBean(Configuration.class);
851                 if (relatedConfiguration.isPresent() && vrfConfigurationAlreadyExists(relatedVpnBinding,
852                         relatedConfiguration.get(), configWrapper)) {
853                     return relatedConfiguration.get().getConfigurationId();
854                 }
855             }
856         }
857         return null;
858     }
859
860     protected boolean vrfConfigurationAlreadyExists(RelatedInstance relatedVpnBinding, Configuration vrfConfiguration,
861             AAIResultWrapper configWrapper) throws VrfBondingServiceException {
862         if ("VRF-ENTRY".equalsIgnoreCase(vrfConfiguration.getConfigurationType())) {
863             Optional<Relationships> relationshipsConfigOp = configWrapper.getRelationships();
864             if (relationshipsConfigOp.isPresent()) {
865                 Optional<VpnBinding> relatedInfraVpnBindingOp =
866                         workflowActionUtils.extractRelationshipsVpnBinding(relationshipsConfigOp.get());
867                 if (relatedInfraVpnBindingOp.isPresent()) {
868                     VpnBinding relatedInfraVpnBinding = relatedInfraVpnBindingOp.get();
869                     if (!relatedInfraVpnBinding.getVpnId().equalsIgnoreCase(relatedVpnBinding.getInstanceId())) {
870                         throw new VrfBondingServiceException("Configuration: " + vrfConfiguration.getConfigurationId()
871                                 + " is not connected to the same vpn binding id provided in request: "
872                                 + relatedVpnBinding.getInstanceId());
873                     } else {
874                         return true;
875                     }
876                 }
877             }
878         }
879         return false;
880     }
881
882     protected void traverseNetworkCollection(DelegateExecution execution, List<Resource> resourceList,
883             org.onap.so.db.catalog.beans.Service service) {
884         if (isVnfCustomizationsInTheService(service)) {
885             buildAndThrowException(execution,
886                     "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");
887         }
888         if (isPnfCustomizationsInTheService(service)) {
889             buildAndThrowException(execution,
890                     "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");
891         }
892         List<CollectionResourceCustomization> customizations = service.getCollectionResourceCustomizations();
893         if (customizations.isEmpty()) {
894             logger.debug("No Collections found. CollectionResourceCustomization list is empty.");
895         } else {
896             CollectionResourceCustomization collectionResourceCustomization =
897                     findCatalogNetworkCollection(execution, service);
898             traverseNetworkCollectionResourceCustomization(resourceList, collectionResourceCustomization);
899         }
900         traverseNetworkCollectionCustomization(resourceList, service);
901     }
902
903     private void traverseNetworkCollectionResourceCustomization(List<Resource> resourceList,
904             CollectionResourceCustomization collectionResourceCustomization) {
905         if (collectionResourceCustomizationShouldNotBeProcessed(resourceList, collectionResourceCustomization))
906             return;
907         int minNetworks = 0;
908         org.onap.so.db.catalog.beans.InstanceGroup instanceGroup =
909                 collectionResourceCustomization.getCollectionResource().getInstanceGroup();
910         CollectionResourceInstanceGroupCustomization collectionInstCust = null;
911         if (!instanceGroup.getCollectionInstanceGroupCustomizations().isEmpty()) {
912             for (CollectionResourceInstanceGroupCustomization collectionInstanceGroupTemp : instanceGroup
913                     .getCollectionInstanceGroupCustomizations()) {
914                 if (collectionInstanceGroupTemp.getModelCustomizationUUID()
915                         .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
916                     collectionInstCust = collectionInstanceGroupTemp;
917                     break;
918                 }
919             }
920             if (interfaceNetworkQuantityIsAvailableInCollection(collectionInstCust)) {
921                 minNetworks = collectionInstCust.getSubInterfaceNetworkQuantity();
922             }
923         }
924         logger.debug("minNetworks: {}", minNetworks);
925         CollectionNetworkResourceCustomization collectionNetworkResourceCust =
926                 getCollectionNetworkResourceCustomization(collectionResourceCustomization, instanceGroup);
927         for (int i = 0; i < minNetworks; i++) {
928             if (collectionNetworkResourceCust != null) {
929                 Resource resource = new Resource(WorkflowType.VIRTUAL_LINK,
930                         collectionNetworkResourceCust.getModelCustomizationUUID(), false);
931                 resource.setVirtualLinkKey(Integer.toString(i));
932                 resourceList.add(resource);
933             }
934         }
935     }
936
937     private CollectionNetworkResourceCustomization getCollectionNetworkResourceCustomization(
938             CollectionResourceCustomization collectionResourceCustomization, InstanceGroup instanceGroup) {
939         CollectionNetworkResourceCustomization collectionNetworkResourceCust = null;
940         for (CollectionNetworkResourceCustomization collectionNetworkTemp : instanceGroup
941                 .getCollectionNetworkResourceCustomizations()) {
942             if (collectionNetworkTemp.getNetworkResourceCustomization().getModelCustomizationUUID()
943                     .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
944                 collectionNetworkResourceCust = collectionNetworkTemp;
945                 break;
946             }
947         }
948         return collectionNetworkResourceCust;
949     }
950
951     private boolean collectionResourceCustomizationShouldNotBeProcessed(List<Resource> resourceList,
952             CollectionResourceCustomization collectionResourceCustomization) {
953         if (collectionResourceCustomization == null) {
954             logger.debug("No Network Collection Customization found");
955             return true;
956         }
957         resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
958                 collectionResourceCustomization.getModelCustomizationUUID(), false));
959         logger.debug("Found a network collection");
960         if (collectionResourceCustomization.getCollectionResource() == null) {
961             logger.debug("No Network Collection found. collectionResource is null");
962             return true;
963         }
964         if (collectionResourceCustomization.getCollectionResource().getInstanceGroup() == null) {
965             logger.debug("No Instance Group found for network collection.");
966             return true;
967         }
968         String toscaNodeType =
969                 collectionResourceCustomization.getCollectionResource().getInstanceGroup().getToscaNodeType();
970         if (!toscaNodeTypeHasNetworkCollection(toscaNodeType)) {
971             logger.debug("Instance Group tosca node type does not contain NetworkCollection:  {}", toscaNodeType);
972             return true;
973         }
974         return false;
975     }
976
977     private boolean interfaceNetworkQuantityIsAvailableInCollection(
978             CollectionResourceInstanceGroupCustomization collectionInstCust) {
979         return collectionInstCust != null && collectionInstCust.getSubInterfaceNetworkQuantity() != null;
980     }
981
982     private boolean toscaNodeTypeHasNetworkCollection(String toscaNodeType) {
983         return toscaNodeType != null && toscaNodeType.contains(NETWORKCOLLECTION);
984     }
985
986     private void traverseNetworkCollectionCustomization(List<Resource> resourceList,
987             org.onap.so.db.catalog.beans.Service service) {
988         if (isNetworkCollectionInTheResourceList(resourceList)) {
989             return;
990         }
991         if (service.getNetworkCustomizations() == null) {
992             logger.debug("No networks were found on this service model");
993             return;
994         }
995         for (int i = 0; i < service.getNetworkCustomizations().size(); i++) {
996             resourceList.add(new Resource(WorkflowType.NETWORK,
997                     service.getNetworkCustomizations().get(i).getModelCustomizationUUID(), false));
998         }
999     }
1000
1001     private boolean isNetworkCollectionInTheResourceList(List<Resource> resourceList) {
1002         return resourceList.stream().anyMatch(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType());
1003     }
1004
1005     private boolean isVnfCustomizationsInTheService(org.onap.so.db.catalog.beans.Service service) {
1006         return !(service.getVnfCustomizations() == null || service.getVnfCustomizations().isEmpty());
1007     }
1008
1009     private boolean isPnfCustomizationsInTheService(org.onap.so.db.catalog.beans.Service service) {
1010         return !(service.getPnfCustomizations() == null || service.getPnfCustomizations().isEmpty());
1011     }
1012
1013     protected void traverseAAIService(DelegateExecution execution, List<Resource> resourceList, String resourceId,
1014             List<Pair<WorkflowType, String>> aaiResourceIds) {
1015         try {
1016             ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(resourceId);
1017             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
1018                     bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
1019             resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
1020             traverseServiceInstanceMSOVnfs(resourceList, aaiResourceIds, serviceInstanceMSO);
1021             traverseServiceInstanceMSOPnfs(resourceList, aaiResourceIds, serviceInstanceMSO);
1022             if (serviceInstanceMSO.getNetworks() != null) {
1023                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network network : serviceInstanceMSO
1024                         .getNetworks()) {
1025                     aaiResourceIds.add(new Pair<>(WorkflowType.NETWORK, network.getNetworkId()));
1026                     resourceList.add(new Resource(WorkflowType.NETWORK, network.getNetworkId(), false));
1027                 }
1028             }
1029             if (serviceInstanceMSO.getCollection() != null) {
1030                 logger.debug("found networkcollection");
1031                 aaiResourceIds
1032                         .add(new Pair<>(WorkflowType.NETWORKCOLLECTION, serviceInstanceMSO.getCollection().getId()));
1033                 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
1034                         serviceInstanceMSO.getCollection().getId(), false));
1035             }
1036             if (serviceInstanceMSO.getConfigurations() != null) {
1037                 for (Configuration config : serviceInstanceMSO.getConfigurations()) {
1038                     Optional<org.onap.aai.domain.yang.Configuration> aaiConfig =
1039                             aaiConfigurationResources.getConfiguration(config.getConfigurationId());
1040                     if (aaiConfig.isPresent() && aaiConfig.get().getRelationshipList() != null) {
1041                         for (Relationship relationship : aaiConfig.get().getRelationshipList().getRelationship()) {
1042                             if (relationship.getRelatedTo().contains("vnfc")
1043                                     || relationship.getRelatedTo().contains("vpn-binding")) {
1044                                 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.getConfigurationId()));
1045                                 resourceList.add(
1046                                         new Resource(WorkflowType.CONFIGURATION, config.getConfigurationId(), false));
1047                                 break;
1048                             }
1049                         }
1050                     }
1051                 }
1052             }
1053         } catch (Exception ex) {
1054             logger.error("Exception in traverseAAIService", ex);
1055             buildAndThrowException(execution,
1056                     "Could not find existing Service Instance or related Instances to execute the request on.");
1057         }
1058     }
1059
1060     private void traverseServiceInstanceMSOVnfs(List<Resource> resourceList,
1061             List<Pair<WorkflowType, String>> aaiResourceIds,
1062             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO) {
1063         if (serviceInstanceMSO.getVnfs() == null) {
1064             return;
1065         }
1066         for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
1067             aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
1068             resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
1069             traverseVnfModules(resourceList, aaiResourceIds, vnf);
1070             if (vnf.getVolumeGroups() != null) {
1071                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf.getVolumeGroups()) {
1072                     aaiResourceIds.add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1073                     resourceList.add(new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1074                 }
1075             }
1076         }
1077     }
1078
1079     private void traverseServiceInstanceMSOPnfs(List<Resource> resourceList,
1080             List<Pair<WorkflowType, String>> aaiResourceIds,
1081             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO) {
1082         if (serviceInstanceMSO.getPnfs() == null) {
1083             return;
1084         }
1085         for (org.onap.so.bpmn.servicedecomposition.bbobjects.Pnf pnf : serviceInstanceMSO.getPnfs()) {
1086             aaiResourceIds.add(new Pair<>(WorkflowType.PNF, pnf.getPnfId()));
1087             resourceList.add(new Resource(WorkflowType.PNF, pnf.getPnfId(), false));
1088         }
1089     }
1090
1091     private void traverseVnfModules(List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds,
1092             org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf) {
1093         if (vnf.getVfModules() == null) {
1094             return;
1095         }
1096         for (VfModule vfModule : vnf.getVfModules()) {
1097             aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1098             Resource resource = new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false);
1099             resource.setBaseVfModule(vfModule.getModelInfoVfModule().getIsBaseBoolean());
1100             resourceList.add(resource);
1101         }
1102     }
1103
1104     private void traverseAAIVnf(DelegateExecution execution, List<Resource> resourceList, String serviceId,
1105             String vnfId, List<Pair<WorkflowType, String>> aaiResourceIds) {
1106         try {
1107             ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(serviceId);
1108             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
1109                     bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
1110             resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
1111             if (serviceInstanceMSO.getVnfs() != null) {
1112                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
1113                     if (vnf.getVnfId().equals(vnfId)) {
1114                         aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
1115                         resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
1116                         if (vnf.getVfModules() != null) {
1117                             for (VfModule vfModule : vnf.getVfModules()) {
1118                                 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1119                                 resourceList.add(new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false));
1120                                 findConfigurationsInsideVfModule(execution, vnf.getVnfId(), vfModule.getVfModuleId(),
1121                                         resourceList, aaiResourceIds);
1122                             }
1123                         }
1124                         if (vnf.getVolumeGroups() != null) {
1125                             for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
1126                                     .getVolumeGroups()) {
1127                                 aaiResourceIds
1128                                         .add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1129                                 resourceList.add(
1130                                         new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1131                             }
1132                         }
1133                         break;
1134                     }
1135                 }
1136             }
1137         } catch (Exception ex) {
1138             logger.error("Exception in traverseAAIVnf", ex);
1139             buildAndThrowException(execution,
1140                     "Could not find existing Vnf or related Instances to execute the request on.");
1141         }
1142     }
1143
1144     private void customTraverseAAIVnf(DelegateExecution execution, List<Resource> resourceList, String serviceId,
1145             String vnfId, List<Pair<WorkflowType, String>> aaiResourceIds) {
1146         try {
1147             ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(serviceId);
1148             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
1149                     bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
1150             resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
1151             if (serviceInstanceMSO.getVnfs() != null) {
1152                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
1153                     if (vnf.getVnfId().equals(vnfId)) {
1154                         aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
1155
1156                         String vnfCustomizationUUID =
1157                                 bbInputSetupUtils.getAAIGenericVnf(vnfId).getModelCustomizationId();
1158                         resourceList.add(new Resource(WorkflowType.VNF, vnfCustomizationUUID, false));
1159
1160                         if (vnf.getVfModules() != null) {
1161                             for (VfModule vfModule : vnf.getVfModules()) {
1162                                 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1163                                 resourceList.add(new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false));
1164                                 findConfigurationsInsideVfModule(execution, vnf.getVnfId(), vfModule.getVfModuleId(),
1165                                         resourceList, aaiResourceIds);
1166                             }
1167                         }
1168                         if (vnf.getVolumeGroups() != null) {
1169                             for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
1170                                     .getVolumeGroups()) {
1171                                 aaiResourceIds
1172                                         .add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1173                                 resourceList.add(
1174                                         new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1175                             }
1176                         }
1177                         break;
1178                     }
1179                 }
1180             }
1181         } catch (Exception ex) {
1182             logger.error("Exception in customTraverseAAIVnf", ex);
1183             buildAndThrowException(execution,
1184                     "Could not find existing Vnf or related Instances to execute the request on.");
1185         }
1186
1187     }
1188
1189     private void findConfigurationsInsideVfModule(DelegateExecution execution, String vnfId, String vfModuleId,
1190             List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds) {
1191         try {
1192             org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
1193             AAIResultWrapper vfModuleWrapper = new AAIResultWrapper(
1194                     new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiVfModule));
1195             Optional<Relationships> relationshipsOp;
1196             relationshipsOp = vfModuleWrapper.getRelationships();
1197             if (relationshipsOp.isPresent()) {
1198                 relationshipsOp = workflowActionUtils.extractRelationshipsVnfc(relationshipsOp.get());
1199                 if (relationshipsOp.isPresent()) {
1200                     Optional<Configuration> config =
1201                             workflowActionUtils.extractRelationshipsConfiguration(relationshipsOp.get());
1202                     if (config.isPresent()) {
1203                         aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.get().getConfigurationId()));
1204                         resourceList.add(
1205                                 new Resource(WorkflowType.CONFIGURATION, config.get().getConfigurationId(), false));
1206                     }
1207                 }
1208             }
1209         } catch (Exception ex) {
1210             logger.error("Exception in findConfigurationsInsideVfModule", ex);
1211             buildAndThrowException(execution, "Failed to find Configuration object from the vfModule.");
1212         }
1213     }
1214
1215     protected boolean traverseUserParamsService(DelegateExecution execution, List<Resource> resourceList,
1216             ServiceInstancesRequest sIRequest, String requestAction) throws IOException {
1217         boolean foundRelated = false;
1218         boolean foundVfModuleOrVG = false;
1219         String vnfCustomizationUUID = "";
1220         String vfModuleCustomizationUUID = "";
1221         if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
1222             List<Map<String, Object>> userParams = getListOfUserParams(sIRequest);
1223             for (Map<String, Object> params : userParams) {
1224                 if (params.containsKey(USERPARAMSERVICE)) {
1225                     ObjectMapper obj = new ObjectMapper();
1226                     String input = obj.writeValueAsString(params.get(USERPARAMSERVICE));
1227                     Service validate = obj.readValue(input, Service.class);
1228                     resourceList.add(
1229                             new Resource(WorkflowType.SERVICE, validate.getModelInfo().getModelVersionId(), false));
1230                     if (validate.getResources().getVnfs() != null) {
1231                         for (Vnfs vnf : validate.getResources().getVnfs()) {
1232                             resourceList.add(new Resource(WorkflowType.VNF,
1233                                     vnf.getModelInfo().getModelCustomizationId(), false));
1234                             foundRelated = true;
1235                             if (vnf.getModelInfo() != null && vnf.getModelInfo().getModelCustomizationUuid() != null) {
1236                                 vnfCustomizationUUID = vnf.getModelInfo().getModelCustomizationUuid();
1237                             }
1238                             if (vnf.getVfModules() != null) {
1239                                 for (VfModules vfModule : vnf.getVfModules()) {
1240                                     VfModuleCustomization vfModuleCustomization =
1241                                             catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
1242                                                     vfModule.getModelInfo().getModelCustomizationUuid());
1243                                     if (vfModuleCustomization != null) {
1244
1245                                         if (vfModuleCustomization.getVfModule() != null
1246                                                 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
1247                                                 && vfModuleCustomization.getVolumeHeatEnv() != null) {
1248                                             resourceList.add(new Resource(WorkflowType.VOLUMEGROUP,
1249                                                     vfModuleCustomization.getModelCustomizationUUID(), false));
1250                                             foundVfModuleOrVG = true;
1251                                         }
1252
1253                                         if (vfModuleCustomization.getVfModule() != null
1254                                                 && vfModuleCustomization.getVfModule().getModuleHeatTemplate() != null
1255                                                 && vfModuleCustomization.getHeatEnvironment() != null) {
1256                                             foundVfModuleOrVG = true;
1257                                             Resource resource = new Resource(WorkflowType.VFMODULE,
1258                                                     vfModuleCustomization.getModelCustomizationUUID(), false);
1259                                             resource.setBaseVfModule(
1260                                                     vfModuleCustomization.getVfModule().getIsBase() != null
1261                                                             && vfModuleCustomization.getVfModule().getIsBase());
1262                                             resourceList.add(resource);
1263                                             if (vfModule.getModelInfo() != null
1264                                                     && vfModule.getModelInfo().getModelCustomizationUuid() != null) {
1265                                                 vfModuleCustomizationUUID =
1266                                                         vfModule.getModelInfo().getModelCustomizationUuid();
1267                                             }
1268                                             if (!vnfCustomizationUUID.isEmpty()
1269                                                     && !vfModuleCustomizationUUID.isEmpty()) {
1270                                                 List<CvnfcConfigurationCustomization> configs =
1271                                                         traverseCatalogDbForConfiguration(
1272                                                                 validate.getModelInfo().getModelVersionId(),
1273                                                                 vnfCustomizationUUID, vfModuleCustomizationUUID);
1274                                                 for (CvnfcConfigurationCustomization config : configs) {
1275                                                     Resource configResource = new Resource(WorkflowType.CONFIGURATION,
1276                                                             config.getConfigurationResource().getModelUUID(), false);
1277                                                     resource.setVnfCustomizationId(
1278                                                             vnf.getModelInfo().getModelCustomizationId());
1279                                                     resource.setVfModuleCustomizationId(
1280                                                             vfModule.getModelInfo().getModelCustomizationId());
1281                                                     resourceList.add(configResource);
1282                                                 }
1283                                             }
1284                                         }
1285                                         if (!foundVfModuleOrVG) {
1286                                             buildAndThrowException(execution,
1287                                                     "Could not determine if vfModule was a vfModule or volume group. Heat template and Heat env are null");
1288                                         }
1289                                     }
1290                                 }
1291                             }
1292                         }
1293                     }
1294                     if (validate.getResources().getPnfs() != null) {
1295                         for (Pnfs pnf : validate.getResources().getPnfs()) {
1296                             resourceList.add(new Resource(WorkflowType.PNF,
1297                                     pnf.getModelInfo().getModelCustomizationId(), false));
1298                             foundRelated = true;
1299                         }
1300                     }
1301                     if (validate.getResources().getNetworks() != null) {
1302                         for (Networks network : validate.getResources().getNetworks()) {
1303                             resourceList.add(new Resource(WorkflowType.NETWORK,
1304                                     network.getModelInfo().getModelCustomizationId(), false));
1305                             foundRelated = true;
1306                         }
1307                         if (requestAction.equals(CREATEINSTANCE)) {
1308                             String networkColCustId = queryCatalogDBforNetworkCollection(execution, sIRequest);
1309                             if (networkColCustId != null) {
1310                                 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION, networkColCustId, false));
1311                                 foundRelated = true;
1312                             }
1313                         }
1314                     }
1315                     break;
1316                 }
1317             }
1318         }
1319         return foundRelated;
1320     }
1321
1322     protected List<CvnfcConfigurationCustomization> traverseCatalogDbForConfiguration(String serviceModelUUID,
1323             String vnfCustomizationUUID, String vfModuleCustomizationUUID) {
1324         List<CvnfcConfigurationCustomization> configurations = new ArrayList<>();
1325         try {
1326             List<CvnfcCustomization> cvnfcCustomizations = catalogDbClient.getCvnfcCustomization(serviceModelUUID,
1327                     vnfCustomizationUUID, vfModuleCustomizationUUID);
1328             for (CvnfcCustomization cvnfc : cvnfcCustomizations) {
1329                 for (CvnfcConfigurationCustomization customization : cvnfc.getCvnfcConfigurationCustomization()) {
1330                     if (customization.getConfigurationResource().getToscaNodeType().contains(FABRIC_CONFIGURATION)) {
1331                         configurations.add(customization);
1332                     }
1333                 }
1334             }
1335             logger.debug("found {} fabric configuration(s)", configurations.size());
1336             return configurations;
1337         } catch (Exception ex) {
1338             logger.error("Error in finding configurations", ex);
1339             return configurations;
1340         }
1341     }
1342
1343     protected String queryCatalogDBforNetworkCollection(DelegateExecution execution,
1344             ServiceInstancesRequest sIRequest) {
1345         org.onap.so.db.catalog.beans.Service service =
1346                 catalogDbClient.getServiceByID(sIRequest.getRequestDetails().getModelInfo().getModelVersionId());
1347         if (service != null) {
1348             CollectionResourceCustomization networkCollection = this.findCatalogNetworkCollection(execution, service);
1349             if (networkCollection != null) {
1350                 return networkCollection.getModelCustomizationUUID();
1351             }
1352         }
1353         return null;
1354     }
1355
1356     protected WorkflowResourceIds populateResourceIdsFromApiHandler(DelegateExecution execution) {
1357         return WorkflowResourceIdsUtils.getWorkflowResourceIdsFromExecution(execution);
1358     }
1359
1360     protected Resource extractResourceIdAndTypeFromUri(String uri) {
1361         Pattern patt = Pattern.compile("[vV]\\d+.*?(?:(?:/(?<type>" + SUPPORTEDTYPES
1362                 + ")(?:/(?<id>[^/]+))?)(?:/(?<action>[^/]+))?(?:/resume)?)?$");
1363         Matcher m = patt.matcher(uri);
1364         boolean generated = false;
1365
1366         if (m.find()) {
1367             logger.debug("found match on {} : {} ", uri, m);
1368             String type = m.group("type");
1369             String id = m.group("id");
1370             String action = m.group("action");
1371             if (type == null) {
1372                 throw new IllegalArgumentException("Uri could not be parsed. No type found. " + uri);
1373             }
1374             if (action == null) {
1375                 if (type.equals(SERVICE_INSTANCES) && (id == null || "assign".equals(id))) {
1376                     id = UUID.randomUUID().toString();
1377                     generated = true;
1378                 } else if (type.equals(VF_MODULES) && "scaleOut".equals(id)) {
1379                     id = UUID.randomUUID().toString();
1380                     generated = true;
1381                 }
1382             } else {
1383                 if (action.matches(SUPPORTEDTYPES)) {
1384                     id = UUID.randomUUID().toString();
1385                     generated = true;
1386                     type = action;
1387                 }
1388             }
1389             return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated);
1390         } else {
1391             throw new IllegalArgumentException("Uri could not be parsed: " + uri);
1392         }
1393     }
1394
1395     protected String validateResourceIdInAAI(String generatedResourceId, WorkflowType type, String instanceName,
1396             RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws Exception {
1397         try {
1398             if ("SERVICE".equalsIgnoreCase(type.toString())) {
1399                 return validateServiceResourceIdInAAI(generatedResourceId, instanceName, reqDetails);
1400             } else if ("NETWORK".equalsIgnoreCase(type.toString())) {
1401                 return validateNetworkResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1402                         workflowResourceIds);
1403             } else if ("VNF".equalsIgnoreCase(type.toString())) {
1404                 return validateVnfResourceIdInAAI(generatedResourceId, instanceName, reqDetails, workflowResourceIds);
1405             } else if ("VFMODULE".equalsIgnoreCase(type.toString())) {
1406                 return validateVfModuleResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1407                         workflowResourceIds);
1408             } else if ("VOLUMEGROUP".equalsIgnoreCase(type.toString())) {
1409                 return validateVolumeGroupResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1410                         workflowResourceIds);
1411             } else if ("CONFIGURATION".equalsIgnoreCase(type.toString())) {
1412                 return validateConfigurationResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1413                         workflowResourceIds);
1414             }
1415             return generatedResourceId;
1416         } catch (DuplicateNameException dne) {
1417             throw dne;
1418         } catch (Exception ex) {
1419             logger.error(WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI, ex);
1420             throw new IllegalStateException(
1421                     WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI);
1422         }
1423     }
1424
1425     protected String convertTypeFromPlural(String type) {
1426         if (!type.matches(SUPPORTEDTYPES)) {
1427             return type;
1428         } else {
1429             if (type.equals(SERVICE_INSTANCES)) {
1430                 return SERVICE;
1431             } else {
1432                 return type.substring(0, 1).toUpperCase() + type.substring(1, type.length() - 1);
1433             }
1434         }
1435     }
1436
1437     protected List<ExecuteBuildingBlock> sortExecutionPathByObjectForVlanTagging(List<ExecuteBuildingBlock> orchFlows,
1438             String requestAction) {
1439         List<ExecuteBuildingBlock> sortedOrchFlows = new ArrayList<>();
1440         if (requestAction.equals(CREATEINSTANCE)) {
1441             for (ExecuteBuildingBlock ebb : orchFlows) {
1442                 if (ebb.getBuildingBlock().getBpmnFlowName().equals("AssignNetworkBB")) {
1443                     String key = ebb.getBuildingBlock().getKey();
1444                     boolean isVirtualLink = Boolean.TRUE.equals(ebb.getBuildingBlock().isVirtualLink());
1445                     String virtualLinkKey = ebb.getBuildingBlock().getVirtualLinkKey();
1446                     sortedOrchFlows.add(ebb);
1447                     for (ExecuteBuildingBlock ebb2 : orchFlows) {
1448                         if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1449                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1450                             sortedOrchFlows.add(ebb2);
1451                             break;
1452                         }
1453                         if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1454                                 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1455                             sortedOrchFlows.add(ebb2);
1456                             break;
1457                         }
1458                     }
1459                     for (ExecuteBuildingBlock ebb2 : orchFlows) {
1460                         if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1461                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1462                             sortedOrchFlows.add(ebb2);
1463                             break;
1464                         }
1465                         if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1466                                 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1467                             sortedOrchFlows.add(ebb2);
1468                             break;
1469                         }
1470                     }
1471                 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1472                         || ebb.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)) {
1473                     continue;
1474                 } else if (!"".equals(ebb.getBuildingBlock().getBpmnFlowName())) {
1475                     sortedOrchFlows.add(ebb);
1476                 }
1477             }
1478         } else if (requestAction.equals("deleteInstance")) {
1479             for (ExecuteBuildingBlock ebb : orchFlows) {
1480                 if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeactivateNetworkBB")) {
1481                     sortedOrchFlows.add(ebb);
1482                     String key = ebb.getBuildingBlock().getKey();
1483                     for (ExecuteBuildingBlock ebb2 : orchFlows) {
1484                         if (ebb2.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1485                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1486                             sortedOrchFlows.add(ebb2);
1487                             break;
1488                         }
1489                     }
1490                     for (ExecuteBuildingBlock ebb2 : orchFlows) {
1491                         if (ebb2.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")
1492                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1493                             sortedOrchFlows.add(ebb2);
1494                             break;
1495                         }
1496                     }
1497                 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1498                         || ebb.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")) {
1499                     continue;
1500                 } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) {
1501                     sortedOrchFlows.add(ebb);
1502                 }
1503             }
1504         }
1505         return sortedOrchFlows;
1506     }
1507
1508     private void addBuildingBlockToExecuteBBList(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
1509             WorkflowType workflowType, OrchestrationFlow orchFlow, String requestId, String apiVersion,
1510             String resourceId, String requestAction, String vnfType, WorkflowResourceIds workflowResourceIds,
1511             RequestDetails requestDetails, boolean isVirtualLink, boolean isConfiguration) {
1512
1513         resourceList.stream().filter(resource -> resource.getResourceType().equals(workflowType))
1514                 .forEach(resource -> flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource,
1515                         apiVersion, resourceId, requestAction, false, vnfType, workflowResourceIds, requestDetails,
1516                         isVirtualLink, resource.getVirtualLinkKey(), null, isConfiguration, null)));
1517     }
1518
1519     protected List<ExecuteBuildingBlock> buildExecuteBuildingBlockList(List<OrchestrationFlow> orchFlows,
1520             List<Resource> resourceList, String requestId, String apiVersion, String resourceId, String requestAction,
1521             String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1522             boolean replaceVnf) {
1523         List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
1524         for (OrchestrationFlow orchFlow : orchFlows) {
1525             if (orchFlow.getFlowName().contains(SERVICE)) {
1526                 if (!replaceVnf) {
1527                     workflowResourceIds.setServiceInstanceId(resourceId);
1528                 }
1529                 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.SERVICE, orchFlow, requestId,
1530                         apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1531                         false);
1532             } else if (orchFlow.getFlowName().contains(VNF) || (orchFlow.getFlowName().contains(CONTROLLER)
1533                     && (VNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1534                 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VNF, orchFlow, requestId,
1535                         apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1536                         false);
1537             } else if (orchFlow.getFlowName().contains(PNF) || (orchFlow.getFlowName().contains(CONTROLLER)
1538                     && (PNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1539                 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.PNF, orchFlow, requestId,
1540                         apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1541                         false);
1542             } else if (orchFlow.getFlowName().contains(NETWORK)
1543                     && !orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1544                 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORK, orchFlow, requestId,
1545                         apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1546                         false);
1547                 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VIRTUAL_LINK, orchFlow,
1548                         requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1549                         true, false);
1550             } else if (orchFlow.getFlowName().contains(VFMODULE) || (orchFlow.getFlowName().contains(CONTROLLER)
1551                     && (VFMODULE).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1552                 List<Resource> vfModuleResourcesSorted;
1553                 if (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE)
1554                         || requestAction.equals("activateInstance")) {
1555                     vfModuleResourcesSorted = sortVfModulesByBaseFirst(resourceList.stream()
1556                             .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1557                 } else {
1558                     vfModuleResourcesSorted = sortVfModulesByBaseLast(resourceList.stream()
1559                             .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1560                 }
1561                 for (Resource resource : vfModuleResourcesSorted) {
1562                     flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource, apiVersion, resourceId,
1563                             requestAction, false, vnfType, workflowResourceIds, requestDetails, false, null, null,
1564                             false, null));
1565                 }
1566             } else if (orchFlow.getFlowName().contains(VOLUMEGROUP)) {
1567                 if (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1568                         || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)) {
1569                     logger.debug("Replacing workflow resource id by volume group id");
1570                     resourceId = workflowResourceIds.getVolumeGroupId();
1571                 }
1572                 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VOLUMEGROUP, orchFlow,
1573                         requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1574                         false, false);
1575             } else if (orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1576                 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORKCOLLECTION, orchFlow,
1577                         requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1578                         false, false);
1579             } else if (orchFlow.getFlowName().contains(CONFIGURATION)) {
1580                 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.CONFIGURATION, orchFlow,
1581                         requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1582                         false, true);
1583             } else {
1584                 flowsToExecute
1585                         .add(buildExecuteBuildingBlock(orchFlow, requestId, null, apiVersion, resourceId, requestAction,
1586                                 false, vnfType, workflowResourceIds, requestDetails, false, null, null, false, null));
1587             }
1588         }
1589         return flowsToExecute;
1590     }
1591
1592     protected ExecuteBuildingBlock buildExecuteBuildingBlock(OrchestrationFlow orchFlow, String requestId,
1593             Resource resource, String apiVersion, String resourceId, String requestAction, boolean aLaCarte,
1594             String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1595             boolean isVirtualLink, String virtualLinkKey, String vnfcName, boolean isConfiguration,
1596             ReplaceInstanceRelatedInformation replaceInfo) {
1597
1598         BuildingBlock buildingBlock =
1599                 new BuildingBlock().setBpmnFlowName(orchFlow.getFlowName()).setMsoId(UUID.randomUUID().toString())
1600                         .setIsVirtualLink(isVirtualLink).setVirtualLinkKey(virtualLinkKey)
1601                         .setKey(Optional.ofNullable(resource).map(Resource::getResourceId).orElse(""));
1602         Optional.ofNullable(orchFlow.getBpmnAction()).ifPresent(buildingBlock::setBpmnAction);
1603         Optional.ofNullable(orchFlow.getBpmnScope()).ifPresent(buildingBlock::setBpmnScope);
1604         String oldVolumeGroupName = "";
1605         if (replaceInfo != null) {
1606             oldVolumeGroupName = replaceInfo.getOldVolumeGroupName();
1607         }
1608         if (resource != null
1609                 && (orchFlow.getFlowName().contains(VOLUMEGROUP) && (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1610                         || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)))) {
1611             logger.debug("Setting resourceId to volume group id for volume group flow on replace");
1612             resourceId = workflowResourceIds.getVolumeGroupId();
1613         }
1614
1615         ExecuteBuildingBlock executeBuildingBlock = new ExecuteBuildingBlock().setApiVersion(apiVersion)
1616                 .setaLaCarte(aLaCarte).setRequestAction(requestAction).setResourceId(resourceId).setVnfType(vnfType)
1617                 .setWorkflowResourceIds(workflowResourceIds).setRequestId(requestId).setBuildingBlock(buildingBlock)
1618                 .setRequestDetails(requestDetails).setOldVolumeGroupName(oldVolumeGroupName);
1619
1620         if (resource != null && (isConfiguration || resource.getResourceType().equals(WorkflowType.CONFIGURATION))) {
1621             ConfigurationResourceKeys configurationResourceKeys = getConfigurationResourceKeys(resource, vnfcName);
1622             executeBuildingBlock.setConfigurationResourceKeys(configurationResourceKeys);
1623         }
1624         return executeBuildingBlock;
1625     }
1626
1627     private ConfigurationResourceKeys getConfigurationResourceKeys(Resource resource, String vnfcName) {
1628         ConfigurationResourceKeys configurationResourceKeys = new ConfigurationResourceKeys();
1629         Optional.ofNullable(vnfcName).ifPresent(configurationResourceKeys::setVnfcName);
1630         configurationResourceKeys.setCvnfcCustomizationUUID(resource.getCvnfModuleCustomizationId());
1631         configurationResourceKeys.setVfModuleCustomizationUUID(resource.getVfModuleCustomizationId());
1632         configurationResourceKeys.setVnfResourceCustomizationUUID(resource.getVnfCustomizationId());
1633         return configurationResourceKeys;
1634     }
1635
1636     protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1637             WorkflowType resourceName, boolean aLaCarte, String cloudOwner) {
1638         return this.queryNorthBoundRequestCatalogDb(execution, requestAction, resourceName, aLaCarte, cloudOwner, "");
1639     }
1640
1641     protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1642             WorkflowType resourceName, boolean aLaCarte, String cloudOwner, String serviceType) {
1643         List<OrchestrationFlow> listToExecute = new ArrayList<>();
1644         NorthBoundRequest northBoundRequest;
1645         if (serviceType.equalsIgnoreCase(SERVICE_TYPE_TRANSPORT)
1646                 || serviceType.equalsIgnoreCase(SERVICE_TYPE_BONDING)) {
1647             northBoundRequest =
1648                     catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwnerAndServiceType(
1649                             requestAction, resourceName.toString(), aLaCarte, cloudOwner, serviceType);
1650         } else {
1651             northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1652                     requestAction, resourceName.toString(), aLaCarte, cloudOwner);
1653         }
1654         if (northBoundRequest == null) {
1655             northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1656                     requestAction, resourceName.toString(), aLaCarte, CLOUD_OWNER);
1657         }
1658         if (northBoundRequest == null) {
1659             buildAndThrowException(execution, String.format("The request: %s %s %s is not supported by GR_API.",
1660                     (aLaCarte ? "AlaCarte" : "Macro"), resourceName, requestAction));
1661         } else {
1662             if (northBoundRequest.getIsToplevelflow() != null) {
1663                 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, northBoundRequest.getIsToplevelflow());
1664             }
1665             List<OrchestrationFlow> flows = northBoundRequest.getOrchestrationFlowList();
1666             if (flows == null)
1667                 flows = new ArrayList<>();
1668             for (OrchestrationFlow flow : flows) {
1669                 if (!flow.getFlowName().contains("BB") && !flow.getFlowName().contains("Activity")) {
1670                     List<OrchestrationFlow> macroQueryFlows =
1671                             catalogDbClient.getOrchestrationFlowByAction(flow.getFlowName());
1672                     listToExecute.addAll(macroQueryFlows);
1673                 } else {
1674                     listToExecute.add(flow);
1675                 }
1676             }
1677         }
1678         return listToExecute;
1679     }
1680
1681     protected void buildAndThrowException(DelegateExecution execution, String msg, Exception ex) {
1682         logger.error(msg, ex);
1683         execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg + ex.getMessage());
1684         exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg + ex.getMessage());
1685     }
1686
1687     protected void buildAndThrowException(DelegateExecution execution, String msg) {
1688         logger.error(msg);
1689         execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg);
1690         exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
1691     }
1692
1693     public void handleRuntimeException(DelegateExecution execution) {
1694         StringBuilder wfeExpMsg = new StringBuilder("Runtime error ");
1695         String runtimeErrorMessage;
1696         try {
1697             String javaExpMsg = (String) execution.getVariable("BPMN_javaExpMsg");
1698             if (javaExpMsg != null && !javaExpMsg.isEmpty()) {
1699                 wfeExpMsg.append(": ").append(javaExpMsg);
1700             }
1701             runtimeErrorMessage = wfeExpMsg.toString();
1702             logger.error(runtimeErrorMessage);
1703             execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, runtimeErrorMessage);
1704         } catch (Exception e) {
1705             logger.error("Runtime error", e);
1706             // if runtime message was mulformed
1707             runtimeErrorMessage = "Runtime error";
1708         }
1709         exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, runtimeErrorMessage);
1710     }
1711
1712     protected boolean isUriResume(String uri) {
1713         return uri.endsWith("/resume");
1714     }
1715
1716     protected boolean isRequestMacroServiceResume(boolean aLaCarte, WorkflowType resourceType, String requestAction,
1717             String serviceInstanceId) {
1718         return (!aLaCarte && resourceType == WorkflowType.SERVICE
1719                 && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE) || requestAction.equalsIgnoreCase(CREATEINSTANCE))
1720                 && (serviceInstanceId != null && serviceInstanceId.trim().length() > 1)
1721                 && (bbInputSetupUtils.getAAIServiceInstanceById(serviceInstanceId) != null));
1722     }
1723
1724     protected String validateServiceResourceIdInAAI(String generatedResourceId, String instanceName,
1725             RequestDetails reqDetails) throws DuplicateNameException {
1726         String globalCustomerId = reqDetails.getSubscriberInfo().getGlobalSubscriberId();
1727         String serviceType = reqDetails.getRequestParameters().getSubscriptionServiceType();
1728         if (instanceName != null) {
1729             Optional<ServiceInstance> serviceInstanceAAI =
1730                     bbInputSetupUtils.getAAIServiceInstanceByName(globalCustomerId, serviceType, instanceName);
1731             if (serviceInstanceAAI.isPresent()) {
1732                 if (serviceInstanceAAI.get().getModelVersionId()
1733                         .equalsIgnoreCase(reqDetails.getModelInfo().getModelVersionId())) {
1734                     return serviceInstanceAAI.get().getServiceInstanceId();
1735                 } else {
1736                     throw new DuplicateNameException(SERVICE_INSTANCE, String.format(NAME_EXISTS_WITH_DIFF_VERSION_ID,
1737                             instanceName, reqDetails.getModelInfo().getModelVersionId()));
1738                 }
1739             } else {
1740                 ServiceInstances aaiServiceInstances =
1741                         bbInputSetupUtils.getAAIServiceInstancesGloballyByName(instanceName);
1742                 if (aaiServiceInstances != null) {
1743                     if (aaiServiceInstances.getServiceInstance() != null
1744                             && !aaiServiceInstances.getServiceInstance().isEmpty()) {
1745                         if (aaiServiceInstances.getServiceInstance().size() > 1) {
1746                             throw new DuplicateNameException(SERVICE_INSTANCE,
1747                                     String.format(NAME_EXISTS_MULTIPLE, instanceName));
1748                         } else {
1749                             ServiceInstance si = aaiServiceInstances.getServiceInstance().stream().findFirst().get();
1750                             Map<String, String> keys =
1751                                     bbInputSetupUtils.getURIKeysFromServiceInstance(si.getServiceInstanceId());
1752
1753                             throw new DuplicateNameException(SERVICE_INSTANCE, String.format(
1754                                     NAME_EXISTS_WITH_DIFF_COMBINATION, instanceName,
1755                                     keys.get(AAIFluentTypeBuilder.Types.CUSTOMER.getUriParams().globalCustomerId),
1756                                     keys.get(
1757                                             AAIFluentTypeBuilder.Types.SERVICE_SUBSCRIPTION.getUriParams().serviceType),
1758                                     si.getModelVersionId()));
1759                         }
1760                     }
1761                 }
1762             }
1763         }
1764         return generatedResourceId;
1765     }
1766
1767     protected String validateNetworkResourceIdInAAI(String generatedResourceId, String instanceName,
1768             RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1769             throws DuplicateNameException, MultipleObjectsFoundException {
1770         Optional<L3Network> network = bbInputSetupUtils
1771                 .getRelatedNetworkByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1772         if (network.isPresent()) {
1773             if (network.get().getModelCustomizationId()
1774                     .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1775                 return network.get().getNetworkId();
1776             } else {
1777                 throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1778                         instanceName, network.get().getModelCustomizationId()));
1779             }
1780         }
1781         if (bbInputSetupUtils.existsAAINetworksGloballyByName(instanceName)) {
1782             throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName,
1783                     workflowResourceIds.getServiceInstanceId()));
1784         }
1785         return generatedResourceId;
1786     }
1787
1788     protected String validateVnfResourceIdInAAI(String generatedResourceId, String instanceName,
1789             RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1790         Optional<GenericVnf> vnf = bbInputSetupUtils
1791                 .getRelatedVnfByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1792         if (vnf.isPresent()) {
1793             if (vnf.get().getModelCustomizationId()
1794                     .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1795                 return vnf.get().getVnfId();
1796             } else {
1797                 throw new DuplicateNameException("generic-vnf", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1798                         instanceName, vnf.get().getModelCustomizationId()));
1799             }
1800         }
1801         GenericVnfs vnfs = bbInputSetupUtils.getAAIVnfsGloballyByName(instanceName);
1802         if (vnfs != null) {
1803             throw new DuplicateNameException("generic-vnf",
1804                     String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName, vnfs.getGenericVnf().get(0).getVnfId()));
1805         }
1806         return generatedResourceId;
1807     }
1808
1809     protected String validateVfModuleResourceIdInAAI(String generatedResourceId, String instanceName,
1810             RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1811         GenericVnf vnf = bbInputSetupUtils.getAAIGenericVnf(workflowResourceIds.getVnfId());
1812         if (vnf != null && vnf.getVfModules() != null) {
1813             for (org.onap.aai.domain.yang.VfModule vfModule : vnf.getVfModules().getVfModule()) {
1814                 if (vfModule.getVfModuleName().equalsIgnoreCase(instanceName)) {
1815                     if (vfModule.getModelCustomizationId()
1816                             .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1817                         return vfModule.getVfModuleId();
1818                     } else {
1819                         throw new DuplicateNameException("vfModule",
1820                                 String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID, instanceName,
1821                                         reqDetails.getModelInfo().getModelCustomizationId()));
1822                     }
1823                 }
1824             }
1825         }
1826         if (bbInputSetupUtils.existsAAIVfModuleGloballyByName(instanceName)) {
1827             throw new DuplicateNameException("vfModule", instanceName);
1828         }
1829         return generatedResourceId;
1830     }
1831
1832     protected String validateVolumeGroupResourceIdInAAI(String generatedResourceId, String instanceName,
1833             RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1834         Optional<VolumeGroup> volumeGroup =
1835                 bbInputSetupUtils.getRelatedVolumeGroupByNameFromVnf(workflowResourceIds.getVnfId(), instanceName);
1836         if (volumeGroup.isPresent()) {
1837             if (volumeGroup.get().getVfModuleModelCustomizationId()
1838                     .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1839                 return volumeGroup.get().getVolumeGroupId();
1840             } else {
1841                 throw new DuplicateNameException("volumeGroup", volumeGroup.get().getVolumeGroupName());
1842             }
1843         }
1844         if (bbInputSetupUtils.existsAAIVolumeGroupGloballyByName(instanceName)) {
1845             throw new DuplicateNameException("volumeGroup", instanceName);
1846         }
1847         return generatedResourceId;
1848     }
1849
1850     protected String validateConfigurationResourceIdInAAI(String generatedResourceId, String instanceName,
1851             RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1852         Optional<org.onap.aai.domain.yang.Configuration> configuration =
1853                 bbInputSetupUtils.getRelatedConfigurationByNameFromServiceInstance(
1854                         workflowResourceIds.getServiceInstanceId(), instanceName);
1855         if (configuration.isPresent()) {
1856             if (configuration.get().getModelCustomizationId()
1857                     .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1858                 return configuration.get().getConfigurationId();
1859             } else {
1860                 throw new DuplicateNameException("configuration", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1861                         instanceName, configuration.get().getConfigurationId()));
1862             }
1863         }
1864         if (bbInputSetupUtils.existsAAIConfigurationGloballyByName(instanceName)) {
1865             throw new DuplicateNameException("configuration", instanceName);
1866         }
1867         return generatedResourceId;
1868     }
1869
1870     private void fillExecution(DelegateExecution execution, boolean suppressRollback, String resourceId,
1871             WorkflowType resourceType) {
1872         execution.setVariable("sentSyncResponse", false);
1873         execution.setVariable(HOMING, false);
1874         execution.setVariable("calledHoming", false);
1875         execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, true);
1876         execution.setVariable("suppressRollback", suppressRollback);
1877         execution.setVariable("resourceId", resourceId);
1878         execution.setVariable("resourceType", resourceType);
1879         execution.setVariable("resourceName", resourceType.toString());
1880     }
1881
1882     private Resource getResource(BBInputSetupUtils bbInputSetupUtils, boolean isResume, boolean alaCarte, String uri,
1883             String requestId) {
1884         if (!alaCarte && isResume) {
1885             logger.debug("replacing URI {}", uri);
1886             uri = bbInputSetupUtils.loadOriginalInfraActiveRequestById(requestId).getRequestUrl();
1887             logger.debug("for RESUME with original value {}", uri);
1888         }
1889         return extractResourceIdAndTypeFromUri(uri);
1890     }
1891
1892     private String getResourceId(Resource resource, String requestAction, RequestDetails requestDetails,
1893             WorkflowResourceIds workflowResourceIds) throws Exception {
1894         if (resource.isGenerated() && requestAction.equalsIgnoreCase("createInstance")
1895                 && requestDetails.getRequestInfo().getInstanceName() != null) {
1896             return validateResourceIdInAAI(resource.getResourceId(), resource.getResourceType(),
1897                     requestDetails.getRequestInfo().getInstanceName(), requestDetails, workflowResourceIds);
1898         } else {
1899             return resource.getResourceId();
1900         }
1901     }
1902
1903     private String getServiceInstanceId(DelegateExecution execution, String resourceId, WorkflowType resourceType) {
1904         String serviceInstanceId = (String) execution.getVariable("serviceInstanceId");
1905         if ((serviceInstanceId == null || serviceInstanceId.isEmpty()) && WorkflowType.SERVICE.equals(resourceType)) {
1906             serviceInstanceId = resourceId;
1907         }
1908         return serviceInstanceId;
1909     }
1910
1911 }