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