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