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.apache.commons.lang3.SerializationUtils;
41 import org.camunda.bpm.engine.delegate.DelegateExecution;
42 import org.javatuples.Pair;
43 import org.onap.aai.domain.yang.GenericVnf;
44 import org.onap.aai.domain.yang.GenericVnfs;
45 import org.onap.aai.domain.yang.L3Network;
46 import org.onap.aai.domain.yang.Relationship;
47 import org.onap.aai.domain.yang.ServiceInstance;
48 import org.onap.aai.domain.yang.ServiceInstances;
49 import org.onap.aai.domain.yang.Vnfc;
50 import org.onap.aai.domain.yang.VolumeGroup;
51 import org.onap.aai.domain.yang.VpnBinding;
52 import org.onap.aaiclient.client.aai.AAICommonObjectMapperProvider;
53 import org.onap.aaiclient.client.aai.AAIObjectType;
54 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper;
55 import org.onap.aaiclient.client.aai.entities.Relationships;
56 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri;
57 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory;
58 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder;
59 import org.onap.so.bpmn.common.BBConstants;
60 import org.onap.so.bpmn.infrastructure.workflow.tasks.utils.WorkflowResourceIdsUtils;
61 import org.onap.so.bpmn.servicedecomposition.bbobjects.Configuration;
62 import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule;
63 import org.onap.so.bpmn.servicedecomposition.entities.BuildingBlock;
64 import org.onap.so.bpmn.servicedecomposition.entities.ConfigurationResourceKeys;
65 import org.onap.so.bpmn.servicedecomposition.entities.ExecuteBuildingBlock;
66 import org.onap.so.bpmn.servicedecomposition.entities.WorkflowResourceIds;
67 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetup;
68 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetupUtils;
69 import org.onap.so.bpmn.servicedecomposition.tasks.exceptions.DuplicateNameException;
70 import org.onap.so.bpmn.servicedecomposition.tasks.exceptions.MultipleObjectsFoundException;
71 import org.onap.so.client.exception.ExceptionBuilder;
72 import org.onap.so.client.orchestration.AAIConfigurationResources;
73 import org.onap.so.client.orchestration.AAIEntityNotFoundException;
74 import org.onap.so.db.catalog.beans.CollectionNetworkResourceCustomization;
75 import org.onap.so.db.catalog.beans.CollectionResourceCustomization;
76 import org.onap.so.db.catalog.beans.CollectionResourceInstanceGroupCustomization;
77 import org.onap.so.db.catalog.beans.CvnfcConfigurationCustomization;
78 import org.onap.so.db.catalog.beans.CvnfcCustomization;
79 import org.onap.so.db.catalog.beans.InstanceGroup;
80 import org.onap.so.db.catalog.beans.VfModuleCustomization;
81 import org.onap.so.db.catalog.beans.macro.NorthBoundRequest;
82 import org.onap.so.db.catalog.beans.macro.OrchestrationFlow;
83 import org.onap.so.db.catalog.client.CatalogDbClient;
84 import org.onap.so.serviceinstancebeans.CloudConfiguration;
85 import org.onap.so.serviceinstancebeans.ModelInfo;
86 import org.onap.so.serviceinstancebeans.ModelType;
87 import org.onap.so.serviceinstancebeans.Networks;
88 import org.onap.so.serviceinstancebeans.Pnfs;
89 import org.onap.so.serviceinstancebeans.RelatedInstance;
90 import org.onap.so.serviceinstancebeans.RequestDetails;
91 import org.onap.so.serviceinstancebeans.Service;
92 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
93 import org.onap.so.serviceinstancebeans.VfModules;
94 import org.onap.so.serviceinstancebeans.Vnfs;
95 import org.slf4j.Logger;
96 import org.slf4j.LoggerFactory;
97 import org.springframework.beans.factory.annotation.Autowired;
98 import org.springframework.core.env.Environment;
99 import org.springframework.stereotype.Component;
100 import org.springframework.util.CollectionUtils;
101 import com.fasterxml.jackson.core.JsonProcessingException;
102 import com.fasterxml.jackson.databind.ObjectMapper;
105 public class WorkflowAction {
107 private static final String WORKFLOW_ACTION_ERROR_MESSAGE = "WorkflowActionErrorMessage";
108 private static final String SERVICE_INSTANCES = "serviceInstances";
109 private static final String SERVICE_INSTANCE = "serviceInstance";
110 private static final String VF_MODULES = "vfModules";
111 private static final String WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI =
112 "WorkflowAction was unable to verify if the instance name already exist in AAI.";
113 private static final String VNF_TYPE = "vnfType";
114 private static final String SERVICE = "Service";
115 private static final String VNF = "Vnf";
116 private static final String PNF = "Pnf";
117 private static final String VFMODULE = "VfModule";
118 private static final String VOLUMEGROUP = "VolumeGroup";
119 private static final String NETWORK = "Network";
120 private static final String NETWORKCOLLECTION = "NetworkCollection";
121 private static final String CONFIGURATION = "Configuration";
122 private static final String ASSIGNINSTANCE = "assignInstance";
123 private static final String CREATEINSTANCE = "createInstance";
124 private static final String REPLACEINSTANCE = "replaceInstance";
125 private static final String REPLACEINSTANCERETAINASSIGNMENTS = "replaceInstanceRetainAssignments";
126 private static final String USERPARAMSERVICE = "service";
127 private static final String SUPPORTEDTYPES =
128 "vnfs|vfModules|networks|networkCollections|volumeGroups|serviceInstances|instanceGroups";
129 private static final String HOMINGSOLUTION = "Homing_Solution";
130 private static final String FABRIC_CONFIGURATION = "FabricConfiguration";
131 private static final String SERVICE_TYPE_TRANSPORT = "TRANSPORT";
132 private static final String SERVICE_TYPE_BONDING = "BONDING";
133 private static final String CLOUD_OWNER = "DEFAULT";
134 private static final Logger logger = LoggerFactory.getLogger(WorkflowAction.class);
135 private static final String NAME_EXISTS_WITH_DIFF_VERSION_ID = "(%s) and different version id (%s)";
136 private static final String NAME_EXISTS_MULTIPLE =
137 "(%s) and multiple combination of model-version-id + service-type + global-customer-id";
138 private static final String NAME_EXISTS_WITH_DIFF_COMBINATION =
139 "(%s) and global-customer-id (%s), service-type (%s), model-version-id (%s)";
140 private static final String NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID =
141 "(%s), same parent and different customization id (%s)";
142 private static final String NAME_EXISTS_WITH_DIFF_PARENT = "(%s) id (%s) and different parent relationship";
143 private static final String CREATENETWORKBB = "CreateNetworkBB";
144 private static final String ACTIVATENETWORKBB = "ActivateNetworkBB";
145 private static final String VOLUMEGROUP_DELETE_PATTERN = "(Un|De)(.*)Volume(.*)";
146 private static final String VOLUMEGROUP_CREATE_PATTERN = "(A|C)(.*)Volume(.*)";
147 private static final String CONTROLLER = "Controller";
148 private static final String DEFAULT_CLOUD_OWNER = "org.onap.so.cloud-owner";
151 protected BBInputSetup bbInputSetup;
153 protected BBInputSetupUtils bbInputSetupUtils;
155 private ExceptionBuilder exceptionBuilder;
157 private CatalogDbClient catalogDbClient;
159 private AAIConfigurationResources aaiConfigurationResources;
161 private WorkflowActionExtractResourcesAAI workflowActionUtils;
163 private VrfValidation vrfValidation;
165 private Environment environment;
167 public void setBbInputSetupUtils(BBInputSetupUtils bbInputSetupUtils) {
168 this.bbInputSetupUtils = bbInputSetupUtils;
171 public void setBbInputSetup(BBInputSetup bbInputSetup) {
172 this.bbInputSetup = bbInputSetup;
175 public void selectExecutionList(DelegateExecution execution) throws Exception {
177 final String bpmnRequest = (String) execution.getVariable(BBConstants.G_BPMN_REQUEST);
178 ServiceInstancesRequest sIRequest =
179 new ObjectMapper().readValue(bpmnRequest, ServiceInstancesRequest.class);
181 final String requestId = (String) execution.getVariable(BBConstants.G_REQUEST_ID);
183 String uri = (String) execution.getVariable(BBConstants.G_URI);
184 boolean isResume = isUriResume(uri);
186 final boolean isALaCarte = (boolean) execution.getVariable(BBConstants.G_ALACARTE);
187 Resource resource = getResource(bbInputSetupUtils, isResume, isALaCarte, uri, requestId);
189 WorkflowResourceIds workflowResourceIds = populateResourceIdsFromApiHandler(execution);
190 RequestDetails requestDetails = sIRequest.getRequestDetails();
191 String requestAction = (String) execution.getVariable(BBConstants.G_ACTION);
192 String resourceId = getResourceId(resource, requestAction, requestDetails, workflowResourceIds);
193 WorkflowType resourceType = resource.getResourceType();
195 String serviceInstanceId = getServiceInstanceId(execution, resourceId, resourceType);
197 fillExecution(execution, requestDetails.getRequestInfo().getSuppressRollback(), resourceId, resourceType);
198 List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
200 if (isRequestMacroServiceResume(isALaCarte, resourceType, requestAction, serviceInstanceId)) {
201 flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
202 if (flowsToExecute == null) {
203 buildAndThrowException(execution, "Could not resume Macro flow. Error loading execution path.");
205 } else if (isALaCarte && isResume) {
206 flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
207 if (flowsToExecute == null) {
208 buildAndThrowException(execution,
209 "Could not resume request with request Id: " + requestId + ". No flowsToExecute was found");
212 String vnfType = (String) execution.getVariable(VNF_TYPE);
213 String cloudOwner = getCloudOwner(requestDetails.getCloudConfiguration());
214 List<OrchestrationFlow> orchFlows =
215 (List<OrchestrationFlow>) execution.getVariable(BBConstants.G_ORCHESTRATION_FLOW);
216 final String apiVersion = (String) execution.getVariable(BBConstants.G_APIVERSION);
217 final String serviceType =
218 Optional.ofNullable((String) execution.getVariable(BBConstants.G_SERVICE_TYPE)).orElse("");
220 if (orchFlows == null || orchFlows.isEmpty()) {
221 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, true,
222 cloudOwner, serviceType);
224 Resource resourceKey = getResourceKey(sIRequest, resourceType);
226 ReplaceInstanceRelatedInformation replaceInfo = new ReplaceInstanceRelatedInformation();
227 if ((requestAction.equalsIgnoreCase(REPLACEINSTANCE)
228 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS))
229 && resourceType.equals(WorkflowType.VFMODULE)) {
230 logger.debug("Build a BB list for replacing BB modules");
231 orchFlows = getVfModuleReplaceBuildingBlocks(new ConfigBuildingBlocksDataObject()
232 .setsIRequest(sIRequest).setOrchFlows(orchFlows).setRequestId(requestId)
233 .setResourceKey(resourceKey).setApiVersion(apiVersion).setResourceId(resourceId)
234 .setRequestAction(requestAction).setaLaCarte(true).setVnfType(vnfType)
235 .setWorkflowResourceIds(workflowResourceIds).setRequestDetails(requestDetails)
236 .setExecution(execution).setReplaceInformation(replaceInfo));
237 for (OrchestrationFlow orchFlow : orchFlows) {
238 if (orchFlow.getFlowName().contains(CONFIGURATION)) {
239 List<OrchestrationFlow> configOrchFlows = new ArrayList<>();
240 configOrchFlows.add(orchFlow);
241 List<ExecuteBuildingBlock> configBuildingBlocks =
242 getConfigBuildingBlocks(new ConfigBuildingBlocksDataObject()
243 .setsIRequest(sIRequest).setOrchFlows(configOrchFlows)
244 .setRequestId(requestId).setResourceKey(resourceKey)
245 .setApiVersion(apiVersion).setResourceId(resourceId)
246 .setRequestAction(requestAction).setaLaCarte(true).setVnfType(vnfType)
247 .setWorkflowResourceIds(workflowResourceIds)
248 .setRequestDetails(requestDetails).setExecution(execution)
249 .setReplaceInformation(replaceInfo));
250 flowsToExecute.addAll(configBuildingBlocks);
252 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, resourceKey,
253 apiVersion, resourceId, requestAction, true, vnfType, workflowResourceIds,
254 requestDetails, false, null, null, false, replaceInfo);
255 flowsToExecute.add(ebb);
259 if (isConfiguration(orchFlows) && !requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
260 List<ExecuteBuildingBlock> configBuildingBlocks =
261 getConfigBuildingBlocks(new ConfigBuildingBlocksDataObject().setsIRequest(sIRequest)
262 .setOrchFlows(orchFlows).setRequestId(requestId).setResourceKey(resourceKey)
263 .setApiVersion(apiVersion).setResourceId(resourceId)
264 .setRequestAction(requestAction).setaLaCarte(true).setVnfType(vnfType)
265 .setWorkflowResourceIds(workflowResourceIds)
266 .setRequestDetails(requestDetails).setExecution(execution));
268 flowsToExecute.addAll(configBuildingBlocks);
271 orchFlows.stream().filter(item -> !item.getFlowName().contains(FABRIC_CONFIGURATION))
272 .collect(Collectors.toList());
274 for (OrchestrationFlow orchFlow : orchFlows) {
275 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, resourceKey,
276 apiVersion, resourceId, requestAction, true, vnfType, workflowResourceIds,
277 requestDetails, false, null, null, false, replaceInfo);
278 flowsToExecute.add(ebb);
282 boolean foundRelated = false;
283 boolean containsService = false;
284 List<Resource> resourceList = new ArrayList<>();
285 List<Pair<WorkflowType, String>> aaiResourceIds = new ArrayList<>();
286 if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(ASSIGNINSTANCE)) {
287 // SERVICE-MACRO-ASSIGN will always get user params with a
289 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
290 List<Map<String, Object>> userParams =
291 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
293 userParams.stream().anyMatch(param -> param.containsKey(USERPARAMSERVICE));
294 if (containsService) {
295 traverseUserParamsService(execution, resourceList, sIRequest, requestAction);
298 buildAndThrowException(execution,
299 "Service-Macro-Assign request details must contain user params with a service");
301 } else if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
302 // SERVICE-MACRO-CREATE will get user params with a service,
303 // a service with a network, a service with a
304 // networkcollection, OR an empty service.
305 // If user params is just a service or null and macro
306 // queries the SI and finds a VNF, macro fails.
308 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
309 List<Map<String, Object>> userParams =
310 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
312 userParams.stream().anyMatch(param -> param.containsKey(USERPARAMSERVICE));
314 if (containsService) {
315 foundRelated = traverseUserParamsService(execution, resourceList, sIRequest, requestAction);
318 traverseCatalogDbService(execution, sIRequest, resourceList, aaiResourceIds);
320 } else if (resourceType == WorkflowType.SERVICE
321 && ("activateInstance".equalsIgnoreCase(requestAction)
322 || "unassignInstance".equalsIgnoreCase(requestAction)
323 || "deleteInstance".equalsIgnoreCase(requestAction)
324 || requestAction.equalsIgnoreCase("activate" + FABRIC_CONFIGURATION))) {
325 // SERVICE-MACRO-ACTIVATE, SERVICE-MACRO-UNASSIGN, and
326 // SERVICE-MACRO-DELETE
327 // Will never get user params with service, macro will have
328 // to query the SI in AAI to find related instances.
329 traverseAAIService(execution, resourceList, resourceId, aaiResourceIds);
330 } else if (resourceType == WorkflowType.SERVICE
331 && "deactivateInstance".equalsIgnoreCase(requestAction)) {
332 resourceList.add(new Resource(WorkflowType.SERVICE, "", false));
333 } else if (resourceType == WorkflowType.VNF && ("replaceInstance".equalsIgnoreCase(requestAction)
334 || ("recreateInstance".equalsIgnoreCase(requestAction)))) {
335 traverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
336 workflowResourceIds.getVnfId(), aaiResourceIds);
338 buildAndThrowException(execution, "Current Macro Request is not supported");
340 StringBuilder foundObjects = new StringBuilder();
341 for (WorkflowType type : WorkflowType.values()) {
342 foundObjects.append(type).append(" - ").append(
343 (int) resourceList.stream().filter(x -> type.equals(x.getResourceType())).count())
346 logger.info("Found {}", foundObjects.toString());
348 if (orchFlows == null || orchFlows.isEmpty()) {
349 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, isALaCarte,
350 cloudOwner, serviceType);
352 boolean vnfReplace = false;
353 if (resourceType.equals(WorkflowType.VNF) && ("replaceInstance".equalsIgnoreCase(requestAction)
354 || "replaceInstanceRetainAssignments".equalsIgnoreCase(requestAction))) {
357 flowsToExecute = buildExecuteBuildingBlockList(orchFlows, resourceList, requestId, apiVersion,
358 resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, vnfReplace);
359 if (isNetworkCollectionInTheResourceList(resourceList)) {
360 logger.info("Sorting for Vlan Tagging");
361 flowsToExecute = sortExecutionPathByObjectForVlanTagging(flowsToExecute, requestAction);
363 // By default, enable homing at VNF level for CREATEINSTANCE and ASSIGNINSTANCE
364 if (resourceType == WorkflowType.SERVICE
365 && (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE))
366 && resourceList.stream().anyMatch(x -> WorkflowType.VNF.equals(x.getResourceType()))) {
367 execution.setVariable("homing", true);
368 execution.setVariable("calledHoming", false);
370 if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE)
371 || requestAction.equalsIgnoreCase(CREATEINSTANCE))) {
372 generateResourceIds(flowsToExecute, resourceList, serviceInstanceId);
374 updateResourceIdsFromAAITraversal(flowsToExecute, resourceList, aaiResourceIds,
379 // If the user set "Homing_Solution" to "none", disable homing, else if "Homing_Solution" is specified,
381 if (sIRequest.getRequestDetails().getRequestParameters() != null
382 && sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
383 List<Map<String, Object>> userParams =
384 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
385 for (Map<String, Object> params : userParams) {
386 if (params.containsKey(HOMINGSOLUTION)) {
387 execution.setVariable("homing", !"none".equals(params.get(HOMINGSOLUTION)));
392 if (CollectionUtils.isEmpty(flowsToExecute)) {
393 throw new IllegalStateException("Macro did not come up with a valid execution path.");
396 List<String> flowNames = new ArrayList<>();
397 logger.info("List of BuildingBlocks to execute:");
399 flowsToExecute.forEach(ebb -> {
400 logger.info(ebb.getBuildingBlock().getBpmnFlowName());
401 flowNames.add(ebb.getBuildingBlock().getBpmnFlowName());
405 bbInputSetupUtils.persistFlowExecutionPath(requestId, flowsToExecute);
407 execution.setVariable("flowNames", flowNames);
408 execution.setVariable(BBConstants.G_CURRENT_SEQUENCE, 0);
409 execution.setVariable("retryCount", 0);
410 execution.setVariable("isRollback", false);
411 execution.setVariable("flowsToExecute", flowsToExecute);
412 execution.setVariable("isRollbackComplete", false);
414 } catch (Exception ex) {
415 if (!(execution.hasVariable("WorkflowException")
416 || execution.hasVariable("WorkflowExceptionExceptionMessage"))) {
417 buildAndThrowException(execution, "Exception while setting execution list. ", ex);
424 private Resource getResourceKey(ServiceInstancesRequest sIRequest, WorkflowType resourceType) {
425 String resourceId = "";
426 ModelInfo modelInfo = sIRequest.getRequestDetails().getModelInfo();
427 if (modelInfo != null) {
428 if (modelInfo.getModelType().equals(ModelType.service)) {
429 resourceId = modelInfo.getModelVersionId();
431 resourceId = modelInfo.getModelCustomizationId();
434 return new Resource(resourceType, resourceId, true);
437 private String getCloudOwner(CloudConfiguration cloudConfiguration) {
438 if (cloudConfiguration != null && cloudConfiguration.getCloudOwner() != null) {
439 return cloudConfiguration.getCloudOwner();
441 logger.warn("cloud owner value not found in request details, it will be set as default");
442 return environment.getProperty(DEFAULT_CLOUD_OWNER);
445 protected <T> List<T> getRelatedResourcesInVfModule(String vnfId, String vfModuleId, Class<T> resultClass,
446 AAIObjectType type) {
447 List<T> vnfcs = new ArrayList<>();
448 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VF_MODULE, vnfId, vfModuleId);
449 AAIResultWrapper vfModuleResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
450 Optional<Relationships> relationshipsOp = vfModuleResultsWrapper.getRelationships();
451 if (!relationshipsOp.isPresent()) {
452 logger.debug("No relationships were found for vfModule in AAI");
454 Relationships relationships = relationshipsOp.get();
455 List<AAIResultWrapper> vnfcResultWrappers = relationships.getByType(type);
456 for (AAIResultWrapper vnfcResultWrapper : vnfcResultWrappers) {
457 Optional<T> vnfcOp = vnfcResultWrapper.asBean(resultClass);
458 vnfcOp.ifPresent(vnfcs::add);
464 protected <T> T getRelatedResourcesInVnfc(Vnfc vnfc, Class<T> resultClass, AAIObjectType type) throws Exception {
465 T configuration = null;
466 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VNFC, vnfc.getVnfcName());
467 AAIResultWrapper vnfcResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
468 Optional<Relationships> relationshipsOp = vnfcResultsWrapper.getRelationships();
469 if (!relationshipsOp.isPresent()) {
470 logger.debug("No relationships were found for VNFC in AAI");
472 Relationships relationships = relationshipsOp.get();
473 List<AAIResultWrapper> configurationResultWrappers =
474 this.getResultWrappersFromRelationships(relationships, type);
475 if (configurationResultWrappers.size() > 1) {
476 String multipleRelationshipsError =
477 "Multiple relationships exist from VNFC " + vnfc.getVnfcName() + " to Configurations";
478 throw new Exception(multipleRelationshipsError);
480 if (!configurationResultWrappers.isEmpty()) {
481 Optional<T> configurationOp = configurationResultWrappers.get(0).asBean(resultClass);
482 if (configurationOp.isPresent()) {
483 configuration = configurationOp.get();
487 return configuration;
490 protected List<AAIResultWrapper> getResultWrappersFromRelationships(Relationships relationships,
491 AAIObjectType type) {
492 return relationships.getByType(type);
495 protected boolean isConfiguration(List<OrchestrationFlow> orchFlows) {
496 for (OrchestrationFlow flow : orchFlows) {
497 if (flow.getFlowName().contains(CONFIGURATION) && !"ConfigurationScaleOutBB".equals(flow.getFlowName())) {
504 protected List<ExecuteBuildingBlock> getConfigBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
507 List<ExecuteBuildingBlock> flowsToExecuteConfigs = new ArrayList<>();
508 List<OrchestrationFlow> result = dataObj.getOrchFlows().stream()
509 .filter(item -> item.getFlowName().contains(FABRIC_CONFIGURATION)).collect(Collectors.toList());
510 String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
511 String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
513 String vnfCustomizationUUID = bbInputSetupUtils.getAAIGenericVnf(vnfId).getModelCustomizationId();
514 String vfModuleCustomizationUUID;
515 org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
517 if (aaiVfModule == null) {
518 logger.error("No matching VfModule is found in Generic-Vnf in AAI for vnfId: {} and vfModuleId : {}", vnfId,
520 throw new AAIEntityNotFoundException("No matching VfModule is found in Generic-Vnf in AAI for vnfId: "
521 + vnfId + " and vfModuleId : " + vfModuleId);
523 vfModuleCustomizationUUID = aaiVfModule.getModelCustomizationId();
526 List<org.onap.aai.domain.yang.Vnfc> vnfcs = getRelatedResourcesInVfModule(vnfId, vfModuleId,
527 org.onap.aai.domain.yang.Vnfc.class, AAIObjectType.VNFC);
528 for (org.onap.aai.domain.yang.Vnfc vnfc : vnfcs) {
529 WorkflowResourceIds workflowIdsCopy = SerializationUtils.clone(dataObj.getWorkflowResourceIds());
530 org.onap.aai.domain.yang.Configuration configuration = getRelatedResourcesInVnfc(vnfc,
531 org.onap.aai.domain.yang.Configuration.class, AAIObjectType.CONFIGURATION);
532 workflowIdsCopy.setConfigurationId(configuration.getConfigurationId());
533 for (OrchestrationFlow orchFlow : result) {
534 dataObj.getResourceKey().setVfModuleCustomizationId(vfModuleCustomizationUUID);
535 dataObj.getResourceKey().setCvnfModuleCustomizationId(vnfc.getModelCustomizationId());
536 dataObj.getResourceKey().setVnfCustomizationId(vnfCustomizationUUID);
537 String vnfcName = vnfc.getVnfcName();
538 if (vnfcName == null || vnfcName.isEmpty()) {
539 buildAndThrowException(dataObj.getExecution(), "Exception in create execution list "
540 + ": VnfcName does not exist or is null while there is a configuration for the vfModule",
541 new Exception("Vnfc and Configuration do not match"));
543 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, dataObj.getRequestId(),
544 dataObj.getResourceKey(), dataObj.getApiVersion(), dataObj.getResourceId(),
545 dataObj.getRequestAction(), dataObj.isaLaCarte(), dataObj.getVnfType(), workflowIdsCopy,
546 dataObj.getRequestDetails(), false, null, vnfcName, true, null);
547 flowsToExecuteConfigs.add(ebb);
551 return flowsToExecuteConfigs;
554 protected List<OrchestrationFlow> getVfModuleReplaceBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
557 String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
558 String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
560 logger.debug("BUILDING REPLACE LIST");
562 boolean volumeGroupExisted = false;
563 boolean volumeGroupWillExist = false;
564 boolean keepVolumeGroup = false;
566 boolean rebuildVolumeGroups = false;
567 if (dataObj.getRequestDetails().getRequestParameters() != null
568 && dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups() != null) {
569 rebuildVolumeGroups = dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups();
571 String volumeGroupName = "";
572 Optional<VolumeGroup> volumeGroupFromVfModule =
573 bbInputSetupUtils.getRelatedVolumeGroupFromVfModule(vnfId, vfModuleId);
574 if (volumeGroupFromVfModule.isPresent()) {
575 String volumeGroupId = volumeGroupFromVfModule.get().getVolumeGroupId();
576 volumeGroupName = volumeGroupFromVfModule.get().getVolumeGroupName();
577 logger.debug("Volume group id of the existing volume group is: " + volumeGroupId);
578 volumeGroupExisted = true;
579 dataObj.getWorkflowResourceIds().setVolumeGroupId(volumeGroupId);
580 dataObj.getReplaceInformation().setOldVolumeGroupName(volumeGroupName);
583 List<OrchestrationFlow> orchFlows = dataObj.getOrchFlows();
584 VfModuleCustomization vfModuleCustomization = catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
585 dataObj.getRequestDetails().getModelInfo().getModelCustomizationUuid());
586 if (vfModuleCustomization != null && vfModuleCustomization.getVfModule() != null
587 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
588 && vfModuleCustomization.getVolumeHeatEnv() != null) {
589 volumeGroupWillExist = true;
590 if (!volumeGroupExisted) {
591 String newVolumeGroupId = UUID.randomUUID().toString();
592 dataObj.getWorkflowResourceIds().setVolumeGroupId(newVolumeGroupId);
593 dataObj.getReplaceInformation().setOldVolumeGroupName(volumeGroupName);
594 logger.debug("newVolumeGroupId: " + newVolumeGroupId);
598 if (volumeGroupExisted && volumeGroupWillExist && !rebuildVolumeGroups) {
599 keepVolumeGroup = true;
602 if (!volumeGroupExisted || keepVolumeGroup) {
603 logger.debug("Filtering out deletion of volume groups");
604 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_DELETE_PATTERN))
605 .collect(Collectors.toList());
607 if (!volumeGroupWillExist || keepVolumeGroup) {
608 logger.debug("Filtering out creation of volume groups");
609 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_CREATE_PATTERN))
610 .collect(Collectors.toList());
616 protected List<Resource> sortVfModulesByBaseFirst(List<Resource> vfModuleResources) {
618 for (Resource resource : vfModuleResources) {
619 if (resource.isBaseVfModule()) {
620 Collections.swap(vfModuleResources, 0, count);
625 return vfModuleResources;
628 protected List<Resource> sortVfModulesByBaseLast(List<Resource> vfModuleResources) {
630 for (Resource resource : vfModuleResources) {
631 if (resource.isBaseVfModule()) {
632 Collections.swap(vfModuleResources, vfModuleResources.size() - 1, count);
637 return vfModuleResources;
640 private void updateResourceIdsFromAAITraversal(List<ExecuteBuildingBlock> flowsToExecute,
641 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds, String serviceInstanceId) {
642 for (Pair<WorkflowType, String> pair : aaiResourceIds) {
643 logger.debug(pair.getValue0() + ", " + pair.getValue1());
646 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
647 .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
648 .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
649 retrieveAAIResourceId(aaiResourceIds, type), null, serviceInstanceId)));
652 private String retrieveAAIResourceId(List<Pair<WorkflowType, String>> aaiResourceIds, WorkflowType resource) {
654 for (int i = 0; i < aaiResourceIds.size(); i++) {
655 if (aaiResourceIds.get(i).getValue0() == resource) {
656 id = aaiResourceIds.get(i).getValue1();
657 aaiResourceIds.remove(i);
664 private void generateResourceIds(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
665 String serviceInstanceId) {
666 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
667 .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
668 .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
669 null, resource.getVirtualLinkKey(), serviceInstanceId)));
672 protected void updateWorkflowResourceIds(List<ExecuteBuildingBlock> flowsToExecute, WorkflowType resourceType,
673 String key, String id, String virtualLinkKey, String serviceInstanceId) {
674 String resourceId = id;
675 if (resourceId == null) {
676 resourceId = UUID.randomUUID().toString();
678 for (ExecuteBuildingBlock ebb : flowsToExecute) {
679 if (key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey()) && (ebb.getBuildingBlock()
680 .getBpmnFlowName().contains(resourceType.toString())
681 || (ebb.getBuildingBlock().getBpmnFlowName().contains(CONTROLLER)
682 && ebb.getBuildingBlock().getBpmnScope().equalsIgnoreCase(resourceType.toString())))) {
683 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
684 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
685 WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, resourceType, resourceId);
686 ebb.setWorkflowResourceIds(workflowResourceIds);
688 if (virtualLinkKey != null && ebb.getBuildingBlock().isVirtualLink()
689 && virtualLinkKey.equalsIgnoreCase(ebb.getBuildingBlock().getVirtualLinkKey())) {
690 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
691 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
692 workflowResourceIds.setNetworkId(resourceId);
693 ebb.setWorkflowResourceIds(workflowResourceIds);
698 protected CollectionResourceCustomization findCatalogNetworkCollection(DelegateExecution execution,
699 org.onap.so.db.catalog.beans.Service service) {
700 CollectionResourceCustomization networkCollection = null;
702 for (CollectionResourceCustomization collectionCust : service.getCollectionResourceCustomizations()) {
703 if (catalogDbClient.getNetworkCollectionResourceCustomizationByID(
704 collectionCust.getModelCustomizationUUID()) != null) {
705 networkCollection = collectionCust;
711 } else if (count > 1) {
712 buildAndThrowException(execution,
713 "Found multiple Network Collections in the Service model, only one per Service is supported.");
715 return networkCollection;
718 protected void traverseCatalogDbService(DelegateExecution execution, ServiceInstancesRequest sIRequest,
719 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds)
720 throws JsonProcessingException, VrfBondingServiceException {
721 String modelUUID = sIRequest.getRequestDetails().getModelInfo().getModelVersionId();
722 org.onap.so.db.catalog.beans.Service service = catalogDbClient.getServiceByID(modelUUID);
723 if (service == null) {
724 buildAndThrowException(execution, "Could not find the service model in catalog db.");
726 resourceList.add(new Resource(WorkflowType.SERVICE, service.getModelUUID(), false));
727 RelatedInstance relatedVpnBinding =
728 bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.vpnBinding);
729 RelatedInstance relatedLocalNetwork =
730 bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.network);
731 if (relatedVpnBinding != null && relatedLocalNetwork != null) {
732 traverseVrfConfiguration(aaiResourceIds, resourceList, service, relatedVpnBinding, relatedLocalNetwork);
734 traverseNetworkCollection(execution, resourceList, service);
739 protected void traverseVrfConfiguration(List<Pair<WorkflowType, String>> aaiResourceIds,
740 List<Resource> resourceList, org.onap.so.db.catalog.beans.Service service,
741 RelatedInstance relatedVpnBinding, RelatedInstance relatedLocalNetwork)
742 throws VrfBondingServiceException, JsonProcessingException {
743 org.onap.aai.domain.yang.L3Network aaiLocalNetwork =
744 bbInputSetupUtils.getAAIL3Network(relatedLocalNetwork.getInstanceId());
745 vrfValidation.vrfServiceValidation(service);
746 vrfValidation.vrfCatalogDbChecks(service);
747 vrfValidation.aaiVpnBindingValidation(relatedVpnBinding.getInstanceId(),
748 bbInputSetupUtils.getAAIVpnBinding(relatedVpnBinding.getInstanceId()));
749 vrfValidation.aaiNetworkValidation(relatedLocalNetwork.getInstanceId(), aaiLocalNetwork);
750 vrfValidation.aaiSubnetValidation(aaiLocalNetwork);
751 vrfValidation.aaiAggregateRouteValidation(aaiLocalNetwork);
752 vrfValidation.aaiRouteTargetValidation(aaiLocalNetwork);
753 String existingAAIVrfConfiguration = getExistingAAIVrfConfiguration(relatedVpnBinding, aaiLocalNetwork);
754 if (existingAAIVrfConfiguration != null) {
755 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, existingAAIVrfConfiguration));
757 resourceList.add(new Resource(WorkflowType.CONFIGURATION,
758 service.getConfigurationCustomizations().get(0).getModelCustomizationUUID(), false));
762 protected String getExistingAAIVrfConfiguration(RelatedInstance relatedVpnBinding,
763 org.onap.aai.domain.yang.L3Network aaiLocalNetwork)
764 throws JsonProcessingException, VrfBondingServiceException {
765 Optional<Relationships> relationshipsOp = new AAIResultWrapper(
766 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiLocalNetwork)).getRelationships();
767 if (relationshipsOp.isPresent()) {
768 List<AAIResultWrapper> configurationsRelatedToLocalNetwork =
769 relationshipsOp.get().getByType(AAIObjectType.CONFIGURATION);
770 if (configurationsRelatedToLocalNetwork.size() > 1) {
771 throw new VrfBondingServiceException(
772 "Network: " + aaiLocalNetwork.getNetworkId() + " has more than 1 configuration related to it");
774 if (configurationsRelatedToLocalNetwork.size() == 1) {
775 AAIResultWrapper configWrapper = configurationsRelatedToLocalNetwork.get(0);
776 Optional<Configuration> relatedConfiguration = configWrapper.asBean(Configuration.class);
777 if (relatedConfiguration.isPresent() && vrfConfigurationAlreadyExists(relatedVpnBinding,
778 relatedConfiguration.get(), configWrapper)) {
779 return relatedConfiguration.get().getConfigurationId();
786 protected boolean vrfConfigurationAlreadyExists(RelatedInstance relatedVpnBinding, Configuration vrfConfiguration,
787 AAIResultWrapper configWrapper) throws VrfBondingServiceException {
788 if ("VRF-ENTRY".equalsIgnoreCase(vrfConfiguration.getConfigurationType())) {
789 Optional<Relationships> relationshipsConfigOp = configWrapper.getRelationships();
790 if (relationshipsConfigOp.isPresent()) {
791 Optional<VpnBinding> relatedInfraVpnBindingOp =
792 workflowActionUtils.extractRelationshipsVpnBinding(relationshipsConfigOp.get());
793 if (relatedInfraVpnBindingOp.isPresent()) {
794 VpnBinding relatedInfraVpnBinding = relatedInfraVpnBindingOp.get();
795 if (!relatedInfraVpnBinding.getVpnId().equalsIgnoreCase(relatedVpnBinding.getInstanceId())) {
796 throw new VrfBondingServiceException("Configuration: " + vrfConfiguration.getConfigurationId()
797 + " is not connected to the same vpn binding id provided in request: "
798 + relatedVpnBinding.getInstanceId());
808 protected void traverseNetworkCollection(DelegateExecution execution, List<Resource> resourceList,
809 org.onap.so.db.catalog.beans.Service service) {
810 if (isVnfCustomizationsInTheService(service)) {
811 buildAndThrowException(execution,
812 "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");
814 List<CollectionResourceCustomization> customizations = service.getCollectionResourceCustomizations();
815 if (customizations.isEmpty()) {
816 logger.debug("No Collections found. CollectionResourceCustomization list is empty.");
818 CollectionResourceCustomization collectionResourceCustomization =
819 findCatalogNetworkCollection(execution, service);
820 traverseNetworkCollectionResourceCustomization(resourceList, collectionResourceCustomization);
822 traverseNetworkCollectionCustomization(resourceList, service);
825 private void traverseNetworkCollectionResourceCustomization(List<Resource> resourceList,
826 CollectionResourceCustomization collectionResourceCustomization) {
827 if (collectionResourceCustomizationShouldNotBeProcessed(resourceList, collectionResourceCustomization))
830 org.onap.so.db.catalog.beans.InstanceGroup instanceGroup =
831 collectionResourceCustomization.getCollectionResource().getInstanceGroup();
832 CollectionResourceInstanceGroupCustomization collectionInstCust = null;
833 if (!instanceGroup.getCollectionInstanceGroupCustomizations().isEmpty()) {
834 for (CollectionResourceInstanceGroupCustomization collectionInstanceGroupTemp : instanceGroup
835 .getCollectionInstanceGroupCustomizations()) {
836 if (collectionInstanceGroupTemp.getModelCustomizationUUID()
837 .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
838 collectionInstCust = collectionInstanceGroupTemp;
842 if (interfaceNetworkQuantityIsAvailableInCollection(collectionInstCust)) {
843 minNetworks = collectionInstCust.getSubInterfaceNetworkQuantity();
846 logger.debug("minNetworks: {}", minNetworks);
847 CollectionNetworkResourceCustomization collectionNetworkResourceCust =
848 getCollectionNetworkResourceCustomization(collectionResourceCustomization, instanceGroup);
849 for (int i = 0; i < minNetworks; i++) {
850 if (collectionNetworkResourceCust != null && collectionInstCust != null) {
851 Resource resource = new Resource(WorkflowType.VIRTUAL_LINK,
852 collectionNetworkResourceCust.getModelCustomizationUUID(), false);
853 resource.setVirtualLinkKey(Integer.toString(i));
854 resourceList.add(resource);
859 private CollectionNetworkResourceCustomization getCollectionNetworkResourceCustomization(
860 CollectionResourceCustomization collectionResourceCustomization, InstanceGroup instanceGroup) {
861 CollectionNetworkResourceCustomization collectionNetworkResourceCust = null;
862 for (CollectionNetworkResourceCustomization collectionNetworkTemp : instanceGroup
863 .getCollectionNetworkResourceCustomizations()) {
864 if (collectionNetworkTemp.getNetworkResourceCustomization().getModelCustomizationUUID()
865 .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
866 collectionNetworkResourceCust = collectionNetworkTemp;
870 return collectionNetworkResourceCust;
873 private boolean collectionResourceCustomizationShouldNotBeProcessed(List<Resource> resourceList,
874 CollectionResourceCustomization collectionResourceCustomization) {
875 if (collectionResourceCustomization == null) {
876 logger.debug("No Network Collection Customization found");
879 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
880 collectionResourceCustomization.getModelCustomizationUUID(), false));
881 logger.debug("Found a network collection");
882 if (collectionResourceCustomization.getCollectionResource() == null) {
883 logger.debug("No Network Collection found. collectionResource is null");
886 if (collectionResourceCustomization.getCollectionResource().getInstanceGroup() == null) {
887 logger.debug("No Instance Group found for network collection.");
890 String toscaNodeType =
891 collectionResourceCustomization.getCollectionResource().getInstanceGroup().getToscaNodeType();
892 if (!toscaNodeTypeHasNetworkCollection(toscaNodeType)) {
893 logger.debug("Instance Group tosca node type does not contain NetworkCollection: {}", toscaNodeType);
899 private boolean interfaceNetworkQuantityIsAvailableInCollection(
900 CollectionResourceInstanceGroupCustomization collectionInstCust) {
901 return collectionInstCust != null && collectionInstCust.getSubInterfaceNetworkQuantity() != null;
904 private boolean toscaNodeTypeHasNetworkCollection(String toscaNodeType) {
905 return toscaNodeType != null && toscaNodeType.contains(NETWORKCOLLECTION);
908 private void traverseNetworkCollectionCustomization(List<Resource> resourceList,
909 org.onap.so.db.catalog.beans.Service service) {
910 if (isNetworkCollectionInTheResourceList(resourceList)) {
913 if (service.getNetworkCustomizations() == null) {
914 logger.debug("No networks were found on this service model");
917 for (int i = 0; i < service.getNetworkCustomizations().size(); i++) {
918 resourceList.add(new Resource(WorkflowType.NETWORK,
919 service.getNetworkCustomizations().get(i).getModelCustomizationUUID(), false));
923 private boolean isNetworkCollectionInTheResourceList(List<Resource> resourceList) {
924 return resourceList.stream().anyMatch(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType());
927 private boolean isVnfCustomizationsInTheService(org.onap.so.db.catalog.beans.Service service) {
928 return !(service.getVnfCustomizations() == null || service.getVnfCustomizations().isEmpty());
931 protected void traverseAAIService(DelegateExecution execution, List<Resource> resourceList, String resourceId,
932 List<Pair<WorkflowType, String>> aaiResourceIds) {
934 ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(resourceId);
935 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
936 bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
937 resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
938 traverseServiceInstanceMSOVnfs(resourceList, aaiResourceIds, serviceInstanceMSO);
939 traverseServiceInstanceMSOPnfs(resourceList, aaiResourceIds, serviceInstanceMSO);
940 if (serviceInstanceMSO.getNetworks() != null) {
941 for (org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network network : serviceInstanceMSO
943 aaiResourceIds.add(new Pair<>(WorkflowType.NETWORK, network.getNetworkId()));
944 resourceList.add(new Resource(WorkflowType.NETWORK, network.getNetworkId(), false));
947 if (serviceInstanceMSO.getCollection() != null) {
948 logger.debug("found networkcollection");
950 .add(new Pair<>(WorkflowType.NETWORKCOLLECTION, serviceInstanceMSO.getCollection().getId()));
951 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
952 serviceInstanceMSO.getCollection().getId(), false));
954 if (serviceInstanceMSO.getConfigurations() != null) {
955 for (Configuration config : serviceInstanceMSO.getConfigurations()) {
956 Optional<org.onap.aai.domain.yang.Configuration> aaiConfig =
957 aaiConfigurationResources.getConfiguration(config.getConfigurationId());
958 if (aaiConfig.isPresent() && aaiConfig.get().getRelationshipList() != null) {
959 for (Relationship relationship : aaiConfig.get().getRelationshipList().getRelationship()) {
960 if (relationship.getRelatedTo().contains("vnfc")
961 || relationship.getRelatedTo().contains("vpn-binding")) {
962 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.getConfigurationId()));
964 new Resource(WorkflowType.CONFIGURATION, config.getConfigurationId(), false));
971 } catch (Exception ex) {
972 logger.error("Exception in traverseAAIService", ex);
973 buildAndThrowException(execution,
974 "Could not find existing Service Instance or related Instances to execute the request on.");
978 private void traverseServiceInstanceMSOVnfs(List<Resource> resourceList,
979 List<Pair<WorkflowType, String>> aaiResourceIds,
980 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO) {
981 if (serviceInstanceMSO.getVnfs() == null) {
984 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
985 aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
986 resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
987 traverseVnfModules(resourceList, aaiResourceIds, vnf);
988 if (vnf.getVolumeGroups() != null) {
989 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf.getVolumeGroups()) {
990 aaiResourceIds.add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
991 resourceList.add(new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
997 private void traverseServiceInstanceMSOPnfs(List<Resource> resourceList,
998 List<Pair<WorkflowType, String>> aaiResourceIds,
999 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO) {
1000 if (serviceInstanceMSO.getPnfs() == null) {
1003 for (org.onap.so.bpmn.servicedecomposition.bbobjects.Pnf pnf : serviceInstanceMSO.getPnfs()) {
1004 aaiResourceIds.add(new Pair<>(WorkflowType.PNF, pnf.getPnfId()));
1005 resourceList.add(new Resource(WorkflowType.PNF, pnf.getPnfId(), false));
1009 private void traverseVnfModules(List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds,
1010 org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf) {
1011 if (vnf.getVfModules() == null) {
1014 for (VfModule vfModule : vnf.getVfModules()) {
1015 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1016 Resource resource = new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false);
1017 resource.setBaseVfModule(vfModule.getModelInfoVfModule().getIsBaseBoolean());
1018 resourceList.add(resource);
1022 private void traverseAAIVnf(DelegateExecution execution, List<Resource> resourceList, String serviceId,
1023 String vnfId, List<Pair<WorkflowType, String>> aaiResourceIds) {
1025 ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(serviceId);
1026 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
1027 bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
1028 resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
1029 if (serviceInstanceMSO.getVnfs() != null) {
1030 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
1031 if (vnf.getVnfId().equals(vnfId)) {
1032 aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
1033 resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
1034 if (vnf.getVfModules() != null) {
1035 for (VfModule vfModule : vnf.getVfModules()) {
1036 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1037 resourceList.add(new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false));
1038 findConfigurationsInsideVfModule(execution, vnf.getVnfId(), vfModule.getVfModuleId(),
1039 resourceList, aaiResourceIds);
1042 if (vnf.getVolumeGroups() != null) {
1043 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
1044 .getVolumeGroups()) {
1046 .add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1048 new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1055 } catch (Exception ex) {
1056 logger.error("Exception in traverseAAIVnf", ex);
1057 buildAndThrowException(execution,
1058 "Could not find existing Vnf or related Instances to execute the request on.");
1062 private void findConfigurationsInsideVfModule(DelegateExecution execution, String vnfId, String vfModuleId,
1063 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds) {
1065 org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
1066 AAIResultWrapper vfModuleWrapper = new AAIResultWrapper(
1067 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiVfModule));
1068 Optional<Relationships> relationshipsOp;
1069 relationshipsOp = vfModuleWrapper.getRelationships();
1070 if (relationshipsOp.isPresent()) {
1071 relationshipsOp = workflowActionUtils.extractRelationshipsVnfc(relationshipsOp.get());
1072 if (relationshipsOp.isPresent()) {
1073 Optional<Configuration> config =
1074 workflowActionUtils.extractRelationshipsConfiguration(relationshipsOp.get());
1075 if (config.isPresent()) {
1076 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.get().getConfigurationId()));
1078 new Resource(WorkflowType.CONFIGURATION, config.get().getConfigurationId(), false));
1082 } catch (Exception ex) {
1083 logger.error("Exception in findConfigurationsInsideVfModule", ex);
1084 buildAndThrowException(execution, "Failed to find Configuration object from the vfModule.");
1088 protected boolean traverseUserParamsService(DelegateExecution execution, List<Resource> resourceList,
1089 ServiceInstancesRequest sIRequest, String requestAction) throws IOException {
1090 boolean foundRelated = false;
1091 boolean foundVfModuleOrVG = false;
1092 String vnfCustomizationUUID = "";
1093 String vfModuleCustomizationUUID = "";
1094 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
1095 List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
1096 for (Map<String, Object> params : userParams) {
1097 if (params.containsKey(USERPARAMSERVICE)) {
1098 ObjectMapper obj = new ObjectMapper();
1099 String input = obj.writeValueAsString(params.get(USERPARAMSERVICE));
1100 Service validate = obj.readValue(input, Service.class);
1102 new Resource(WorkflowType.SERVICE, validate.getModelInfo().getModelVersionId(), false));
1103 if (validate.getResources().getVnfs() != null) {
1104 for (Vnfs vnf : validate.getResources().getVnfs()) {
1105 resourceList.add(new Resource(WorkflowType.VNF,
1106 vnf.getModelInfo().getModelCustomizationId(), false));
1107 foundRelated = true;
1108 if (vnf.getModelInfo() != null && vnf.getModelInfo().getModelCustomizationUuid() != null) {
1109 vnfCustomizationUUID = vnf.getModelInfo().getModelCustomizationUuid();
1111 if (vnf.getVfModules() != null) {
1112 for (VfModules vfModule : vnf.getVfModules()) {
1113 VfModuleCustomization vfModuleCustomization =
1114 catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
1115 vfModule.getModelInfo().getModelCustomizationUuid());
1116 if (vfModuleCustomization != null) {
1118 if (vfModuleCustomization.getVfModule() != null
1119 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
1120 && vfModuleCustomization.getVolumeHeatEnv() != null) {
1121 resourceList.add(new Resource(WorkflowType.VOLUMEGROUP,
1122 vfModuleCustomization.getModelCustomizationUUID(), false));
1123 foundRelated = true;
1124 foundVfModuleOrVG = true;
1127 if (vfModuleCustomization.getVfModule() != null
1128 && vfModuleCustomization.getVfModule().getModuleHeatTemplate() != null
1129 && vfModuleCustomization.getHeatEnvironment() != null) {
1130 foundRelated = true;
1131 foundVfModuleOrVG = true;
1132 Resource resource = new Resource(WorkflowType.VFMODULE,
1133 vfModuleCustomization.getModelCustomizationUUID(), false);
1134 resource.setBaseVfModule(
1135 vfModuleCustomization.getVfModule().getIsBase() != null
1136 && vfModuleCustomization.getVfModule().getIsBase());
1137 resourceList.add(resource);
1138 if (vfModule.getModelInfo() != null
1139 && vfModule.getModelInfo().getModelCustomizationUuid() != null) {
1140 vfModuleCustomizationUUID =
1141 vfModule.getModelInfo().getModelCustomizationUuid();
1143 if (!vnfCustomizationUUID.isEmpty()
1144 && !vfModuleCustomizationUUID.isEmpty()) {
1145 List<CvnfcConfigurationCustomization> configs =
1146 traverseCatalogDbForConfiguration(
1147 validate.getModelInfo().getModelVersionId(),
1148 vnfCustomizationUUID, vfModuleCustomizationUUID);
1149 for (CvnfcConfigurationCustomization config : configs) {
1150 Resource configResource = new Resource(WorkflowType.CONFIGURATION,
1151 config.getConfigurationResource().getModelUUID(), false);
1152 resource.setVnfCustomizationId(
1153 vnf.getModelInfo().getModelCustomizationId());
1154 resource.setVfModuleCustomizationId(
1155 vfModule.getModelInfo().getModelCustomizationId());
1156 resourceList.add(configResource);
1160 if (!foundVfModuleOrVG) {
1161 buildAndThrowException(execution,
1162 "Could not determine if vfModule was a vfModule or volume group. Heat template and Heat env are null");
1169 if (validate.getResources().getPnfs() != null) {
1170 for (Pnfs pnf : validate.getResources().getPnfs()) {
1171 resourceList.add(new Resource(WorkflowType.PNF,
1172 pnf.getModelInfo().getModelCustomizationId(), false));
1173 foundRelated = true;
1176 if (validate.getResources().getNetworks() != null) {
1177 for (Networks network : validate.getResources().getNetworks()) {
1178 resourceList.add(new Resource(WorkflowType.NETWORK,
1179 network.getModelInfo().getModelCustomizationId(), false));
1180 foundRelated = true;
1182 if (requestAction.equals(CREATEINSTANCE)) {
1183 String networkColCustId = queryCatalogDBforNetworkCollection(execution, sIRequest);
1184 if (networkColCustId != null) {
1185 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION, networkColCustId, false));
1186 foundRelated = true;
1194 return foundRelated;
1197 protected List<CvnfcConfigurationCustomization> traverseCatalogDbForConfiguration(String serviceModelUUID,
1198 String vnfCustomizationUUID, String vfModuleCustomizationUUID) {
1199 List<CvnfcConfigurationCustomization> configurations = new ArrayList<>();
1201 List<CvnfcCustomization> cvnfcCustomizations = catalogDbClient.getCvnfcCustomization(serviceModelUUID,
1202 vnfCustomizationUUID, vfModuleCustomizationUUID);
1203 for (CvnfcCustomization cvnfc : cvnfcCustomizations) {
1204 for (CvnfcConfigurationCustomization customization : cvnfc.getCvnfcConfigurationCustomization()) {
1205 if (customization.getConfigurationResource().getToscaNodeType().contains(FABRIC_CONFIGURATION)) {
1206 configurations.add(customization);
1210 logger.debug("found {} fabric configuration(s)", configurations.size());
1211 return configurations;
1212 } catch (Exception ex) {
1213 logger.error("Error in finding configurations", ex);
1214 return configurations;
1218 protected String queryCatalogDBforNetworkCollection(DelegateExecution execution,
1219 ServiceInstancesRequest sIRequest) {
1220 org.onap.so.db.catalog.beans.Service service =
1221 catalogDbClient.getServiceByID(sIRequest.getRequestDetails().getModelInfo().getModelVersionId());
1222 if (service != null) {
1223 CollectionResourceCustomization networkCollection = this.findCatalogNetworkCollection(execution, service);
1224 if (networkCollection != null) {
1225 return networkCollection.getModelCustomizationUUID();
1231 protected WorkflowResourceIds populateResourceIdsFromApiHandler(DelegateExecution execution) {
1232 return WorkflowResourceIdsUtils.getWorkflowResourceIdsFromExecution(execution);
1235 protected Resource extractResourceIdAndTypeFromUri(String uri) {
1236 Pattern patt = Pattern.compile("[vV]\\d+.*?(?:(?:/(?<type>" + SUPPORTEDTYPES
1237 + ")(?:/(?<id>[^/]+))?)(?:/(?<action>[^/]+))?(?:/resume)?)?$");
1238 Matcher m = patt.matcher(uri);
1239 boolean generated = false;
1242 logger.debug("found match on {} : {} ", uri, m);
1243 String type = m.group("type");
1244 String id = m.group("id");
1245 String action = m.group("action");
1247 throw new IllegalArgumentException("Uri could not be parsed. No type found. " + uri);
1249 if (action == null) {
1250 if (type.equals(SERVICE_INSTANCES) && (id == null || "assign".equals(id))) {
1251 id = UUID.randomUUID().toString();
1253 } else if (type.equals(VF_MODULES) && "scaleOut".equals(id)) {
1254 id = UUID.randomUUID().toString();
1258 if (action.matches(SUPPORTEDTYPES)) {
1259 id = UUID.randomUUID().toString();
1264 return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated);
1266 throw new IllegalArgumentException("Uri could not be parsed: " + uri);
1270 protected String validateResourceIdInAAI(String generatedResourceId, WorkflowType type, String instanceName,
1271 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws Exception {
1273 if ("SERVICE".equalsIgnoreCase(type.toString())) {
1274 return validateServiceResourceIdInAAI(generatedResourceId, instanceName, reqDetails);
1275 } else if ("NETWORK".equalsIgnoreCase(type.toString())) {
1276 return validateNetworkResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1277 workflowResourceIds);
1278 } else if ("VNF".equalsIgnoreCase(type.toString())) {
1279 return validateVnfResourceIdInAAI(generatedResourceId, instanceName, reqDetails, workflowResourceIds);
1280 } else if ("VFMODULE".equalsIgnoreCase(type.toString())) {
1281 return validateVfModuleResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1282 workflowResourceIds);
1283 } else if ("VOLUMEGROUP".equalsIgnoreCase(type.toString())) {
1284 return validateVolumeGroupResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1285 workflowResourceIds);
1286 } else if ("CONFIGURATION".equalsIgnoreCase(type.toString())) {
1287 return validateConfigurationResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1288 workflowResourceIds);
1290 return generatedResourceId;
1291 } catch (DuplicateNameException dne) {
1293 } catch (Exception ex) {
1294 logger.error(WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI, ex);
1295 throw new IllegalStateException(
1296 WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI);
1300 protected String convertTypeFromPlural(String type) {
1301 if (!type.matches(SUPPORTEDTYPES)) {
1304 if (type.equals(SERVICE_INSTANCES)) {
1307 return type.substring(0, 1).toUpperCase() + type.substring(1, type.length() - 1);
1312 protected List<ExecuteBuildingBlock> sortExecutionPathByObjectForVlanTagging(List<ExecuteBuildingBlock> orchFlows,
1313 String requestAction) {
1314 List<ExecuteBuildingBlock> sortedOrchFlows = new ArrayList<>();
1315 if (requestAction.equals(CREATEINSTANCE)) {
1316 for (ExecuteBuildingBlock ebb : orchFlows) {
1317 if (ebb.getBuildingBlock().getBpmnFlowName().equals("AssignNetworkBB")) {
1318 String key = ebb.getBuildingBlock().getKey();
1319 boolean isVirtualLink = Boolean.TRUE.equals(ebb.getBuildingBlock().isVirtualLink());
1320 String virtualLinkKey = ebb.getBuildingBlock().getVirtualLinkKey();
1321 sortedOrchFlows.add(ebb);
1322 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1323 if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1324 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1325 sortedOrchFlows.add(ebb2);
1328 if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1329 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1330 sortedOrchFlows.add(ebb2);
1334 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1335 if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1336 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1337 sortedOrchFlows.add(ebb2);
1340 if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1341 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1342 sortedOrchFlows.add(ebb2);
1346 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1347 || ebb.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)) {
1349 } else if (!"".equals(ebb.getBuildingBlock().getBpmnFlowName())) {
1350 sortedOrchFlows.add(ebb);
1353 } else if (requestAction.equals("deleteInstance")) {
1354 for (ExecuteBuildingBlock ebb : orchFlows) {
1355 if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeactivateNetworkBB")) {
1356 sortedOrchFlows.add(ebb);
1357 String key = ebb.getBuildingBlock().getKey();
1358 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1359 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1360 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1361 sortedOrchFlows.add(ebb2);
1365 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1366 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")
1367 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1368 sortedOrchFlows.add(ebb2);
1372 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1373 || ebb.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")) {
1375 } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) {
1376 sortedOrchFlows.add(ebb);
1380 return sortedOrchFlows;
1383 private void addBuildingBlockToExecuteBBList(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
1384 WorkflowType workflowType, OrchestrationFlow orchFlow, String requestId, String apiVersion,
1385 String resourceId, String requestAction, String vnfType, WorkflowResourceIds workflowResourceIds,
1386 RequestDetails requestDetails, boolean isVirtualLink, boolean isConfiguration) {
1388 resourceList.stream().filter(resource -> resource.getResourceType().equals(workflowType))
1389 .forEach(resource -> flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource,
1390 apiVersion, resourceId, requestAction, false, vnfType, workflowResourceIds, requestDetails,
1391 isVirtualLink, resource.getVirtualLinkKey(), null, isConfiguration, null)));
1394 protected List<ExecuteBuildingBlock> buildExecuteBuildingBlockList(List<OrchestrationFlow> orchFlows,
1395 List<Resource> resourceList, String requestId, String apiVersion, String resourceId, String requestAction,
1396 String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1397 boolean replaceVnf) {
1398 List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
1399 for (OrchestrationFlow orchFlow : orchFlows) {
1400 if (orchFlow.getFlowName().contains(SERVICE)) {
1402 workflowResourceIds.setServiceInstanceId(resourceId);
1404 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.SERVICE, orchFlow, requestId,
1405 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1407 } else if (orchFlow.getFlowName().contains(VNF) || (orchFlow.getFlowName().contains(CONTROLLER)
1408 && (VNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1409 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VNF, orchFlow, requestId,
1410 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1412 } else if (orchFlow.getFlowName().contains(PNF)) {
1413 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.PNF, orchFlow, requestId,
1414 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1416 } else if (orchFlow.getFlowName().contains(NETWORK)
1417 && !orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1418 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORK, orchFlow, requestId,
1419 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1421 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VIRTUAL_LINK, orchFlow,
1422 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1424 } else if (orchFlow.getFlowName().contains(VFMODULE) || (orchFlow.getFlowName().contains(CONTROLLER)
1425 && (VFMODULE).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1426 List<Resource> vfModuleResourcesSorted;
1427 if (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE)
1428 || requestAction.equals("activateInstance")) {
1429 vfModuleResourcesSorted = sortVfModulesByBaseFirst(resourceList.stream()
1430 .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1432 vfModuleResourcesSorted = sortVfModulesByBaseLast(resourceList.stream()
1433 .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1435 for (Resource resource : vfModuleResourcesSorted) {
1436 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource, apiVersion, resourceId,
1437 requestAction, false, vnfType, workflowResourceIds, requestDetails, false, null, null,
1440 } else if (orchFlow.getFlowName().contains(VOLUMEGROUP)) {
1441 if (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1442 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)) {
1443 logger.debug("Replacing workflow resource id by volume group id");
1444 resourceId = workflowResourceIds.getVolumeGroupId();
1446 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VOLUMEGROUP, orchFlow,
1447 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1449 } else if (orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1450 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORKCOLLECTION, orchFlow,
1451 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1453 } else if (orchFlow.getFlowName().contains(CONFIGURATION)) {
1454 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.CONFIGURATION, orchFlow,
1455 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1459 .add(buildExecuteBuildingBlock(orchFlow, requestId, null, apiVersion, resourceId, requestAction,
1460 false, vnfType, workflowResourceIds, requestDetails, false, null, null, false, null));
1463 return flowsToExecute;
1466 protected ExecuteBuildingBlock buildExecuteBuildingBlock(OrchestrationFlow orchFlow, String requestId,
1467 Resource resource, String apiVersion, String resourceId, String requestAction, boolean aLaCarte,
1468 String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1469 boolean isVirtualLink, String virtualLinkKey, String vnfcName, boolean isConfiguration,
1470 ReplaceInstanceRelatedInformation replaceInfo) {
1472 BuildingBlock buildingBlock =
1473 new BuildingBlock().setBpmnFlowName(orchFlow.getFlowName()).setMsoId(UUID.randomUUID().toString())
1474 .setIsVirtualLink(isVirtualLink).setVirtualLinkKey(virtualLinkKey)
1475 .setKey(Optional.ofNullable(resource).map(Resource::getResourceId).orElse(""));
1476 Optional.ofNullable(orchFlow.getBpmnAction()).ifPresent(buildingBlock::setBpmnAction);
1477 Optional.ofNullable(orchFlow.getBpmnScope()).ifPresent(buildingBlock::setBpmnScope);
1478 String oldVolumeGroupName = "";
1479 if (replaceInfo != null) {
1480 oldVolumeGroupName = replaceInfo.getOldVolumeGroupName();
1482 if (resource != null
1483 && (orchFlow.getFlowName().contains(VOLUMEGROUP) && (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1484 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)))) {
1485 logger.debug("Setting resourceId to volume group id for volume group flow on replace");
1486 resourceId = workflowResourceIds.getVolumeGroupId();
1489 ExecuteBuildingBlock executeBuildingBlock = new ExecuteBuildingBlock().setApiVersion(apiVersion)
1490 .setaLaCarte(aLaCarte).setRequestAction(requestAction).setResourceId(resourceId).setVnfType(vnfType)
1491 .setWorkflowResourceIds(workflowResourceIds).setRequestId(requestId).setBuildingBlock(buildingBlock)
1492 .setRequestDetails(requestDetails).setOldVolumeGroupName(oldVolumeGroupName);
1494 if (resource != null && (isConfiguration || resource.getResourceType().equals(WorkflowType.CONFIGURATION))) {
1495 ConfigurationResourceKeys configurationResourceKeys = getConfigurationResourceKeys(resource, vnfcName);
1496 executeBuildingBlock.setConfigurationResourceKeys(configurationResourceKeys);
1498 return executeBuildingBlock;
1501 private ConfigurationResourceKeys getConfigurationResourceKeys(Resource resource, String vnfcName) {
1502 ConfigurationResourceKeys configurationResourceKeys = new ConfigurationResourceKeys();
1503 Optional.ofNullable(vnfcName).ifPresent(configurationResourceKeys::setVnfcName);
1504 configurationResourceKeys.setCvnfcCustomizationUUID(resource.getCvnfModuleCustomizationId());
1505 configurationResourceKeys.setVfModuleCustomizationUUID(resource.getVfModuleCustomizationId());
1506 configurationResourceKeys.setVnfResourceCustomizationUUID(resource.getVnfCustomizationId());
1507 return configurationResourceKeys;
1510 protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1511 WorkflowType resourceName, boolean aLaCarte, String cloudOwner) {
1512 return this.queryNorthBoundRequestCatalogDb(execution, requestAction, resourceName, aLaCarte, cloudOwner, "");
1515 protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1516 WorkflowType resourceName, boolean aLaCarte, String cloudOwner, String serviceType) {
1517 List<OrchestrationFlow> listToExecute = new ArrayList<>();
1518 NorthBoundRequest northBoundRequest;
1519 if (serviceType.equalsIgnoreCase(SERVICE_TYPE_TRANSPORT)
1520 || serviceType.equalsIgnoreCase(SERVICE_TYPE_BONDING)) {
1522 catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwnerAndServiceType(
1523 requestAction, resourceName.toString(), aLaCarte, cloudOwner, serviceType);
1525 northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1526 requestAction, resourceName.toString(), aLaCarte, cloudOwner);
1528 if (northBoundRequest == null) {
1529 northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1530 requestAction, resourceName.toString(), aLaCarte, CLOUD_OWNER);
1532 if (northBoundRequest == null) {
1533 buildAndThrowException(execution, String.format("The request: %s %s %s is not supported by GR_API.",
1534 (aLaCarte ? "AlaCarte" : "Macro"), resourceName, requestAction));
1536 if (northBoundRequest.getIsToplevelflow() != null) {
1537 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, northBoundRequest.getIsToplevelflow());
1539 List<OrchestrationFlow> flows = northBoundRequest.getOrchestrationFlowList();
1541 flows = new ArrayList<>();
1542 for (OrchestrationFlow flow : flows) {
1543 if (!flow.getFlowName().contains("BB") && !flow.getFlowName().contains("Activity")) {
1544 List<OrchestrationFlow> macroQueryFlows =
1545 catalogDbClient.getOrchestrationFlowByAction(flow.getFlowName());
1546 listToExecute.addAll(macroQueryFlows);
1548 listToExecute.add(flow);
1552 return listToExecute;
1555 protected void buildAndThrowException(DelegateExecution execution, String msg, Exception ex) {
1556 logger.error(msg, ex);
1557 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg + ex.getMessage());
1558 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg + ex.getMessage());
1561 protected void buildAndThrowException(DelegateExecution execution, String msg) {
1563 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg);
1564 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
1567 public void handleRuntimeException(DelegateExecution execution) {
1568 StringBuilder wfeExpMsg = new StringBuilder("Runtime error ");
1569 String runtimeErrorMessage;
1571 String javaExpMsg = (String) execution.getVariable("BPMN_javaExpMsg");
1572 if (javaExpMsg != null && !javaExpMsg.isEmpty()) {
1573 wfeExpMsg.append(": ").append(javaExpMsg);
1575 runtimeErrorMessage = wfeExpMsg.toString();
1576 logger.error(runtimeErrorMessage);
1577 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, runtimeErrorMessage);
1578 } catch (Exception e) {
1579 logger.error("Runtime error", e);
1580 // if runtime message was mulformed
1581 runtimeErrorMessage = "Runtime error";
1583 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, runtimeErrorMessage);
1586 protected boolean isUriResume(String uri) {
1587 return uri.endsWith("/resume");
1590 protected boolean isRequestMacroServiceResume(boolean aLaCarte, WorkflowType resourceType, String requestAction,
1591 String serviceInstanceId) {
1592 return (!aLaCarte && resourceType == WorkflowType.SERVICE
1593 && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE) || requestAction.equalsIgnoreCase(CREATEINSTANCE))
1594 && (serviceInstanceId != null && serviceInstanceId.trim().length() > 1)
1595 && (bbInputSetupUtils.getAAIServiceInstanceById(serviceInstanceId) != null));
1598 protected String validateServiceResourceIdInAAI(String generatedResourceId, String instanceName,
1599 RequestDetails reqDetails) throws DuplicateNameException {
1600 String globalCustomerId = reqDetails.getSubscriberInfo().getGlobalSubscriberId();
1601 String serviceType = reqDetails.getRequestParameters().getSubscriptionServiceType();
1602 if (instanceName != null) {
1603 Optional<ServiceInstance> serviceInstanceAAI =
1604 bbInputSetupUtils.getAAIServiceInstanceByName(globalCustomerId, serviceType, instanceName);
1605 if (serviceInstanceAAI.isPresent()) {
1606 if (serviceInstanceAAI.get().getModelVersionId()
1607 .equalsIgnoreCase(reqDetails.getModelInfo().getModelVersionId())) {
1608 return serviceInstanceAAI.get().getServiceInstanceId();
1610 throw new DuplicateNameException(SERVICE_INSTANCE, String.format(NAME_EXISTS_WITH_DIFF_VERSION_ID,
1611 instanceName, reqDetails.getModelInfo().getModelVersionId()));
1614 ServiceInstances aaiServiceInstances =
1615 bbInputSetupUtils.getAAIServiceInstancesGloballyByName(instanceName);
1616 if (aaiServiceInstances != null) {
1617 if (aaiServiceInstances.getServiceInstance() != null
1618 && !aaiServiceInstances.getServiceInstance().isEmpty()) {
1619 if (aaiServiceInstances.getServiceInstance().size() > 1) {
1620 throw new DuplicateNameException(SERVICE_INSTANCE,
1621 String.format(NAME_EXISTS_MULTIPLE, instanceName));
1623 ServiceInstance si = aaiServiceInstances.getServiceInstance().stream().findFirst().get();
1624 Map<String, String> keys =
1625 bbInputSetupUtils.getURIKeysFromServiceInstance(si.getServiceInstanceId());
1627 throw new DuplicateNameException(SERVICE_INSTANCE, String.format(
1628 NAME_EXISTS_WITH_DIFF_COMBINATION, instanceName,
1629 keys.get(AAIFluentTypeBuilder.Types.CUSTOMER.getUriParams().globalCustomerId),
1631 AAIFluentTypeBuilder.Types.SERVICE_SUBSCRIPTION.getUriParams().serviceType),
1632 si.getModelVersionId()));
1638 return generatedResourceId;
1641 protected String validateNetworkResourceIdInAAI(String generatedResourceId, String instanceName,
1642 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1643 throws DuplicateNameException, MultipleObjectsFoundException {
1644 Optional<L3Network> network = bbInputSetupUtils
1645 .getRelatedNetworkByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1646 if (network.isPresent()) {
1647 if (network.get().getModelCustomizationId()
1648 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1649 return network.get().getNetworkId();
1651 throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1652 instanceName, network.get().getModelCustomizationId()));
1655 if (bbInputSetupUtils.existsAAINetworksGloballyByName(instanceName)) {
1656 throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName,
1657 workflowResourceIds.getServiceInstanceId()));
1659 return generatedResourceId;
1662 protected String validateVnfResourceIdInAAI(String generatedResourceId, String instanceName,
1663 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1664 Optional<GenericVnf> vnf = bbInputSetupUtils
1665 .getRelatedVnfByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1666 if (vnf.isPresent()) {
1667 if (vnf.get().getModelCustomizationId()
1668 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1669 return vnf.get().getVnfId();
1671 throw new DuplicateNameException("generic-vnf", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1672 instanceName, vnf.get().getModelCustomizationId()));
1675 GenericVnfs vnfs = bbInputSetupUtils.getAAIVnfsGloballyByName(instanceName);
1677 throw new DuplicateNameException("generic-vnf",
1678 String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName, vnfs.getGenericVnf().get(0).getVnfId()));
1680 return generatedResourceId;
1683 protected String validateVfModuleResourceIdInAAI(String generatedResourceId, String instanceName,
1684 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1685 GenericVnf vnf = bbInputSetupUtils.getAAIGenericVnf(workflowResourceIds.getVnfId());
1686 if (vnf != null && vnf.getVfModules() != null) {
1687 for (org.onap.aai.domain.yang.VfModule vfModule : vnf.getVfModules().getVfModule()) {
1688 if (vfModule.getVfModuleName().equalsIgnoreCase(instanceName)) {
1689 if (vfModule.getModelCustomizationId()
1690 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1691 return vfModule.getVfModuleId();
1693 throw new DuplicateNameException("vfModule",
1694 String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID, instanceName,
1695 reqDetails.getModelInfo().getModelCustomizationId()));
1700 if (bbInputSetupUtils.existsAAIVfModuleGloballyByName(instanceName)) {
1701 throw new DuplicateNameException("vfModule", instanceName);
1703 return generatedResourceId;
1706 protected String validateVolumeGroupResourceIdInAAI(String generatedResourceId, String instanceName,
1707 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1708 Optional<VolumeGroup> volumeGroup =
1709 bbInputSetupUtils.getRelatedVolumeGroupByNameFromVnf(workflowResourceIds.getVnfId(), instanceName);
1710 if (volumeGroup.isPresent()) {
1711 if (volumeGroup.get().getVfModuleModelCustomizationId()
1712 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1713 return volumeGroup.get().getVolumeGroupId();
1715 throw new DuplicateNameException("volumeGroup", volumeGroup.get().getVolumeGroupName());
1718 if (bbInputSetupUtils.existsAAIVolumeGroupGloballyByName(instanceName)) {
1719 throw new DuplicateNameException("volumeGroup", instanceName);
1721 return generatedResourceId;
1724 protected String validateConfigurationResourceIdInAAI(String generatedResourceId, String instanceName,
1725 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1726 Optional<org.onap.aai.domain.yang.Configuration> configuration =
1727 bbInputSetupUtils.getRelatedConfigurationByNameFromServiceInstance(
1728 workflowResourceIds.getServiceInstanceId(), instanceName);
1729 if (configuration.isPresent()) {
1730 if (configuration.get().getModelCustomizationId()
1731 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1732 return configuration.get().getConfigurationId();
1734 throw new DuplicateNameException("configuration", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1735 instanceName, configuration.get().getConfigurationId()));
1738 if (bbInputSetupUtils.existsAAIConfigurationGloballyByName(instanceName)) {
1739 throw new DuplicateNameException("configuration", instanceName);
1741 return generatedResourceId;
1744 private void fillExecution(DelegateExecution execution, boolean suppressRollback, String resourceId,
1745 WorkflowType resourceType) {
1746 execution.setVariable("sentSyncResponse", false);
1747 execution.setVariable("homing", false);
1748 execution.setVariable("calledHoming", false);
1749 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, true);
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;