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