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 java.io.IOException;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Collections;
33 import java.util.List;
35 import java.util.Optional;
36 import java.util.UUID;
37 import java.util.regex.Matcher;
38 import java.util.regex.Pattern;
39 import java.util.stream.Collectors;
40 import org.camunda.bpm.engine.delegate.DelegateExecution;
41 import org.javatuples.Pair;
42 import org.onap.aai.domain.yang.GenericVnf;
43 import org.onap.aai.domain.yang.GenericVnfs;
44 import org.onap.aai.domain.yang.L3Network;
45 import org.onap.aai.domain.yang.Relationship;
46 import org.onap.aai.domain.yang.ServiceInstance;
47 import org.onap.aai.domain.yang.ServiceInstances;
48 import org.onap.aai.domain.yang.Vnfc;
49 import org.onap.aai.domain.yang.VolumeGroup;
50 import org.onap.aai.domain.yang.VpnBinding;
51 import org.onap.aaiclient.client.aai.AAICommonObjectMapperProvider;
52 import org.onap.aaiclient.client.aai.AAIObjectType;
53 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper;
54 import org.onap.aaiclient.client.aai.entities.Relationships;
55 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri;
56 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory;
57 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder;
58 import org.onap.so.bpmn.common.BBConstants;
59 import org.onap.so.bpmn.infrastructure.workflow.tasks.utils.WorkflowResourceIdsUtils;
60 import org.onap.so.bpmn.servicedecomposition.bbobjects.Configuration;
61 import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule;
62 import org.onap.so.bpmn.servicedecomposition.entities.BuildingBlock;
63 import org.onap.so.bpmn.servicedecomposition.entities.ConfigurationResourceKeys;
64 import org.onap.so.bpmn.servicedecomposition.entities.ExecuteBuildingBlock;
65 import org.onap.so.bpmn.servicedecomposition.entities.WorkflowResourceIds;
66 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetup;
67 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetupUtils;
68 import org.onap.so.bpmn.servicedecomposition.tasks.exceptions.DuplicateNameException;
69 import org.onap.so.bpmn.servicedecomposition.tasks.exceptions.MultipleObjectsFoundException;
70 import org.onap.so.client.exception.ExceptionBuilder;
71 import org.onap.so.client.orchestration.AAIConfigurationResources;
72 import org.onap.so.client.orchestration.AAIEntityNotFoundException;
73 import org.onap.so.db.catalog.beans.CollectionNetworkResourceCustomization;
74 import org.onap.so.db.catalog.beans.CollectionResourceCustomization;
75 import org.onap.so.db.catalog.beans.CollectionResourceInstanceGroupCustomization;
76 import org.onap.so.db.catalog.beans.CvnfcConfigurationCustomization;
77 import org.onap.so.db.catalog.beans.CvnfcCustomization;
78 import org.onap.so.db.catalog.beans.InstanceGroup;
79 import org.onap.so.db.catalog.beans.VfModuleCustomization;
80 import org.onap.so.db.catalog.beans.macro.NorthBoundRequest;
81 import org.onap.so.db.catalog.beans.macro.OrchestrationFlow;
82 import org.onap.so.db.catalog.client.CatalogDbClient;
83 import org.onap.so.serviceinstancebeans.CloudConfiguration;
84 import org.onap.so.serviceinstancebeans.ModelInfo;
85 import org.onap.so.serviceinstancebeans.ModelType;
86 import org.onap.so.serviceinstancebeans.Networks;
87 import org.onap.so.serviceinstancebeans.Pnfs;
88 import org.onap.so.serviceinstancebeans.RelatedInstance;
89 import org.onap.so.serviceinstancebeans.RequestDetails;
90 import org.onap.so.serviceinstancebeans.Service;
91 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
92 import org.onap.so.serviceinstancebeans.VfModules;
93 import org.onap.so.serviceinstancebeans.Vnfs;
94 import org.slf4j.Logger;
95 import org.slf4j.LoggerFactory;
96 import org.springframework.beans.factory.annotation.Autowired;
97 import org.springframework.core.env.Environment;
98 import org.springframework.stereotype.Component;
99 import org.springframework.util.CollectionUtils;
100 import com.fasterxml.jackson.core.JsonProcessingException;
101 import com.fasterxml.jackson.databind.ObjectMapper;
104 public class WorkflowAction {
106 private static final String WORKFLOW_ACTION_ERROR_MESSAGE = "WorkflowActionErrorMessage";
107 private static final String SERVICE_INSTANCES = "serviceInstances";
108 private static final String SERVICE_INSTANCE = "serviceInstance";
109 private static final String VF_MODULES = "vfModules";
110 private static final String WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI =
111 "WorkflowAction was unable to verify if the instance name already exist in AAI.";
112 private static final String VNF_TYPE = "vnfType";
113 private static final String SERVICE = "Service";
114 private static final String VNF = "Vnf";
115 private static final String PNF = "Pnf";
116 private static final String VFMODULE = "VfModule";
117 private static final String VOLUMEGROUP = "VolumeGroup";
118 private static final String NETWORK = "Network";
119 private static final String NETWORKCOLLECTION = "NetworkCollection";
120 private static final String CONFIGURATION = "Configuration";
121 private static final String ASSIGNINSTANCE = "assignInstance";
122 private static final String CREATEINSTANCE = "createInstance";
123 private static final String REPLACEINSTANCE = "replaceInstance";
124 private static final String REPLACEINSTANCERETAINASSIGNMENTS = "replaceInstanceRetainAssignments";
125 private static final String USERPARAMSERVICE = "service";
126 private static final String SUPPORTEDTYPES =
127 "vnfs|vfModules|networks|networkCollections|volumeGroups|serviceInstances|instanceGroups";
128 private static final String HOMINGSOLUTION = "Homing_Solution";
129 private static final String FABRIC_CONFIGURATION = "FabricConfiguration";
130 private static final String SERVICE_TYPE_TRANSPORT = "TRANSPORT";
131 private static final String SERVICE_TYPE_BONDING = "BONDING";
132 private static final String CLOUD_OWNER = "DEFAULT";
133 private static final Logger logger = LoggerFactory.getLogger(WorkflowAction.class);
134 private static final String NAME_EXISTS_WITH_DIFF_VERSION_ID = "(%s) and different version id (%s)";
135 private static final String NAME_EXISTS_MULTIPLE =
136 "(%s) and multiple combination of model-version-id + service-type + global-customer-id";
137 private static final String NAME_EXISTS_WITH_DIFF_COMBINATION =
138 "(%s) and global-customer-id (%s), service-type (%s), model-version-id (%s)";
139 private static final String NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID =
140 "(%s), same parent and different customization id (%s)";
141 private static final String NAME_EXISTS_WITH_DIFF_PARENT = "(%s) id (%s) and different parent relationship";
142 private static final String CREATENETWORKBB = "CreateNetworkBB";
143 private static final String ACTIVATENETWORKBB = "ActivateNetworkBB";
144 private static final String VOLUMEGROUP_DELETE_PATTERN = "(Un|De)(.*)Volume(.*)";
145 private static final String VOLUMEGROUP_CREATE_PATTERN = "(A|C)(.*)Volume(.*)";
146 private static final String CONTROLLER = "Controller";
147 private static final String DEFAULT_CLOUD_OWNER = "org.onap.so.cloud-owner";
150 protected BBInputSetup bbInputSetup;
152 protected BBInputSetupUtils bbInputSetupUtils;
154 private ExceptionBuilder exceptionBuilder;
156 private CatalogDbClient catalogDbClient;
158 private AAIConfigurationResources aaiConfigurationResources;
160 private WorkflowActionExtractResourcesAAI workflowActionUtils;
162 private VrfValidation vrfValidation;
164 private Environment environment;
166 public void setBbInputSetupUtils(BBInputSetupUtils bbInputSetupUtils) {
167 this.bbInputSetupUtils = bbInputSetupUtils;
170 public void setBbInputSetup(BBInputSetup bbInputSetup) {
171 this.bbInputSetup = bbInputSetup;
174 public void selectExecutionList(DelegateExecution execution) throws Exception {
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 flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
201 if (flowsToExecute == null) {
202 buildAndThrowException(execution, "Could not resume Macro flow. Error loading execution path.");
204 } else if (isALaCarte && isResume) {
205 flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
206 if (flowsToExecute == null) {
207 buildAndThrowException(execution,
208 "Could not resume request with request Id: " + requestId + ". No flowsToExecute was found");
211 String vnfType = (String) execution.getVariable(VNF_TYPE);
212 String cloudOwner = getCloudOwner(requestDetails.getCloudConfiguration());
213 List<OrchestrationFlow> orchFlows =
214 (List<OrchestrationFlow>) execution.getVariable(BBConstants.G_ORCHESTRATION_FLOW);
215 final String apiVersion = (String) execution.getVariable(BBConstants.G_APIVERSION);
216 final String serviceType =
217 Optional.ofNullable((String) execution.getVariable(BBConstants.G_SERVICE_TYPE)).orElse("");
219 if (orchFlows == null || orchFlows.isEmpty()) {
220 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, true,
221 cloudOwner, serviceType);
223 Resource resourceKey = getResourceKey(sIRequest, resourceType);
225 if ((requestAction.equalsIgnoreCase(REPLACEINSTANCE)
226 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS))
227 && resourceType.equals(WorkflowType.VFMODULE)) {
228 logger.debug("Build a BB list for replacing BB modules");
229 orchFlows = getVfModuleReplaceBuildingBlocks(
230 new ConfigBuildingBlocksDataObject().setsIRequest(sIRequest).setOrchFlows(orchFlows)
231 .setRequestId(requestId).setResourceKey(resourceKey).setApiVersion(apiVersion)
232 .setResourceId(resourceId).setRequestAction(requestAction).setaLaCarte(true)
233 .setVnfType(vnfType).setWorkflowResourceIds(workflowResourceIds)
234 .setRequestDetails(requestDetails).setExecution(execution));
235 for (OrchestrationFlow orchFlow : orchFlows) {
236 if (orchFlow.getFlowName().contains(CONFIGURATION)) {
237 List<OrchestrationFlow> configOrchFlows = new ArrayList<>();
238 configOrchFlows.add(orchFlow);
239 List<ExecuteBuildingBlock> configBuildingBlocks =
240 getConfigBuildingBlocks(new ConfigBuildingBlocksDataObject()
241 .setsIRequest(sIRequest).setOrchFlows(configOrchFlows)
242 .setRequestId(requestId).setResourceKey(resourceKey)
243 .setApiVersion(apiVersion).setResourceId(resourceId)
244 .setRequestAction(requestAction).setaLaCarte(true).setVnfType(vnfType)
245 .setWorkflowResourceIds(workflowResourceIds)
246 .setRequestDetails(requestDetails).setExecution(execution));
247 flowsToExecute.addAll(configBuildingBlocks);
249 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, resourceKey,
250 apiVersion, resourceId, requestAction, true, vnfType, workflowResourceIds,
251 requestDetails, false, null, null, false);
252 flowsToExecute.add(ebb);
256 if (isConfiguration(orchFlows) && !requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
257 List<ExecuteBuildingBlock> configBuildingBlocks =
258 getConfigBuildingBlocks(new ConfigBuildingBlocksDataObject().setsIRequest(sIRequest)
259 .setOrchFlows(orchFlows).setRequestId(requestId).setResourceKey(resourceKey)
260 .setApiVersion(apiVersion).setResourceId(resourceId)
261 .setRequestAction(requestAction).setaLaCarte(true).setVnfType(vnfType)
262 .setWorkflowResourceIds(workflowResourceIds)
263 .setRequestDetails(requestDetails).setExecution(execution));
265 flowsToExecute.addAll(configBuildingBlocks);
268 orchFlows.stream().filter(item -> !item.getFlowName().contains(FABRIC_CONFIGURATION))
269 .collect(Collectors.toList());
271 for (OrchestrationFlow orchFlow : orchFlows) {
272 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, resourceKey,
273 apiVersion, resourceId, requestAction, true, vnfType, workflowResourceIds,
274 requestDetails, false, null, null, false);
275 flowsToExecute.add(ebb);
279 boolean foundRelated = false;
280 boolean containsService = false;
281 List<Resource> resourceList = new ArrayList<>();
282 List<Pair<WorkflowType, String>> aaiResourceIds = new ArrayList<>();
283 if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(ASSIGNINSTANCE)) {
284 // SERVICE-MACRO-ASSIGN will always get user params with a
286 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
287 List<Map<String, Object>> userParams =
288 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
290 userParams.stream().anyMatch(param -> param.containsKey(USERPARAMSERVICE));
291 if (containsService) {
292 traverseUserParamsService(execution, resourceList, sIRequest, requestAction);
295 buildAndThrowException(execution,
296 "Service-Macro-Assign request details must contain user params with a service");
298 } else if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
299 // SERVICE-MACRO-CREATE will get user params with a service,
300 // a service with a network, a service with a
301 // networkcollection, OR an empty service.
302 // If user params is just a service or null and macro
303 // queries the SI and finds a VNF, macro fails.
305 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
306 List<Map<String, Object>> userParams =
307 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
309 userParams.stream().anyMatch(param -> param.containsKey(USERPARAMSERVICE));
311 if (containsService) {
312 foundRelated = traverseUserParamsService(execution, resourceList, sIRequest, requestAction);
315 traverseCatalogDbService(execution, sIRequest, resourceList, aaiResourceIds);
317 } else if (resourceType == WorkflowType.SERVICE
318 && ("activateInstance".equalsIgnoreCase(requestAction)
319 || "unassignInstance".equalsIgnoreCase(requestAction)
320 || "deleteInstance".equalsIgnoreCase(requestAction)
321 || requestAction.equalsIgnoreCase("activate" + FABRIC_CONFIGURATION))) {
322 // SERVICE-MACRO-ACTIVATE, SERVICE-MACRO-UNASSIGN, and
323 // SERVICE-MACRO-DELETE
324 // Will never get user params with service, macro will have
325 // to query the SI in AAI to find related instances.
326 traverseAAIService(execution, resourceList, resourceId, aaiResourceIds);
327 } else if (resourceType == WorkflowType.SERVICE
328 && "deactivateInstance".equalsIgnoreCase(requestAction)) {
329 resourceList.add(new Resource(WorkflowType.SERVICE, "", false));
330 } else if (resourceType == WorkflowType.VNF && ("replaceInstance".equalsIgnoreCase(requestAction)
331 || ("recreateInstance".equalsIgnoreCase(requestAction)))) {
332 traverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
333 workflowResourceIds.getVnfId(), aaiResourceIds);
335 buildAndThrowException(execution, "Current Macro Request is not supported");
337 StringBuilder foundObjects = new StringBuilder();
338 for (WorkflowType type : WorkflowType.values()) {
339 foundObjects.append(type).append(" - ").append(
340 (int) resourceList.stream().filter(x -> type.equals(x.getResourceType())).count())
343 logger.info("Found {}", foundObjects.toString());
345 if (orchFlows == null || orchFlows.isEmpty()) {
346 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, isALaCarte,
347 cloudOwner, serviceType);
349 boolean vnfReplace = false;
350 if (resourceType.equals(WorkflowType.VNF) && ("replaceInstance".equalsIgnoreCase(requestAction)
351 || "replaceInstanceRetainAssignments".equalsIgnoreCase(requestAction))) {
354 flowsToExecute = buildExecuteBuildingBlockList(orchFlows, resourceList, requestId, apiVersion,
355 resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, vnfReplace);
356 if (isNetworkCollectionInTheResourceList(resourceList)) {
357 logger.info("Sorting for Vlan Tagging");
358 flowsToExecute = sortExecutionPathByObjectForVlanTagging(flowsToExecute, requestAction);
360 // By default, enable homing at VNF level for CREATEINSTANCE and ASSIGNINSTANCE
361 if (resourceType == WorkflowType.SERVICE
362 && (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE))
363 && resourceList.stream().anyMatch(x -> WorkflowType.VNF.equals(x.getResourceType()))) {
364 execution.setVariable("homing", true);
365 execution.setVariable("calledHoming", false);
367 if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE)
368 || requestAction.equalsIgnoreCase(CREATEINSTANCE))) {
369 generateResourceIds(flowsToExecute, resourceList, serviceInstanceId);
371 updateResourceIdsFromAAITraversal(flowsToExecute, resourceList, aaiResourceIds,
376 // If the user set "Homing_Solution" to "none", disable homing, else if "Homing_Solution" is specified,
378 if (sIRequest.getRequestDetails().getRequestParameters() != null
379 && sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
380 List<Map<String, Object>> userParams =
381 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
382 for (Map<String, Object> params : userParams) {
383 if (params.containsKey(HOMINGSOLUTION)) {
384 execution.setVariable("homing", !"none".equals(params.get(HOMINGSOLUTION)));
389 if (CollectionUtils.isEmpty(flowsToExecute)) {
390 throw new IllegalStateException("Macro did not come up with a valid execution path.");
393 List<String> flowNames = new ArrayList<>();
394 logger.info("List of BuildingBlocks to execute:");
396 flowsToExecute.forEach(ebb -> {
397 logger.info(ebb.getBuildingBlock().getBpmnFlowName());
398 flowNames.add(ebb.getBuildingBlock().getBpmnFlowName());
402 bbInputSetupUtils.persistFlowExecutionPath(requestId, flowsToExecute);
404 execution.setVariable("flowNames", flowNames);
405 execution.setVariable(BBConstants.G_CURRENT_SEQUENCE, 0);
406 execution.setVariable("retryCount", 0);
407 execution.setVariable("isRollback", false);
408 execution.setVariable("flowsToExecute", flowsToExecute);
409 execution.setVariable("isRollbackComplete", false);
411 } catch (Exception ex) {
412 if (!(execution.hasVariable("WorkflowException")
413 || execution.hasVariable("WorkflowExceptionExceptionMessage"))) {
414 buildAndThrowException(execution, "Exception while setting execution list. ", ex);
421 private Resource getResourceKey(ServiceInstancesRequest sIRequest, WorkflowType resourceType) {
422 String resourceId = "";
423 ModelInfo modelInfo = sIRequest.getRequestDetails().getModelInfo();
424 if (modelInfo != null) {
425 if (modelInfo.getModelType().equals(ModelType.service)) {
426 resourceId = modelInfo.getModelVersionId();
428 resourceId = modelInfo.getModelCustomizationId();
431 return new Resource(resourceType, resourceId, true);
434 private String getCloudOwner(CloudConfiguration cloudConfiguration) {
435 if (cloudConfiguration != null && cloudConfiguration.getCloudOwner() != null) {
436 return cloudConfiguration.getCloudOwner();
438 logger.warn("cloud owner value not found in request details, it will be set as default");
439 return environment.getProperty(DEFAULT_CLOUD_OWNER);
442 protected <T> List<T> getRelatedResourcesInVfModule(String vnfId, String vfModuleId, Class<T> resultClass,
443 AAIObjectType type) {
444 List<T> vnfcs = new ArrayList<>();
445 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VF_MODULE, vnfId, vfModuleId);
446 AAIResultWrapper vfModuleResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
447 Optional<Relationships> relationshipsOp = vfModuleResultsWrapper.getRelationships();
448 if (!relationshipsOp.isPresent()) {
449 logger.debug("No relationships were found for vfModule in AAI");
451 Relationships relationships = relationshipsOp.get();
452 List<AAIResultWrapper> vnfcResultWrappers = relationships.getByType(type);
453 for (AAIResultWrapper vnfcResultWrapper : vnfcResultWrappers) {
454 Optional<T> vnfcOp = vnfcResultWrapper.asBean(resultClass);
455 vnfcOp.ifPresent(vnfcs::add);
461 protected <T> List<T> getRelatedResourcesInVnfc(Vnfc vnfc, Class<T> resultClass, AAIObjectType type) {
463 List<T> configurations = new ArrayList<>();
464 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VNFC, vnfc.getVnfcName());
465 AAIResultWrapper vnfcResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
466 Optional<Relationships> relationshipsOp = vnfcResultsWrapper.getRelationships();
467 if (!relationshipsOp.isPresent()) {
468 logger.debug("No relationships were found for VNFC in AAI");
470 Relationships relationships = relationshipsOp.get();
471 List<AAIResultWrapper> configurationResultWrappers =
472 this.getResultWrappersFromRelationships(relationships, type);
473 for (AAIResultWrapper configurationResultWrapper : configurationResultWrappers) {
474 Optional<T> configurationOp = configurationResultWrapper.asBean(resultClass);
475 configurationOp.ifPresent(configurations::add);
478 return configurations;
481 protected List<AAIResultWrapper> getResultWrappersFromRelationships(Relationships relationships,
482 AAIObjectType type) {
483 return relationships.getByType(type);
486 protected boolean isConfiguration(List<OrchestrationFlow> orchFlows) {
487 for (OrchestrationFlow flow : orchFlows) {
488 if (flow.getFlowName().contains(CONFIGURATION) && !"ConfigurationScaleOutBB".equals(flow.getFlowName())) {
495 protected List<ExecuteBuildingBlock> getConfigBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
498 List<ExecuteBuildingBlock> flowsToExecuteConfigs = new ArrayList<>();
499 List<OrchestrationFlow> result = dataObj.getOrchFlows().stream()
500 .filter(item -> item.getFlowName().contains(FABRIC_CONFIGURATION)).collect(Collectors.toList());
501 String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
502 String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
504 String vnfCustomizationUUID = bbInputSetupUtils.getAAIGenericVnf(vnfId).getModelCustomizationId();
505 String vfModuleCustomizationUUID;
506 org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
508 if (aaiVfModule == null) {
509 logger.error("No matching VfModule is found in Generic-Vnf in AAI for vnfId: {} and vfModuleId : {}", vnfId,
511 throw new AAIEntityNotFoundException("No matching VfModule is found in Generic-Vnf in AAI for vnfId: "
512 + vnfId + " and vfModuleId : " + vfModuleId);
514 vfModuleCustomizationUUID = aaiVfModule.getModelCustomizationId();
517 List<org.onap.aai.domain.yang.Vnfc> vnfcs = getRelatedResourcesInVfModule(vnfId, vfModuleId,
518 org.onap.aai.domain.yang.Vnfc.class, AAIObjectType.VNFC);
519 for (org.onap.aai.domain.yang.Vnfc vnfc : vnfcs) {
520 List<org.onap.aai.domain.yang.Configuration> configurations = getRelatedResourcesInVnfc(vnfc,
521 org.onap.aai.domain.yang.Configuration.class, AAIObjectType.CONFIGURATION);
522 if (configurations.size() > 1) {
523 String multipleRelationshipsError =
524 "Multiple relationships exist from VNFC " + vnfc.getVnfcName() + " to Configurations";
525 buildAndThrowException(dataObj.getExecution(), "Exception in getConfigBuildingBlock: ",
526 new Exception(multipleRelationshipsError));
528 for (org.onap.aai.domain.yang.Configuration configuration : configurations) {
529 dataObj.getWorkflowResourceIds().setConfigurationId(configuration.getConfigurationId());
530 for (OrchestrationFlow orchFlow : result) {
531 dataObj.getResourceKey().setVfModuleCustomizationId(vfModuleCustomizationUUID);
532 dataObj.getResourceKey().setCvnfModuleCustomizationId(vnfc.getModelCustomizationId());
533 dataObj.getResourceKey().setVnfCustomizationId(vnfCustomizationUUID);
534 String vnfcName = getVnfcNameForConfiguration(configuration);
535 if (vnfcName == null || vnfcName.isEmpty()) {
536 buildAndThrowException(dataObj.getExecution(), "Exception in create execution list "
537 + ": VnfcName does not exist or is null while there is a configuration for the vfModule",
538 new Exception("Vnfc and Configuration do not match"));
540 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, dataObj.getRequestId(),
541 dataObj.getResourceKey(), dataObj.getApiVersion(), dataObj.getResourceId(),
542 dataObj.getRequestAction(), dataObj.isaLaCarte(), dataObj.getVnfType(),
543 dataObj.getWorkflowResourceIds(), dataObj.getRequestDetails(), false, null, vnfcName, true);
544 flowsToExecuteConfigs.add(ebb);
548 return flowsToExecuteConfigs;
551 protected List<OrchestrationFlow> getVfModuleReplaceBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
554 String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
555 String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
557 logger.debug("BUILDING REPLACE LIST");
559 boolean volumeGroupExisted = false;
560 boolean volumeGroupWillExist = false;
561 boolean keepVolumeGroup = false;
563 boolean rebuildVolumeGroups = false;
564 if (dataObj.getRequestDetails().getRequestParameters() != null
565 && dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups() != null) {
566 rebuildVolumeGroups = dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups();
569 Optional<VolumeGroup> volumeGroupFromVfModule =
570 bbInputSetupUtils.getRelatedVolumeGroupFromVfModule(vnfId, vfModuleId);
571 if (volumeGroupFromVfModule.isPresent()) {
572 String volumeGroupId = volumeGroupFromVfModule.get().getVolumeGroupId();
573 logger.debug("Volume group id of the existing volume group is: " + volumeGroupId);
574 volumeGroupExisted = true;
575 dataObj.getWorkflowResourceIds().setVolumeGroupId(volumeGroupId);
578 List<OrchestrationFlow> orchFlows = dataObj.getOrchFlows();
579 VfModuleCustomization vfModuleCustomization = catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
580 dataObj.getRequestDetails().getModelInfo().getModelCustomizationUuid());
581 if (vfModuleCustomization != null && vfModuleCustomization.getVfModule() != null
582 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
583 && vfModuleCustomization.getVolumeHeatEnv() != null) {
584 volumeGroupWillExist = true;
585 if (!volumeGroupExisted) {
586 String newVolumeGroupId = UUID.randomUUID().toString();
587 dataObj.getWorkflowResourceIds().setVolumeGroupId(newVolumeGroupId);
588 logger.debug("newVolumeGroupId: " + newVolumeGroupId);
592 if (volumeGroupExisted && volumeGroupWillExist && !rebuildVolumeGroups) {
593 keepVolumeGroup = true;
596 if (!volumeGroupExisted || keepVolumeGroup) {
597 logger.debug("Filtering out deletion of volume groups");
598 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_DELETE_PATTERN))
599 .collect(Collectors.toList());
601 if (!volumeGroupWillExist || keepVolumeGroup) {
602 logger.debug("Filtering out creation of volume groups");
603 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_CREATE_PATTERN))
604 .collect(Collectors.toList());
610 protected String getVnfcNameForConfiguration(org.onap.aai.domain.yang.Configuration configuration) {
611 AAIResultWrapper wrapper = new AAIResultWrapper(configuration);
612 Optional<Relationships> relationshipsOp = wrapper.getRelationships();
613 if (!relationshipsOp.isPresent()) {
614 logger.debug("No relationships were found for Configuration in AAI");
617 Relationships relationships = relationshipsOp.get();
618 List<AAIResultWrapper> vnfcResultWrappers = relationships.getByType(AAIObjectType.VNFC);
619 if (vnfcResultWrappers.size() != 1) {
620 logger.debug("Too many vnfcs or no vnfc found that are related to configuration");
622 Optional<Vnfc> vnfcOp = vnfcResultWrappers.get(0).asBean(Vnfc.class);
623 return vnfcOp.map(Vnfc::getVnfcName).orElse(null);
627 protected List<Resource> sortVfModulesByBaseFirst(List<Resource> vfModuleResources) {
629 for (Resource resource : vfModuleResources) {
630 if (resource.isBaseVfModule()) {
631 Collections.swap(vfModuleResources, 0, count);
636 return vfModuleResources;
639 protected List<Resource> sortVfModulesByBaseLast(List<Resource> vfModuleResources) {
641 for (Resource resource : vfModuleResources) {
642 if (resource.isBaseVfModule()) {
643 Collections.swap(vfModuleResources, vfModuleResources.size() - 1, count);
648 return vfModuleResources;
651 private void updateResourceIdsFromAAITraversal(List<ExecuteBuildingBlock> flowsToExecute,
652 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds, String serviceInstanceId) {
653 for (Pair<WorkflowType, String> pair : aaiResourceIds) {
654 logger.debug(pair.getValue0() + ", " + pair.getValue1());
657 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
658 .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
659 .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
660 retrieveAAIResourceId(aaiResourceIds, type), null, serviceInstanceId)));
663 private String retrieveAAIResourceId(List<Pair<WorkflowType, String>> aaiResourceIds, WorkflowType resource) {
665 for (int i = 0; i < aaiResourceIds.size(); i++) {
666 if (aaiResourceIds.get(i).getValue0() == resource) {
667 id = aaiResourceIds.get(i).getValue1();
668 aaiResourceIds.remove(i);
675 private void generateResourceIds(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
676 String serviceInstanceId) {
677 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
678 .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
679 .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
680 null, resource.getVirtualLinkKey(), serviceInstanceId)));
683 protected void updateWorkflowResourceIds(List<ExecuteBuildingBlock> flowsToExecute, WorkflowType resourceType,
684 String key, String id, String virtualLinkKey, String serviceInstanceId) {
685 String resourceId = id;
686 if (resourceId == null) {
687 resourceId = UUID.randomUUID().toString();
689 for (ExecuteBuildingBlock ebb : flowsToExecute) {
690 if (key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey()) && (ebb.getBuildingBlock()
691 .getBpmnFlowName().contains(resourceType.toString())
692 || (ebb.getBuildingBlock().getBpmnFlowName().contains(CONTROLLER)
693 && ebb.getBuildingBlock().getBpmnScope().equalsIgnoreCase(resourceType.toString())))) {
694 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
695 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
696 WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, resourceType, resourceId);
697 ebb.setWorkflowResourceIds(workflowResourceIds);
699 if (virtualLinkKey != null && ebb.getBuildingBlock().isVirtualLink()
700 && virtualLinkKey.equalsIgnoreCase(ebb.getBuildingBlock().getVirtualLinkKey())) {
701 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
702 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
703 workflowResourceIds.setNetworkId(resourceId);
704 ebb.setWorkflowResourceIds(workflowResourceIds);
709 protected CollectionResourceCustomization findCatalogNetworkCollection(DelegateExecution execution,
710 org.onap.so.db.catalog.beans.Service service) {
711 CollectionResourceCustomization networkCollection = null;
713 for (CollectionResourceCustomization collectionCust : service.getCollectionResourceCustomizations()) {
714 if (catalogDbClient.getNetworkCollectionResourceCustomizationByID(
715 collectionCust.getModelCustomizationUUID()) != null) {
716 networkCollection = collectionCust;
722 } else if (count > 1) {
723 buildAndThrowException(execution,
724 "Found multiple Network Collections in the Service model, only one per Service is supported.");
726 return networkCollection;
729 protected void traverseCatalogDbService(DelegateExecution execution, ServiceInstancesRequest sIRequest,
730 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds)
731 throws JsonProcessingException, VrfBondingServiceException {
732 String modelUUID = sIRequest.getRequestDetails().getModelInfo().getModelVersionId();
733 org.onap.so.db.catalog.beans.Service service = catalogDbClient.getServiceByID(modelUUID);
734 if (service == null) {
735 buildAndThrowException(execution, "Could not find the service model in catalog db.");
737 resourceList.add(new Resource(WorkflowType.SERVICE, service.getModelUUID(), false));
738 RelatedInstance relatedVpnBinding =
739 bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.vpnBinding);
740 RelatedInstance relatedLocalNetwork =
741 bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.network);
742 if (relatedVpnBinding != null && relatedLocalNetwork != null) {
743 traverseVrfConfiguration(aaiResourceIds, resourceList, service, relatedVpnBinding, relatedLocalNetwork);
745 traverseNetworkCollection(execution, resourceList, service);
750 protected void traverseVrfConfiguration(List<Pair<WorkflowType, String>> aaiResourceIds,
751 List<Resource> resourceList, org.onap.so.db.catalog.beans.Service service,
752 RelatedInstance relatedVpnBinding, RelatedInstance relatedLocalNetwork)
753 throws VrfBondingServiceException, JsonProcessingException {
754 org.onap.aai.domain.yang.L3Network aaiLocalNetwork =
755 bbInputSetupUtils.getAAIL3Network(relatedLocalNetwork.getInstanceId());
756 vrfValidation.vrfServiceValidation(service);
757 vrfValidation.vrfCatalogDbChecks(service);
758 vrfValidation.aaiVpnBindingValidation(relatedVpnBinding.getInstanceId(),
759 bbInputSetupUtils.getAAIVpnBinding(relatedVpnBinding.getInstanceId()));
760 vrfValidation.aaiNetworkValidation(relatedLocalNetwork.getInstanceId(), aaiLocalNetwork);
761 vrfValidation.aaiSubnetValidation(aaiLocalNetwork);
762 vrfValidation.aaiAggregateRouteValidation(aaiLocalNetwork);
763 vrfValidation.aaiRouteTargetValidation(aaiLocalNetwork);
764 String existingAAIVrfConfiguration = getExistingAAIVrfConfiguration(relatedVpnBinding, aaiLocalNetwork);
765 if (existingAAIVrfConfiguration != null) {
766 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, existingAAIVrfConfiguration));
768 resourceList.add(new Resource(WorkflowType.CONFIGURATION,
769 service.getConfigurationCustomizations().get(0).getModelCustomizationUUID(), false));
773 protected String getExistingAAIVrfConfiguration(RelatedInstance relatedVpnBinding,
774 org.onap.aai.domain.yang.L3Network aaiLocalNetwork)
775 throws JsonProcessingException, VrfBondingServiceException {
776 Optional<Relationships> relationshipsOp = new AAIResultWrapper(
777 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiLocalNetwork)).getRelationships();
778 if (relationshipsOp.isPresent()) {
779 List<AAIResultWrapper> configurationsRelatedToLocalNetwork =
780 relationshipsOp.get().getByType(AAIObjectType.CONFIGURATION);
781 if (configurationsRelatedToLocalNetwork.size() > 1) {
782 throw new VrfBondingServiceException(
783 "Network: " + aaiLocalNetwork.getNetworkId() + " has more than 1 configuration related to it");
785 if (configurationsRelatedToLocalNetwork.size() == 1) {
786 AAIResultWrapper configWrapper = configurationsRelatedToLocalNetwork.get(0);
787 Optional<Configuration> relatedConfiguration = configWrapper.asBean(Configuration.class);
788 if (relatedConfiguration.isPresent() && vrfConfigurationAlreadyExists(relatedVpnBinding,
789 relatedConfiguration.get(), configWrapper)) {
790 return relatedConfiguration.get().getConfigurationId();
797 protected boolean vrfConfigurationAlreadyExists(RelatedInstance relatedVpnBinding, Configuration vrfConfiguration,
798 AAIResultWrapper configWrapper) throws VrfBondingServiceException {
799 if ("VRF-ENTRY".equalsIgnoreCase(vrfConfiguration.getConfigurationType())) {
800 Optional<Relationships> relationshipsConfigOp = configWrapper.getRelationships();
801 if (relationshipsConfigOp.isPresent()) {
802 Optional<VpnBinding> relatedInfraVpnBindingOp =
803 workflowActionUtils.extractRelationshipsVpnBinding(relationshipsConfigOp.get());
804 if (relatedInfraVpnBindingOp.isPresent()) {
805 VpnBinding relatedInfraVpnBinding = relatedInfraVpnBindingOp.get();
806 if (!relatedInfraVpnBinding.getVpnId().equalsIgnoreCase(relatedVpnBinding.getInstanceId())) {
807 throw new VrfBondingServiceException("Configuration: " + vrfConfiguration.getConfigurationId()
808 + " is not connected to the same vpn binding id provided in request: "
809 + relatedVpnBinding.getInstanceId());
819 protected void traverseNetworkCollection(DelegateExecution execution, List<Resource> resourceList,
820 org.onap.so.db.catalog.beans.Service service) {
821 if (isVnfCustomizationsInTheService(service)) {
822 buildAndThrowException(execution,
823 "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");
825 List<CollectionResourceCustomization> customizations = service.getCollectionResourceCustomizations();
826 if (customizations.isEmpty()) {
827 logger.debug("No Collections found. CollectionResourceCustomization list is empty.");
829 CollectionResourceCustomization collectionResourceCustomization =
830 findCatalogNetworkCollection(execution, service);
831 traverseNetworkCollectionResourceCustomization(resourceList, collectionResourceCustomization);
833 traverseNetworkCollectionCustomization(resourceList, service);
836 private void traverseNetworkCollectionResourceCustomization(List<Resource> resourceList,
837 CollectionResourceCustomization collectionResourceCustomization) {
838 if (collectionResourceCustomizationShouldNotBeProcessed(resourceList, collectionResourceCustomization))
841 org.onap.so.db.catalog.beans.InstanceGroup instanceGroup =
842 collectionResourceCustomization.getCollectionResource().getInstanceGroup();
843 CollectionResourceInstanceGroupCustomization collectionInstCust = null;
844 if (!instanceGroup.getCollectionInstanceGroupCustomizations().isEmpty()) {
845 for (CollectionResourceInstanceGroupCustomization collectionInstanceGroupTemp : instanceGroup
846 .getCollectionInstanceGroupCustomizations()) {
847 if (collectionInstanceGroupTemp.getModelCustomizationUUID()
848 .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
849 collectionInstCust = collectionInstanceGroupTemp;
853 if (interfaceNetworkQuantityIsAvailableInCollection(collectionInstCust)) {
854 minNetworks = collectionInstCust.getSubInterfaceNetworkQuantity();
857 logger.debug("minNetworks: {}", minNetworks);
858 CollectionNetworkResourceCustomization collectionNetworkResourceCust =
859 getCollectionNetworkResourceCustomization(collectionResourceCustomization, instanceGroup);
860 for (int i = 0; i < minNetworks; i++) {
861 if (collectionNetworkResourceCust != null && collectionInstCust != null) {
862 Resource resource = new Resource(WorkflowType.VIRTUAL_LINK,
863 collectionNetworkResourceCust.getModelCustomizationUUID(), false);
864 resource.setVirtualLinkKey(Integer.toString(i));
865 resourceList.add(resource);
870 private CollectionNetworkResourceCustomization getCollectionNetworkResourceCustomization(
871 CollectionResourceCustomization collectionResourceCustomization, InstanceGroup instanceGroup) {
872 CollectionNetworkResourceCustomization collectionNetworkResourceCust = null;
873 for (CollectionNetworkResourceCustomization collectionNetworkTemp : instanceGroup
874 .getCollectionNetworkResourceCustomizations()) {
875 if (collectionNetworkTemp.getNetworkResourceCustomization().getModelCustomizationUUID()
876 .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
877 collectionNetworkResourceCust = collectionNetworkTemp;
881 return collectionNetworkResourceCust;
884 private boolean collectionResourceCustomizationShouldNotBeProcessed(List<Resource> resourceList,
885 CollectionResourceCustomization collectionResourceCustomization) {
886 if (collectionResourceCustomization == null) {
887 logger.debug("No Network Collection Customization found");
890 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
891 collectionResourceCustomization.getModelCustomizationUUID(), false));
892 logger.debug("Found a network collection");
893 if (collectionResourceCustomization.getCollectionResource() == null) {
894 logger.debug("No Network Collection found. collectionResource is null");
897 if (collectionResourceCustomization.getCollectionResource().getInstanceGroup() == null) {
898 logger.debug("No Instance Group found for network collection.");
901 String toscaNodeType =
902 collectionResourceCustomization.getCollectionResource().getInstanceGroup().getToscaNodeType();
903 if (!toscaNodeTypeHasNetworkCollection(toscaNodeType)) {
904 logger.debug("Instance Group tosca node type does not contain NetworkCollection: {}", toscaNodeType);
910 private boolean interfaceNetworkQuantityIsAvailableInCollection(
911 CollectionResourceInstanceGroupCustomization collectionInstCust) {
912 return collectionInstCust != null && collectionInstCust.getSubInterfaceNetworkQuantity() != null;
915 private boolean toscaNodeTypeHasNetworkCollection(String toscaNodeType) {
916 return toscaNodeType != null && toscaNodeType.contains(NETWORKCOLLECTION);
919 private void traverseNetworkCollectionCustomization(List<Resource> resourceList,
920 org.onap.so.db.catalog.beans.Service service) {
921 if (isNetworkCollectionInTheResourceList(resourceList)) {
924 if (service.getNetworkCustomizations() == null) {
925 logger.debug("No networks were found on this service model");
928 for (int i = 0; i < service.getNetworkCustomizations().size(); i++) {
929 resourceList.add(new Resource(WorkflowType.NETWORK,
930 service.getNetworkCustomizations().get(i).getModelCustomizationUUID(), false));
934 private boolean isNetworkCollectionInTheResourceList(List<Resource> resourceList) {
935 return resourceList.stream().anyMatch(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType());
938 private boolean isVnfCustomizationsInTheService(org.onap.so.db.catalog.beans.Service service) {
939 return !(service.getVnfCustomizations() == null || service.getVnfCustomizations().isEmpty());
942 protected void traverseAAIService(DelegateExecution execution, List<Resource> resourceList, String resourceId,
943 List<Pair<WorkflowType, String>> aaiResourceIds) {
945 ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(resourceId);
946 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
947 bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
948 resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
949 traverseServiceInstanceMSOVnfs(resourceList, aaiResourceIds, serviceInstanceMSO);
950 if (serviceInstanceMSO.getNetworks() != null) {
951 for (org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network network : serviceInstanceMSO
953 aaiResourceIds.add(new Pair<>(WorkflowType.NETWORK, network.getNetworkId()));
954 resourceList.add(new Resource(WorkflowType.NETWORK, network.getNetworkId(), false));
957 if (serviceInstanceMSO.getCollection() != null) {
958 logger.debug("found networkcollection");
960 .add(new Pair<>(WorkflowType.NETWORKCOLLECTION, serviceInstanceMSO.getCollection().getId()));
961 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
962 serviceInstanceMSO.getCollection().getId(), false));
964 if (serviceInstanceMSO.getConfigurations() != null) {
965 for (Configuration config : serviceInstanceMSO.getConfigurations()) {
966 Optional<org.onap.aai.domain.yang.Configuration> aaiConfig =
967 aaiConfigurationResources.getConfiguration(config.getConfigurationId());
968 if (aaiConfig.isPresent() && aaiConfig.get().getRelationshipList() != null) {
969 for (Relationship relationship : aaiConfig.get().getRelationshipList().getRelationship()) {
970 if (relationship.getRelatedTo().contains("vnfc")
971 || relationship.getRelatedTo().contains("vpn-binding")) {
972 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.getConfigurationId()));
974 new Resource(WorkflowType.CONFIGURATION, config.getConfigurationId(), false));
981 } catch (Exception ex) {
982 logger.error("Exception in traverseAAIService", ex);
983 buildAndThrowException(execution,
984 "Could not find existing Service Instance or related Instances to execute the request on.");
988 private void traverseServiceInstanceMSOVnfs(List<Resource> resourceList,
989 List<Pair<WorkflowType, String>> aaiResourceIds,
990 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO) {
991 if (serviceInstanceMSO.getVnfs() == null) {
994 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
995 aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
996 resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
997 traverseVnfModules(resourceList, aaiResourceIds, vnf);
998 if (vnf.getVolumeGroups() != null) {
999 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf.getVolumeGroups()) {
1000 aaiResourceIds.add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1001 resourceList.add(new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1007 private void traverseVnfModules(List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds,
1008 org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf) {
1009 if (vnf.getVfModules() == null) {
1012 for (VfModule vfModule : vnf.getVfModules()) {
1013 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1014 Resource resource = new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false);
1015 resource.setBaseVfModule(vfModule.getModelInfoVfModule().getIsBaseBoolean());
1016 resourceList.add(resource);
1020 private void traverseAAIVnf(DelegateExecution execution, List<Resource> resourceList, String serviceId,
1021 String vnfId, List<Pair<WorkflowType, String>> aaiResourceIds) {
1023 ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(serviceId);
1024 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
1025 bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
1026 resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
1027 if (serviceInstanceMSO.getVnfs() != null) {
1028 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
1029 if (vnf.getVnfId().equals(vnfId)) {
1030 aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
1031 resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
1032 if (vnf.getVfModules() != null) {
1033 for (VfModule vfModule : vnf.getVfModules()) {
1034 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1035 resourceList.add(new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false));
1036 findConfigurationsInsideVfModule(execution, vnf.getVnfId(), vfModule.getVfModuleId(),
1037 resourceList, aaiResourceIds);
1040 if (vnf.getVolumeGroups() != null) {
1041 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
1042 .getVolumeGroups()) {
1044 .add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1046 new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1053 } catch (Exception ex) {
1054 logger.error("Exception in traverseAAIVnf", ex);
1055 buildAndThrowException(execution,
1056 "Could not find existing Vnf or related Instances to execute the request on.");
1060 private void findConfigurationsInsideVfModule(DelegateExecution execution, String vnfId, String vfModuleId,
1061 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds) {
1063 org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
1064 AAIResultWrapper vfModuleWrapper = new AAIResultWrapper(
1065 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiVfModule));
1066 Optional<Relationships> relationshipsOp;
1067 relationshipsOp = vfModuleWrapper.getRelationships();
1068 if (relationshipsOp.isPresent()) {
1069 relationshipsOp = workflowActionUtils.extractRelationshipsVnfc(relationshipsOp.get());
1070 if (relationshipsOp.isPresent()) {
1071 Optional<Configuration> config =
1072 workflowActionUtils.extractRelationshipsConfiguration(relationshipsOp.get());
1073 if (config.isPresent()) {
1074 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.get().getConfigurationId()));
1076 new Resource(WorkflowType.CONFIGURATION, config.get().getConfigurationId(), false));
1080 } catch (Exception ex) {
1081 logger.error("Exception in findConfigurationsInsideVfModule", ex);
1082 buildAndThrowException(execution, "Failed to find Configuration object from the vfModule.");
1086 protected boolean traverseUserParamsService(DelegateExecution execution, List<Resource> resourceList,
1087 ServiceInstancesRequest sIRequest, String requestAction) throws IOException {
1088 boolean foundRelated = false;
1089 boolean foundVfModuleOrVG = false;
1090 String vnfCustomizationUUID = "";
1091 String vfModuleCustomizationUUID = "";
1092 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
1093 List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
1094 for (Map<String, Object> params : userParams) {
1095 if (params.containsKey(USERPARAMSERVICE)) {
1096 ObjectMapper obj = new ObjectMapper();
1097 String input = obj.writeValueAsString(params.get(USERPARAMSERVICE));
1098 Service validate = obj.readValue(input, Service.class);
1100 new Resource(WorkflowType.SERVICE, validate.getModelInfo().getModelVersionId(), false));
1101 if (validate.getResources().getVnfs() != null) {
1102 for (Vnfs vnf : validate.getResources().getVnfs()) {
1103 resourceList.add(new Resource(WorkflowType.VNF,
1104 vnf.getModelInfo().getModelCustomizationId(), false));
1105 foundRelated = true;
1106 if (vnf.getModelInfo() != null && vnf.getModelInfo().getModelCustomizationUuid() != null) {
1107 vnfCustomizationUUID = vnf.getModelInfo().getModelCustomizationUuid();
1109 if (vnf.getVfModules() != null) {
1110 for (VfModules vfModule : vnf.getVfModules()) {
1111 VfModuleCustomization vfModuleCustomization =
1112 catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
1113 vfModule.getModelInfo().getModelCustomizationUuid());
1114 if (vfModuleCustomization != null) {
1116 if (vfModuleCustomization.getVfModule() != null
1117 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
1118 && vfModuleCustomization.getVolumeHeatEnv() != null) {
1119 resourceList.add(new Resource(WorkflowType.VOLUMEGROUP,
1120 vfModuleCustomization.getModelCustomizationUUID(), false));
1121 foundRelated = true;
1122 foundVfModuleOrVG = true;
1125 if (vfModuleCustomization.getVfModule() != null
1126 && vfModuleCustomization.getVfModule().getModuleHeatTemplate() != null
1127 && vfModuleCustomization.getHeatEnvironment() != null) {
1128 foundRelated = true;
1129 foundVfModuleOrVG = true;
1130 Resource resource = new Resource(WorkflowType.VFMODULE,
1131 vfModuleCustomization.getModelCustomizationUUID(), false);
1132 resource.setBaseVfModule(
1133 vfModuleCustomization.getVfModule().getIsBase() != null
1134 && vfModuleCustomization.getVfModule().getIsBase());
1135 resourceList.add(resource);
1136 if (vfModule.getModelInfo() != null
1137 && vfModule.getModelInfo().getModelCustomizationUuid() != null) {
1138 vfModuleCustomizationUUID =
1139 vfModule.getModelInfo().getModelCustomizationUuid();
1141 if (!vnfCustomizationUUID.isEmpty()
1142 && !vfModuleCustomizationUUID.isEmpty()) {
1143 List<CvnfcConfigurationCustomization> configs =
1144 traverseCatalogDbForConfiguration(
1145 validate.getModelInfo().getModelVersionId(),
1146 vnfCustomizationUUID, vfModuleCustomizationUUID);
1147 for (CvnfcConfigurationCustomization config : configs) {
1148 Resource configResource = new Resource(WorkflowType.CONFIGURATION,
1149 config.getConfigurationResource().getModelUUID(), false);
1150 resource.setVnfCustomizationId(
1151 vnf.getModelInfo().getModelCustomizationId());
1152 resource.setVfModuleCustomizationId(
1153 vfModule.getModelInfo().getModelCustomizationId());
1154 resourceList.add(configResource);
1158 if (!foundVfModuleOrVG) {
1159 buildAndThrowException(execution,
1160 "Could not determine if vfModule was a vfModule or volume group. Heat template and Heat env are null");
1167 if (validate.getResources().getPnfs() != null) {
1168 for (Pnfs pnf : validate.getResources().getPnfs()) {
1169 resourceList.add(new Resource(WorkflowType.PNF,
1170 pnf.getModelInfo().getModelCustomizationId(), false));
1171 foundRelated = true;
1174 if (validate.getResources().getNetworks() != null) {
1175 for (Networks network : validate.getResources().getNetworks()) {
1176 resourceList.add(new Resource(WorkflowType.NETWORK,
1177 network.getModelInfo().getModelCustomizationId(), false));
1178 foundRelated = true;
1180 if (requestAction.equals(CREATEINSTANCE)) {
1181 String networkColCustId = queryCatalogDBforNetworkCollection(execution, sIRequest);
1182 if (networkColCustId != null) {
1183 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION, networkColCustId, false));
1184 foundRelated = true;
1192 return foundRelated;
1195 protected List<CvnfcConfigurationCustomization> traverseCatalogDbForConfiguration(String serviceModelUUID,
1196 String vnfCustomizationUUID, String vfModuleCustomizationUUID) {
1197 List<CvnfcConfigurationCustomization> configurations = new ArrayList<>();
1199 List<CvnfcCustomization> cvnfcCustomizations = catalogDbClient.getCvnfcCustomization(serviceModelUUID,
1200 vnfCustomizationUUID, vfModuleCustomizationUUID);
1201 for (CvnfcCustomization cvnfc : cvnfcCustomizations) {
1202 for (CvnfcConfigurationCustomization customization : cvnfc.getCvnfcConfigurationCustomization()) {
1203 if (customization.getConfigurationResource().getToscaNodeType().contains(FABRIC_CONFIGURATION)) {
1204 configurations.add(customization);
1208 logger.debug("found {} fabric configuration(s)", configurations.size());
1209 return configurations;
1210 } catch (Exception ex) {
1211 logger.error("Error in finding configurations", ex);
1212 return configurations;
1216 protected String queryCatalogDBforNetworkCollection(DelegateExecution execution,
1217 ServiceInstancesRequest sIRequest) {
1218 org.onap.so.db.catalog.beans.Service service =
1219 catalogDbClient.getServiceByID(sIRequest.getRequestDetails().getModelInfo().getModelVersionId());
1220 if (service != null) {
1221 CollectionResourceCustomization networkCollection = this.findCatalogNetworkCollection(execution, service);
1222 if (networkCollection != null) {
1223 return networkCollection.getModelCustomizationUUID();
1229 protected WorkflowResourceIds populateResourceIdsFromApiHandler(DelegateExecution execution) {
1230 return WorkflowResourceIdsUtils.getWorkflowResourceIdsFromExecution(execution);
1233 protected Resource extractResourceIdAndTypeFromUri(String uri) {
1234 Pattern patt = Pattern.compile("[vV]\\d+.*?(?:(?:/(?<type>" + SUPPORTEDTYPES
1235 + ")(?:/(?<id>[^/]+))?)(?:/(?<action>[^/]+))?(?:/resume)?)?$");
1236 Matcher m = patt.matcher(uri);
1237 boolean generated = false;
1240 logger.debug("found match on {} : {} ", uri, m);
1241 String type = m.group("type");
1242 String id = m.group("id");
1243 String action = m.group("action");
1245 throw new IllegalArgumentException("Uri could not be parsed. No type found. " + uri);
1247 if (action == null) {
1248 if (type.equals(SERVICE_INSTANCES) && (id == null || "assign".equals(id))) {
1249 id = UUID.randomUUID().toString();
1251 } else if (type.equals(VF_MODULES) && "scaleOut".equals(id)) {
1252 id = UUID.randomUUID().toString();
1256 if (action.matches(SUPPORTEDTYPES)) {
1257 id = UUID.randomUUID().toString();
1262 return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated);
1264 throw new IllegalArgumentException("Uri could not be parsed: " + uri);
1268 protected String validateResourceIdInAAI(String generatedResourceId, WorkflowType type, String instanceName,
1269 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws Exception {
1271 if ("SERVICE".equalsIgnoreCase(type.toString())) {
1272 return validateServiceResourceIdInAAI(generatedResourceId, instanceName, reqDetails);
1273 } else if ("NETWORK".equalsIgnoreCase(type.toString())) {
1274 return validateNetworkResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1275 workflowResourceIds);
1276 } else if ("VNF".equalsIgnoreCase(type.toString())) {
1277 return validateVnfResourceIdInAAI(generatedResourceId, instanceName, reqDetails, workflowResourceIds);
1278 } else if ("VFMODULE".equalsIgnoreCase(type.toString())) {
1279 return validateVfModuleResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1280 workflowResourceIds);
1281 } else if ("VOLUMEGROUP".equalsIgnoreCase(type.toString())) {
1282 return validateVolumeGroupResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1283 workflowResourceIds);
1284 } else if ("CONFIGURATION".equalsIgnoreCase(type.toString())) {
1285 return validateConfigurationResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1286 workflowResourceIds);
1288 return generatedResourceId;
1289 } catch (DuplicateNameException dne) {
1291 } catch (Exception ex) {
1292 logger.error(WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI, ex);
1293 throw new IllegalStateException(
1294 WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI);
1298 protected String convertTypeFromPlural(String type) {
1299 if (!type.matches(SUPPORTEDTYPES)) {
1302 if (type.equals(SERVICE_INSTANCES)) {
1305 return type.substring(0, 1).toUpperCase() + type.substring(1, type.length() - 1);
1310 protected List<ExecuteBuildingBlock> sortExecutionPathByObjectForVlanTagging(List<ExecuteBuildingBlock> orchFlows,
1311 String requestAction) {
1312 List<ExecuteBuildingBlock> sortedOrchFlows = new ArrayList<>();
1313 if (requestAction.equals(CREATEINSTANCE)) {
1314 for (ExecuteBuildingBlock ebb : orchFlows) {
1315 if (ebb.getBuildingBlock().getBpmnFlowName().equals("AssignNetworkBB")) {
1316 String key = ebb.getBuildingBlock().getKey();
1317 boolean isVirtualLink = Boolean.TRUE.equals(ebb.getBuildingBlock().isVirtualLink());
1318 String virtualLinkKey = ebb.getBuildingBlock().getVirtualLinkKey();
1319 sortedOrchFlows.add(ebb);
1320 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1321 if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1322 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1323 sortedOrchFlows.add(ebb2);
1326 if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1327 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1328 sortedOrchFlows.add(ebb2);
1332 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1333 if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1334 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1335 sortedOrchFlows.add(ebb2);
1338 if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1339 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1340 sortedOrchFlows.add(ebb2);
1344 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1345 || ebb.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)) {
1347 } else if (!"".equals(ebb.getBuildingBlock().getBpmnFlowName())) {
1348 sortedOrchFlows.add(ebb);
1351 } else if (requestAction.equals("deleteInstance")) {
1352 for (ExecuteBuildingBlock ebb : orchFlows) {
1353 if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeactivateNetworkBB")) {
1354 sortedOrchFlows.add(ebb);
1355 String key = ebb.getBuildingBlock().getKey();
1356 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1357 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1358 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1359 sortedOrchFlows.add(ebb2);
1363 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1364 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")
1365 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1366 sortedOrchFlows.add(ebb2);
1370 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1371 || ebb.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")) {
1373 } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) {
1374 sortedOrchFlows.add(ebb);
1378 return sortedOrchFlows;
1381 private void addBuildingBlockToExecuteBBList(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
1382 WorkflowType workflowType, OrchestrationFlow orchFlow, String requestId, String apiVersion,
1383 String resourceId, String requestAction, String vnfType, WorkflowResourceIds workflowResourceIds,
1384 RequestDetails requestDetails, boolean isVirtualLink, boolean isConfiguration) {
1386 resourceList.stream().filter(resource -> resource.getResourceType().equals(workflowType))
1387 .forEach(resource -> flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource,
1388 apiVersion, resourceId, requestAction, false, vnfType, workflowResourceIds, requestDetails,
1389 isVirtualLink, resource.getVirtualLinkKey(), null, isConfiguration)));
1392 protected List<ExecuteBuildingBlock> buildExecuteBuildingBlockList(List<OrchestrationFlow> orchFlows,
1393 List<Resource> resourceList, String requestId, String apiVersion, String resourceId, String requestAction,
1394 String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1395 boolean replaceVnf) {
1396 List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
1397 for (OrchestrationFlow orchFlow : orchFlows) {
1398 if (orchFlow.getFlowName().contains(SERVICE)) {
1400 workflowResourceIds.setServiceInstanceId(resourceId);
1402 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.SERVICE, orchFlow, requestId,
1403 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1405 } else if (orchFlow.getFlowName().contains(VNF) || (orchFlow.getFlowName().contains(CONTROLLER)
1406 && (VNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1407 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VNF, orchFlow, requestId,
1408 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1410 } else if (orchFlow.getFlowName().contains(PNF)) {
1411 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.PNF, orchFlow, requestId,
1412 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1414 } else if (orchFlow.getFlowName().contains(NETWORK)
1415 && !orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1416 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORK, orchFlow, requestId,
1417 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1419 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VIRTUAL_LINK, orchFlow,
1420 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1422 } else if (orchFlow.getFlowName().contains(VFMODULE) || (orchFlow.getFlowName().contains(CONTROLLER)
1423 && (VFMODULE).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1424 List<Resource> vfModuleResourcesSorted;
1425 if (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE)
1426 || requestAction.equals("activateInstance")) {
1427 vfModuleResourcesSorted = sortVfModulesByBaseFirst(resourceList.stream()
1428 .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1430 vfModuleResourcesSorted = sortVfModulesByBaseLast(resourceList.stream()
1431 .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1433 for (Resource resource : vfModuleResourcesSorted) {
1434 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource, apiVersion, resourceId,
1435 requestAction, false, vnfType, workflowResourceIds, requestDetails, false, null, null,
1438 } else if (orchFlow.getFlowName().contains(VOLUMEGROUP)) {
1439 if (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1440 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)) {
1441 logger.debug("Replacing workflow resource id by volume group id");
1442 resourceId = workflowResourceIds.getVolumeGroupId();
1444 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VOLUMEGROUP, orchFlow,
1445 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1447 } else if (orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1448 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORKCOLLECTION, orchFlow,
1449 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1451 } else if (orchFlow.getFlowName().contains(CONFIGURATION)) {
1452 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.CONFIGURATION, orchFlow,
1453 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1456 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, null, apiVersion, resourceId,
1457 requestAction, false, vnfType, workflowResourceIds, requestDetails, false, null, null, false));
1460 return flowsToExecute;
1463 protected ExecuteBuildingBlock buildExecuteBuildingBlock(OrchestrationFlow orchFlow, String requestId,
1464 Resource resource, String apiVersion, String resourceId, String requestAction, boolean aLaCarte,
1465 String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1466 boolean isVirtualLink, String virtualLinkKey, String vnfcName, boolean isConfiguration) {
1468 BuildingBlock buildingBlock =
1469 new BuildingBlock().setBpmnFlowName(orchFlow.getFlowName()).setMsoId(UUID.randomUUID().toString())
1470 .setIsVirtualLink(isVirtualLink).setVirtualLinkKey(virtualLinkKey)
1471 .setKey(Optional.ofNullable(resource).map(Resource::getResourceId).orElse(""));
1472 Optional.ofNullable(orchFlow.getBpmnAction()).ifPresent(buildingBlock::setBpmnAction);
1473 Optional.ofNullable(orchFlow.getBpmnScope()).ifPresent(buildingBlock::setBpmnScope);
1475 if (resource != null
1476 && (orchFlow.getFlowName().contains(VOLUMEGROUP) && (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1477 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)))) {
1478 logger.debug("Setting resourceId to volume group id for volume group flow on replace");
1479 resourceId = workflowResourceIds.getVolumeGroupId();
1482 ExecuteBuildingBlock executeBuildingBlock = new ExecuteBuildingBlock().setApiVersion(apiVersion)
1483 .setaLaCarte(aLaCarte).setRequestAction(requestAction).setResourceId(resourceId).setVnfType(vnfType)
1484 .setWorkflowResourceIds(workflowResourceIds).setRequestId(requestId).setBuildingBlock(buildingBlock)
1485 .setRequestDetails(requestDetails);
1487 if (resource != null && (isConfiguration || resource.getResourceType().equals(WorkflowType.CONFIGURATION))) {
1488 ConfigurationResourceKeys configurationResourceKeys = getConfigurationResourceKeys(resource, vnfcName);
1489 executeBuildingBlock.setConfigurationResourceKeys(configurationResourceKeys);
1491 return executeBuildingBlock;
1494 private ConfigurationResourceKeys getConfigurationResourceKeys(Resource resource, String vnfcName) {
1495 ConfigurationResourceKeys configurationResourceKeys = new ConfigurationResourceKeys();
1496 Optional.ofNullable(vnfcName).ifPresent(configurationResourceKeys::setVnfcName);
1497 configurationResourceKeys.setCvnfcCustomizationUUID(resource.getCvnfModuleCustomizationId());
1498 configurationResourceKeys.setVfModuleCustomizationUUID(resource.getVfModuleCustomizationId());
1499 configurationResourceKeys.setVnfResourceCustomizationUUID(resource.getVnfCustomizationId());
1500 return configurationResourceKeys;
1503 protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1504 WorkflowType resourceName, boolean aLaCarte, String cloudOwner) {
1505 return this.queryNorthBoundRequestCatalogDb(execution, requestAction, resourceName, aLaCarte, cloudOwner, "");
1508 protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1509 WorkflowType resourceName, boolean aLaCarte, String cloudOwner, String serviceType) {
1510 List<OrchestrationFlow> listToExecute = new ArrayList<>();
1511 NorthBoundRequest northBoundRequest;
1512 if (serviceType.equalsIgnoreCase(SERVICE_TYPE_TRANSPORT)
1513 || serviceType.equalsIgnoreCase(SERVICE_TYPE_BONDING)) {
1515 catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwnerAndServiceType(
1516 requestAction, resourceName.toString(), aLaCarte, cloudOwner, serviceType);
1518 northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1519 requestAction, resourceName.toString(), aLaCarte, cloudOwner);
1521 if (northBoundRequest == null) {
1522 northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1523 requestAction, resourceName.toString(), aLaCarte, CLOUD_OWNER);
1525 if (northBoundRequest == null) {
1526 buildAndThrowException(execution, String.format("The request: %s %s %s is not supported by GR_API.",
1527 (aLaCarte ? "AlaCarte" : "Macro"), resourceName, requestAction));
1529 if (northBoundRequest.getIsToplevelflow() != null) {
1530 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, northBoundRequest.getIsToplevelflow());
1532 List<OrchestrationFlow> flows = northBoundRequest.getOrchestrationFlowList();
1534 flows = new ArrayList<>();
1535 for (OrchestrationFlow flow : flows) {
1536 if (!flow.getFlowName().contains("BB") && !flow.getFlowName().contains("Activity")) {
1537 List<OrchestrationFlow> macroQueryFlows =
1538 catalogDbClient.getOrchestrationFlowByAction(flow.getFlowName());
1539 listToExecute.addAll(macroQueryFlows);
1541 listToExecute.add(flow);
1545 return listToExecute;
1548 protected void buildAndThrowException(DelegateExecution execution, String msg, Exception ex) {
1549 logger.error(msg, ex);
1550 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg + ex.getMessage());
1551 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg + ex.getMessage());
1554 protected void buildAndThrowException(DelegateExecution execution, String msg) {
1556 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg);
1557 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
1560 public void handleRuntimeException(DelegateExecution execution) {
1561 StringBuilder wfeExpMsg = new StringBuilder("Runtime error ");
1562 String runtimeErrorMessage;
1564 String javaExpMsg = (String) execution.getVariable("BPMN_javaExpMsg");
1565 if (javaExpMsg != null && !javaExpMsg.isEmpty()) {
1566 wfeExpMsg.append(": ").append(javaExpMsg);
1568 runtimeErrorMessage = wfeExpMsg.toString();
1569 logger.error(runtimeErrorMessage);
1570 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, runtimeErrorMessage);
1571 } catch (Exception e) {
1572 logger.error("Runtime error", e);
1573 // if runtime message was mulformed
1574 runtimeErrorMessage = "Runtime error";
1576 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, runtimeErrorMessage);
1579 protected boolean isUriResume(String uri) {
1580 return uri.endsWith("/resume");
1583 protected boolean isRequestMacroServiceResume(boolean aLaCarte, WorkflowType resourceType, String requestAction,
1584 String serviceInstanceId) {
1585 return (!aLaCarte && resourceType == WorkflowType.SERVICE
1586 && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE) || requestAction.equalsIgnoreCase(CREATEINSTANCE))
1587 && (serviceInstanceId != null && serviceInstanceId.trim().length() > 1)
1588 && (bbInputSetupUtils.getAAIServiceInstanceById(serviceInstanceId) != null));
1591 protected String validateServiceResourceIdInAAI(String generatedResourceId, String instanceName,
1592 RequestDetails reqDetails) throws DuplicateNameException {
1593 String globalCustomerId = reqDetails.getSubscriberInfo().getGlobalSubscriberId();
1594 String serviceType = reqDetails.getRequestParameters().getSubscriptionServiceType();
1595 if (instanceName != null) {
1596 Optional<ServiceInstance> serviceInstanceAAI =
1597 bbInputSetupUtils.getAAIServiceInstanceByName(globalCustomerId, serviceType, instanceName);
1598 if (serviceInstanceAAI.isPresent()) {
1599 if (serviceInstanceAAI.get().getModelVersionId()
1600 .equalsIgnoreCase(reqDetails.getModelInfo().getModelVersionId())) {
1601 return serviceInstanceAAI.get().getServiceInstanceId();
1603 throw new DuplicateNameException(SERVICE_INSTANCE, String.format(NAME_EXISTS_WITH_DIFF_VERSION_ID,
1604 instanceName, reqDetails.getModelInfo().getModelVersionId()));
1607 ServiceInstances aaiServiceInstances =
1608 bbInputSetupUtils.getAAIServiceInstancesGloballyByName(instanceName);
1609 if (aaiServiceInstances != null) {
1610 if (aaiServiceInstances.getServiceInstance() != null
1611 && !aaiServiceInstances.getServiceInstance().isEmpty()) {
1612 if (aaiServiceInstances.getServiceInstance().size() > 1) {
1613 throw new DuplicateNameException(SERVICE_INSTANCE,
1614 String.format(NAME_EXISTS_MULTIPLE, instanceName));
1616 ServiceInstance si = aaiServiceInstances.getServiceInstance().stream().findFirst().get();
1617 Map<String, String> keys =
1618 bbInputSetupUtils.getURIKeysFromServiceInstance(si.getServiceInstanceId());
1620 throw new DuplicateNameException(SERVICE_INSTANCE, String.format(
1621 NAME_EXISTS_WITH_DIFF_COMBINATION, instanceName,
1622 keys.get(AAIFluentTypeBuilder.Types.CUSTOMER.getUriParams().globalCustomerId),
1624 AAIFluentTypeBuilder.Types.SERVICE_SUBSCRIPTION.getUriParams().serviceType),
1625 si.getModelVersionId()));
1631 return generatedResourceId;
1634 protected String validateNetworkResourceIdInAAI(String generatedResourceId, String instanceName,
1635 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1636 throws DuplicateNameException, MultipleObjectsFoundException {
1637 Optional<L3Network> network = bbInputSetupUtils
1638 .getRelatedNetworkByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1639 if (network.isPresent()) {
1640 if (network.get().getModelCustomizationId()
1641 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1642 return network.get().getNetworkId();
1644 throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1645 instanceName, network.get().getModelCustomizationId()));
1648 if (bbInputSetupUtils.existsAAINetworksGloballyByName(instanceName)) {
1649 throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName,
1650 workflowResourceIds.getServiceInstanceId()));
1652 return generatedResourceId;
1655 protected String validateVnfResourceIdInAAI(String generatedResourceId, String instanceName,
1656 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1657 Optional<GenericVnf> vnf = bbInputSetupUtils
1658 .getRelatedVnfByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1659 if (vnf.isPresent()) {
1660 if (vnf.get().getModelCustomizationId()
1661 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1662 return vnf.get().getVnfId();
1664 throw new DuplicateNameException("generic-vnf", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1665 instanceName, vnf.get().getModelCustomizationId()));
1668 GenericVnfs vnfs = bbInputSetupUtils.getAAIVnfsGloballyByName(instanceName);
1670 throw new DuplicateNameException("generic-vnf",
1671 String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName, vnfs.getGenericVnf().get(0).getVnfId()));
1673 return generatedResourceId;
1676 protected String validateVfModuleResourceIdInAAI(String generatedResourceId, String instanceName,
1677 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1678 GenericVnf vnf = bbInputSetupUtils.getAAIGenericVnf(workflowResourceIds.getVnfId());
1679 if (vnf != null && vnf.getVfModules() != null) {
1680 for (org.onap.aai.domain.yang.VfModule vfModule : vnf.getVfModules().getVfModule()) {
1681 if (vfModule.getVfModuleName().equalsIgnoreCase(instanceName)) {
1682 if (vfModule.getModelCustomizationId()
1683 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1684 return vfModule.getVfModuleId();
1686 throw new DuplicateNameException("vfModule",
1687 String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID, instanceName,
1688 reqDetails.getModelInfo().getModelCustomizationId()));
1693 if (bbInputSetupUtils.existsAAIVfModuleGloballyByName(instanceName)) {
1694 throw new DuplicateNameException("vfModule", instanceName);
1696 return generatedResourceId;
1699 protected String validateVolumeGroupResourceIdInAAI(String generatedResourceId, String instanceName,
1700 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1701 Optional<VolumeGroup> volumeGroup =
1702 bbInputSetupUtils.getRelatedVolumeGroupByNameFromVnf(workflowResourceIds.getVnfId(), instanceName);
1703 if (volumeGroup.isPresent()) {
1704 if (volumeGroup.get().getVfModuleModelCustomizationId()
1705 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1706 return volumeGroup.get().getVolumeGroupId();
1708 throw new DuplicateNameException("volumeGroup", volumeGroup.get().getVolumeGroupName());
1711 if (bbInputSetupUtils.existsAAIVolumeGroupGloballyByName(instanceName)) {
1712 throw new DuplicateNameException("volumeGroup", instanceName);
1714 return generatedResourceId;
1717 protected String validateConfigurationResourceIdInAAI(String generatedResourceId, String instanceName,
1718 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1719 Optional<org.onap.aai.domain.yang.Configuration> configuration =
1720 bbInputSetupUtils.getRelatedConfigurationByNameFromServiceInstance(
1721 workflowResourceIds.getServiceInstanceId(), instanceName);
1722 if (configuration.isPresent()) {
1723 if (configuration.get().getModelCustomizationId()
1724 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1725 return configuration.get().getConfigurationId();
1727 throw new DuplicateNameException("configuration", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1728 instanceName, configuration.get().getConfigurationId()));
1731 if (bbInputSetupUtils.existsAAIConfigurationGloballyByName(instanceName)) {
1732 throw new DuplicateNameException("configuration", instanceName);
1734 return generatedResourceId;
1737 private void fillExecution(DelegateExecution execution, boolean suppressRollback, String resourceId,
1738 WorkflowType resourceType) {
1739 execution.setVariable("sentSyncResponse", false);
1740 execution.setVariable("homing", false);
1741 execution.setVariable("calledHoming", false);
1742 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, true);
1743 execution.setVariable("suppressRollback", suppressRollback);
1744 execution.setVariable("resourceId", resourceId);
1745 execution.setVariable("resourceType", resourceType);
1746 execution.setVariable("resourceName", resourceType.toString());
1749 private Resource getResource(BBInputSetupUtils bbInputSetupUtils, boolean isResume, boolean alaCarte, String uri,
1751 if (!alaCarte && isResume) {
1752 logger.debug("replacing URI {}", uri);
1753 uri = bbInputSetupUtils.loadOriginalInfraActiveRequestById(requestId).getRequestUrl();
1754 logger.debug("for RESUME with original value {}", uri);
1756 return extractResourceIdAndTypeFromUri(uri);
1759 private String getResourceId(Resource resource, String requestAction, RequestDetails requestDetails,
1760 WorkflowResourceIds workflowResourceIds) throws Exception {
1761 if (resource.isGenerated() && requestAction.equalsIgnoreCase("createInstance")
1762 && requestDetails.getRequestInfo().getInstanceName() != null) {
1763 return validateResourceIdInAAI(resource.getResourceId(), resource.getResourceType(),
1764 requestDetails.getRequestInfo().getInstanceName(), requestDetails, workflowResourceIds);
1766 return resource.getResourceId();
1770 private String getServiceInstanceId(DelegateExecution execution, String resourceId, WorkflowType resourceType) {
1771 String serviceInstanceId = (String) execution.getVariable("serviceInstanceId");
1772 if ((serviceInstanceId == null || serviceInstanceId.isEmpty()) && WorkflowType.SERVICE.equals(resourceType)) {
1773 serviceInstanceId = resourceId;
1775 return serviceInstanceId;