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