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