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