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.VfModuleCustomization;
79 import org.onap.so.db.catalog.beans.macro.NorthBoundRequest;
80 import org.onap.so.db.catalog.beans.macro.OrchestrationFlow;
81 import org.onap.so.db.catalog.client.CatalogDbClient;
82 import org.onap.so.serviceinstancebeans.CloudConfiguration;
83 import org.onap.so.serviceinstancebeans.ModelInfo;
84 import org.onap.so.serviceinstancebeans.ModelType;
85 import org.onap.so.serviceinstancebeans.Networks;
86 import org.onap.so.serviceinstancebeans.Pnfs;
87 import org.onap.so.serviceinstancebeans.RelatedInstance;
88 import org.onap.so.serviceinstancebeans.RequestDetails;
89 import org.onap.so.serviceinstancebeans.Service;
90 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
91 import org.onap.so.serviceinstancebeans.VfModules;
92 import org.onap.so.serviceinstancebeans.Vnfs;
93 import org.slf4j.Logger;
94 import org.slf4j.LoggerFactory;
95 import org.springframework.beans.factory.annotation.Autowired;
96 import org.springframework.core.env.Environment;
97 import org.springframework.stereotype.Component;
98 import org.springframework.util.CollectionUtils;
99 import com.fasterxml.jackson.core.JsonProcessingException;
100 import com.fasterxml.jackson.databind.ObjectMapper;
103 public class WorkflowAction {
105 private static final String WORKFLOW_ACTION_ERROR_MESSAGE = "WorkflowActionErrorMessage";
106 private static final String SERVICE_INSTANCES = "serviceInstances";
107 private static final String SERVICE_INSTANCE = "serviceInstance";
108 private static final String VF_MODULES = "vfModules";
109 private static final String WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI =
110 "WorkflowAction was unable to verify if the instance name already exist in AAI.";
111 private static final String VNF_TYPE = "vnfType";
112 private static final String SERVICE = "Service";
113 private static final String VNF = "Vnf";
114 private static final String PNF = "Pnf";
115 private static final String VFMODULE = "VfModule";
116 private static final String VOLUMEGROUP = "VolumeGroup";
117 private static final String NETWORK = "Network";
118 private static final String NETWORKCOLLECTION = "NetworkCollection";
119 private static final String CONFIGURATION = "Configuration";
120 private static final String ASSIGNINSTANCE = "assignInstance";
121 private static final String CREATEINSTANCE = "createInstance";
122 private static final String REPLACEINSTANCE = "replaceInstance";
123 private static final String REPLACEINSTANCERETAINASSIGNMENTS = "replaceInstanceRetainAssignments";
124 private static final String USERPARAMSERVICE = "service";
125 private static final String SUPPORTEDTYPES =
126 "vnfs|vfModules|networks|networkCollections|volumeGroups|serviceInstances|instanceGroups";
127 private static final String HOMINGSOLUTION = "Homing_Solution";
128 private static final String FABRIC_CONFIGURATION = "FabricConfiguration";
129 private static final String SERVICE_TYPE_TRANSPORT = "TRANSPORT";
130 private static final String SERVICE_TYPE_BONDING = "BONDING";
131 private static final String CLOUD_OWNER = "DEFAULT";
132 private static final Logger logger = LoggerFactory.getLogger(WorkflowAction.class);
133 private static final String NAME_EXISTS_WITH_DIFF_VERSION_ID = "(%s) and different version id (%s)";
134 private static final String NAME_EXISTS_MULTIPLE =
135 "(%s) and multiple combination of model-version-id + service-type + global-customer-id";
136 private static final String NAME_EXISTS_WITH_DIFF_COMBINATION =
137 "(%s) and global-customer-id (%s), service-type (%s), model-version-id (%s)";
138 private static final String NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID =
139 "(%s), same parent and different customization id (%s)";
140 private static final String NAME_EXISTS_WITH_DIFF_PARENT = "(%s) id (%s) and different parent relationship";
141 private static final String CREATENETWORKBB = "CreateNetworkBB";
142 private static final String ACTIVATENETWORKBB = "ActivateNetworkBB";
143 private static final String VOLUMEGROUP_DELETE_PATTERN = "(Un|De)(.*)Volume(.*)";
144 private static final String VOLUMEGROUP_CREATE_PATTERN = "(A|C)(.*)Volume(.*)";
145 private static final String CONTROLLER = "Controller";
148 protected BBInputSetup bbInputSetup;
150 protected BBInputSetupUtils bbInputSetupUtils;
152 private ExceptionBuilder exceptionBuilder;
154 private CatalogDbClient catalogDbClient;
156 private AAIConfigurationResources aaiConfigurationResources;
158 private WorkflowActionExtractResourcesAAI workflowActionUtils;
160 private VrfValidation vrfValidation;
163 private Environment environment;
164 private String defaultCloudOwner = "org.onap.so.cloud-owner";
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);
224 if (isConfiguration(orchFlows) && !requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
225 ConfigBuildingBlocksDataObject configBuildingBlocksDataObject =
226 new ConfigBuildingBlocksDataObject();
227 configBuildingBlocksDataObject.setsIRequest(sIRequest);
228 configBuildingBlocksDataObject.setOrchFlows(orchFlows);
229 configBuildingBlocksDataObject.setRequestId(requestId);
230 configBuildingBlocksDataObject.setResourceKey(resourceKey);
231 configBuildingBlocksDataObject.setApiVersion(apiVersion);
232 configBuildingBlocksDataObject.setResourceId(resourceId);
233 configBuildingBlocksDataObject.setRequestAction(requestAction);
234 configBuildingBlocksDataObject.setaLaCarte(true);
235 configBuildingBlocksDataObject.setVnfType(vnfType);
236 configBuildingBlocksDataObject.setWorkflowResourceIds(workflowResourceIds);
237 configBuildingBlocksDataObject.setRequestDetails(requestDetails);
238 configBuildingBlocksDataObject.setExecution(execution);
240 List<ExecuteBuildingBlock> configBuildingBlocks =
241 getConfigBuildingBlocks(configBuildingBlocksDataObject);
243 flowsToExecute.addAll(configBuildingBlocks);
245 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().contains(FABRIC_CONFIGURATION))
246 .collect(Collectors.toList());
248 if ((requestAction.equalsIgnoreCase(REPLACEINSTANCE)
249 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS))
250 && resourceType.equals(WorkflowType.VFMODULE)) {
251 logger.debug("Build a BB list for replacing BB modules");
253 ConfigBuildingBlocksDataObject configBuildingBlocksDataObject =
254 new ConfigBuildingBlocksDataObject();
255 configBuildingBlocksDataObject.setsIRequest(sIRequest);
256 configBuildingBlocksDataObject.setOrchFlows(orchFlows);
257 configBuildingBlocksDataObject.setRequestId(requestId);
258 configBuildingBlocksDataObject.setResourceKey(resourceKey);
259 configBuildingBlocksDataObject.setApiVersion(apiVersion);
260 configBuildingBlocksDataObject.setResourceId(resourceId);
261 configBuildingBlocksDataObject.setRequestAction(requestAction);
262 configBuildingBlocksDataObject.setaLaCarte(true);
263 configBuildingBlocksDataObject.setVnfType(vnfType);
264 configBuildingBlocksDataObject.setWorkflowResourceIds(workflowResourceIds);
265 configBuildingBlocksDataObject.setRequestDetails(requestDetails);
266 configBuildingBlocksDataObject.setExecution(execution);
268 orchFlows = getVfModuleReplaceBuildingBlocks(configBuildingBlocksDataObject);
270 for (OrchestrationFlow orchFlow : orchFlows) {
271 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, resourceKey,
272 apiVersion, resourceId, requestAction, true, vnfType, workflowResourceIds,
273 requestDetails, false, null, null, false);
274 flowsToExecute.add(ebb);
277 boolean foundRelated = false;
278 boolean containsService = false;
279 List<Resource> resourceList = new ArrayList<>();
280 List<Pair<WorkflowType, String>> aaiResourceIds = new ArrayList<>();
281 if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(ASSIGNINSTANCE)) {
282 // SERVICE-MACRO-ASSIGN will always get user params with a
284 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
285 List<Map<String, Object>> userParams =
286 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
287 for (Map<String, Object> params : userParams) {
288 if (params.containsKey(USERPARAMSERVICE)) {
289 containsService = true;
292 if (containsService) {
293 traverseUserParamsService(execution, resourceList, sIRequest, requestAction);
296 buildAndThrowException(execution,
297 "Service-Macro-Assign request details must contain user params with a service");
299 } else if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
300 // SERVICE-MACRO-CREATE will get user params with a service,
301 // a service with a network, a service with a
302 // networkcollection, OR an empty service.
303 // If user params is just a service or null and macro
304 // queries the SI and finds a VNF, macro fails.
306 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
307 List<Map<String, Object>> userParams =
308 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
309 for (Map<String, Object> params : userParams) {
310 if (params.containsKey(USERPARAMSERVICE)) {
311 containsService = true;
315 if (containsService) {
316 foundRelated = traverseUserParamsService(execution, resourceList, sIRequest, requestAction);
319 traverseCatalogDbService(execution, sIRequest, resourceList, aaiResourceIds);
321 } else if (resourceType == WorkflowType.SERVICE
322 && ("activateInstance".equalsIgnoreCase(requestAction)
323 || "unassignInstance".equalsIgnoreCase(requestAction)
324 || "deleteInstance".equalsIgnoreCase(requestAction)
325 || requestAction.equalsIgnoreCase("activate" + FABRIC_CONFIGURATION))) {
326 // SERVICE-MACRO-ACTIVATE, SERVICE-MACRO-UNASSIGN, and
327 // SERVICE-MACRO-DELETE
328 // Will never get user params with service, macro will have
329 // to query the SI in AAI to find related instances.
330 traverseAAIService(execution, resourceList, resourceId, aaiResourceIds);
331 } else if (resourceType == WorkflowType.SERVICE
332 && "deactivateInstance".equalsIgnoreCase(requestAction)) {
333 resourceList.add(new Resource(WorkflowType.SERVICE, "", false));
334 } else if (resourceType == WorkflowType.VNF && ("replaceInstance".equalsIgnoreCase(requestAction)
335 || ("recreateInstance".equalsIgnoreCase(requestAction)))) {
336 traverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
337 workflowResourceIds.getVnfId(), aaiResourceIds);
339 buildAndThrowException(execution, "Current Macro Request is not supported");
341 String foundObjects = "";
342 for (WorkflowType type : WorkflowType.values()) {
343 foundObjects = foundObjects + type + " - " + resourceList.stream()
344 .filter(x -> type.equals(x.getResourceType())).collect(Collectors.toList()).size()
347 logger.info("Found {}", foundObjects);
349 if (orchFlows == null || orchFlows.isEmpty()) {
350 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, isALaCarte,
351 cloudOwner, serviceType);
353 boolean vnfReplace = false;
354 if (resourceType.equals(WorkflowType.VNF) && ("replaceInstance".equalsIgnoreCase(requestAction)
355 || "replaceInstanceRetainAssignments".equalsIgnoreCase(requestAction))) {
358 flowsToExecute = buildExecuteBuildingBlockList(orchFlows, resourceList, requestId, apiVersion,
359 resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, vnfReplace);
360 if (isNetworkCollectionInTheResourceList(resourceList)) {
361 logger.info("Sorting for Vlan Tagging");
362 flowsToExecute = sortExecutionPathByObjectForVlanTagging(flowsToExecute, requestAction);
364 // By default, enable homing at VNF level for CREATEINSTANCE and ASSIGNINSTANCE
365 if (resourceType == WorkflowType.SERVICE
366 && (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE))
367 && !resourceList.stream().filter(x -> WorkflowType.VNF.equals(x.getResourceType()))
368 .collect(Collectors.toList()).isEmpty()) {
369 execution.setVariable("homing", true);
370 execution.setVariable("calledHoming", false);
372 if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE)
373 || requestAction.equalsIgnoreCase(CREATEINSTANCE))) {
374 generateResourceIds(flowsToExecute, resourceList, serviceInstanceId);
376 updateResourceIdsFromAAITraversal(flowsToExecute, resourceList, aaiResourceIds,
381 // If the user set "Homing_Solution" to "none", disable homing, else if "Homing_Solution" is specified,
383 if (sIRequest.getRequestDetails().getRequestParameters() != null
384 && sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
385 List<Map<String, Object>> userParams =
386 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
387 for (Map<String, Object> params : userParams) {
388 if (params.containsKey(HOMINGSOLUTION)) {
389 if ("none".equals(params.get(HOMINGSOLUTION))) {
390 execution.setVariable("homing", false);
392 execution.setVariable("homing", true);
398 if (CollectionUtils.isEmpty(flowsToExecute)) {
399 throw new IllegalStateException("Macro did not come up with a valid execution path.");
402 List<String> flowNames = new ArrayList<>();
403 logger.info("List of BuildingBlocks to execute:");
405 flowsToExecute.forEach(ebb -> {
406 logger.info(ebb.getBuildingBlock().getBpmnFlowName());
407 flowNames.add(ebb.getBuildingBlock().getBpmnFlowName());
411 bbInputSetupUtils.persistFlowExecutionPath(requestId, flowsToExecute);
413 execution.setVariable("flowNames", flowNames);
414 execution.setVariable(BBConstants.G_CURRENT_SEQUENCE, 0);
415 execution.setVariable("retryCount", 0);
416 execution.setVariable("isRollback", false);
417 execution.setVariable("flowsToExecute", flowsToExecute);
418 execution.setVariable("isRollbackComplete", false);
420 } catch (Exception ex) {
421 if (!(execution.hasVariable("WorkflowException")
422 || execution.hasVariable("WorkflowExceptionExceptionMessage"))) {
423 buildAndThrowException(execution, "Exception while setting execution list. ", ex);
430 private Resource getResourceKey(ServiceInstancesRequest sIRequest, WorkflowType resourceType) {
431 String resourceId = "";
432 ModelInfo modelInfo = sIRequest.getRequestDetails().getModelInfo();
433 if (modelInfo != null) {
434 if (modelInfo.getModelType().equals(ModelType.service)) {
435 resourceId = modelInfo.getModelVersionId();
437 resourceId = modelInfo.getModelCustomizationId();
440 return new Resource(resourceType, resourceId, true);
443 private String getCloudOwner(CloudConfiguration cloudConfiguration) {
444 if (cloudConfiguration != null && cloudConfiguration.getCloudOwner() != null) {
445 return cloudConfiguration.getCloudOwner();
447 logger.warn("cloud owner value not found in request details, it will be set as default");
448 return environment.getProperty(defaultCloudOwner);
451 protected <T> List<T> getRelatedResourcesInVfModule(String vnfId, String vfModuleId, Class<T> resultClass,
452 AAIObjectType type) {
453 List<T> vnfcs = new ArrayList<>();
454 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VF_MODULE, vnfId, vfModuleId);
455 AAIResultWrapper vfModuleResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
456 Optional<Relationships> relationshipsOp = vfModuleResultsWrapper.getRelationships();
457 if (!relationshipsOp.isPresent()) {
458 logger.debug("No relationships were found for vfModule in AAI");
460 Relationships relationships = relationshipsOp.get();
461 List<AAIResultWrapper> vnfcResultWrappers = relationships.getByType(type);
462 for (AAIResultWrapper vnfcResultWrapper : vnfcResultWrappers) {
463 Optional<T> vnfcOp = vnfcResultWrapper.asBean(resultClass);
464 vnfcOp.ifPresent(vnfcs::add);
470 protected <T> List<T> getRelatedResourcesInVnfc(Vnfc vnfc, Class<T> resultClass, AAIObjectType type) {
472 List<T> configurations = new ArrayList<>();
473 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VNFC, vnfc.getVnfcName());
474 AAIResultWrapper vnfcResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
475 Optional<Relationships> relationshipsOp = vnfcResultsWrapper.getRelationships();
476 if (!relationshipsOp.isPresent()) {
477 logger.debug("No relationships were found for VNFC in AAI");
479 Relationships relationships = relationshipsOp.get();
480 List<AAIResultWrapper> configurationResultWrappers =
481 this.getResultWrappersFromRelationships(relationships, type);
482 for (AAIResultWrapper configurationResultWrapper : configurationResultWrappers) {
483 Optional<T> configurationOp = configurationResultWrapper.asBean(resultClass);
484 configurationOp.ifPresent(configurations::add);
487 return configurations;
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 List<org.onap.aai.domain.yang.Configuration> configurations = getRelatedResourcesInVnfc(vnfc,
530 org.onap.aai.domain.yang.Configuration.class, AAIObjectType.CONFIGURATION);
531 if (configurations.size() > 1) {
532 String multipleRelationshipsError =
533 "Multiple relationships exist from VNFC " + vnfc.getVnfcName() + " to Configurations";
534 buildAndThrowException(dataObj.getExecution(), "Exception in getConfigBuildingBlock: ",
535 new Exception(multipleRelationshipsError));
537 for (org.onap.aai.domain.yang.Configuration configuration : configurations) {
538 dataObj.getWorkflowResourceIds().setConfigurationId(configuration.getConfigurationId());
539 for (OrchestrationFlow orchFlow : result) {
540 dataObj.getResourceKey().setVfModuleCustomizationId(vfModuleCustomizationUUID);
541 dataObj.getResourceKey().setCvnfModuleCustomizationId(vnfc.getModelCustomizationId());
542 dataObj.getResourceKey().setVnfCustomizationId(vnfCustomizationUUID);
543 String vnfcName = getVnfcNameForConfiguration(configuration);
544 if (vnfcName == null || vnfcName.isEmpty()) {
545 buildAndThrowException(dataObj.getExecution(), "Exception in create execution list "
546 + ": VnfcName does not exist or is null while there is a configuration for the vfModule",
547 new Exception("Vnfc and Configuration do not match"));
549 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, dataObj.getRequestId(),
550 dataObj.getResourceKey(), dataObj.getApiVersion(), dataObj.getResourceId(),
551 dataObj.getRequestAction(), dataObj.isaLaCarte(), dataObj.getVnfType(),
552 dataObj.getWorkflowResourceIds(), dataObj.getRequestDetails(), false, null, vnfcName, true);
553 flowsToExecuteConfigs.add(ebb);
557 return flowsToExecuteConfigs;
560 protected List<OrchestrationFlow> getVfModuleReplaceBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
563 String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
564 String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
566 logger.debug("BUILDING REPLACE LIST");
568 boolean volumeGroupExisted = false;
569 boolean volumeGroupWillExist = false;
570 boolean keepVolumeGroup = false;
572 boolean rebuildVolumeGroups = false;
573 if (dataObj.getRequestDetails().getRequestParameters() != null
574 && dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups() != null) {
575 rebuildVolumeGroups =
576 dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups().booleanValue();
579 Optional<VolumeGroup> volumeGroupFromVfModule =
580 bbInputSetupUtils.getRelatedVolumeGroupFromVfModule(vnfId, vfModuleId);
581 if (volumeGroupFromVfModule.isPresent()) {
582 String volumeGroupId = volumeGroupFromVfModule.get().getVolumeGroupId();
583 logger.debug("Volume group id of the existing volume group is: " + volumeGroupId);
584 volumeGroupExisted = true;
585 dataObj.getWorkflowResourceIds().setVolumeGroupId(volumeGroupId);
588 List<OrchestrationFlow> orchFlows = dataObj.getOrchFlows();
589 VfModuleCustomization vfModuleCustomization = catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
590 dataObj.getRequestDetails().getModelInfo().getModelCustomizationUuid());
591 if (vfModuleCustomization != null && vfModuleCustomization.getVfModule() != null
592 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
593 && vfModuleCustomization.getVolumeHeatEnv() != null) {
594 volumeGroupWillExist = true;
595 if (!volumeGroupExisted) {
596 String newVolumeGroupId = UUID.randomUUID().toString();
597 dataObj.getWorkflowResourceIds().setVolumeGroupId(newVolumeGroupId);
598 logger.debug("newVolumeGroupId: " + newVolumeGroupId);
602 if (volumeGroupExisted && volumeGroupWillExist && !rebuildVolumeGroups) {
603 keepVolumeGroup = true;
606 if (!volumeGroupExisted || keepVolumeGroup) {
607 logger.debug("Filtering out deletion of volume groups");
608 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_DELETE_PATTERN))
609 .collect(Collectors.toList());
611 if (!volumeGroupWillExist || keepVolumeGroup) {
612 logger.debug("Filtering out creation of volume groups");
613 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_CREATE_PATTERN))
614 .collect(Collectors.toList());
620 protected String getVnfcNameForConfiguration(org.onap.aai.domain.yang.Configuration configuration) {
621 AAIResultWrapper wrapper = new AAIResultWrapper(configuration);
622 Optional<Relationships> relationshipsOp = wrapper.getRelationships();
623 if (!relationshipsOp.isPresent()) {
624 logger.debug("No relationships were found for Configuration in AAI");
627 Relationships relationships = relationshipsOp.get();
628 List<AAIResultWrapper> vnfcResultWrappers = relationships.getByType(AAIObjectType.VNFC);
629 if (vnfcResultWrappers.size() > 1 || vnfcResultWrappers.isEmpty()) {
630 logger.debug("Too many vnfcs or no vnfc found that are related to configuration");
632 Optional<Vnfc> vnfcOp = vnfcResultWrappers.get(0).asBean(Vnfc.class);
633 return vnfcOp.map(Vnfc::getVnfcName).orElse(null);
637 protected List<Resource> sortVfModulesByBaseFirst(List<Resource> vfModuleResources) {
639 for (Resource resource : vfModuleResources) {
640 if (resource.isBaseVfModule()) {
641 Collections.swap(vfModuleResources, 0, count);
646 return vfModuleResources;
649 protected List<Resource> sortVfModulesByBaseLast(List<Resource> vfModuleResources) {
651 for (Resource resource : vfModuleResources) {
652 if (resource.isBaseVfModule()) {
653 Collections.swap(vfModuleResources, vfModuleResources.size() - 1, count);
658 return vfModuleResources;
661 private void updateResourceIdsFromAAITraversal(List<ExecuteBuildingBlock> flowsToExecute,
662 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds, String serviceInstanceId) {
663 for (Pair<WorkflowType, String> pair : aaiResourceIds) {
664 logger.debug(pair.getValue0() + ", " + pair.getValue1());
667 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE)).forEach(type -> {
668 resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
669 .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
670 retrieveAAIResourceId(aaiResourceIds, type), null, serviceInstanceId));
674 private String retrieveAAIResourceId(List<Pair<WorkflowType, String>> aaiResourceIds, WorkflowType resource) {
676 for (int i = 0; i < aaiResourceIds.size(); i++) {
677 if (aaiResourceIds.get(i).getValue0() == resource) {
678 id = aaiResourceIds.get(i).getValue1();
679 aaiResourceIds.remove(i);
686 private void generateResourceIds(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
687 String serviceInstanceId) {
688 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE)).forEach(type -> {
689 resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
690 .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(), null,
691 resource.getVirtualLinkKey(), serviceInstanceId));
695 protected void updateWorkflowResourceIds(List<ExecuteBuildingBlock> flowsToExecute, WorkflowType resourceType,
696 String key, String id, String virtualLinkKey, String serviceInstanceId) {
697 String resourceId = id;
698 if (resourceId == null) {
699 resourceId = UUID.randomUUID().toString();
701 for (ExecuteBuildingBlock ebb : flowsToExecute) {
702 if (key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey()) && (ebb.getBuildingBlock()
703 .getBpmnFlowName().contains(resourceType.toString())
704 || (ebb.getBuildingBlock().getBpmnFlowName().contains(CONTROLLER)
705 && ebb.getBuildingBlock().getBpmnScope().equalsIgnoreCase(resourceType.toString())))) {
706 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
707 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
708 WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, resourceType, resourceId);
709 ebb.setWorkflowResourceIds(workflowResourceIds);
711 if (virtualLinkKey != null && ebb.getBuildingBlock().isVirtualLink()
712 && virtualLinkKey.equalsIgnoreCase(ebb.getBuildingBlock().getVirtualLinkKey())) {
713 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
714 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
715 workflowResourceIds.setNetworkId(resourceId);
716 ebb.setWorkflowResourceIds(workflowResourceIds);
721 protected CollectionResourceCustomization findCatalogNetworkCollection(DelegateExecution execution,
722 org.onap.so.db.catalog.beans.Service service) {
723 CollectionResourceCustomization networkCollection = null;
725 for (CollectionResourceCustomization collectionCust : service.getCollectionResourceCustomizations()) {
726 if (catalogDbClient.getNetworkCollectionResourceCustomizationByID(
727 collectionCust.getModelCustomizationUUID()) != null) {
728 networkCollection = collectionCust;
734 } else if (count > 1) {
735 buildAndThrowException(execution,
736 "Found multiple Network Collections in the Service model, only one per Service is supported.");
738 return networkCollection;
741 protected void traverseCatalogDbService(DelegateExecution execution, ServiceInstancesRequest sIRequest,
742 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds)
743 throws JsonProcessingException, VrfBondingServiceException {
744 String modelUUID = sIRequest.getRequestDetails().getModelInfo().getModelVersionId();
745 org.onap.so.db.catalog.beans.Service service = catalogDbClient.getServiceByID(modelUUID);
746 if (service == null) {
747 buildAndThrowException(execution, "Could not find the service model in catalog db.");
749 resourceList.add(new Resource(WorkflowType.SERVICE, service.getModelUUID(), false));
750 RelatedInstance relatedVpnBinding =
751 bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.vpnBinding);
752 RelatedInstance relatedLocalNetwork =
753 bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.network);
754 if (relatedVpnBinding != null && relatedLocalNetwork != null) {
755 traverseVrfConfiguration(aaiResourceIds, resourceList, service, relatedVpnBinding, relatedLocalNetwork);
757 traverseNetworkCollection(execution, resourceList, service);
762 protected void traverseVrfConfiguration(List<Pair<WorkflowType, String>> aaiResourceIds,
763 List<Resource> resourceList, org.onap.so.db.catalog.beans.Service service,
764 RelatedInstance relatedVpnBinding, RelatedInstance relatedLocalNetwork)
765 throws VrfBondingServiceException, JsonProcessingException {
766 org.onap.aai.domain.yang.L3Network aaiLocalNetwork =
767 bbInputSetupUtils.getAAIL3Network(relatedLocalNetwork.getInstanceId());
768 vrfValidation.vrfServiceValidation(service);
769 vrfValidation.vrfCatalogDbChecks(service);
770 vrfValidation.aaiVpnBindingValidation(relatedVpnBinding.getInstanceId(),
771 bbInputSetupUtils.getAAIVpnBinding(relatedVpnBinding.getInstanceId()));
772 vrfValidation.aaiNetworkValidation(relatedLocalNetwork.getInstanceId(), aaiLocalNetwork);
773 vrfValidation.aaiSubnetValidation(aaiLocalNetwork);
774 vrfValidation.aaiAggregateRouteValidation(aaiLocalNetwork);
775 vrfValidation.aaiRouteTargetValidation(aaiLocalNetwork);
776 String existingAAIVrfConfiguration = getExistingAAIVrfConfiguration(relatedVpnBinding, aaiLocalNetwork);
777 if (existingAAIVrfConfiguration != null) {
778 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, existingAAIVrfConfiguration));
780 resourceList.add(new Resource(WorkflowType.CONFIGURATION,
781 service.getConfigurationCustomizations().get(0).getModelCustomizationUUID(), false));
785 protected String getExistingAAIVrfConfiguration(RelatedInstance relatedVpnBinding,
786 org.onap.aai.domain.yang.L3Network aaiLocalNetwork)
787 throws JsonProcessingException, VrfBondingServiceException {
788 Optional<Relationships> relationshipsOp = new AAIResultWrapper(
789 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiLocalNetwork)).getRelationships();
790 if (relationshipsOp.isPresent()) {
791 List<AAIResultWrapper> configurationsRelatedToLocalNetwork =
792 relationshipsOp.get().getByType(AAIObjectType.CONFIGURATION);
793 if (configurationsRelatedToLocalNetwork.size() > 1) {
794 throw new VrfBondingServiceException(
795 "Network: " + aaiLocalNetwork.getNetworkId() + " has more than 1 configuration related to it");
797 if (configurationsRelatedToLocalNetwork.size() == 1) {
798 AAIResultWrapper configWrapper = configurationsRelatedToLocalNetwork.get(0);
799 Optional<Configuration> relatedConfiguration = configWrapper.asBean(Configuration.class);
800 if (relatedConfiguration.isPresent() && vrfConfigurationAlreadyExists(relatedVpnBinding,
801 relatedConfiguration.get(), configWrapper)) {
802 return relatedConfiguration.get().getConfigurationId();
809 protected boolean vrfConfigurationAlreadyExists(RelatedInstance relatedVpnBinding, Configuration vrfConfiguration,
810 AAIResultWrapper configWrapper) throws VrfBondingServiceException {
811 if ("VRF-ENTRY".equalsIgnoreCase(vrfConfiguration.getConfigurationType())) {
812 Optional<Relationships> relationshipsConfigOp = configWrapper.getRelationships();
813 if (relationshipsConfigOp.isPresent()) {
814 Optional<VpnBinding> relatedInfraVpnBindingOp =
815 workflowActionUtils.extractRelationshipsVpnBinding(relationshipsConfigOp.get());
816 if (relatedInfraVpnBindingOp.isPresent()) {
817 VpnBinding relatedInfraVpnBinding = relatedInfraVpnBindingOp.get();
818 if (!relatedInfraVpnBinding.getVpnId().equalsIgnoreCase(relatedVpnBinding.getInstanceId())) {
819 throw new VrfBondingServiceException("Configuration: " + vrfConfiguration.getConfigurationId()
820 + " is not connected to the same vpn binding id provided in request: "
821 + relatedVpnBinding.getInstanceId());
831 protected void traverseNetworkCollection(DelegateExecution execution, List<Resource> resourceList,
832 org.onap.so.db.catalog.beans.Service service) {
833 if (isVnfCustomizationsEmpty(service)) {
834 List<CollectionResourceCustomization> customizations = service.getCollectionResourceCustomizations();
835 if (customizations.isEmpty()) {
836 logger.debug("No Collections found. CollectionResourceCustomization list is empty.");
838 CollectionResourceCustomization collectionResourceCustomization =
839 findCatalogNetworkCollection(execution, service);
840 traverseNetworkCollectionResourceCustomization(resourceList, collectionResourceCustomization);
842 traverseNetworkCollectionCustomization(resourceList, service);
844 buildAndThrowException(execution,
845 "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");
849 private void traverseNetworkCollectionResourceCustomization(List<Resource> resourceList,
850 CollectionResourceCustomization collectionResourceCustomization) {
851 if (collectionResourceCustomization != null) {
852 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
853 collectionResourceCustomization.getModelCustomizationUUID(), false));
854 logger.debug("Found a network collection");
855 if (collectionResourceCustomization.getCollectionResource() != null) {
856 if (collectionResourceCustomization.getCollectionResource().getInstanceGroup() != null) {
857 String toscaNodeType = collectionResourceCustomization.getCollectionResource().getInstanceGroup()
859 if (toscaNodeType != null && toscaNodeType.contains(NETWORKCOLLECTION)) {
861 org.onap.so.db.catalog.beans.InstanceGroup instanceGroup =
862 collectionResourceCustomization.getCollectionResource().getInstanceGroup();
863 CollectionResourceInstanceGroupCustomization collectionInstCust = null;
864 if (!instanceGroup.getCollectionInstanceGroupCustomizations().isEmpty()) {
865 for (CollectionResourceInstanceGroupCustomization collectionInstanceGroupTemp : instanceGroup
866 .getCollectionInstanceGroupCustomizations()) {
867 if (collectionInstanceGroupTemp.getModelCustomizationUUID().equalsIgnoreCase(
868 collectionResourceCustomization.getModelCustomizationUUID())) {
869 collectionInstCust = collectionInstanceGroupTemp;
873 if (collectionInstCust != null
874 && collectionInstCust.getSubInterfaceNetworkQuantity() != null) {
875 minNetworks = collectionInstCust.getSubInterfaceNetworkQuantity();
878 logger.debug("minNetworks: {}", minNetworks);
879 CollectionNetworkResourceCustomization collectionNetworkResourceCust = null;
880 for (CollectionNetworkResourceCustomization collectionNetworkTemp : instanceGroup
881 .getCollectionNetworkResourceCustomizations()) {
882 if (collectionNetworkTemp.getNetworkResourceCustomization().getModelCustomizationUUID()
883 .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
884 collectionNetworkResourceCust = collectionNetworkTemp;
888 for (int i = 0; i < minNetworks; i++) {
889 if (collectionNetworkResourceCust != null && collectionInstCust != null) {
890 Resource resource = new Resource(WorkflowType.VIRTUAL_LINK,
891 collectionNetworkResourceCust.getModelCustomizationUUID(), false);
892 resource.setVirtualLinkKey(Integer.toString(i));
893 resourceList.add(resource);
897 logger.debug("Instance Group tosca node type does not contain NetworkCollection: {}",
901 logger.debug("No Instance Group found for network collection.");
904 logger.debug("No Network Collection found. collectionResource is null");
907 logger.debug("No Network Collection Customization found");
911 private void traverseNetworkCollectionCustomization(List<Resource> resourceList,
912 org.onap.so.db.catalog.beans.Service service) {
913 if (isNetworkCollectionInTheResourceList(resourceList)) {
916 if (service.getNetworkCustomizations() == null) {
917 logger.debug("No networks were found on this service model");
920 for (int i = 0; i < service.getNetworkCustomizations().size(); i++) {
921 resourceList.add(new Resource(WorkflowType.NETWORK,
922 service.getNetworkCustomizations().get(i).getModelCustomizationUUID(), false));
926 private boolean isNetworkCollectionInTheResourceList(List<Resource> resourceList) {
927 return !(resourceList.stream().filter(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType())
928 .collect(Collectors.toList()).isEmpty());
931 private boolean isVnfCustomizationsEmpty(org.onap.so.db.catalog.beans.Service service) {
932 return service.getVnfCustomizations() == null || service.getVnfCustomizations().isEmpty();
935 protected void traverseAAIService(DelegateExecution execution, List<Resource> resourceList, String resourceId,
936 List<Pair<WorkflowType, String>> aaiResourceIds) {
938 ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(resourceId);
939 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
940 bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
941 resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
942 if (serviceInstanceMSO.getVnfs() != null) {
943 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
944 aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
945 resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
946 if (vnf.getVfModules() != null) {
947 for (VfModule vfModule : vnf.getVfModules()) {
948 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
949 Resource resource = new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false);
950 resource.setBaseVfModule(vfModule.getModelInfoVfModule().getIsBaseBoolean());
951 resourceList.add(resource);
954 if (vnf.getVolumeGroups() != null) {
955 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
956 .getVolumeGroups()) {
957 aaiResourceIds.add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
959 .add(new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
964 if (serviceInstanceMSO.getNetworks() != null) {
965 for (org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network network : serviceInstanceMSO
967 aaiResourceIds.add(new Pair<>(WorkflowType.NETWORK, network.getNetworkId()));
968 resourceList.add(new Resource(WorkflowType.NETWORK, network.getNetworkId(), false));
971 if (serviceInstanceMSO.getCollection() != null) {
972 logger.debug("found networkcollection");
974 .add(new Pair<>(WorkflowType.NETWORKCOLLECTION, serviceInstanceMSO.getCollection().getId()));
975 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
976 serviceInstanceMSO.getCollection().getId(), false));
978 if (serviceInstanceMSO.getConfigurations() != null) {
979 for (Configuration config : serviceInstanceMSO.getConfigurations()) {
980 Optional<org.onap.aai.domain.yang.Configuration> aaiConfig =
981 aaiConfigurationResources.getConfiguration(config.getConfigurationId());
982 if (aaiConfig.isPresent() && aaiConfig.get().getRelationshipList() != null) {
983 for (Relationship relationship : aaiConfig.get().getRelationshipList().getRelationship()) {
984 if (relationship.getRelatedTo().contains("vnfc")
985 || relationship.getRelatedTo().contains("vpn-binding")) {
986 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.getConfigurationId()));
988 new Resource(WorkflowType.CONFIGURATION, config.getConfigurationId(), false));
995 } catch (Exception ex) {
996 logger.error("Exception in traverseAAIService", ex);
997 buildAndThrowException(execution,
998 "Could not find existing Service Instance or related Instances to execute the request on.");
1002 private void traverseAAIVnf(DelegateExecution execution, List<Resource> resourceList, String serviceId,
1003 String vnfId, List<Pair<WorkflowType, String>> aaiResourceIds) {
1005 ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(serviceId);
1006 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
1007 bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
1008 resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
1009 if (serviceInstanceMSO.getVnfs() != null) {
1010 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
1011 if (vnf.getVnfId().equals(vnfId)) {
1012 aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
1013 resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
1014 if (vnf.getVfModules() != null) {
1015 for (VfModule vfModule : vnf.getVfModules()) {
1016 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1017 resourceList.add(new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false));
1018 findConfigurationsInsideVfModule(execution, vnf.getVnfId(), vfModule.getVfModuleId(),
1019 resourceList, aaiResourceIds);
1022 if (vnf.getVolumeGroups() != null) {
1023 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
1024 .getVolumeGroups()) {
1026 .add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1028 new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1035 } catch (Exception ex) {
1036 logger.error("Exception in traverseAAIVnf", ex);
1037 buildAndThrowException(execution,
1038 "Could not find existing Vnf or related Instances to execute the request on.");
1042 private void findConfigurationsInsideVfModule(DelegateExecution execution, String vnfId, String vfModuleId,
1043 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds) {
1045 org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
1046 AAIResultWrapper vfModuleWrapper = new AAIResultWrapper(
1047 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiVfModule));
1048 Optional<Relationships> relationshipsOp;
1049 relationshipsOp = vfModuleWrapper.getRelationships();
1050 if (relationshipsOp.isPresent()) {
1051 relationshipsOp = workflowActionUtils.extractRelationshipsVnfc(relationshipsOp.get());
1052 if (relationshipsOp.isPresent()) {
1053 Optional<Configuration> config =
1054 workflowActionUtils.extractRelationshipsConfiguration(relationshipsOp.get());
1055 if (config.isPresent()) {
1056 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.get().getConfigurationId()));
1058 new Resource(WorkflowType.CONFIGURATION, config.get().getConfigurationId(), false));
1062 } catch (Exception ex) {
1063 logger.error("Exception in findConfigurationsInsideVfModule", ex);
1064 buildAndThrowException(execution, "Failed to find Configuration object from the vfModule.");
1068 protected boolean traverseUserParamsService(DelegateExecution execution, List<Resource> resourceList,
1069 ServiceInstancesRequest sIRequest, String requestAction) throws IOException {
1070 boolean foundRelated = false;
1071 boolean foundVfModuleOrVG = false;
1072 String vnfCustomizationUUID = "";
1073 String vfModuleCustomizationUUID = "";
1074 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
1075 List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
1076 for (Map<String, Object> params : userParams) {
1077 if (params.containsKey(USERPARAMSERVICE)) {
1078 ObjectMapper obj = new ObjectMapper();
1079 String input = obj.writeValueAsString(params.get(USERPARAMSERVICE));
1080 Service validate = obj.readValue(input, Service.class);
1082 new Resource(WorkflowType.SERVICE, validate.getModelInfo().getModelVersionId(), false));
1083 if (validate.getResources().getVnfs() != null) {
1084 for (Vnfs vnf : validate.getResources().getVnfs()) {
1085 resourceList.add(new Resource(WorkflowType.VNF,
1086 vnf.getModelInfo().getModelCustomizationId(), false));
1087 foundRelated = true;
1088 if (vnf.getModelInfo() != null && vnf.getModelInfo().getModelCustomizationUuid() != null) {
1089 vnfCustomizationUUID = vnf.getModelInfo().getModelCustomizationUuid();
1091 if (vnf.getVfModules() != null) {
1092 for (VfModules vfModule : vnf.getVfModules()) {
1093 VfModuleCustomization vfModuleCustomization =
1094 catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
1095 vfModule.getModelInfo().getModelCustomizationUuid());
1096 if (vfModuleCustomization != null) {
1098 if (vfModuleCustomization.getVfModule() != null
1099 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
1100 && vfModuleCustomization.getVolumeHeatEnv() != null) {
1101 resourceList.add(new Resource(WorkflowType.VOLUMEGROUP,
1102 vfModuleCustomization.getModelCustomizationUUID(), false));
1103 foundRelated = true;
1104 foundVfModuleOrVG = true;
1107 if (vfModuleCustomization.getVfModule() != null
1108 && vfModuleCustomization.getVfModule().getModuleHeatTemplate() != null
1109 && vfModuleCustomization.getHeatEnvironment() != null) {
1110 foundRelated = true;
1111 foundVfModuleOrVG = true;
1112 Resource resource = new Resource(WorkflowType.VFMODULE,
1113 vfModuleCustomization.getModelCustomizationUUID(), false);
1114 if (vfModuleCustomization.getVfModule().getIsBase() != null
1115 && vfModuleCustomization.getVfModule().getIsBase()) {
1116 resource.setBaseVfModule(true);
1118 resource.setBaseVfModule(false);
1120 resourceList.add(resource);
1121 if (vfModule.getModelInfo() != null
1122 && vfModule.getModelInfo().getModelCustomizationUuid() != null) {
1123 vfModuleCustomizationUUID =
1124 vfModule.getModelInfo().getModelCustomizationUuid();
1126 if (!vnfCustomizationUUID.isEmpty()
1127 && !vfModuleCustomizationUUID.isEmpty()) {
1128 List<CvnfcConfigurationCustomization> configs =
1129 traverseCatalogDbForConfiguration(
1130 validate.getModelInfo().getModelVersionId(),
1131 vnfCustomizationUUID, vfModuleCustomizationUUID);
1132 for (CvnfcConfigurationCustomization config : configs) {
1133 Resource configResource = new Resource(WorkflowType.CONFIGURATION,
1134 config.getConfigurationResource().getModelUUID(), false);
1135 resource.setVnfCustomizationId(
1136 vnf.getModelInfo().getModelCustomizationId());
1137 resource.setVfModuleCustomizationId(
1138 vfModule.getModelInfo().getModelCustomizationId());
1139 resourceList.add(configResource);
1143 if (!foundVfModuleOrVG) {
1144 buildAndThrowException(execution,
1145 "Could not determine if vfModule was a vfModule or volume group. Heat template and Heat env are null");
1152 if (validate.getResources().getPnfs() != null) {
1153 for (Pnfs pnf : validate.getResources().getPnfs()) {
1154 resourceList.add(new Resource(WorkflowType.PNF,
1155 pnf.getModelInfo().getModelCustomizationId(), false));
1156 foundRelated = true;
1159 if (validate.getResources().getNetworks() != null) {
1160 for (Networks network : validate.getResources().getNetworks()) {
1161 resourceList.add(new Resource(WorkflowType.NETWORK,
1162 network.getModelInfo().getModelCustomizationId(), false));
1163 foundRelated = true;
1165 if (requestAction.equals(CREATEINSTANCE)) {
1166 String networkColCustId = queryCatalogDBforNetworkCollection(execution, sIRequest);
1167 if (networkColCustId != null) {
1168 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION, networkColCustId, false));
1169 foundRelated = true;
1177 return foundRelated;
1180 protected List<CvnfcConfigurationCustomization> traverseCatalogDbForConfiguration(String serviceModelUUID,
1181 String vnfCustomizationUUID, String vfModuleCustomizationUUID) {
1182 List<CvnfcConfigurationCustomization> configurations = new ArrayList<>();
1184 List<CvnfcCustomization> cvnfcCustomizations = catalogDbClient.getCvnfcCustomization(serviceModelUUID,
1185 vnfCustomizationUUID, vfModuleCustomizationUUID);
1186 for (CvnfcCustomization cvnfc : cvnfcCustomizations) {
1187 for (CvnfcConfigurationCustomization customization : cvnfc.getCvnfcConfigurationCustomization()) {
1188 if (customization.getConfigurationResource().getToscaNodeType().contains(FABRIC_CONFIGURATION)) {
1189 configurations.add(customization);
1193 logger.debug("found {} fabric configuration(s)", configurations.size());
1194 return configurations;
1195 } catch (Exception ex) {
1196 logger.error("Error in finding configurations", ex);
1197 return configurations;
1201 protected String queryCatalogDBforNetworkCollection(DelegateExecution execution,
1202 ServiceInstancesRequest sIRequest) {
1203 org.onap.so.db.catalog.beans.Service service =
1204 catalogDbClient.getServiceByID(sIRequest.getRequestDetails().getModelInfo().getModelVersionId());
1205 if (service != null) {
1206 CollectionResourceCustomization networkCollection = this.findCatalogNetworkCollection(execution, service);
1207 if (networkCollection != null) {
1208 return networkCollection.getModelCustomizationUUID();
1214 protected WorkflowResourceIds populateResourceIdsFromApiHandler(DelegateExecution execution) {
1215 return WorkflowResourceIdsUtils.getWorkflowResourceIdsFromExecution(execution);
1218 protected Resource extractResourceIdAndTypeFromUri(String uri) {
1219 Pattern patt = Pattern.compile("[vV]\\d+.*?(?:(?:/(?<type>" + SUPPORTEDTYPES
1220 + ")(?:/(?<id>[^/]+))?)(?:/(?<action>[^/]+))?(?:/resume)?)?$");
1221 Matcher m = patt.matcher(uri);
1222 boolean generated = false;
1225 logger.debug("found match on {} : {} ", uri, m);
1226 String type = m.group("type");
1227 String id = m.group("id");
1228 String action = m.group("action");
1230 throw new IllegalArgumentException("Uri could not be parsed. No type found. " + uri);
1232 if (action == null) {
1233 if (type.equals(SERVICE_INSTANCES) && (id == null || "assign".equals(id))) {
1234 id = UUID.randomUUID().toString();
1236 } else if (type.equals(VF_MODULES) && "scaleOut".equals(id)) {
1237 id = UUID.randomUUID().toString();
1241 if (action.matches(SUPPORTEDTYPES)) {
1242 id = UUID.randomUUID().toString();
1247 return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated);
1249 throw new IllegalArgumentException("Uri could not be parsed: " + uri);
1253 protected String validateResourceIdInAAI(String generatedResourceId, WorkflowType type, String instanceName,
1254 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws Exception {
1256 if ("SERVICE".equalsIgnoreCase(type.toString())) {
1257 return validateServiceResourceIdInAAI(generatedResourceId, instanceName, reqDetails);
1258 } else if ("NETWORK".equalsIgnoreCase(type.toString())) {
1259 return validateNetworkResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1260 workflowResourceIds);
1261 } else if ("VNF".equalsIgnoreCase(type.toString())) {
1262 return validateVnfResourceIdInAAI(generatedResourceId, instanceName, reqDetails, workflowResourceIds);
1263 } else if ("VFMODULE".equalsIgnoreCase(type.toString())) {
1264 return validateVfModuleResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1265 workflowResourceIds);
1266 } else if ("VOLUMEGROUP".equalsIgnoreCase(type.toString())) {
1267 return validateVolumeGroupResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1268 workflowResourceIds);
1269 } else if ("CONFIGURATION".equalsIgnoreCase(type.toString())) {
1270 return validateConfigurationResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1271 workflowResourceIds);
1273 return generatedResourceId;
1274 } catch (DuplicateNameException dne) {
1276 } catch (Exception ex) {
1277 logger.error(WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI, ex);
1278 throw new IllegalStateException(
1279 WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI);
1283 protected String convertTypeFromPlural(String type) {
1284 if (!type.matches(SUPPORTEDTYPES)) {
1287 if (type.equals(SERVICE_INSTANCES)) {
1290 return type.substring(0, 1).toUpperCase() + type.substring(1, type.length() - 1);
1295 protected List<ExecuteBuildingBlock> sortExecutionPathByObjectForVlanTagging(List<ExecuteBuildingBlock> orchFlows,
1296 String requestAction) {
1297 List<ExecuteBuildingBlock> sortedOrchFlows = new ArrayList<>();
1298 if (requestAction.equals(CREATEINSTANCE)) {
1299 for (ExecuteBuildingBlock ebb : orchFlows) {
1300 if (ebb.getBuildingBlock().getBpmnFlowName().equals("AssignNetworkBB")) {
1301 String key = ebb.getBuildingBlock().getKey();
1302 boolean isVirtualLink = Boolean.TRUE.equals(ebb.getBuildingBlock().isVirtualLink());
1303 String virtualLinkKey = ebb.getBuildingBlock().getVirtualLinkKey();
1304 sortedOrchFlows.add(ebb);
1305 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1306 if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1307 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1308 sortedOrchFlows.add(ebb2);
1311 if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1312 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1313 sortedOrchFlows.add(ebb2);
1317 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1318 if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1319 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1320 sortedOrchFlows.add(ebb2);
1323 if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1324 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1325 sortedOrchFlows.add(ebb2);
1329 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1330 || ebb.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)) {
1332 } else if (!"".equals(ebb.getBuildingBlock().getBpmnFlowName())) {
1333 sortedOrchFlows.add(ebb);
1336 } else if (requestAction.equals("deleteInstance")) {
1337 for (ExecuteBuildingBlock ebb : orchFlows) {
1338 if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeactivateNetworkBB")) {
1339 sortedOrchFlows.add(ebb);
1340 String key = ebb.getBuildingBlock().getKey();
1341 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1342 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1343 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1344 sortedOrchFlows.add(ebb2);
1348 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1349 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")
1350 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1351 sortedOrchFlows.add(ebb2);
1355 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1356 || ebb.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")) {
1358 } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) {
1359 sortedOrchFlows.add(ebb);
1363 return sortedOrchFlows;
1366 private void addBuildingBlockToExecuteBBList(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
1367 WorkflowType workflowType, OrchestrationFlow orchFlow, String requestId, String apiVersion,
1368 String resourceId, String requestAction, String vnfType, WorkflowResourceIds workflowResourceIds,
1369 RequestDetails requestDetails, boolean isVirtualLink, boolean isConfiguration) {
1371 resourceList.stream().filter(resource -> resource.getResourceType().equals(workflowType))
1372 .forEach(resource -> flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource,
1373 apiVersion, resourceId, requestAction, false, vnfType, workflowResourceIds, requestDetails,
1374 isVirtualLink, resource.getVirtualLinkKey(), null, isConfiguration)));
1377 protected List<ExecuteBuildingBlock> buildExecuteBuildingBlockList(List<OrchestrationFlow> orchFlows,
1378 List<Resource> resourceList, String requestId, String apiVersion, String resourceId, String requestAction,
1379 String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1380 boolean replaceVnf) {
1381 List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
1382 for (OrchestrationFlow orchFlow : orchFlows) {
1383 if (orchFlow.getFlowName().contains(SERVICE)) {
1385 workflowResourceIds.setServiceInstanceId(resourceId);
1387 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.SERVICE, orchFlow, requestId,
1388 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1390 } else if (orchFlow.getFlowName().contains(VNF) || (orchFlow.getFlowName().contains(CONTROLLER)
1391 && (VNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1392 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VNF, orchFlow, requestId,
1393 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1395 } else if (orchFlow.getFlowName().contains(PNF)) {
1396 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.PNF, orchFlow, requestId,
1397 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1399 } else if (orchFlow.getFlowName().contains(NETWORK)
1400 && !orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1401 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORK, orchFlow, requestId,
1402 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1404 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VIRTUAL_LINK, orchFlow,
1405 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1407 } else if (orchFlow.getFlowName().contains(VFMODULE) || (orchFlow.getFlowName().contains(CONTROLLER)
1408 && (VFMODULE).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1409 List<Resource> vfModuleResourcesSorted = null;
1410 if (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE)
1411 || requestAction.equals("activateInstance")) {
1412 vfModuleResourcesSorted = sortVfModulesByBaseFirst(resourceList.stream()
1413 .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1415 vfModuleResourcesSorted = sortVfModulesByBaseLast(resourceList.stream()
1416 .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1418 for (int i = 0; i < vfModuleResourcesSorted.size(); i++) {
1419 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, vfModuleResourcesSorted.get(i),
1420 apiVersion, resourceId, requestAction, false, vnfType, workflowResourceIds, requestDetails,
1421 false, null, null, false));
1423 } else if (orchFlow.getFlowName().contains(VOLUMEGROUP)) {
1424 if (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1425 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)) {
1426 logger.debug("Replacing workflow resource id by volume group id");
1427 resourceId = workflowResourceIds.getVolumeGroupId();
1429 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VOLUMEGROUP, orchFlow,
1430 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1432 } else if (orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1433 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORKCOLLECTION, orchFlow,
1434 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1436 } else if (orchFlow.getFlowName().contains(CONFIGURATION)) {
1437 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.CONFIGURATION, orchFlow,
1438 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1441 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, null, apiVersion, resourceId,
1442 requestAction, false, vnfType, workflowResourceIds, requestDetails, false, null, null, false));
1445 return flowsToExecute;
1448 protected ExecuteBuildingBlock buildExecuteBuildingBlock(OrchestrationFlow orchFlow, String requestId,
1449 Resource resource, String apiVersion, String resourceId, String requestAction, boolean aLaCarte,
1450 String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1451 boolean isVirtualLink, String virtualLinkKey, String vnfcName, boolean isConfiguration) {
1453 BuildingBlock buildingBlock =
1454 new BuildingBlock().setBpmnFlowName(orchFlow.getFlowName()).setMsoId(UUID.randomUUID().toString())
1455 .setIsVirtualLink(isVirtualLink).setVirtualLinkKey(virtualLinkKey)
1456 .setKey(Optional.ofNullable(resource).map(Resource::getResourceId).orElse(""));
1457 Optional.ofNullable(orchFlow.getBpmnAction()).ifPresent(action -> buildingBlock.setBpmnAction(action));
1458 Optional.ofNullable(orchFlow.getBpmnScope()).ifPresent(scope -> buildingBlock.setBpmnScope(scope));
1460 if (resource != null
1461 && (orchFlow.getFlowName().contains(VOLUMEGROUP) && (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1462 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)))) {
1463 logger.debug("Setting resourceId to volume group id for volume group flow on replace");
1464 resourceId = workflowResourceIds.getVolumeGroupId();
1467 ExecuteBuildingBlock executeBuildingBlock = new ExecuteBuildingBlock();
1468 executeBuildingBlock.setApiVersion(apiVersion);
1469 executeBuildingBlock.setaLaCarte(aLaCarte);
1470 executeBuildingBlock.setRequestAction(requestAction);
1471 executeBuildingBlock.setResourceId(resourceId);
1472 executeBuildingBlock.setVnfType(vnfType);
1473 executeBuildingBlock.setWorkflowResourceIds(workflowResourceIds);
1474 executeBuildingBlock.setRequestId(requestId);
1475 executeBuildingBlock.setBuildingBlock(buildingBlock);
1476 executeBuildingBlock.setRequestDetails(requestDetails);
1478 if (resource != null && (isConfiguration || resource.getResourceType().equals(WorkflowType.CONFIGURATION))) {
1479 ConfigurationResourceKeys configurationResourceKeys = new ConfigurationResourceKeys();
1480 Optional.ofNullable(vnfcName).ifPresent(name -> configurationResourceKeys.setVnfcName(name));
1481 configurationResourceKeys.setCvnfcCustomizationUUID(resource.getCvnfModuleCustomizationId());
1482 configurationResourceKeys.setVfModuleCustomizationUUID(resource.getVfModuleCustomizationId());
1483 configurationResourceKeys.setVnfResourceCustomizationUUID(resource.getVnfCustomizationId());
1484 executeBuildingBlock.setConfigurationResourceKeys(configurationResourceKeys);
1486 return executeBuildingBlock;
1489 protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1490 WorkflowType resourceName, boolean aLaCarte, String cloudOwner) {
1491 return this.queryNorthBoundRequestCatalogDb(execution, requestAction, resourceName, aLaCarte, cloudOwner, "");
1494 protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1495 WorkflowType resourceName, boolean aLaCarte, String cloudOwner, String serviceType) {
1496 List<OrchestrationFlow> listToExecute = new ArrayList<>();
1497 NorthBoundRequest northBoundRequest = null;
1498 if (serviceType.equalsIgnoreCase(SERVICE_TYPE_TRANSPORT)
1499 || serviceType.equalsIgnoreCase(SERVICE_TYPE_BONDING)) {
1501 catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwnerAndServiceType(
1502 requestAction, resourceName.toString(), aLaCarte, cloudOwner, serviceType);
1504 northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1505 requestAction, resourceName.toString(), aLaCarte, cloudOwner);
1507 if (northBoundRequest == null) {
1508 northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1509 requestAction, resourceName.toString(), aLaCarte, CLOUD_OWNER);
1511 if (northBoundRequest == null) {
1512 buildAndThrowException(execution, String.format("The request: %s %s %s is not supported by GR_API.",
1513 (aLaCarte ? "AlaCarte" : "Macro"), resourceName, requestAction));
1515 if (northBoundRequest.getIsToplevelflow() != null) {
1516 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, northBoundRequest.getIsToplevelflow());
1518 List<OrchestrationFlow> flows = northBoundRequest.getOrchestrationFlowList();
1520 flows = new ArrayList<>();
1521 for (OrchestrationFlow flow : flows) {
1522 if (!flow.getFlowName().contains("BB") && !flow.getFlowName().contains("Activity")) {
1523 List<OrchestrationFlow> macroQueryFlows =
1524 catalogDbClient.getOrchestrationFlowByAction(flow.getFlowName());
1525 listToExecute.addAll(macroQueryFlows);
1527 listToExecute.add(flow);
1531 return listToExecute;
1534 protected void buildAndThrowException(DelegateExecution execution, String msg, Exception ex) {
1535 logger.error(msg, ex);
1536 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg + ex.getMessage());
1537 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg + ex.getMessage());
1540 protected void buildAndThrowException(DelegateExecution execution, String msg) {
1542 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg);
1543 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
1546 public void handleRuntimeException(DelegateExecution execution) {
1547 StringBuilder wfeExpMsg = new StringBuilder("Runtime error ");
1548 String runtimeErrorMessage;
1550 String javaExpMsg = (String) execution.getVariable("BPMN_javaExpMsg");
1551 if (javaExpMsg != null && !javaExpMsg.isEmpty()) {
1552 wfeExpMsg.append(": ").append(javaExpMsg);
1554 runtimeErrorMessage = wfeExpMsg.toString();
1555 logger.error(runtimeErrorMessage);
1556 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, runtimeErrorMessage);
1557 } catch (Exception e) {
1558 logger.error("Runtime error", e);
1559 // if runtime message was mulformed
1560 runtimeErrorMessage = "Runtime error";
1562 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, runtimeErrorMessage);
1565 protected boolean isUriResume(String uri) {
1566 return uri.endsWith("/resume");
1569 protected boolean isRequestMacroServiceResume(boolean aLaCarte, WorkflowType resourceType, String requestAction,
1570 String serviceInstanceId) {
1571 return (!aLaCarte && resourceType == WorkflowType.SERVICE
1572 && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE) || requestAction.equalsIgnoreCase(CREATEINSTANCE))
1573 && (serviceInstanceId != null && serviceInstanceId.trim().length() > 1)
1574 && (bbInputSetupUtils.getAAIServiceInstanceById(serviceInstanceId) != null));
1577 protected String validateServiceResourceIdInAAI(String generatedResourceId, String instanceName,
1578 RequestDetails reqDetails) throws DuplicateNameException, MultipleObjectsFoundException {
1579 String globalCustomerId = reqDetails.getSubscriberInfo().getGlobalSubscriberId();
1580 String serviceType = reqDetails.getRequestParameters().getSubscriptionServiceType();
1581 if (instanceName != null) {
1582 Optional<ServiceInstance> serviceInstanceAAI =
1583 bbInputSetupUtils.getAAIServiceInstanceByName(globalCustomerId, serviceType, instanceName);
1584 if (serviceInstanceAAI.isPresent()) {
1585 if (serviceInstanceAAI.get().getModelVersionId()
1586 .equalsIgnoreCase(reqDetails.getModelInfo().getModelVersionId())) {
1587 return serviceInstanceAAI.get().getServiceInstanceId();
1589 throw new DuplicateNameException(SERVICE_INSTANCE, String.format(NAME_EXISTS_WITH_DIFF_VERSION_ID,
1590 instanceName, reqDetails.getModelInfo().getModelVersionId()));
1593 ServiceInstances aaiServiceInstances =
1594 bbInputSetupUtils.getAAIServiceInstancesGloballyByName(instanceName);
1595 if (aaiServiceInstances != null) {
1596 if (aaiServiceInstances.getServiceInstance() != null
1597 && !aaiServiceInstances.getServiceInstance().isEmpty()) {
1598 if (aaiServiceInstances.getServiceInstance().size() > 1) {
1599 throw new DuplicateNameException(SERVICE_INSTANCE,
1600 String.format(NAME_EXISTS_MULTIPLE, instanceName));
1602 ServiceInstance si = aaiServiceInstances.getServiceInstance().stream().findFirst().get();
1603 Map<String, String> keys =
1604 bbInputSetupUtils.getURIKeysFromServiceInstance(si.getServiceInstanceId());
1606 throw new DuplicateNameException(SERVICE_INSTANCE, String.format(
1607 NAME_EXISTS_WITH_DIFF_COMBINATION, instanceName,
1608 keys.get(AAIFluentTypeBuilder.Types.CUSTOMER.getUriParams().globalCustomerId),
1610 AAIFluentTypeBuilder.Types.SERVICE_SUBSCRIPTION.getUriParams().serviceType),
1611 si.getModelVersionId()));
1617 return generatedResourceId;
1620 protected String validateNetworkResourceIdInAAI(String generatedResourceId, String instanceName,
1621 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1622 throws DuplicateNameException, MultipleObjectsFoundException {
1623 Optional<L3Network> network = bbInputSetupUtils
1624 .getRelatedNetworkByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1625 if (network.isPresent()) {
1626 if (network.get().getModelCustomizationId()
1627 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1628 return network.get().getNetworkId();
1630 throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1631 instanceName, network.get().getModelCustomizationId()));
1634 if (bbInputSetupUtils.existsAAINetworksGloballyByName(instanceName)) {
1635 throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName,
1636 workflowResourceIds.getServiceInstanceId()));
1638 return generatedResourceId;
1641 protected String validateVnfResourceIdInAAI(String generatedResourceId, String instanceName,
1642 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1643 throws DuplicateNameException, MultipleObjectsFoundException {
1644 Optional<GenericVnf> vnf = bbInputSetupUtils
1645 .getRelatedVnfByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1646 if (vnf.isPresent()) {
1647 if (vnf.get().getModelCustomizationId()
1648 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1649 return vnf.get().getVnfId();
1651 throw new DuplicateNameException("generic-vnf", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1652 instanceName, vnf.get().getModelCustomizationId()));
1655 GenericVnfs vnfs = bbInputSetupUtils.getAAIVnfsGloballyByName(instanceName);
1657 throw new DuplicateNameException("generic-vnf",
1658 String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName, vnfs.getGenericVnf().get(0).getVnfId()));
1660 return generatedResourceId;
1663 protected String validateVfModuleResourceIdInAAI(String generatedResourceId, String instanceName,
1664 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1665 GenericVnf vnf = bbInputSetupUtils.getAAIGenericVnf(workflowResourceIds.getVnfId());
1666 if (vnf != null && vnf.getVfModules() != null) {
1667 for (org.onap.aai.domain.yang.VfModule vfModule : vnf.getVfModules().getVfModule()) {
1668 if (vfModule.getVfModuleName().equalsIgnoreCase(instanceName)) {
1669 if (vfModule.getModelCustomizationId()
1670 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1671 return vfModule.getVfModuleId();
1673 throw new DuplicateNameException("vfModule",
1674 String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID, instanceName,
1675 reqDetails.getModelInfo().getModelCustomizationId()));
1680 if (bbInputSetupUtils.existsAAIVfModuleGloballyByName(instanceName)) {
1681 throw new DuplicateNameException("vfModule", instanceName);
1683 return generatedResourceId;
1686 protected String validateVolumeGroupResourceIdInAAI(String generatedResourceId, String instanceName,
1687 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1688 throws DuplicateNameException, MultipleObjectsFoundException {
1689 Optional<VolumeGroup> volumeGroup =
1690 bbInputSetupUtils.getRelatedVolumeGroupByNameFromVnf(workflowResourceIds.getVnfId(), instanceName);
1691 if (volumeGroup.isPresent()) {
1692 if (volumeGroup.get().getVfModuleModelCustomizationId()
1693 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1694 return volumeGroup.get().getVolumeGroupId();
1696 throw new DuplicateNameException("volumeGroup", volumeGroup.get().getVolumeGroupName());
1699 if (bbInputSetupUtils.existsAAIVolumeGroupGloballyByName(instanceName)) {
1700 throw new DuplicateNameException("volumeGroup", instanceName);
1702 return generatedResourceId;
1705 protected String validateConfigurationResourceIdInAAI(String generatedResourceId, String instanceName,
1706 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1707 throws DuplicateNameException, MultipleObjectsFoundException {
1708 Optional<org.onap.aai.domain.yang.Configuration> configuration =
1709 bbInputSetupUtils.getRelatedConfigurationByNameFromServiceInstance(
1710 workflowResourceIds.getServiceInstanceId(), instanceName);
1711 if (configuration.isPresent()) {
1712 if (configuration.get().getModelCustomizationId()
1713 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1714 return configuration.get().getConfigurationId();
1716 throw new DuplicateNameException("configuration", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1717 instanceName, configuration.get().getConfigurationId()));
1720 if (bbInputSetupUtils.existsAAIConfigurationGloballyByName(instanceName)) {
1721 throw new DuplicateNameException("configuration", instanceName);
1723 return generatedResourceId;
1726 private void fillExecution(DelegateExecution execution, boolean suppressRollback, String resourceId,
1727 WorkflowType resourceType) {
1728 execution.setVariable("sentSyncResponse", false);
1729 execution.setVariable("homing", false);
1730 execution.setVariable("calledHoming", false);
1731 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, true);
1732 execution.setVariable("suppressRollback", suppressRollback);
1733 execution.setVariable("resourceId", resourceId);
1734 execution.setVariable("resourceType", resourceType);
1735 execution.setVariable("resourceName", resourceType.toString());
1738 private Resource getResource(BBInputSetupUtils bbInputSetupUtils, boolean isResume, boolean alaCarte, String uri,
1740 if (!alaCarte && isResume) {
1741 logger.debug("replacing URI {}", uri);
1742 uri = bbInputSetupUtils.loadOriginalInfraActiveRequestById(requestId).getRequestUrl();
1743 logger.debug("for RESUME with original value {}", uri);
1745 return extractResourceIdAndTypeFromUri(uri);
1748 private String getResourceId(Resource resource, String requestAction, RequestDetails requestDetails,
1749 WorkflowResourceIds workflowResourceIds) throws Exception {
1750 if (resource.isGenerated() && requestAction.equalsIgnoreCase("createInstance")
1751 && requestDetails.getRequestInfo().getInstanceName() != null) {
1752 return validateResourceIdInAAI(resource.getResourceId(), resource.getResourceType(),
1753 requestDetails.getRequestInfo().getInstanceName(), requestDetails, workflowResourceIds);
1755 return resource.getResourceId();
1759 private String getServiceInstanceId(DelegateExecution execution, String resourceId, WorkflowType resourceType) {
1760 String serviceInstanceId = (String) execution.getVariable("serviceInstanceId");
1761 if ((serviceInstanceId == null || serviceInstanceId.isEmpty()) && WorkflowType.SERVICE.equals(resourceType)) {
1762 serviceInstanceId = resourceId;
1764 return serviceInstanceId;