2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Modifications Copyright (c) 2019 Samsung
8 * ================================================================================
9 * Modifications Copyright (c) 2020 Nokia
10 * ================================================================================
11 * Modifications Copyright (c) 2020 Tech Mahindra
12 * ================================================================================
13 * Licensed under the Apache License, Version 2.0 (the "License");
14 * you may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
17 * http://www.apache.org/licenses/LICENSE-2.0
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 * ============LICENSE_END=========================================================
27 package org.onap.so.bpmn.infrastructure.workflow.tasks;
29 import com.fasterxml.jackson.core.JsonProcessingException;
30 import com.fasterxml.jackson.databind.ObjectMapper;
31 import org.apache.commons.lang3.SerializationUtils;
32 import org.camunda.bpm.engine.delegate.DelegateExecution;
33 import org.javatuples.Pair;
34 import org.onap.aai.domain.yang.GenericVnf;
35 import org.onap.aai.domain.yang.GenericVnfs;
36 import org.onap.aai.domain.yang.L3Network;
37 import org.onap.aai.domain.yang.Relationship;
38 import org.onap.aai.domain.yang.ServiceInstance;
39 import org.onap.aai.domain.yang.ServiceInstances;
40 import org.onap.aai.domain.yang.Vnfc;
41 import org.onap.aai.domain.yang.VolumeGroup;
42 import org.onap.aai.domain.yang.VpnBinding;
43 import org.onap.aaiclient.client.aai.AAICommonObjectMapperProvider;
44 import org.onap.aaiclient.client.aai.AAIObjectName;
45 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper;
46 import org.onap.aaiclient.client.aai.entities.Relationships;
47 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri;
48 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory;
49 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder;
50 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types;
51 import org.onap.so.bpmn.common.BBConstants;
52 import org.onap.so.bpmn.infrastructure.workflow.tasks.utils.WorkflowResourceIdsUtils;
53 import org.onap.so.bpmn.servicedecomposition.bbobjects.Configuration;
54 import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule;
55 import org.onap.so.bpmn.servicedecomposition.entities.BuildingBlock;
56 import org.onap.so.bpmn.servicedecomposition.entities.ConfigurationResourceKeys;
57 import org.onap.so.bpmn.servicedecomposition.entities.ExecuteBuildingBlock;
58 import org.onap.so.bpmn.servicedecomposition.entities.WorkflowResourceIds;
59 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetup;
60 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetupUtils;
61 import org.onap.so.bpmn.servicedecomposition.tasks.exceptions.DuplicateNameException;
62 import org.onap.so.bpmn.servicedecomposition.tasks.exceptions.MultipleObjectsFoundException;
63 import org.onap.so.client.exception.ExceptionBuilder;
64 import org.onap.so.client.orchestration.AAIConfigurationResources;
65 import org.onap.so.client.orchestration.AAIEntityNotFoundException;
66 import org.onap.so.db.catalog.beans.CollectionNetworkResourceCustomization;
67 import org.onap.so.db.catalog.beans.CollectionResourceCustomization;
68 import org.onap.so.db.catalog.beans.CollectionResourceInstanceGroupCustomization;
69 import org.onap.so.db.catalog.beans.InstanceGroup;
70 import org.onap.so.db.catalog.beans.VfModuleCustomization;
71 import org.onap.so.db.catalog.beans.macro.NorthBoundRequest;
72 import org.onap.so.db.catalog.beans.macro.OrchestrationFlow;
73 import org.onap.so.db.catalog.client.CatalogDbClient;
74 import org.onap.so.serviceinstancebeans.CloudConfiguration;
75 import org.onap.so.serviceinstancebeans.ModelInfo;
76 import org.onap.so.serviceinstancebeans.ModelType;
77 import org.onap.so.serviceinstancebeans.RelatedInstance;
78 import org.onap.so.serviceinstancebeans.RelatedInstanceList;
79 import org.onap.so.serviceinstancebeans.RequestDetails;
80 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
81 import org.slf4j.Logger;
82 import org.slf4j.LoggerFactory;
83 import org.springframework.beans.factory.annotation.Autowired;
84 import org.springframework.core.env.Environment;
85 import org.springframework.stereotype.Component;
86 import org.springframework.util.CollectionUtils;
87 import java.util.ArrayList;
88 import java.util.Arrays;
89 import java.util.Collections;
90 import java.util.Comparator;
91 import java.util.List;
93 import java.util.Optional;
94 import java.util.UUID;
95 import java.util.regex.Matcher;
96 import java.util.regex.Pattern;
97 import java.util.stream.Collectors;
98 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.CREATE_INSTANCE;
99 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.FABRIC_CONFIGURATION;
100 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.USER_PARAM_SERVICE;
101 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.WORKFLOW_ACTION_ERROR_MESSAGE;
104 public class WorkflowAction {
106 private static final String SERVICE_INSTANCES = "serviceInstances";
107 private static final String SERVICE_INSTANCE = "serviceInstance";
108 private static final String VF_MODULES = "vfModules";
109 private static final String WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI =
110 "WorkflowAction was unable to verify if the instance name already exist in AAI.";
111 private static final String VNF_TYPE = "vnfType";
112 private static final String SERVICE = "Service";
113 private static final String VNF = "Vnf";
114 private static final String PNF = "Pnf";
115 private static final String VFMODULE = "VfModule";
116 private static final String VOLUMEGROUP = "VolumeGroup";
117 private static final String NETWORK = "Network";
118 private static final String NETWORKCOLLECTION = "NetworkCollection";
119 private static final String CONFIGURATION = "Configuration";
120 private static final String ASSIGNINSTANCE = "assignInstance";
121 private static final String REPLACEINSTANCE = "replaceInstance";
122 private static final String REPLACEINSTANCERETAINASSIGNMENTS = "replaceInstanceRetainAssignments";
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 SERVICE_TYPE_TRANSPORT = "TRANSPORT";
127 private static final String SERVICE_TYPE_BONDING = "BONDING";
128 private static final String CLOUD_OWNER = "DEFAULT";
129 private static final Logger logger = LoggerFactory.getLogger(WorkflowAction.class);
130 private static final String NAME_EXISTS_WITH_DIFF_VERSION_ID = "(%s) and different version id (%s)";
131 private static final String NAME_EXISTS_MULTIPLE =
132 "(%s) and multiple combination of model-version-id + service-type + global-customer-id";
133 private static final String NAME_EXISTS_WITH_DIFF_COMBINATION =
134 "(%s) and global-customer-id (%s), service-type (%s), model-version-id (%s)";
135 private static final String NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID =
136 "(%s), same parent and different customization id (%s)";
137 private static final String NAME_EXISTS_WITH_DIFF_PARENT = "(%s) id (%s) and different parent relationship";
138 private static final String CREATENETWORKBB = "CreateNetworkBB";
139 private static final String ACTIVATENETWORKBB = "ActivateNetworkBB";
140 private static final String VOLUMEGROUP_DELETE_PATTERN = "(Un|De)(.*)Volume(.*)";
141 private static final String VOLUMEGROUP_CREATE_PATTERN = "(A|C)(.*)Volume(.*)";
142 private static final String CONTROLLER = "Controller";
143 private static final String DEFAULT_CLOUD_OWNER = "org.onap.so.cloud-owner";
144 private static final String HOMING = "homing";
147 protected BBInputSetup bbInputSetup;
149 protected BBInputSetupUtils bbInputSetupUtils;
151 private ExceptionBuilder exceptionBuilder;
153 private CatalogDbClient catalogDbClient;
155 private AAIConfigurationResources aaiConfigurationResources;
157 private WorkflowActionExtractResourcesAAI workflowActionUtils;
159 private VrfValidation vrfValidation;
161 private Environment environment;
163 private UserParamsServiceTraversal userParamsServiceTraversal;
165 public void setBbInputSetupUtils(BBInputSetupUtils bbInputSetupUtils) {
166 this.bbInputSetupUtils = bbInputSetupUtils;
169 public void setBbInputSetup(BBInputSetup bbInputSetup) {
170 this.bbInputSetup = bbInputSetup;
173 public void selectExecutionList(DelegateExecution execution) throws Exception {
175 fillExecutionDefault(execution);
176 final String bpmnRequest = (String) execution.getVariable(BBConstants.G_BPMN_REQUEST);
177 ServiceInstancesRequest sIRequest =
178 new ObjectMapper().readValue(bpmnRequest, ServiceInstancesRequest.class);
180 final String requestId = (String) execution.getVariable(BBConstants.G_REQUEST_ID);
182 String uri = (String) execution.getVariable(BBConstants.G_URI);
183 boolean isResume = isUriResume(uri);
185 final boolean isALaCarte = (boolean) execution.getVariable(BBConstants.G_ALACARTE);
186 Resource resource = getResource(bbInputSetupUtils, isResume, isALaCarte, uri, requestId);
188 WorkflowResourceIds workflowResourceIds = populateResourceIdsFromApiHandler(execution);
189 RequestDetails requestDetails = sIRequest.getRequestDetails();
190 String requestAction = (String) execution.getVariable(BBConstants.G_ACTION);
191 String resourceId = getResourceId(resource, requestAction, requestDetails, workflowResourceIds);
192 WorkflowType resourceType = resource.getResourceType();
194 String serviceInstanceId = getServiceInstanceId(execution, resourceId, resourceType);
196 fillExecution(execution, requestDetails.getRequestInfo().getSuppressRollback(), resourceId, resourceType);
197 List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
199 if (isRequestMacroServiceResume(isALaCarte, resourceType, requestAction, serviceInstanceId)) {
200 String errorMessage = "Could not resume Macro flow. Error loading execution path.";
201 flowsToExecute = loadExecuteBuildingBlocks(execution, requestId, errorMessage);
202 } else if (isALaCarte && isResume) {
203 String errorMessage =
204 "Could not resume request with request Id: " + requestId + ". No flowsToExecute was found";
205 flowsToExecute = loadExecuteBuildingBlocks(execution, requestId, errorMessage);
207 String vnfType = (String) execution.getVariable(VNF_TYPE);
208 String cloudOwner = getCloudOwner(requestDetails.getCloudConfiguration());
209 List<OrchestrationFlow> orchFlows =
210 (List<OrchestrationFlow>) execution.getVariable(BBConstants.G_ORCHESTRATION_FLOW);
211 final String apiVersion = (String) execution.getVariable(BBConstants.G_APIVERSION);
212 final String serviceType =
213 Optional.ofNullable((String) execution.getVariable(BBConstants.G_SERVICE_TYPE)).orElse("");
215 if (orchFlows == null || orchFlows.isEmpty()) {
216 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, true,
217 cloudOwner, serviceType);
219 Resource resourceKey = getResourceKey(sIRequest, resourceType);
221 ReplaceInstanceRelatedInformation replaceInfo = new ReplaceInstanceRelatedInformation();
222 if ((requestAction.equalsIgnoreCase(REPLACEINSTANCE)
223 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS))
224 && resourceType.equals(WorkflowType.VFMODULE)) {
225 logger.debug("Build a BB list for replacing BB modules");
226 ConfigBuildingBlocksDataObject cbbdo = createConfigBuildingBlocksDataObject(execution,
227 sIRequest, requestId, workflowResourceIds, requestDetails, requestAction, resourceId,
228 vnfType, orchFlows, apiVersion, resourceKey, replaceInfo);
229 orchFlows = getVfModuleReplaceBuildingBlocks(cbbdo);
231 createBuildingBlocksForOrchFlows(execution, sIRequest, requestId, workflowResourceIds,
232 requestDetails, requestAction, resourceId, flowsToExecute, vnfType, orchFlows,
233 apiVersion, resourceKey, replaceInfo);
235 if (isConfiguration(orchFlows) && !requestAction.equalsIgnoreCase(CREATE_INSTANCE)) {
236 addConfigBuildingBlocksToFlowsToExecuteList(execution, sIRequest, requestId,
237 workflowResourceIds, requestDetails, requestAction, resourceId, flowsToExecute,
238 vnfType, apiVersion, resourceKey, replaceInfo, orchFlows);
241 orchFlows.stream().filter(item -> !item.getFlowName().contains(FABRIC_CONFIGURATION))
242 .collect(Collectors.toList());
244 for (OrchestrationFlow orchFlow : orchFlows) {
245 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, resourceKey,
246 apiVersion, resourceId, requestAction, true, vnfType, workflowResourceIds,
247 requestDetails, false, null, null, false, replaceInfo);
248 flowsToExecute.add(ebb);
252 boolean containsService = false;
253 List<Resource> resourceList = new ArrayList<>();
254 List<Pair<WorkflowType, String>> aaiResourceIds = new ArrayList<>();
255 List<Map<String, Object>> userParams =
256 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
257 if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(ASSIGNINSTANCE)) {
258 // SERVICE-MACRO-ASSIGN will always get user params with a
261 if (userParams != null) {
262 containsService = isContainsService(sIRequest);
263 if (containsService) {
264 resourceList = userParamsServiceTraversal.getResourceListFromUserParams(execution,
265 userParams, serviceInstanceId, requestAction);
268 buildAndThrowException(execution,
269 "Service-Macro-Assign request details must contain user params with a service");
271 } else if (resourceType == WorkflowType.SERVICE
272 && requestAction.equalsIgnoreCase(CREATE_INSTANCE)) {
273 // SERVICE-MACRO-CREATE will get user params with a service,
274 // a service with a network, a service with a
275 // network collection, OR an empty service.
276 // If user params is just a service or null and macro
277 // queries the SI and finds a VNF, macro fails.
279 if (userParams != null) {
280 containsService = isContainsService(sIRequest);
282 if (containsService) {
283 resourceList = userParamsServiceTraversal.getResourceListFromUserParams(execution,
284 userParams, serviceInstanceId, requestAction);
286 if (!foundRelated(resourceList)) {
287 traverseCatalogDbService(execution, sIRequest, resourceList, aaiResourceIds);
289 } else if (resourceType == WorkflowType.SERVICE
290 && ("activateInstance".equalsIgnoreCase(requestAction)
291 || "unassignInstance".equalsIgnoreCase(requestAction)
292 || "deleteInstance".equalsIgnoreCase(requestAction)
293 || requestAction.equalsIgnoreCase("activate" + FABRIC_CONFIGURATION))) {
294 // SERVICE-MACRO-ACTIVATE, SERVICE-MACRO-UNASSIGN, and
295 // SERVICE-MACRO-DELETE
296 // Will never get user params with service, macro will have
297 // to query the SI in AAI to find related instances.
298 traverseAAIService(execution, resourceList, resourceId, aaiResourceIds);
299 } else if (resourceType == WorkflowType.SERVICE
300 && "deactivateInstance".equalsIgnoreCase(requestAction)) {
301 resourceList.add(new Resource(WorkflowType.SERVICE, "", false));
302 } else if (resourceType == WorkflowType.VNF && (REPLACEINSTANCE.equalsIgnoreCase(requestAction)
303 || ("recreateInstance".equalsIgnoreCase(requestAction)))) {
304 traverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
305 workflowResourceIds.getVnfId(), aaiResourceIds);
306 } else if (resourceType == WorkflowType.VNF && "updateInstance".equalsIgnoreCase(requestAction)) {
307 customTraverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
308 workflowResourceIds.getVnfId(), aaiResourceIds);
310 buildAndThrowException(execution, "Current Macro Request is not supported");
312 StringBuilder foundObjects = new StringBuilder();
313 for (WorkflowType type : WorkflowType.values()) {
314 foundObjects.append(type).append(" - ").append(
315 (int) resourceList.stream().filter(x -> type.equals(x.getResourceType())).count())
318 logger.info("Found {}", foundObjects);
320 if (orchFlows == null || orchFlows.isEmpty()) {
321 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, isALaCarte,
322 cloudOwner, serviceType);
324 boolean vnfReplace = false;
325 if (resourceType.equals(WorkflowType.VNF) && (REPLACEINSTANCE.equalsIgnoreCase(requestAction)
326 || REPLACEINSTANCERETAINASSIGNMENTS.equalsIgnoreCase(requestAction))) {
329 flowsToExecute = buildExecuteBuildingBlockList(orchFlows, resourceList, requestId, apiVersion,
330 resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, vnfReplace);
331 if (isNetworkCollectionInTheResourceList(resourceList)) {
332 logger.info("Sorting for Vlan Tagging");
333 flowsToExecute = sortExecutionPathByObjectForVlanTagging(flowsToExecute, requestAction);
335 // By default, enable homing at VNF level for CREATE_INSTANCE and ASSIGNINSTANCE
336 if (resourceType == WorkflowType.SERVICE
337 && (requestAction.equals(CREATE_INSTANCE) || requestAction.equals(ASSIGNINSTANCE))
338 && resourceList.stream().anyMatch(x -> WorkflowType.VNF.equals(x.getResourceType()))) {
339 execution.setVariable(HOMING, true);
340 execution.setVariable("calledHoming", false);
342 if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE)
343 || requestAction.equalsIgnoreCase(CREATE_INSTANCE))) {
344 generateResourceIds(flowsToExecute, resourceList, serviceInstanceId);
346 updateResourceIdsFromAAITraversal(flowsToExecute, resourceList, aaiResourceIds,
351 // If the user set "Homing_Solution" to "none", disable homing, else if "Homing_Solution" is specified,
353 List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
354 if (sIRequest.getRequestDetails().getRequestParameters() != null && userParams != null) {
355 for (Map<String, Object> params : userParams) {
356 if (params.containsKey(HOMINGSOLUTION)) {
357 execution.setVariable(HOMING, !"none".equals(params.get(HOMINGSOLUTION)));
362 if (CollectionUtils.isEmpty(flowsToExecute)) {
363 throw new IllegalStateException("Macro did not come up with a valid execution path.");
366 List<String> flowNames = new ArrayList<>();
367 logger.info("List of BuildingBlocks to execute:");
369 flowsToExecute.forEach(ebb -> {
370 logger.info(ebb.getBuildingBlock().getBpmnFlowName());
371 flowNames.add(ebb.getBuildingBlock().getBpmnFlowName());
375 bbInputSetupUtils.persistFlowExecutionPath(requestId, flowsToExecute);
377 setExecutionVariables(execution, flowsToExecute, flowNames);
379 } catch (Exception ex) {
380 if (!(execution.hasVariable("WorkflowException")
381 || execution.hasVariable("WorkflowExceptionExceptionMessage"))) {
382 buildAndThrowException(execution, "Exception while setting execution list. ", ex);
389 private void setExecutionVariables(DelegateExecution execution, List<ExecuteBuildingBlock> flowsToExecute,
390 List<String> flowNames) {
391 execution.setVariable("flowNames", flowNames);
392 execution.setVariable(BBConstants.G_CURRENT_SEQUENCE, 0);
393 execution.setVariable("retryCount", 0);
394 execution.setVariable("isRollback", false);
395 execution.setVariable("flowsToExecute", flowsToExecute);
396 execution.setVariable("isRollbackComplete", false);
399 private boolean isContainsService(ServiceInstancesRequest sIRequest) {
400 boolean containsService;
401 List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
402 containsService = userParams.stream().anyMatch(param -> param.containsKey(USER_PARAM_SERVICE));
403 return containsService;
408 private List<ExecuteBuildingBlock> loadExecuteBuildingBlocks(DelegateExecution execution, String requestId,
409 String errorMessage) {
410 List<ExecuteBuildingBlock> flowsToExecute;
411 flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
412 if (flowsToExecute == null) {
413 buildAndThrowException(execution, errorMessage);
415 return flowsToExecute;
418 private ConfigBuildingBlocksDataObject createConfigBuildingBlocksDataObject(DelegateExecution execution,
419 ServiceInstancesRequest sIRequest, String requestId, WorkflowResourceIds workflowResourceIds,
420 RequestDetails requestDetails, String requestAction, String resourceId, String vnfType,
421 List<OrchestrationFlow> orchFlows, String apiVersion, Resource resourceKey,
422 ReplaceInstanceRelatedInformation replaceInfo) {
424 return new ConfigBuildingBlocksDataObject().setsIRequest(sIRequest).setOrchFlows(orchFlows)
425 .setRequestId(requestId).setResourceKey(resourceKey).setApiVersion(apiVersion).setResourceId(resourceId)
426 .setRequestAction(requestAction).setaLaCarte(true).setVnfType(vnfType)
427 .setWorkflowResourceIds(workflowResourceIds).setRequestDetails(requestDetails).setExecution(execution)
428 .setReplaceInformation(replaceInfo);
431 private void createBuildingBlocksForOrchFlows(DelegateExecution execution, ServiceInstancesRequest sIRequest,
432 String requestId, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
433 String requestAction, String resourceId, List<ExecuteBuildingBlock> flowsToExecute, String vnfType,
434 List<OrchestrationFlow> orchFlows, String apiVersion, Resource resourceKey,
435 ReplaceInstanceRelatedInformation replaceInfo) throws Exception {
437 for (OrchestrationFlow orchFlow : orchFlows) {
438 if (orchFlow.getFlowName().contains(CONFIGURATION)) {
439 List<OrchestrationFlow> configOrchFlows = new ArrayList<>();
440 configOrchFlows.add(orchFlow);
441 addConfigBuildingBlocksToFlowsToExecuteList(execution, sIRequest, requestId, workflowResourceIds,
442 requestDetails, requestAction, resourceId, flowsToExecute, vnfType, apiVersion, resourceKey,
443 replaceInfo, configOrchFlows);
445 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, resourceKey, apiVersion,
446 resourceId, requestAction, true, vnfType, workflowResourceIds, requestDetails, false, null,
447 null, false, replaceInfo);
448 flowsToExecute.add(ebb);
453 private void addConfigBuildingBlocksToFlowsToExecuteList(DelegateExecution execution,
454 ServiceInstancesRequest sIRequest, String requestId, WorkflowResourceIds workflowResourceIds,
455 RequestDetails requestDetails, String requestAction, String resourceId,
456 List<ExecuteBuildingBlock> flowsToExecute, String vnfType, String apiVersion, Resource resourceKey,
457 ReplaceInstanceRelatedInformation replaceInfo, List<OrchestrationFlow> configOrchFlows) throws Exception {
459 ConfigBuildingBlocksDataObject cbbdo = createConfigBuildingBlocksDataObject(execution, sIRequest, requestId,
460 workflowResourceIds, requestDetails, requestAction, resourceId, vnfType, configOrchFlows, apiVersion,
461 resourceKey, replaceInfo);
462 List<ExecuteBuildingBlock> configBuildingBlocks = getConfigBuildingBlocks(cbbdo);
463 flowsToExecute.addAll(configBuildingBlocks);
466 private Resource getResourceKey(ServiceInstancesRequest sIRequest, WorkflowType resourceType) {
467 String resourceId = "";
468 ModelInfo modelInfo = sIRequest.getRequestDetails().getModelInfo();
469 if (modelInfo != null) {
470 if (modelInfo.getModelType().equals(ModelType.service)) {
471 resourceId = modelInfo.getModelVersionId();
473 resourceId = modelInfo.getModelCustomizationId();
476 return new Resource(resourceType, resourceId, true);
479 private String getCloudOwner(CloudConfiguration cloudConfiguration) {
480 if (cloudConfiguration != null && cloudConfiguration.getCloudOwner() != null) {
481 return cloudConfiguration.getCloudOwner();
483 logger.warn("cloud owner value not found in request details, it will be set as default");
484 return environment.getProperty(DEFAULT_CLOUD_OWNER);
487 protected <T> List<T> getRelatedResourcesInVfModule(String vnfId, String vfModuleId, Class<T> resultClass,
488 AAIObjectName name) {
489 List<T> vnfcs = new ArrayList<>();
491 AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId).vfModule(vfModuleId));
492 AAIResultWrapper vfModuleResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
493 Optional<Relationships> relationshipsOp = vfModuleResultsWrapper.getRelationships();
494 if (!relationshipsOp.isPresent()) {
495 logger.debug("No relationships were found for vfModule in AAI");
497 Relationships relationships = relationshipsOp.get();
498 List<AAIResultWrapper> vnfcResultWrappers = relationships.getByType(name);
499 for (AAIResultWrapper vnfcResultWrapper : vnfcResultWrappers) {
500 Optional<T> vnfcOp = vnfcResultWrapper.asBean(resultClass);
501 vnfcOp.ifPresent(vnfcs::add);
507 protected <T> T getRelatedResourcesInVnfc(Vnfc vnfc, Class<T> resultClass, AAIObjectName name) throws Exception {
508 T configuration = null;
509 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().vnfc(vnfc.getVnfcName()));
510 AAIResultWrapper vnfcResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
511 Optional<Relationships> relationshipsOp = vnfcResultsWrapper.getRelationships();
512 if (!relationshipsOp.isPresent()) {
513 logger.debug("No relationships were found for VNFC in AAI");
515 Relationships relationships = relationshipsOp.get();
516 List<AAIResultWrapper> configurationResultWrappers =
517 this.getResultWrappersFromRelationships(relationships, name);
518 if (configurationResultWrappers.size() > 1) {
519 String multipleRelationshipsError =
520 "Multiple relationships exist from VNFC " + vnfc.getVnfcName() + " to Configurations";
521 throw new Exception(multipleRelationshipsError);
523 if (!configurationResultWrappers.isEmpty()) {
524 Optional<T> configurationOp = configurationResultWrappers.get(0).asBean(resultClass);
525 if (configurationOp.isPresent()) {
526 configuration = configurationOp.get();
530 return configuration;
533 protected List<AAIResultWrapper> getResultWrappersFromRelationships(Relationships relationships,
534 AAIObjectName name) {
535 return relationships.getByType(name);
538 protected boolean isConfiguration(List<OrchestrationFlow> orchFlows) {
539 for (OrchestrationFlow flow : orchFlows) {
540 if (flow.getFlowName().contains(CONFIGURATION) && !"ConfigurationScaleOutBB".equals(flow.getFlowName())) {
547 protected List<ExecuteBuildingBlock> getConfigBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
550 List<ExecuteBuildingBlock> flowsToExecuteConfigs = new ArrayList<>();
551 List<OrchestrationFlow> result = dataObj.getOrchFlows().stream()
552 .filter(item -> item.getFlowName().contains(FABRIC_CONFIGURATION)).collect(Collectors.toList());
553 String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
554 String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
556 String vnfCustomizationUUID = bbInputSetupUtils.getAAIGenericVnf(vnfId).getModelCustomizationId();
557 String vfModuleCustomizationUUID;
558 org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
560 if (aaiVfModule == null) {
561 logger.error("No matching VfModule is found in Generic-Vnf in AAI for vnfId: {} and vfModuleId : {}", vnfId,
563 throw new AAIEntityNotFoundException("No matching VfModule is found in Generic-Vnf in AAI for vnfId: "
564 + vnfId + " and vfModuleId : " + vfModuleId);
566 vfModuleCustomizationUUID = aaiVfModule.getModelCustomizationId();
568 String replaceVfModuleCustomizationUUID = "";
569 String replaceVnfModuleCustomizationUUID = "";
570 boolean isReplace = false;
571 if (dataObj.getRequestAction().equalsIgnoreCase("replaceInstance")
572 || dataObj.getRequestAction().equalsIgnoreCase("replaceInstanceRetainAssignments")) {
573 for (RelatedInstanceList relatedInstList : dataObj.getRequestDetails().getRelatedInstanceList()) {
574 RelatedInstance relatedInstance = relatedInstList.getRelatedInstance();
575 if (relatedInstance.getModelInfo().getModelType().equals(ModelType.vnf)) {
576 replaceVnfModuleCustomizationUUID = relatedInstance.getModelInfo().getModelCustomizationId();
579 replaceVfModuleCustomizationUUID = dataObj.getRequestDetails().getModelInfo().getModelCustomizationId();
583 List<org.onap.aai.domain.yang.Vnfc> vnfcs =
584 getRelatedResourcesInVfModule(vnfId, vfModuleId, org.onap.aai.domain.yang.Vnfc.class, Types.VNFC);
585 for (org.onap.aai.domain.yang.Vnfc vnfc : vnfcs) {
586 WorkflowResourceIds workflowIdsCopy = SerializationUtils.clone(dataObj.getWorkflowResourceIds());
587 org.onap.aai.domain.yang.Configuration configuration =
588 getRelatedResourcesInVnfc(vnfc, org.onap.aai.domain.yang.Configuration.class, Types.CONFIGURATION);
589 if (configuration == null) {
590 logger.warn(String.format("No configuration found for VNFC %s in AAI", vnfc.getVnfcName()));
593 workflowIdsCopy.setConfigurationId(configuration.getConfigurationId());
594 for (OrchestrationFlow orchFlow : result) {
596 dataObj.getResourceKey().setVfModuleCustomizationId(vfModuleCustomizationUUID);
597 dataObj.getResourceKey().setVnfCustomizationId(vnfCustomizationUUID);
599 if (orchFlow.getFlowName().contains("Delete")) {
600 dataObj.getResourceKey().setVfModuleCustomizationId(vfModuleCustomizationUUID);
601 dataObj.getResourceKey().setVnfCustomizationId(vnfCustomizationUUID);
603 dataObj.getResourceKey().setVfModuleCustomizationId(replaceVfModuleCustomizationUUID);
604 dataObj.getResourceKey().setVnfCustomizationId(replaceVnfModuleCustomizationUUID);
607 dataObj.getResourceKey().setCvnfModuleCustomizationId(vnfc.getModelCustomizationId());
608 String vnfcName = vnfc.getVnfcName();
609 if (vnfcName == null || vnfcName.isEmpty()) {
610 buildAndThrowException(dataObj.getExecution(), "Exception in create execution list "
611 + ": VnfcName does not exist or is null while there is a configuration for the vfModule",
612 new Exception("Vnfc and Configuration do not match"));
614 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, dataObj.getRequestId(),
615 dataObj.getResourceKey(), dataObj.getApiVersion(), dataObj.getResourceId(),
616 dataObj.getRequestAction(), dataObj.isaLaCarte(), dataObj.getVnfType(), workflowIdsCopy,
617 dataObj.getRequestDetails(), false, null, vnfcName, true, null);
618 flowsToExecuteConfigs.add(ebb);
621 return flowsToExecuteConfigs;
624 protected void buildAndThrowException(DelegateExecution execution, String msg) {
626 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg);
627 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
630 protected void buildAndThrowException(DelegateExecution execution, String msg, Exception ex) {
631 logger.error(msg, ex);
632 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg + ex.getMessage());
633 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg + ex.getMessage());
636 protected List<OrchestrationFlow> getVfModuleReplaceBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
639 String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
640 String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
642 logger.debug("BUILDING REPLACE LIST");
644 boolean volumeGroupExisted = false;
645 boolean volumeGroupWillExist = false;
646 boolean keepVolumeGroup = false;
648 boolean rebuildVolumeGroups = false;
649 if (dataObj.getRequestDetails().getRequestParameters() != null
650 && dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups() != null) {
651 rebuildVolumeGroups = dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups();
653 String volumeGroupName = "";
654 Optional<VolumeGroup> volumeGroupFromVfModule =
655 bbInputSetupUtils.getRelatedVolumeGroupFromVfModule(vnfId, vfModuleId);
656 if (volumeGroupFromVfModule.isPresent()) {
657 String volumeGroupId = volumeGroupFromVfModule.get().getVolumeGroupId();
658 volumeGroupName = volumeGroupFromVfModule.get().getVolumeGroupName();
659 logger.debug("Volume group id of the existing volume group is: " + volumeGroupId);
660 volumeGroupExisted = true;
661 dataObj.getWorkflowResourceIds().setVolumeGroupId(volumeGroupId);
662 dataObj.getReplaceInformation().setOldVolumeGroupName(volumeGroupName);
665 List<OrchestrationFlow> orchFlows = dataObj.getOrchFlows();
666 VfModuleCustomization vfModuleCustomization = catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
667 dataObj.getRequestDetails().getModelInfo().getModelCustomizationUuid());
668 if (vfModuleCustomization != null && vfModuleCustomization.getVfModule() != null
669 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
670 && vfModuleCustomization.getVolumeHeatEnv() != null) {
671 volumeGroupWillExist = true;
672 if (!volumeGroupExisted) {
673 String newVolumeGroupId = UUID.randomUUID().toString();
674 dataObj.getWorkflowResourceIds().setVolumeGroupId(newVolumeGroupId);
675 dataObj.getReplaceInformation().setOldVolumeGroupName(volumeGroupName);
676 logger.debug("newVolumeGroupId: " + newVolumeGroupId);
680 if (volumeGroupExisted && volumeGroupWillExist && !rebuildVolumeGroups) {
681 keepVolumeGroup = true;
684 if (!volumeGroupExisted || keepVolumeGroup) {
685 logger.debug("Filtering out deletion of volume groups");
686 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_DELETE_PATTERN))
687 .collect(Collectors.toList());
689 if (!volumeGroupWillExist || keepVolumeGroup) {
690 logger.debug("Filtering out creation of volume groups");
691 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_CREATE_PATTERN))
692 .collect(Collectors.toList());
698 protected List<Resource> sortVfModulesByBaseFirst(List<Resource> vfModuleResources) {
700 for (Resource resource : vfModuleResources) {
701 if (resource.isBaseVfModule()) {
702 Collections.swap(vfModuleResources, 0, count);
707 return vfModuleResources;
710 protected List<Resource> sortVfModulesByBaseLast(List<Resource> vfModuleResources) {
712 for (Resource resource : vfModuleResources) {
713 if (resource.isBaseVfModule()) {
714 Collections.swap(vfModuleResources, vfModuleResources.size() - 1, count);
719 return vfModuleResources;
722 private void updateResourceIdsFromAAITraversal(List<ExecuteBuildingBlock> flowsToExecute,
723 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds, String serviceInstanceId) {
724 for (Pair<WorkflowType, String> pair : aaiResourceIds) {
725 logger.debug(pair.getValue0() + ", " + pair.getValue1());
728 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
729 .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
730 .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
731 retrieveAAIResourceId(aaiResourceIds, type), null, serviceInstanceId)));
734 private String retrieveAAIResourceId(List<Pair<WorkflowType, String>> aaiResourceIds, WorkflowType resource) {
736 for (int i = 0; i < aaiResourceIds.size(); i++) {
737 if (aaiResourceIds.get(i).getValue0() == resource) {
738 id = aaiResourceIds.get(i).getValue1();
739 aaiResourceIds.remove(i);
746 private void generateResourceIds(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
747 String serviceInstanceId) {
748 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
749 .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
750 .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
751 null, resource.getVirtualLinkKey(), serviceInstanceId)));
754 protected void updateWorkflowResourceIds(List<ExecuteBuildingBlock> flowsToExecute, WorkflowType resourceType,
755 String key, String id, String virtualLinkKey, String serviceInstanceId) {
756 String resourceId = id;
757 if (resourceId == null) {
758 resourceId = UUID.randomUUID().toString();
760 for (ExecuteBuildingBlock ebb : flowsToExecute) {
761 if (key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey()) && (ebb.getBuildingBlock()
762 .getBpmnFlowName().contains(resourceType.toString())
763 || (ebb.getBuildingBlock().getBpmnFlowName().contains(CONTROLLER)
764 && ebb.getBuildingBlock().getBpmnScope().equalsIgnoreCase(resourceType.toString())))) {
765 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
766 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
767 WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, resourceType, resourceId);
768 ebb.setWorkflowResourceIds(workflowResourceIds);
770 if (virtualLinkKey != null && ebb.getBuildingBlock().isVirtualLink()
771 && virtualLinkKey.equalsIgnoreCase(ebb.getBuildingBlock().getVirtualLinkKey())) {
772 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
773 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
774 workflowResourceIds.setNetworkId(resourceId);
775 ebb.setWorkflowResourceIds(workflowResourceIds);
780 protected CollectionResourceCustomization findCatalogNetworkCollection(DelegateExecution execution,
781 org.onap.so.db.catalog.beans.Service service) {
782 CollectionResourceCustomization networkCollection = null;
784 for (CollectionResourceCustomization collectionCust : service.getCollectionResourceCustomizations()) {
785 if (catalogDbClient.getNetworkCollectionResourceCustomizationByID(
786 collectionCust.getModelCustomizationUUID()) != null) {
787 networkCollection = collectionCust;
793 } else if (count > 1) {
794 buildAndThrowException(execution,
795 "Found multiple Network Collections in the Service model, only one per Service is supported.");
797 return networkCollection;
800 protected void traverseCatalogDbService(DelegateExecution execution, ServiceInstancesRequest sIRequest,
801 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds)
802 throws JsonProcessingException, VrfBondingServiceException {
803 String modelUUID = sIRequest.getRequestDetails().getModelInfo().getModelVersionId();
804 org.onap.so.db.catalog.beans.Service service = catalogDbClient.getServiceByID(modelUUID);
806 if (service == null) {
807 buildAndThrowException(execution, "Could not find the service model in catalog db.");
809 resourceList.add(new Resource(WorkflowType.SERVICE, service.getModelUUID(), false));
810 RelatedInstance relatedVpnBinding =
811 bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.vpnBinding);
812 RelatedInstance relatedLocalNetwork =
813 bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.network);
815 if (relatedVpnBinding != null && relatedLocalNetwork != null) {
816 traverseVrfConfiguration(aaiResourceIds, resourceList, service, relatedVpnBinding, relatedLocalNetwork);
818 traverseNetworkCollection(execution, resourceList, service);
823 protected void traverseVrfConfiguration(List<Pair<WorkflowType, String>> aaiResourceIds,
824 List<Resource> resourceList, org.onap.so.db.catalog.beans.Service service,
825 RelatedInstance relatedVpnBinding, RelatedInstance relatedLocalNetwork)
826 throws VrfBondingServiceException, JsonProcessingException {
827 org.onap.aai.domain.yang.L3Network aaiLocalNetwork =
828 bbInputSetupUtils.getAAIL3Network(relatedLocalNetwork.getInstanceId());
829 vrfValidation.vrfServiceValidation(service);
830 vrfValidation.vrfCatalogDbChecks(service);
831 vrfValidation.aaiVpnBindingValidation(relatedVpnBinding.getInstanceId(),
832 bbInputSetupUtils.getAAIVpnBinding(relatedVpnBinding.getInstanceId()));
833 vrfValidation.aaiNetworkValidation(relatedLocalNetwork.getInstanceId(), aaiLocalNetwork);
834 vrfValidation.aaiSubnetValidation(aaiLocalNetwork);
835 vrfValidation.aaiAggregateRouteValidation(aaiLocalNetwork);
836 vrfValidation.aaiRouteTargetValidation(aaiLocalNetwork);
837 String existingAAIVrfConfiguration = getExistingAAIVrfConfiguration(relatedVpnBinding, aaiLocalNetwork);
838 if (existingAAIVrfConfiguration != null) {
839 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, existingAAIVrfConfiguration));
841 resourceList.add(new Resource(WorkflowType.CONFIGURATION,
842 service.getConfigurationCustomizations().get(0).getModelCustomizationUUID(), false));
846 protected String getExistingAAIVrfConfiguration(RelatedInstance relatedVpnBinding,
847 org.onap.aai.domain.yang.L3Network aaiLocalNetwork)
848 throws JsonProcessingException, VrfBondingServiceException {
849 Optional<Relationships> relationshipsOp = new AAIResultWrapper(
850 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiLocalNetwork)).getRelationships();
851 if (relationshipsOp.isPresent()) {
852 List<AAIResultWrapper> configurationsRelatedToLocalNetwork =
853 relationshipsOp.get().getByType(Types.CONFIGURATION);
854 if (configurationsRelatedToLocalNetwork.size() > 1) {
855 throw new VrfBondingServiceException(
856 "Network: " + aaiLocalNetwork.getNetworkId() + " has more than 1 configuration related to it");
858 if (configurationsRelatedToLocalNetwork.size() == 1) {
859 AAIResultWrapper configWrapper = configurationsRelatedToLocalNetwork.get(0);
860 Optional<Configuration> relatedConfiguration = configWrapper.asBean(Configuration.class);
861 if (relatedConfiguration.isPresent() && vrfConfigurationAlreadyExists(relatedVpnBinding,
862 relatedConfiguration.get(), configWrapper)) {
863 return relatedConfiguration.get().getConfigurationId();
870 protected boolean vrfConfigurationAlreadyExists(RelatedInstance relatedVpnBinding, Configuration vrfConfiguration,
871 AAIResultWrapper configWrapper) throws VrfBondingServiceException {
872 if ("VRF-ENTRY".equalsIgnoreCase(vrfConfiguration.getConfigurationType())) {
873 Optional<Relationships> relationshipsConfigOp = configWrapper.getRelationships();
874 if (relationshipsConfigOp.isPresent()) {
875 Optional<VpnBinding> relatedInfraVpnBindingOp =
876 workflowActionUtils.extractRelationshipsVpnBinding(relationshipsConfigOp.get());
877 if (relatedInfraVpnBindingOp.isPresent()) {
878 VpnBinding relatedInfraVpnBinding = relatedInfraVpnBindingOp.get();
879 if (!relatedInfraVpnBinding.getVpnId().equalsIgnoreCase(relatedVpnBinding.getInstanceId())) {
880 throw new VrfBondingServiceException("Configuration: " + vrfConfiguration.getConfigurationId()
881 + " is not connected to the same vpn binding id provided in request: "
882 + relatedVpnBinding.getInstanceId());
892 protected void traverseNetworkCollection(DelegateExecution execution, List<Resource> resourceList,
893 org.onap.so.db.catalog.beans.Service service) {
894 if (isVnfCustomizationsInTheService(service)) {
895 buildAndThrowException(execution,
896 "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");
898 if (isPnfCustomizationsInTheService(service)) {
899 buildAndThrowException(execution,
900 "Cannot orchestrate Service-Macro-Create without user params with a pnf. Please update ASDC model for new macro orchestration support or add service_recipe records to route to old macro flows");
902 List<CollectionResourceCustomization> customizations = service.getCollectionResourceCustomizations();
903 if (customizations.isEmpty()) {
904 logger.debug("No Collections found. CollectionResourceCustomization list is empty.");
906 CollectionResourceCustomization collectionResourceCustomization =
907 findCatalogNetworkCollection(execution, service);
908 traverseNetworkCollectionResourceCustomization(resourceList, collectionResourceCustomization);
910 traverseNetworkCollectionCustomization(resourceList, service);
913 private void traverseNetworkCollectionResourceCustomization(List<Resource> resourceList,
914 CollectionResourceCustomization collectionResourceCustomization) {
915 if (collectionResourceCustomizationShouldNotBeProcessed(resourceList, collectionResourceCustomization))
918 org.onap.so.db.catalog.beans.InstanceGroup instanceGroup =
919 collectionResourceCustomization.getCollectionResource().getInstanceGroup();
920 CollectionResourceInstanceGroupCustomization collectionInstCust = null;
921 if (!instanceGroup.getCollectionInstanceGroupCustomizations().isEmpty()) {
922 for (CollectionResourceInstanceGroupCustomization collectionInstanceGroupTemp : instanceGroup
923 .getCollectionInstanceGroupCustomizations()) {
924 if (collectionInstanceGroupTemp.getModelCustomizationUUID()
925 .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
926 collectionInstCust = collectionInstanceGroupTemp;
930 if (interfaceNetworkQuantityIsAvailableInCollection(collectionInstCust)) {
931 minNetworks = collectionInstCust.getSubInterfaceNetworkQuantity();
934 logger.debug("minNetworks: {}", minNetworks);
935 CollectionNetworkResourceCustomization collectionNetworkResourceCust =
936 getCollectionNetworkResourceCustomization(collectionResourceCustomization, instanceGroup);
937 for (int i = 0; i < minNetworks; i++) {
938 if (collectionNetworkResourceCust != null) {
939 Resource resource = new Resource(WorkflowType.VIRTUAL_LINK,
940 collectionNetworkResourceCust.getModelCustomizationUUID(), false);
941 resource.setVirtualLinkKey(Integer.toString(i));
942 resourceList.add(resource);
947 private CollectionNetworkResourceCustomization getCollectionNetworkResourceCustomization(
948 CollectionResourceCustomization collectionResourceCustomization, InstanceGroup instanceGroup) {
949 CollectionNetworkResourceCustomization collectionNetworkResourceCust = null;
950 for (CollectionNetworkResourceCustomization collectionNetworkTemp : instanceGroup
951 .getCollectionNetworkResourceCustomizations()) {
952 if (collectionNetworkTemp.getNetworkResourceCustomization().getModelCustomizationUUID()
953 .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
954 collectionNetworkResourceCust = collectionNetworkTemp;
958 return collectionNetworkResourceCust;
961 private boolean collectionResourceCustomizationShouldNotBeProcessed(List<Resource> resourceList,
962 CollectionResourceCustomization collectionResourceCustomization) {
963 if (collectionResourceCustomization == null) {
964 logger.debug("No Network Collection Customization found");
967 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
968 collectionResourceCustomization.getModelCustomizationUUID(), false));
969 logger.debug("Found a network collection");
970 if (collectionResourceCustomization.getCollectionResource() == null) {
971 logger.debug("No Network Collection found. collectionResource is null");
974 if (collectionResourceCustomization.getCollectionResource().getInstanceGroup() == null) {
975 logger.debug("No Instance Group found for network collection.");
978 String toscaNodeType =
979 collectionResourceCustomization.getCollectionResource().getInstanceGroup().getToscaNodeType();
980 if (!toscaNodeTypeHasNetworkCollection(toscaNodeType)) {
981 logger.debug("Instance Group tosca node type does not contain NetworkCollection: {}", toscaNodeType);
987 private boolean interfaceNetworkQuantityIsAvailableInCollection(
988 CollectionResourceInstanceGroupCustomization collectionInstCust) {
989 return collectionInstCust != null && collectionInstCust.getSubInterfaceNetworkQuantity() != null;
992 private boolean toscaNodeTypeHasNetworkCollection(String toscaNodeType) {
993 return toscaNodeType != null && toscaNodeType.contains(NETWORKCOLLECTION);
996 private void traverseNetworkCollectionCustomization(List<Resource> resourceList,
997 org.onap.so.db.catalog.beans.Service service) {
998 if (isNetworkCollectionInTheResourceList(resourceList)) {
1001 if (service.getNetworkCustomizations() == null) {
1002 logger.debug("No networks were found on this service model");
1005 for (int i = 0; i < service.getNetworkCustomizations().size(); i++) {
1006 resourceList.add(new Resource(WorkflowType.NETWORK,
1007 service.getNetworkCustomizations().get(i).getModelCustomizationUUID(), false));
1011 private boolean isNetworkCollectionInTheResourceList(List<Resource> resourceList) {
1012 return resourceList.stream().anyMatch(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType());
1015 private boolean isVnfCustomizationsInTheService(org.onap.so.db.catalog.beans.Service service) {
1016 return !(service.getVnfCustomizations() == null || service.getVnfCustomizations().isEmpty());
1019 private boolean isPnfCustomizationsInTheService(org.onap.so.db.catalog.beans.Service service) {
1020 return !(service.getPnfCustomizations() == null || service.getPnfCustomizations().isEmpty());
1023 protected void traverseAAIService(DelegateExecution execution, List<Resource> resourceList, String resourceId,
1024 List<Pair<WorkflowType, String>> aaiResourceIds) {
1026 ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(resourceId);
1027 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
1028 bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
1029 resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
1030 traverseServiceInstanceMSOVnfs(resourceList, aaiResourceIds, serviceInstanceMSO);
1031 traverseServiceInstanceMSOPnfs(resourceList, aaiResourceIds, serviceInstanceMSO);
1032 if (serviceInstanceMSO.getNetworks() != null) {
1033 for (org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network network : serviceInstanceMSO
1035 aaiResourceIds.add(new Pair<>(WorkflowType.NETWORK, network.getNetworkId()));
1036 resourceList.add(new Resource(WorkflowType.NETWORK, network.getNetworkId(), false));
1039 if (serviceInstanceMSO.getCollection() != null) {
1040 logger.debug("found networkcollection");
1042 .add(new Pair<>(WorkflowType.NETWORKCOLLECTION, serviceInstanceMSO.getCollection().getId()));
1043 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
1044 serviceInstanceMSO.getCollection().getId(), false));
1046 if (serviceInstanceMSO.getConfigurations() != null) {
1047 for (Configuration config : serviceInstanceMSO.getConfigurations()) {
1048 Optional<org.onap.aai.domain.yang.Configuration> aaiConfig =
1049 aaiConfigurationResources.getConfiguration(config.getConfigurationId());
1050 if (aaiConfig.isPresent() && aaiConfig.get().getRelationshipList() != null) {
1051 for (Relationship relationship : aaiConfig.get().getRelationshipList().getRelationship()) {
1052 if (relationship.getRelatedTo().contains("vnfc")
1053 || relationship.getRelatedTo().contains("vpn-binding")) {
1054 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.getConfigurationId()));
1056 new Resource(WorkflowType.CONFIGURATION, config.getConfigurationId(), false));
1063 } catch (Exception ex) {
1064 logger.error("Exception in traverseAAIService", ex);
1065 buildAndThrowException(execution,
1066 "Could not find existing Service Instance or related Instances to execute the request on.");
1070 private void traverseServiceInstanceMSOVnfs(List<Resource> resourceList,
1071 List<Pair<WorkflowType, String>> aaiResourceIds,
1072 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO) {
1073 if (serviceInstanceMSO.getVnfs() == null) {
1076 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
1077 aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
1078 resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
1079 traverseVnfModules(resourceList, aaiResourceIds, vnf);
1080 if (vnf.getVolumeGroups() != null) {
1081 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf.getVolumeGroups()) {
1082 aaiResourceIds.add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1083 resourceList.add(new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1089 private void traverseServiceInstanceMSOPnfs(List<Resource> resourceList,
1090 List<Pair<WorkflowType, String>> aaiResourceIds,
1091 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO) {
1092 if (serviceInstanceMSO.getPnfs() == null) {
1095 for (org.onap.so.bpmn.servicedecomposition.bbobjects.Pnf pnf : serviceInstanceMSO.getPnfs()) {
1096 aaiResourceIds.add(new Pair<>(WorkflowType.PNF, pnf.getPnfId()));
1097 resourceList.add(new Resource(WorkflowType.PNF, pnf.getPnfId(), false));
1101 private void traverseVnfModules(List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds,
1102 org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf) {
1103 if (vnf.getVfModules() == null) {
1106 for (VfModule vfModule : vnf.getVfModules()) {
1107 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1108 Resource resource = new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false);
1109 resource.setBaseVfModule(vfModule.getModelInfoVfModule().getIsBaseBoolean());
1110 resourceList.add(resource);
1114 private void traverseAAIVnf(DelegateExecution execution, List<Resource> resourceList, String serviceId,
1115 String vnfId, List<Pair<WorkflowType, String>> aaiResourceIds) {
1117 ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(serviceId);
1118 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
1119 bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
1120 resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
1121 if (serviceInstanceMSO.getVnfs() != null) {
1122 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
1123 if (vnf.getVnfId().equals(vnfId)) {
1124 aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
1125 resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
1126 if (vnf.getVfModules() != null) {
1127 for (VfModule vfModule : vnf.getVfModules()) {
1128 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1129 resourceList.add(new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false));
1130 findConfigurationsInsideVfModule(execution, vnf.getVnfId(), vfModule.getVfModuleId(),
1131 resourceList, aaiResourceIds);
1134 if (vnf.getVolumeGroups() != null) {
1135 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
1136 .getVolumeGroups()) {
1138 .add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1140 new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1147 } catch (Exception ex) {
1148 logger.error("Exception in traverseAAIVnf", ex);
1149 buildAndThrowException(execution,
1150 "Could not find existing Vnf or related Instances to execute the request on.");
1154 private void customTraverseAAIVnf(DelegateExecution execution, List<Resource> resourceList, String serviceId,
1155 String vnfId, List<Pair<WorkflowType, String>> aaiResourceIds) {
1157 ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(serviceId);
1158 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
1159 bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
1160 resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
1161 if (serviceInstanceMSO.getVnfs() != null) {
1162 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
1163 if (vnf.getVnfId().equals(vnfId)) {
1164 aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
1166 String vnfCustomizationUUID =
1167 bbInputSetupUtils.getAAIGenericVnf(vnfId).getModelCustomizationId();
1168 resourceList.add(new Resource(WorkflowType.VNF, vnfCustomizationUUID, false));
1170 if (vnf.getVfModules() != null) {
1171 for (VfModule vfModule : vnf.getVfModules()) {
1172 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1173 resourceList.add(new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false));
1174 findConfigurationsInsideVfModule(execution, vnf.getVnfId(), vfModule.getVfModuleId(),
1175 resourceList, aaiResourceIds);
1178 if (vnf.getVolumeGroups() != null) {
1179 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
1180 .getVolumeGroups()) {
1182 .add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1184 new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1191 } catch (Exception ex) {
1192 logger.error("Exception in customTraverseAAIVnf", ex);
1193 buildAndThrowException(execution,
1194 "Could not find existing Vnf or related Instances to execute the request on.");
1199 private void findConfigurationsInsideVfModule(DelegateExecution execution, String vnfId, String vfModuleId,
1200 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds) {
1202 org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
1203 AAIResultWrapper vfModuleWrapper = new AAIResultWrapper(
1204 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiVfModule));
1205 Optional<Relationships> relationshipsOp;
1206 relationshipsOp = vfModuleWrapper.getRelationships();
1207 if (relationshipsOp.isPresent()) {
1208 relationshipsOp = workflowActionUtils.extractRelationshipsVnfc(relationshipsOp.get());
1209 if (relationshipsOp.isPresent()) {
1210 Optional<Configuration> config =
1211 workflowActionUtils.extractRelationshipsConfiguration(relationshipsOp.get());
1212 if (config.isPresent()) {
1213 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.get().getConfigurationId()));
1215 new Resource(WorkflowType.CONFIGURATION, config.get().getConfigurationId(), false));
1219 } catch (Exception ex) {
1220 logger.error("Exception in findConfigurationsInsideVfModule", ex);
1221 buildAndThrowException(execution, "Failed to find Configuration object from the vfModule.");
1225 protected WorkflowResourceIds populateResourceIdsFromApiHandler(DelegateExecution execution) {
1226 return WorkflowResourceIdsUtils.getWorkflowResourceIdsFromExecution(execution);
1229 protected Resource extractResourceIdAndTypeFromUri(String uri) {
1230 Pattern patt = Pattern.compile("[vV]\\d+.*?(?:(?:/(?<type>" + SUPPORTEDTYPES
1231 + ")(?:/(?<id>[^/]+))?)(?:/(?<action>[^/]+))?(?:/resume)?)?$");
1232 Matcher m = patt.matcher(uri);
1233 boolean generated = false;
1236 logger.debug("found match on {} : {} ", uri, m);
1237 String type = m.group("type");
1238 String id = m.group("id");
1239 String action = m.group("action");
1241 throw new IllegalArgumentException("Uri could not be parsed. No type found. " + uri);
1243 if (action == null) {
1244 if (type.equals(SERVICE_INSTANCES) && (id == null || "assign".equals(id))) {
1245 id = UUID.randomUUID().toString();
1247 } else if (type.equals(VF_MODULES) && "scaleOut".equals(id)) {
1248 id = UUID.randomUUID().toString();
1252 if (action.matches(SUPPORTEDTYPES)) {
1253 id = UUID.randomUUID().toString();
1258 return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated);
1260 throw new IllegalArgumentException("Uri could not be parsed: " + uri);
1264 protected String validateResourceIdInAAI(String generatedResourceId, WorkflowType type, String instanceName,
1265 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws Exception {
1267 if ("SERVICE".equalsIgnoreCase(type.toString())) {
1268 return validateServiceResourceIdInAAI(generatedResourceId, instanceName, reqDetails);
1269 } else if ("NETWORK".equalsIgnoreCase(type.toString())) {
1270 return validateNetworkResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1271 workflowResourceIds);
1272 } else if ("VNF".equalsIgnoreCase(type.toString())) {
1273 return validateVnfResourceIdInAAI(generatedResourceId, instanceName, reqDetails, workflowResourceIds);
1274 } else if ("VFMODULE".equalsIgnoreCase(type.toString())) {
1275 return validateVfModuleResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1276 workflowResourceIds);
1277 } else if ("VOLUMEGROUP".equalsIgnoreCase(type.toString())) {
1278 return validateVolumeGroupResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1279 workflowResourceIds);
1280 } else if ("CONFIGURATION".equalsIgnoreCase(type.toString())) {
1281 return validateConfigurationResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1282 workflowResourceIds);
1284 return generatedResourceId;
1285 } catch (DuplicateNameException dne) {
1287 } catch (Exception ex) {
1288 logger.error(WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI, ex);
1289 throw new IllegalStateException(
1290 WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI);
1294 protected String convertTypeFromPlural(String type) {
1295 if (!type.matches(SUPPORTEDTYPES)) {
1298 if (type.equals(SERVICE_INSTANCES)) {
1301 return type.substring(0, 1).toUpperCase() + type.substring(1, type.length() - 1);
1306 protected List<ExecuteBuildingBlock> sortExecutionPathByObjectForVlanTagging(List<ExecuteBuildingBlock> orchFlows,
1307 String requestAction) {
1308 List<ExecuteBuildingBlock> sortedOrchFlows = new ArrayList<>();
1309 if (requestAction.equals(CREATE_INSTANCE)) {
1310 for (ExecuteBuildingBlock ebb : orchFlows) {
1311 if (ebb.getBuildingBlock().getBpmnFlowName().equals("AssignNetworkBB")) {
1312 String key = ebb.getBuildingBlock().getKey();
1313 boolean isVirtualLink = Boolean.TRUE.equals(ebb.getBuildingBlock().isVirtualLink());
1314 String virtualLinkKey = ebb.getBuildingBlock().getVirtualLinkKey();
1315 sortedOrchFlows.add(ebb);
1316 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1317 if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1318 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1319 sortedOrchFlows.add(ebb2);
1322 if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1323 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1324 sortedOrchFlows.add(ebb2);
1328 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1329 if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1330 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1331 sortedOrchFlows.add(ebb2);
1334 if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1335 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1336 sortedOrchFlows.add(ebb2);
1340 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1341 || ebb.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)) {
1343 } else if (!"".equals(ebb.getBuildingBlock().getBpmnFlowName())) {
1344 sortedOrchFlows.add(ebb);
1347 } else if (requestAction.equals("deleteInstance")) {
1348 for (ExecuteBuildingBlock ebb : orchFlows) {
1349 if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeactivateNetworkBB")) {
1350 sortedOrchFlows.add(ebb);
1351 String key = ebb.getBuildingBlock().getKey();
1352 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1353 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1354 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1355 sortedOrchFlows.add(ebb2);
1359 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1360 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")
1361 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1362 sortedOrchFlows.add(ebb2);
1366 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1367 || ebb.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")) {
1369 } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) {
1370 sortedOrchFlows.add(ebb);
1374 return sortedOrchFlows;
1377 private void addBuildingBlockToExecuteBBList(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
1378 WorkflowType workflowType, OrchestrationFlow orchFlow, String requestId, String apiVersion,
1379 String resourceId, String requestAction, String vnfType, WorkflowResourceIds workflowResourceIds,
1380 RequestDetails requestDetails, boolean isVirtualLink, boolean isConfiguration) {
1382 resourceList.stream().filter(resource -> resource.getResourceType().equals(workflowType))
1383 .forEach(resource -> flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource,
1384 apiVersion, resourceId, requestAction, false, vnfType, workflowResourceIds, requestDetails,
1385 isVirtualLink, resource.getVirtualLinkKey(), null, isConfiguration, null)));
1388 protected List<ExecuteBuildingBlock> buildExecuteBuildingBlockList(List<OrchestrationFlow> orchFlows,
1389 List<Resource> resourceList, String requestId, String apiVersion, String resourceId, String requestAction,
1390 String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1391 boolean replaceVnf) {
1392 List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
1393 for (OrchestrationFlow orchFlow : orchFlows) {
1394 if (orchFlow.getFlowName().contains(SERVICE)) {
1396 workflowResourceIds.setServiceInstanceId(resourceId);
1398 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.SERVICE, orchFlow, requestId,
1399 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1401 } else if (orchFlow.getFlowName().contains(VNF) || (orchFlow.getFlowName().contains(CONTROLLER)
1402 && (VNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1403 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VNF, orchFlow, requestId,
1404 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1406 } else if (orchFlow.getFlowName().contains(PNF) || (orchFlow.getFlowName().contains(CONTROLLER)
1407 && (PNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1408 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.PNF, orchFlow, requestId,
1409 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1411 } else if (orchFlow.getFlowName().contains(NETWORK)
1412 && !orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1413 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORK, orchFlow, requestId,
1414 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1416 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VIRTUAL_LINK, orchFlow,
1417 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1419 } else if (orchFlow.getFlowName().contains(VFMODULE) || (orchFlow.getFlowName().contains(CONTROLLER)
1420 && (VFMODULE).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1421 List<Resource> vfModuleResourcesSorted;
1422 if (requestAction.equals(CREATE_INSTANCE) || requestAction.equals(ASSIGNINSTANCE)
1423 || requestAction.equals("activateInstance")) {
1424 vfModuleResourcesSorted = sortVfModulesByBaseFirst(resourceList.stream()
1425 .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1427 vfModuleResourcesSorted = sortVfModulesByBaseLast(resourceList.stream()
1428 .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1430 for (Resource resource : vfModuleResourcesSorted) {
1431 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource, apiVersion, resourceId,
1432 requestAction, false, vnfType, workflowResourceIds, requestDetails, false, null, null,
1435 } else if (orchFlow.getFlowName().contains(VOLUMEGROUP)) {
1436 if (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1437 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)) {
1438 logger.debug("Replacing workflow resource id by volume group id");
1439 resourceId = workflowResourceIds.getVolumeGroupId();
1441 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VOLUMEGROUP, orchFlow,
1442 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1444 } else if (orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1445 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORKCOLLECTION, orchFlow,
1446 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1448 } else if (orchFlow.getFlowName().contains(CONFIGURATION)) {
1449 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.CONFIGURATION, orchFlow,
1450 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1454 .add(buildExecuteBuildingBlock(orchFlow, requestId, null, apiVersion, resourceId, requestAction,
1455 false, vnfType, workflowResourceIds, requestDetails, false, null, null, false, null));
1458 return flowsToExecute;
1461 protected ExecuteBuildingBlock buildExecuteBuildingBlock(OrchestrationFlow orchFlow, String requestId,
1462 Resource resource, String apiVersion, String resourceId, String requestAction, boolean aLaCarte,
1463 String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1464 boolean isVirtualLink, String virtualLinkKey, String vnfcName, boolean isConfiguration,
1465 ReplaceInstanceRelatedInformation replaceInfo) {
1467 BuildingBlock buildingBlock =
1468 new BuildingBlock().setBpmnFlowName(orchFlow.getFlowName()).setMsoId(UUID.randomUUID().toString())
1469 .setIsVirtualLink(isVirtualLink).setVirtualLinkKey(virtualLinkKey)
1470 .setKey(Optional.ofNullable(resource).map(Resource::getResourceId).orElse(""));
1471 Optional.ofNullable(orchFlow.getBpmnAction()).ifPresent(buildingBlock::setBpmnAction);
1472 Optional.ofNullable(orchFlow.getBpmnScope()).ifPresent(buildingBlock::setBpmnScope);
1473 String oldVolumeGroupName = "";
1474 if (replaceInfo != null) {
1475 oldVolumeGroupName = replaceInfo.getOldVolumeGroupName();
1477 if (resource != null
1478 && (orchFlow.getFlowName().contains(VOLUMEGROUP) && (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1479 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)))) {
1480 logger.debug("Setting resourceId to volume group id for volume group flow on replace");
1481 resourceId = workflowResourceIds.getVolumeGroupId();
1484 ExecuteBuildingBlock executeBuildingBlock = new ExecuteBuildingBlock().setApiVersion(apiVersion)
1485 .setaLaCarte(aLaCarte).setRequestAction(requestAction).setResourceId(resourceId).setVnfType(vnfType)
1486 .setWorkflowResourceIds(workflowResourceIds).setRequestId(requestId).setBuildingBlock(buildingBlock)
1487 .setRequestDetails(requestDetails).setOldVolumeGroupName(oldVolumeGroupName);
1489 if (resource != null && (isConfiguration || resource.getResourceType().equals(WorkflowType.CONFIGURATION))) {
1490 ConfigurationResourceKeys configurationResourceKeys = getConfigurationResourceKeys(resource, vnfcName);
1491 executeBuildingBlock.setConfigurationResourceKeys(configurationResourceKeys);
1493 return executeBuildingBlock;
1496 private ConfigurationResourceKeys getConfigurationResourceKeys(Resource resource, String vnfcName) {
1497 ConfigurationResourceKeys configurationResourceKeys = new ConfigurationResourceKeys();
1498 Optional.ofNullable(vnfcName).ifPresent(configurationResourceKeys::setVnfcName);
1499 configurationResourceKeys.setCvnfcCustomizationUUID(resource.getCvnfModuleCustomizationId());
1500 configurationResourceKeys.setVfModuleCustomizationUUID(resource.getVfModuleCustomizationId());
1501 configurationResourceKeys.setVnfResourceCustomizationUUID(resource.getVnfCustomizationId());
1502 return configurationResourceKeys;
1505 protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1506 WorkflowType resourceName, boolean aLaCarte, String cloudOwner) {
1507 return this.queryNorthBoundRequestCatalogDb(execution, requestAction, resourceName, aLaCarte, cloudOwner, "");
1510 protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1511 WorkflowType resourceName, boolean aLaCarte, String cloudOwner, String serviceType) {
1512 List<OrchestrationFlow> listToExecute = new ArrayList<>();
1513 NorthBoundRequest northBoundRequest;
1514 if (serviceType.equalsIgnoreCase(SERVICE_TYPE_TRANSPORT)
1515 || serviceType.equalsIgnoreCase(SERVICE_TYPE_BONDING)) {
1517 catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwnerAndServiceType(
1518 requestAction, resourceName.toString(), aLaCarte, cloudOwner, serviceType);
1520 northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1521 requestAction, resourceName.toString(), aLaCarte, cloudOwner);
1523 if (northBoundRequest == null) {
1524 northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1525 requestAction, resourceName.toString(), aLaCarte, CLOUD_OWNER);
1527 if (northBoundRequest == null) {
1528 buildAndThrowException(execution, String.format("The request: %s %s %s is not supported by GR_API.",
1529 (aLaCarte ? "AlaCarte" : "Macro"), resourceName, requestAction));
1531 if (northBoundRequest.getIsToplevelflow() != null) {
1532 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, northBoundRequest.getIsToplevelflow());
1534 List<OrchestrationFlow> flows = northBoundRequest.getOrchestrationFlowList();
1535 if (flows == null) {
1536 flows = new ArrayList<>();
1538 flows.sort(Comparator.comparingInt(OrchestrationFlow::getSequenceNumber));
1540 for (OrchestrationFlow flow : flows) {
1541 if (!flow.getFlowName().contains("BB") && !flow.getFlowName().contains("Activity")) {
1542 List<OrchestrationFlow> macroQueryFlows =
1543 catalogDbClient.getOrchestrationFlowByAction(flow.getFlowName());
1544 listToExecute.addAll(macroQueryFlows);
1546 listToExecute.add(flow);
1550 return listToExecute;
1553 public void handleRuntimeException(DelegateExecution execution) {
1554 StringBuilder wfeExpMsg = new StringBuilder("Runtime error ");
1555 String runtimeErrorMessage;
1557 String javaExpMsg = (String) execution.getVariable("BPMN_javaExpMsg");
1558 if (javaExpMsg != null && !javaExpMsg.isEmpty()) {
1559 wfeExpMsg.append(": ").append(javaExpMsg);
1561 runtimeErrorMessage = wfeExpMsg.toString();
1562 logger.error(runtimeErrorMessage);
1563 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, runtimeErrorMessage);
1564 } catch (Exception e) {
1565 logger.error("Runtime error", e);
1566 // if runtime message was mulformed
1567 runtimeErrorMessage = "Runtime error";
1569 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, runtimeErrorMessage);
1572 protected boolean isUriResume(String uri) {
1573 return uri.endsWith("/resume");
1576 protected boolean isRequestMacroServiceResume(boolean aLaCarte, WorkflowType resourceType, String requestAction,
1577 String serviceInstanceId) {
1578 return (!aLaCarte && resourceType == WorkflowType.SERVICE
1579 && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE) || requestAction.equalsIgnoreCase(CREATE_INSTANCE))
1580 && (serviceInstanceId != null && serviceInstanceId.trim().length() > 1)
1581 && (bbInputSetupUtils.getAAIServiceInstanceById(serviceInstanceId) != null));
1584 protected String validateServiceResourceIdInAAI(String generatedResourceId, String instanceName,
1585 RequestDetails reqDetails) throws DuplicateNameException {
1586 String globalCustomerId = reqDetails.getSubscriberInfo().getGlobalSubscriberId();
1587 String serviceType = reqDetails.getRequestParameters().getSubscriptionServiceType();
1588 if (instanceName != null) {
1589 Optional<ServiceInstance> serviceInstanceAAI =
1590 bbInputSetupUtils.getAAIServiceInstanceByName(globalCustomerId, serviceType, instanceName);
1591 if (serviceInstanceAAI.isPresent()) {
1592 if (serviceInstanceAAI.get().getModelVersionId()
1593 .equalsIgnoreCase(reqDetails.getModelInfo().getModelVersionId())) {
1594 return serviceInstanceAAI.get().getServiceInstanceId();
1596 throw new DuplicateNameException(SERVICE_INSTANCE, String.format(NAME_EXISTS_WITH_DIFF_VERSION_ID,
1597 instanceName, reqDetails.getModelInfo().getModelVersionId()));
1600 ServiceInstances aaiServiceInstances =
1601 bbInputSetupUtils.getAAIServiceInstancesGloballyByName(instanceName);
1602 if (aaiServiceInstances != null) {
1603 if (aaiServiceInstances.getServiceInstance() != null
1604 && !aaiServiceInstances.getServiceInstance().isEmpty()) {
1605 if (aaiServiceInstances.getServiceInstance().size() > 1) {
1606 throw new DuplicateNameException(SERVICE_INSTANCE,
1607 String.format(NAME_EXISTS_MULTIPLE, instanceName));
1609 ServiceInstance si = aaiServiceInstances.getServiceInstance().stream().findFirst().get();
1610 Map<String, String> keys =
1611 bbInputSetupUtils.getURIKeysFromServiceInstance(si.getServiceInstanceId());
1613 throw new DuplicateNameException(SERVICE_INSTANCE, String.format(
1614 NAME_EXISTS_WITH_DIFF_COMBINATION, instanceName,
1615 keys.get(AAIFluentTypeBuilder.Types.CUSTOMER.getUriParams().globalCustomerId),
1617 AAIFluentTypeBuilder.Types.SERVICE_SUBSCRIPTION.getUriParams().serviceType),
1618 si.getModelVersionId()));
1624 return generatedResourceId;
1627 protected String validateNetworkResourceIdInAAI(String generatedResourceId, String instanceName,
1628 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1629 throws DuplicateNameException, MultipleObjectsFoundException {
1630 Optional<L3Network> network = bbInputSetupUtils
1631 .getRelatedNetworkByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1632 if (network.isPresent()) {
1633 if (network.get().getModelCustomizationId()
1634 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1635 return network.get().getNetworkId();
1637 throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1638 instanceName, network.get().getModelCustomizationId()));
1641 if (bbInputSetupUtils.existsAAINetworksGloballyByName(instanceName)) {
1642 throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName,
1643 workflowResourceIds.getServiceInstanceId()));
1645 return generatedResourceId;
1648 protected String validateVnfResourceIdInAAI(String generatedResourceId, String instanceName,
1649 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1650 Optional<GenericVnf> vnf = bbInputSetupUtils
1651 .getRelatedVnfByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1652 if (vnf.isPresent()) {
1653 if (vnf.get().getModelCustomizationId()
1654 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1655 return vnf.get().getVnfId();
1657 throw new DuplicateNameException("generic-vnf", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1658 instanceName, vnf.get().getModelCustomizationId()));
1661 GenericVnfs vnfs = bbInputSetupUtils.getAAIVnfsGloballyByName(instanceName);
1663 throw new DuplicateNameException("generic-vnf",
1664 String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName, vnfs.getGenericVnf().get(0).getVnfId()));
1666 return generatedResourceId;
1669 protected String validateVfModuleResourceIdInAAI(String generatedResourceId, String instanceName,
1670 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1671 GenericVnf vnf = bbInputSetupUtils.getAAIGenericVnf(workflowResourceIds.getVnfId());
1672 if (vnf != null && vnf.getVfModules() != null) {
1673 for (org.onap.aai.domain.yang.VfModule vfModule : vnf.getVfModules().getVfModule()) {
1674 if (vfModule.getVfModuleName().equalsIgnoreCase(instanceName)) {
1675 if (vfModule.getModelCustomizationId()
1676 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1677 return vfModule.getVfModuleId();
1679 throw new DuplicateNameException("vfModule",
1680 String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID, instanceName,
1681 reqDetails.getModelInfo().getModelCustomizationId()));
1686 if (bbInputSetupUtils.existsAAIVfModuleGloballyByName(instanceName)) {
1687 throw new DuplicateNameException("vfModule", instanceName);
1689 return generatedResourceId;
1692 protected String validateVolumeGroupResourceIdInAAI(String generatedResourceId, String instanceName,
1693 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1694 Optional<VolumeGroup> volumeGroup =
1695 bbInputSetupUtils.getRelatedVolumeGroupByNameFromVnf(workflowResourceIds.getVnfId(), instanceName);
1696 if (volumeGroup.isPresent()) {
1697 if (volumeGroup.get().getVfModuleModelCustomizationId()
1698 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1699 return volumeGroup.get().getVolumeGroupId();
1701 throw new DuplicateNameException("volumeGroup", volumeGroup.get().getVolumeGroupName());
1704 if (bbInputSetupUtils.existsAAIVolumeGroupGloballyByName(instanceName)) {
1705 throw new DuplicateNameException("volumeGroup", instanceName);
1707 return generatedResourceId;
1710 protected String validateConfigurationResourceIdInAAI(String generatedResourceId, String instanceName,
1711 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1712 Optional<org.onap.aai.domain.yang.Configuration> configuration =
1713 bbInputSetupUtils.getRelatedConfigurationByNameFromServiceInstance(
1714 workflowResourceIds.getServiceInstanceId(), instanceName);
1715 if (configuration.isPresent()) {
1716 if (configuration.get().getModelCustomizationId()
1717 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1718 return configuration.get().getConfigurationId();
1720 throw new DuplicateNameException("configuration", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1721 instanceName, configuration.get().getConfigurationId()));
1724 if (bbInputSetupUtils.existsAAIConfigurationGloballyByName(instanceName)) {
1725 throw new DuplicateNameException("configuration", instanceName);
1727 return generatedResourceId;
1730 protected boolean foundRelated(List<Resource> resourceList) {
1731 return (containsWorkflowType(resourceList, WorkflowType.VNF)
1732 || containsWorkflowType(resourceList, WorkflowType.PNF)
1733 || containsWorkflowType(resourceList, WorkflowType.NETWORK)
1734 || containsWorkflowType(resourceList, WorkflowType.NETWORKCOLLECTION));
1737 protected boolean containsWorkflowType(List<Resource> resourceList, WorkflowType workflowType) {
1738 return resourceList.stream().anyMatch(resource -> resource.getResourceType().equals(workflowType));
1741 private void fillExecutionDefault(DelegateExecution execution) {
1742 execution.setVariable("sentSyncResponse", false);
1743 execution.setVariable(HOMING, false);
1744 execution.setVariable("calledHoming", false);
1745 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, true);
1748 private void fillExecution(DelegateExecution execution, boolean suppressRollback, String resourceId,
1749 WorkflowType resourceType) {
1750 execution.setVariable("suppressRollback", suppressRollback);
1751 execution.setVariable("resourceId", resourceId);
1752 execution.setVariable("resourceType", resourceType);
1753 execution.setVariable("resourceName", resourceType.toString());
1756 private Resource getResource(BBInputSetupUtils bbInputSetupUtils, boolean isResume, boolean alaCarte, String uri,
1758 if (!alaCarte && isResume) {
1759 logger.debug("replacing URI {}", uri);
1760 uri = bbInputSetupUtils.loadOriginalInfraActiveRequestById(requestId).getRequestUrl();
1761 logger.debug("for RESUME with original value {}", uri);
1763 return extractResourceIdAndTypeFromUri(uri);
1766 private String getResourceId(Resource resource, String requestAction, RequestDetails requestDetails,
1767 WorkflowResourceIds workflowResourceIds) throws Exception {
1768 if (resource.isGenerated() && requestAction.equalsIgnoreCase("createInstance")
1769 && requestDetails.getRequestInfo().getInstanceName() != null) {
1770 return validateResourceIdInAAI(resource.getResourceId(), resource.getResourceType(),
1771 requestDetails.getRequestInfo().getInstanceName(), requestDetails, workflowResourceIds);
1773 return resource.getResourceId();
1777 private String getServiceInstanceId(DelegateExecution execution, String resourceId, WorkflowType resourceType) {
1778 String serviceInstanceId = (String) execution.getVariable("serviceInstanceId");
1779 if ((serviceInstanceId == null || serviceInstanceId.isEmpty()) && WorkflowType.SERVICE.equals(resourceType)) {
1780 serviceInstanceId = resourceId;
1782 return serviceInstanceId;