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.so.bpmn.common.BBConstants;
52 import org.onap.so.bpmn.infrastructure.workflow.tasks.utils.WorkflowResourceIdsUtils;
53 import org.onap.so.bpmn.servicedecomposition.bbobjects.Configuration;
54 import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule;
55 import org.onap.so.bpmn.servicedecomposition.entities.BuildingBlock;
56 import org.onap.so.bpmn.servicedecomposition.entities.ConfigurationResourceKeys;
57 import org.onap.so.bpmn.servicedecomposition.entities.ExecuteBuildingBlock;
58 import org.onap.so.bpmn.servicedecomposition.entities.WorkflowResourceIds;
59 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetup;
60 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetupUtils;
61 import org.onap.so.bpmn.servicedecomposition.tasks.exceptions.DuplicateNameException;
62 import org.onap.so.bpmn.servicedecomposition.tasks.exceptions.MultipleObjectsFoundException;
63 import org.onap.so.client.aai.AAICommonObjectMapperProvider;
64 import org.onap.so.client.aai.AAIObjectType;
65 import org.onap.so.client.aai.entities.AAIResultWrapper;
66 import org.onap.so.client.aai.entities.Relationships;
67 import org.onap.so.client.aai.entities.uri.AAIResourceUri;
68 import org.onap.so.client.aai.entities.uri.AAIUriFactory;
69 import org.onap.so.client.exception.ExceptionBuilder;
70 import org.onap.so.client.orchestration.AAIConfigurationResources;
71 import org.onap.so.client.orchestration.AAIEntityNotFoundException;
72 import org.onap.so.db.catalog.beans.CollectionNetworkResourceCustomization;
73 import org.onap.so.db.catalog.beans.CollectionResourceCustomization;
74 import org.onap.so.db.catalog.beans.CollectionResourceInstanceGroupCustomization;
75 import org.onap.so.db.catalog.beans.CvnfcConfigurationCustomization;
76 import org.onap.so.db.catalog.beans.CvnfcCustomization;
77 import org.onap.so.db.catalog.beans.VfModuleCustomization;
78 import org.onap.so.db.catalog.beans.macro.NorthBoundRequest;
79 import org.onap.so.db.catalog.beans.macro.OrchestrationFlow;
80 import org.onap.so.db.catalog.client.CatalogDbClient;
81 import org.onap.so.serviceinstancebeans.CloudConfiguration;
82 import org.onap.so.serviceinstancebeans.ModelInfo;
83 import org.onap.so.serviceinstancebeans.ModelType;
84 import org.onap.so.serviceinstancebeans.Networks;
85 import org.onap.so.serviceinstancebeans.Pnfs;
86 import org.onap.so.serviceinstancebeans.RelatedInstance;
87 import org.onap.so.serviceinstancebeans.RequestDetails;
88 import org.onap.so.serviceinstancebeans.Service;
89 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
90 import org.onap.so.serviceinstancebeans.VfModules;
91 import org.onap.so.serviceinstancebeans.Vnfs;
92 import org.slf4j.Logger;
93 import org.slf4j.LoggerFactory;
94 import org.springframework.beans.factory.annotation.Autowired;
95 import org.springframework.core.env.Environment;
96 import org.springframework.stereotype.Component;
97 import com.fasterxml.jackson.core.JsonProcessingException;
98 import com.fasterxml.jackson.databind.ObjectMapper;
99 import org.springframework.util.CollectionUtils;
102 public class WorkflowAction {
104 private static final String WORKFLOW_ACTION_ERROR_MESSAGE = "WorkflowActionErrorMessage";
105 private static final String SERVICE_INSTANCES = "serviceInstances";
106 private static final String SERVICE_INSTANCE = "serviceInstance";
107 private static final String VF_MODULES = "vfModules";
108 private static final String WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI =
109 "WorkflowAction was unable to verify if the instance name already exist in AAI.";
110 private static final String VNF_TYPE = "vnfType";
111 private static final String SERVICE = "Service";
112 private static final String VNF = "Vnf";
113 private static final String PNF = "Pnf";
114 private static final String VFMODULE = "VfModule";
115 private static final String VOLUMEGROUP = "VolumeGroup";
116 private static final String NETWORK = "Network";
117 private static final String NETWORKCOLLECTION = "NetworkCollection";
118 private static final String CONFIGURATION = "Configuration";
119 private static final String ASSIGNINSTANCE = "assignInstance";
120 private static final String CREATEINSTANCE = "createInstance";
121 private static final String REPLACEINSTANCE = "replaceInstance";
122 private static final String REPLACEINSTANCERETAINASSIGNMENTS = "replaceInstanceRetainAssignments";
123 private static final String USERPARAMSERVICE = "service";
124 private static final String SUPPORTEDTYPES =
125 "vnfs|vfModules|networks|networkCollections|volumeGroups|serviceInstances|instanceGroups";
126 private static final String HOMINGSOLUTION = "Homing_Solution";
127 private static final String FABRIC_CONFIGURATION = "FabricConfiguration";
128 private static final String SERVICE_TYPE_TRANSPORT = "TRANSPORT";
129 private static final String SERVICE_TYPE_BONDING = "BONDING";
130 private static final String CLOUD_OWNER = "DEFAULT";
131 private static final Logger logger = LoggerFactory.getLogger(WorkflowAction.class);
132 private static final String NAME_EXISTS_WITH_DIFF_VERSION_ID = "(%s) and different version id (%s)";
133 private static final String NAME_EXISTS_MULTIPLE =
134 "(%s) and multiple combination of model-version-id + service-type + global-customer-id";
135 private static final String NAME_EXISTS_WITH_DIFF_COMBINATION =
136 "(%s) and global-customer-id (%s), service-type (%s), model-version-id (%s)";
137 private static final String NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID =
138 "(%s), same parent and different customization id (%s)";
139 private static final String NAME_EXISTS_WITH_DIFF_PARENT = "(%s) id (%s) and different parent relationship";
140 private static final String CREATENETWORKBB = "CreateNetworkBB";
141 private static final String ACTIVATENETWORKBB = "ActivateNetworkBB";
142 private static final String VOLUMEGROUP_DELETE_PATTERN = "(Un|De)(.*)Volume(.*)";
143 private static final String VOLUMEGROUP_CREATE_PATTERN = "(A|C)(.*)Volume(.*)";
144 private static final String CONTROLLER = "Controller";
147 protected BBInputSetup bbInputSetup;
149 protected BBInputSetupUtils bbInputSetupUtils;
151 private ExceptionBuilder exceptionBuilder;
153 private CatalogDbClient catalogDbClient;
155 private AAIConfigurationResources aaiConfigurationResources;
157 private WorkflowActionExtractResourcesAAI workflowActionUtils;
159 private VrfValidation vrfValidation;
162 private Environment environment;
163 private String defaultCloudOwner = "org.onap.so.cloud-owner";
165 public void setBbInputSetupUtils(BBInputSetupUtils bbInputSetupUtils) {
166 this.bbInputSetupUtils = bbInputSetupUtils;
169 public void setBbInputSetup(BBInputSetup bbInputSetup) {
170 this.bbInputSetup = bbInputSetup;
173 public void selectExecutionList(DelegateExecution execution) throws Exception {
175 final String bpmnRequest = (String) execution.getVariable(BBConstants.G_BPMN_REQUEST);
176 ServiceInstancesRequest sIRequest =
177 new ObjectMapper().readValue(bpmnRequest, ServiceInstancesRequest.class);
178 RequestDetails requestDetails = sIRequest.getRequestDetails();
179 String uri = (String) execution.getVariable(BBConstants.G_URI);
180 final String requestId = (String) execution.getVariable(BBConstants.G_REQUEST_ID);
181 final boolean aLaCarte = (boolean) execution.getVariable(BBConstants.G_ALACARTE);
182 boolean isResume = isUriResume(uri);
183 String requestAction = (String) execution.getVariable(BBConstants.G_ACTION);
184 WorkflowResourceIds workflowResourceIds = populateResourceIdsFromApiHandler(execution);
185 Resource resource = getResource(bbInputSetupUtils, isResume, aLaCarte, uri, requestId);
186 String resourceId = getResourceId(resource, requestAction, requestDetails, workflowResourceIds);
187 WorkflowType resourceType = resource.getResourceType();
188 String serviceInstanceId = getServiceInstanceId(execution, resourceId, resourceType);
189 fillExecution(execution, requestDetails.getRequestInfo().getSuppressRollback(), resourceId, resourceType);
190 List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
191 if (isRequestMacroServiceResume(aLaCarte, resourceType, requestAction, serviceInstanceId)) {
192 flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
193 if (flowsToExecute == null) {
194 buildAndThrowException(execution, "Could not resume Macro flow. Error loading execution path.");
196 } else if (aLaCarte && isResume) {
197 flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
198 if (flowsToExecute == null) {
199 buildAndThrowException(execution,
200 "Could not resume request with request Id: " + requestId + ". No flowsToExecute was found");
203 String vnfType = (String) execution.getVariable(VNF_TYPE);
204 String cloudOwner = getCloudOwner(requestDetails.getCloudConfiguration());
205 List<OrchestrationFlow> orchFlows =
206 (List<OrchestrationFlow>) execution.getVariable(BBConstants.G_ORCHESTRATION_FLOW);
207 final String apiVersion = (String) execution.getVariable(BBConstants.G_APIVERSION);
208 final String serviceType =
209 Optional.ofNullable((String) execution.getVariable(BBConstants.G_SERVICE_TYPE)).orElse("");
211 if (orchFlows == null || orchFlows.isEmpty()) {
212 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, true,
213 cloudOwner, serviceType);
216 ModelInfo modelInfo = sIRequest.getRequestDetails().getModelInfo();
217 if (modelInfo != null) {
218 if (modelInfo.getModelType().equals(ModelType.service)) {
219 key = modelInfo.getModelVersionId();
221 key = modelInfo.getModelCustomizationId();
224 boolean isConfiguration = isConfiguration(orchFlows);
225 Resource resourceKey = new Resource(resourceType, key, true);
226 if (isConfiguration && !requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
227 List<ExecuteBuildingBlock> configBuildingBlocks = getConfigBuildingBlocks(
228 new ConfigBuildingBlocksDataObject().setsIRequest(sIRequest).setOrchFlows(orchFlows)
229 .setRequestId(requestId).setResourceKey(resourceKey).setApiVersion(apiVersion)
230 .setResourceId(resourceId).setRequestAction(requestAction).setaLaCarte(true)
231 .setVnfType(vnfType).setWorkflowResourceIds(workflowResourceIds)
232 .setRequestDetails(requestDetails).setExecution(execution));
234 flowsToExecute.addAll(configBuildingBlocks);
236 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().contains(FABRIC_CONFIGURATION))
237 .collect(Collectors.toList());
239 if ((requestAction.equalsIgnoreCase(REPLACEINSTANCE)
240 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS))
241 && resourceType.equals(WorkflowType.VFMODULE)) {
242 logger.debug("Build a BB list for replacing BB modules");
243 orchFlows = getVfModuleReplaceBuildingBlocks(
244 new ConfigBuildingBlocksDataObject().setsIRequest(sIRequest).setOrchFlows(orchFlows)
245 .setRequestId(requestId).setResourceKey(resourceKey).setApiVersion(apiVersion)
246 .setResourceId(resourceId).setRequestAction(requestAction).setaLaCarte(true)
247 .setVnfType(vnfType).setWorkflowResourceIds(workflowResourceIds)
248 .setRequestDetails(requestDetails).setExecution(execution));
250 for (OrchestrationFlow orchFlow : orchFlows) {
251 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, resourceKey,
252 apiVersion, resourceId, requestAction, true, vnfType, workflowResourceIds,
253 requestDetails, false, null, null, false);
254 flowsToExecute.add(ebb);
257 boolean foundRelated = false;
258 boolean containsService = false;
259 List<Resource> resourceList = new ArrayList<>();
260 List<Pair<WorkflowType, String>> aaiResourceIds = new ArrayList<>();
261 if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(ASSIGNINSTANCE)) {
262 // SERVICE-MACRO-ASSIGN will always get user params with a
264 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
265 List<Map<String, Object>> userParams =
266 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
267 for (Map<String, Object> params : userParams) {
268 if (params.containsKey(USERPARAMSERVICE)) {
269 containsService = true;
272 if (containsService) {
273 traverseUserParamsService(execution, resourceList, sIRequest, requestAction);
276 buildAndThrowException(execution,
277 "Service-Macro-Assign request details must contain user params with a service");
279 } else if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
280 // SERVICE-MACRO-CREATE will get user params with a service,
281 // a service with a network, a service with a
282 // networkcollection, OR an empty service.
283 // If user params is just a service or null and macro
284 // queries the SI and finds a VNF, macro fails.
286 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
287 List<Map<String, Object>> userParams =
288 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
289 for (Map<String, Object> params : userParams) {
290 if (params.containsKey(USERPARAMSERVICE)) {
291 containsService = true;
295 if (containsService) {
296 foundRelated = traverseUserParamsService(execution, resourceList, sIRequest, requestAction);
299 traverseCatalogDbService(execution, sIRequest, resourceList, aaiResourceIds);
301 } else if (resourceType == WorkflowType.SERVICE
302 && ("activateInstance".equalsIgnoreCase(requestAction)
303 || "unassignInstance".equalsIgnoreCase(requestAction)
304 || "deleteInstance".equalsIgnoreCase(requestAction)
305 || requestAction.equalsIgnoreCase("activate" + FABRIC_CONFIGURATION))) {
306 // SERVICE-MACRO-ACTIVATE, SERVICE-MACRO-UNASSIGN, and
307 // SERVICE-MACRO-DELETE
308 // Will never get user params with service, macro will have
309 // to query the SI in AAI to find related instances.
310 traverseAAIService(execution, resourceList, resourceId, aaiResourceIds);
311 } else if (resourceType == WorkflowType.SERVICE
312 && "deactivateInstance".equalsIgnoreCase(requestAction)) {
313 resourceList.add(new Resource(WorkflowType.SERVICE, "", false));
314 } else if (resourceType == WorkflowType.VNF && ("replaceInstance".equalsIgnoreCase(requestAction)
315 || ("recreateInstance".equalsIgnoreCase(requestAction)))) {
316 traverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
317 workflowResourceIds.getVnfId(), aaiResourceIds);
319 buildAndThrowException(execution, "Current Macro Request is not supported");
321 String foundObjects = "";
322 for (WorkflowType type : WorkflowType.values()) {
323 foundObjects = foundObjects + type + " - " + resourceList.stream()
324 .filter(x -> type.equals(x.getResourceType())).collect(Collectors.toList()).size()
327 logger.info("Found {}", foundObjects);
329 if (orchFlows == null || orchFlows.isEmpty()) {
330 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, aLaCarte,
331 cloudOwner, serviceType);
333 boolean vnfReplace = false;
334 if (resourceType.equals(WorkflowType.VNF) && ("replaceInstance".equalsIgnoreCase(requestAction)
335 || "replaceInstanceRetainAssignments".equalsIgnoreCase(requestAction))) {
338 flowsToExecute = buildExecuteBuildingBlockList(orchFlows, resourceList, requestId, apiVersion,
339 resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, vnfReplace);
340 if (!resourceList.stream().filter(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType())
341 .collect(Collectors.toList()).isEmpty()) {
342 logger.info("Sorting for Vlan Tagging");
343 flowsToExecute = sortExecutionPathByObjectForVlanTagging(flowsToExecute, requestAction);
345 // By default, enable homing at VNF level for CREATEINSTANCE and ASSIGNINSTANCE
346 if (resourceType == WorkflowType.SERVICE
347 && (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE))
348 && !resourceList.stream().filter(x -> WorkflowType.VNF.equals(x.getResourceType()))
349 .collect(Collectors.toList()).isEmpty()) {
350 execution.setVariable("homing", true);
351 execution.setVariable("calledHoming", false);
353 if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE)
354 || requestAction.equalsIgnoreCase(CREATEINSTANCE))) {
355 generateResourceIds(flowsToExecute, resourceList, serviceInstanceId);
357 updateResourceIdsFromAAITraversal(flowsToExecute, resourceList, aaiResourceIds,
362 // If the user set "Homing_Solution" to "none", disable homing, else if "Homing_Solution" is specified,
364 if (sIRequest.getRequestDetails().getRequestParameters() != null
365 && sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
366 List<Map<String, Object>> userParams =
367 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
368 for (Map<String, Object> params : userParams) {
369 if (params.containsKey(HOMINGSOLUTION)) {
370 if ("none".equals(params.get(HOMINGSOLUTION))) {
371 execution.setVariable("homing", false);
373 execution.setVariable("homing", true);
379 if (CollectionUtils.isEmpty(flowsToExecute)) {
380 throw new IllegalStateException("Macro did not come up with a valid execution path.");
383 List<String> flowNames = new ArrayList<>();
384 logger.info("List of BuildingBlocks to execute:");
386 flowsToExecute.forEach(ebb -> {
387 logger.info(ebb.getBuildingBlock().getBpmnFlowName());
388 flowNames.add(ebb.getBuildingBlock().getBpmnFlowName());
392 bbInputSetupUtils.persistFlowExecutionPath(requestId, flowsToExecute);
394 execution.setVariable("flowNames", flowNames);
395 execution.setVariable(BBConstants.G_CURRENT_SEQUENCE, 0);
396 execution.setVariable("retryCount", 0);
397 execution.setVariable("isRollback", false);
398 execution.setVariable("flowsToExecute", flowsToExecute);
399 execution.setVariable("isRollbackComplete", false);
401 } catch (Exception ex) {
402 if (!(execution.hasVariable("WorkflowException")
403 || execution.hasVariable("WorkflowExceptionExceptionMessage"))) {
404 buildAndThrowException(execution, "Exception while setting execution list. ", ex);
411 private String getCloudOwner(CloudConfiguration cloudConfiguration) {
412 if (cloudConfiguration != null && cloudConfiguration.getCloudOwner() != null) {
413 return cloudConfiguration.getCloudOwner();
415 logger.warn("cloud owner value not found in request details, it will be set as default");
416 return environment.getProperty(defaultCloudOwner);
419 protected <T> List<T> getRelatedResourcesInVfModule(String vnfId, String vfModuleId, Class<T> resultClass,
420 AAIObjectType type) {
421 List<T> vnfcs = new ArrayList<>();
422 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VF_MODULE, vnfId, vfModuleId);
423 AAIResultWrapper vfModuleResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
424 Optional<Relationships> relationshipsOp = vfModuleResultsWrapper.getRelationships();
425 if (!relationshipsOp.isPresent()) {
426 logger.debug("No relationships were found for vfModule in AAI");
428 Relationships relationships = relationshipsOp.get();
429 List<AAIResultWrapper> vnfcResultWrappers = relationships.getByType(type);
430 for (AAIResultWrapper vnfcResultWrapper : vnfcResultWrappers) {
431 Optional<T> vnfcOp = vnfcResultWrapper.asBean(resultClass);
432 vnfcOp.ifPresent(vnfcs::add);
438 protected <T> List<T> getRelatedResourcesInVnfc(Vnfc vnfc, Class<T> resultClass, AAIObjectType type) {
440 List<T> configurations = new ArrayList<>();
441 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VNFC, vnfc.getVnfcName());
442 AAIResultWrapper vnfcResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
443 Optional<Relationships> relationshipsOp = vnfcResultsWrapper.getRelationships();
444 if (!relationshipsOp.isPresent()) {
445 logger.debug("No relationships were found for VNFC in AAI");
447 Relationships relationships = relationshipsOp.get();
448 List<AAIResultWrapper> configurationResultWrappers =
449 this.getResultWrappersFromRelationships(relationships, type);
450 for (AAIResultWrapper configurationResultWrapper : configurationResultWrappers) {
451 Optional<T> configurationOp = configurationResultWrapper.asBean(resultClass);
452 configurationOp.ifPresent(configurations::add);
455 return configurations;
458 protected List<AAIResultWrapper> getResultWrappersFromRelationships(Relationships relationships,
459 AAIObjectType type) {
460 return relationships.getByType(type);
463 protected boolean isConfiguration(List<OrchestrationFlow> orchFlows) {
464 for (OrchestrationFlow flow : orchFlows) {
465 if (flow.getFlowName().contains(CONFIGURATION) && !"ConfigurationScaleOutBB".equals(flow.getFlowName())) {
472 protected List<ExecuteBuildingBlock> getConfigBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
475 List<ExecuteBuildingBlock> flowsToExecuteConfigs = new ArrayList<>();
476 List<OrchestrationFlow> result = dataObj.getOrchFlows().stream()
477 .filter(item -> item.getFlowName().contains(FABRIC_CONFIGURATION)).collect(Collectors.toList());
478 String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
479 String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
481 String vnfCustomizationUUID = bbInputSetupUtils.getAAIGenericVnf(vnfId).getModelCustomizationId();
482 String vfModuleCustomizationUUID = "";
483 org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
485 if (aaiVfModule == null) {
486 logger.error("No matching VfModule is found in Generic-Vnf in AAI for vnfId: {} and vfModuleId : {}", vnfId,
488 throw new AAIEntityNotFoundException("No matching VfModule is found in Generic-Vnf in AAI for vnfId: "
489 + vnfId + " and vfModuleId : " + vfModuleId);
491 vfModuleCustomizationUUID = aaiVfModule.getModelCustomizationId();
494 List<org.onap.aai.domain.yang.Vnfc> vnfcs = getRelatedResourcesInVfModule(vnfId, vfModuleId,
495 org.onap.aai.domain.yang.Vnfc.class, AAIObjectType.VNFC);
496 for (org.onap.aai.domain.yang.Vnfc vnfc : vnfcs) {
497 List<org.onap.aai.domain.yang.Configuration> configurations = getRelatedResourcesInVnfc(vnfc,
498 org.onap.aai.domain.yang.Configuration.class, AAIObjectType.CONFIGURATION);
499 if (configurations.size() > 1) {
500 String multipleRelationshipsError =
501 "Multiple relationships exist from VNFC " + vnfc.getVnfcName() + " to Configurations";
502 buildAndThrowException(dataObj.getExecution(), "Exception in getConfigBuildingBlock: ",
503 new Exception(multipleRelationshipsError));
505 for (org.onap.aai.domain.yang.Configuration configuration : configurations) {
506 dataObj.getWorkflowResourceIds().setConfigurationId(configuration.getConfigurationId());
507 for (OrchestrationFlow orchFlow : result) {
508 dataObj.getResourceKey().setVfModuleCustomizationId(vfModuleCustomizationUUID);
509 dataObj.getResourceKey().setCvnfModuleCustomizationId(vnfc.getModelCustomizationId());
510 dataObj.getResourceKey().setVnfCustomizationId(vnfCustomizationUUID);
511 String vnfcName = getVnfcNameForConfiguration(configuration);
512 if (vnfcName == null || vnfcName.isEmpty()) {
513 buildAndThrowException(dataObj.getExecution(), "Exception in create execution list "
514 + ": VnfcName does not exist or is null while there is a configuration for the vfModule",
515 new Exception("Vnfc and Configuration do not match"));
517 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, dataObj.getRequestId(),
518 dataObj.getResourceKey(), dataObj.getApiVersion(), dataObj.getResourceId(),
519 dataObj.getRequestAction(), dataObj.isaLaCarte(), dataObj.getVnfType(),
520 dataObj.getWorkflowResourceIds(), dataObj.getRequestDetails(), false, null, vnfcName, true);
521 flowsToExecuteConfigs.add(ebb);
525 return flowsToExecuteConfigs;
528 protected List<OrchestrationFlow> getVfModuleReplaceBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
531 String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
532 String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
534 logger.debug("BUILDING REPLACE LIST");
536 boolean volumeGroupExisted = false;
537 boolean volumeGroupWillExist = false;
538 boolean keepVolumeGroup = false;
540 boolean rebuildVolumeGroups = false;
541 if (dataObj.getRequestDetails().getRequestParameters() != null
542 && dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups() != null) {
543 rebuildVolumeGroups =
544 dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups().booleanValue();
547 Optional<VolumeGroup> volumeGroupFromVfModule =
548 bbInputSetupUtils.getRelatedVolumeGroupFromVfModule(vnfId, vfModuleId);
549 if (volumeGroupFromVfModule.isPresent()) {
550 String volumeGroupId = volumeGroupFromVfModule.get().getVolumeGroupId();
551 logger.debug("Volume group id of the existing volume group is: " + volumeGroupId);
552 volumeGroupExisted = true;
553 dataObj.getWorkflowResourceIds().setVolumeGroupId(volumeGroupId);
556 List<OrchestrationFlow> orchFlows = dataObj.getOrchFlows();
557 VfModuleCustomization vfModuleCustomization = catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
558 dataObj.getRequestDetails().getModelInfo().getModelCustomizationUuid());
559 if (vfModuleCustomization != null && vfModuleCustomization.getVfModule() != null
560 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
561 && vfModuleCustomization.getVolumeHeatEnv() != null) {
562 volumeGroupWillExist = true;
563 if (!volumeGroupExisted) {
564 String newVolumeGroupId = UUID.randomUUID().toString();
565 dataObj.getWorkflowResourceIds().setVolumeGroupId(newVolumeGroupId);
566 logger.debug("newVolumeGroupId: " + newVolumeGroupId);
570 if (volumeGroupExisted && volumeGroupWillExist && !rebuildVolumeGroups) {
571 keepVolumeGroup = true;
574 if (!volumeGroupExisted || keepVolumeGroup) {
575 logger.debug("Filtering out deletion of volume groups");
576 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_DELETE_PATTERN))
577 .collect(Collectors.toList());
579 if (!volumeGroupWillExist || keepVolumeGroup) {
580 logger.debug("Filtering out creation of volume groups");
581 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_CREATE_PATTERN))
582 .collect(Collectors.toList());
588 protected String getVnfcNameForConfiguration(org.onap.aai.domain.yang.Configuration configuration) {
589 AAIResultWrapper wrapper = new AAIResultWrapper(configuration);
590 Optional<Relationships> relationshipsOp = wrapper.getRelationships();
591 if (!relationshipsOp.isPresent()) {
592 logger.debug("No relationships were found for Configuration in AAI");
595 Relationships relationships = relationshipsOp.get();
596 List<AAIResultWrapper> vnfcResultWrappers = relationships.getByType(AAIObjectType.VNFC);
597 if (vnfcResultWrappers.size() > 1 || vnfcResultWrappers.isEmpty()) {
598 logger.debug("Too many vnfcs or no vnfc found that are related to configuration");
600 Optional<Vnfc> vnfcOp = vnfcResultWrappers.get(0).asBean(Vnfc.class);
601 return vnfcOp.map(Vnfc::getVnfcName).orElse(null);
605 protected List<Resource> sortVfModulesByBaseFirst(List<Resource> vfModuleResources) {
607 for (Resource resource : vfModuleResources) {
608 if (resource.isBaseVfModule()) {
609 Collections.swap(vfModuleResources, 0, count);
614 return vfModuleResources;
617 protected List<Resource> sortVfModulesByBaseLast(List<Resource> vfModuleResources) {
619 for (Resource resource : vfModuleResources) {
620 if (resource.isBaseVfModule()) {
621 Collections.swap(vfModuleResources, vfModuleResources.size() - 1, count);
626 return vfModuleResources;
629 private void updateResourceIdsFromAAITraversal(List<ExecuteBuildingBlock> flowsToExecute,
630 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds, String serviceInstanceId) {
631 for (Pair<WorkflowType, String> pair : aaiResourceIds) {
632 logger.debug(pair.getValue0() + ", " + pair.getValue1());
635 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE)).forEach(type -> {
636 resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
637 .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
638 retrieveAAIResourceId(aaiResourceIds, type), null, serviceInstanceId));
642 private String retrieveAAIResourceId(List<Pair<WorkflowType, String>> aaiResourceIds, WorkflowType resource) {
644 for (int i = 0; i < aaiResourceIds.size(); i++) {
645 if (aaiResourceIds.get(i).getValue0() == resource) {
646 id = aaiResourceIds.get(i).getValue1();
647 aaiResourceIds.remove(i);
654 private void generateResourceIds(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
655 String serviceInstanceId) {
656 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE)).forEach(type -> {
657 resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
658 .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(), null,
659 resource.getVirtualLinkKey(), serviceInstanceId));
663 protected void updateWorkflowResourceIds(List<ExecuteBuildingBlock> flowsToExecute, WorkflowType resourceType,
664 String key, String id, String virtualLinkKey, String serviceInstanceId) {
665 String resourceId = id;
666 if (resourceId == null) {
667 resourceId = UUID.randomUUID().toString();
669 for (ExecuteBuildingBlock ebb : flowsToExecute) {
670 if (key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey()) && (ebb.getBuildingBlock()
671 .getBpmnFlowName().contains(resourceType.toString())
672 || (ebb.getBuildingBlock().getBpmnFlowName().contains(CONTROLLER)
673 && ebb.getBuildingBlock().getBpmnScope().equalsIgnoreCase(resourceType.toString())))) {
674 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
675 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
676 WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, resourceType, resourceId);
677 ebb.setWorkflowResourceIds(workflowResourceIds);
679 if (virtualLinkKey != null && ebb.getBuildingBlock().isVirtualLink()
680 && virtualLinkKey.equalsIgnoreCase(ebb.getBuildingBlock().getVirtualLinkKey())) {
681 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
682 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
683 workflowResourceIds.setNetworkId(resourceId);
684 ebb.setWorkflowResourceIds(workflowResourceIds);
689 protected CollectionResourceCustomization findCatalogNetworkCollection(DelegateExecution execution,
690 org.onap.so.db.catalog.beans.Service service) {
691 CollectionResourceCustomization networkCollection = null;
693 for (CollectionResourceCustomization collectionCust : service.getCollectionResourceCustomizations()) {
694 if (catalogDbClient.getNetworkCollectionResourceCustomizationByID(
695 collectionCust.getModelCustomizationUUID()) != null) {
696 networkCollection = collectionCust;
702 } else if (count > 1) {
703 buildAndThrowException(execution,
704 "Found multiple Network Collections in the Service model, only one per Service is supported.");
706 return networkCollection;
709 protected void traverseCatalogDbService(DelegateExecution execution, ServiceInstancesRequest sIRequest,
710 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds)
711 throws JsonProcessingException, VrfBondingServiceException {
712 String modelUUID = sIRequest.getRequestDetails().getModelInfo().getModelVersionId();
713 org.onap.so.db.catalog.beans.Service service = catalogDbClient.getServiceByID(modelUUID);
714 if (service == null) {
715 buildAndThrowException(execution, "Could not find the service model in catalog db.");
717 resourceList.add(new Resource(WorkflowType.SERVICE, service.getModelUUID(), false));
718 RelatedInstance relatedVpnBinding =
719 bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.vpnBinding);
720 RelatedInstance relatedLocalNetwork =
721 bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.network);
722 if (relatedVpnBinding != null && relatedLocalNetwork != null) {
723 traverseVrfConfiguration(aaiResourceIds, resourceList, service, relatedVpnBinding, relatedLocalNetwork);
725 traverseNetworkCollection(execution, resourceList, service);
730 protected void traverseVrfConfiguration(List<Pair<WorkflowType, String>> aaiResourceIds,
731 List<Resource> resourceList, org.onap.so.db.catalog.beans.Service service,
732 RelatedInstance relatedVpnBinding, RelatedInstance relatedLocalNetwork)
733 throws VrfBondingServiceException, JsonProcessingException {
734 org.onap.aai.domain.yang.L3Network aaiLocalNetwork =
735 bbInputSetupUtils.getAAIL3Network(relatedLocalNetwork.getInstanceId());
736 vrfValidation.vrfServiceValidation(service);
737 vrfValidation.vrfCatalogDbChecks(service);
738 vrfValidation.aaiVpnBindingValidation(relatedVpnBinding.getInstanceId(),
739 bbInputSetupUtils.getAAIVpnBinding(relatedVpnBinding.getInstanceId()));
740 vrfValidation.aaiNetworkValidation(relatedLocalNetwork.getInstanceId(), aaiLocalNetwork);
741 vrfValidation.aaiSubnetValidation(aaiLocalNetwork);
742 vrfValidation.aaiAggregateRouteValidation(aaiLocalNetwork);
743 vrfValidation.aaiRouteTargetValidation(aaiLocalNetwork);
744 String existingAAIVrfConfiguration = getExistingAAIVrfConfiguration(relatedVpnBinding, aaiLocalNetwork);
745 if (existingAAIVrfConfiguration != null) {
746 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, existingAAIVrfConfiguration));
748 resourceList.add(new Resource(WorkflowType.CONFIGURATION,
749 service.getConfigurationCustomizations().get(0).getModelCustomizationUUID(), false));
753 protected String getExistingAAIVrfConfiguration(RelatedInstance relatedVpnBinding,
754 org.onap.aai.domain.yang.L3Network aaiLocalNetwork)
755 throws JsonProcessingException, VrfBondingServiceException {
756 Optional<Relationships> relationshipsOp = new AAIResultWrapper(
757 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiLocalNetwork)).getRelationships();
758 if (relationshipsOp.isPresent()) {
759 List<AAIResultWrapper> configurationsRelatedToLocalNetwork =
760 relationshipsOp.get().getByType(AAIObjectType.CONFIGURATION);
761 if (configurationsRelatedToLocalNetwork.size() > 1) {
762 throw new VrfBondingServiceException(
763 "Network: " + aaiLocalNetwork.getNetworkId() + " has more than 1 configuration related to it");
765 if (configurationsRelatedToLocalNetwork.size() == 1) {
766 AAIResultWrapper configWrapper = configurationsRelatedToLocalNetwork.get(0);
767 Optional<Configuration> relatedConfiguration = configWrapper.asBean(Configuration.class);
768 if (relatedConfiguration.isPresent() && vrfConfigurationAlreadyExists(relatedVpnBinding,
769 relatedConfiguration.get(), configWrapper)) {
770 return relatedConfiguration.get().getConfigurationId();
777 protected boolean vrfConfigurationAlreadyExists(RelatedInstance relatedVpnBinding, Configuration vrfConfiguration,
778 AAIResultWrapper configWrapper) throws VrfBondingServiceException {
779 if ("VRF-ENTRY".equalsIgnoreCase(vrfConfiguration.getConfigurationType())) {
780 Optional<Relationships> relationshipsConfigOp = configWrapper.getRelationships();
781 if (relationshipsConfigOp.isPresent()) {
782 Optional<VpnBinding> relatedInfraVpnBindingOp =
783 workflowActionUtils.extractRelationshipsVpnBinding(relationshipsConfigOp.get());
784 if (relatedInfraVpnBindingOp.isPresent()) {
785 VpnBinding relatedInfraVpnBinding = relatedInfraVpnBindingOp.get();
786 if (!relatedInfraVpnBinding.getVpnId().equalsIgnoreCase(relatedVpnBinding.getInstanceId())) {
787 throw new VrfBondingServiceException("Configuration: " + vrfConfiguration.getConfigurationId()
788 + " is not connected to the same vpn binding id provided in request: "
789 + relatedVpnBinding.getInstanceId());
799 protected void traverseNetworkCollection(DelegateExecution execution, List<Resource> resourceList,
800 org.onap.so.db.catalog.beans.Service service) {
801 if (service.getVnfCustomizations() == null || service.getVnfCustomizations().isEmpty()) {
802 List<CollectionResourceCustomization> customizations = service.getCollectionResourceCustomizations();
803 if (customizations.isEmpty()) {
804 logger.debug("No Collections found. CollectionResourceCustomization list is empty.");
806 CollectionResourceCustomization collectionResourceCustomization =
807 findCatalogNetworkCollection(execution, service);
808 if (collectionResourceCustomization != null) {
809 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
810 collectionResourceCustomization.getModelCustomizationUUID(), false));
811 logger.debug("Found a network collection");
812 if (collectionResourceCustomization.getCollectionResource() != null) {
813 if (collectionResourceCustomization.getCollectionResource().getInstanceGroup() != null) {
814 String toscaNodeType = collectionResourceCustomization.getCollectionResource()
815 .getInstanceGroup().getToscaNodeType();
816 if (toscaNodeType != null && toscaNodeType.contains(NETWORKCOLLECTION)) {
818 org.onap.so.db.catalog.beans.InstanceGroup instanceGroup =
819 collectionResourceCustomization.getCollectionResource().getInstanceGroup();
820 CollectionResourceInstanceGroupCustomization collectionInstCust = null;
821 if (!instanceGroup.getCollectionInstanceGroupCustomizations().isEmpty()) {
822 for (CollectionResourceInstanceGroupCustomization collectionInstanceGroupTemp : instanceGroup
823 .getCollectionInstanceGroupCustomizations()) {
824 if (collectionInstanceGroupTemp.getModelCustomizationUUID().equalsIgnoreCase(
825 collectionResourceCustomization.getModelCustomizationUUID())) {
826 collectionInstCust = collectionInstanceGroupTemp;
830 if (collectionInstCust != null
831 && collectionInstCust.getSubInterfaceNetworkQuantity() != null) {
832 minNetworks = collectionInstCust.getSubInterfaceNetworkQuantity();
835 logger.debug("minNetworks: {}", minNetworks);
836 CollectionNetworkResourceCustomization collectionNetworkResourceCust = null;
837 for (CollectionNetworkResourceCustomization collectionNetworkTemp : instanceGroup
838 .getCollectionNetworkResourceCustomizations()) {
839 if (collectionNetworkTemp.getNetworkResourceCustomization()
840 .getModelCustomizationUUID().equalsIgnoreCase(
841 collectionResourceCustomization.getModelCustomizationUUID())) {
842 collectionNetworkResourceCust = collectionNetworkTemp;
846 for (int i = 0; i < minNetworks; i++) {
847 if (collectionNetworkResourceCust != null && collectionInstCust != null) {
848 Resource resource = new Resource(WorkflowType.VIRTUAL_LINK,
849 collectionNetworkResourceCust.getModelCustomizationUUID(), false);
850 resource.setVirtualLinkKey(Integer.toString(i));
851 resourceList.add(resource);
855 logger.debug("Instance Group tosca node type does not contain NetworkCollection: {}",
859 logger.debug("No Instance Group found for network collection.");
862 logger.debug("No Network Collection found. collectionResource is null");
865 logger.debug("No Network Collection Customization found");
868 if (resourceList.stream().filter(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType())
869 .collect(Collectors.toList()).isEmpty()) {
870 if (service.getNetworkCustomizations() == null) {
871 logger.debug("No networks were found on this service model");
873 for (int i = 0; i < service.getNetworkCustomizations().size(); i++) {
874 resourceList.add(new Resource(WorkflowType.NETWORK,
875 service.getNetworkCustomizations().get(i).getModelCustomizationUUID(), false));
880 buildAndThrowException(execution,
881 "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");
885 protected void traverseAAIService(DelegateExecution execution, List<Resource> resourceList, String resourceId,
886 List<Pair<WorkflowType, String>> aaiResourceIds) {
888 ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(resourceId);
889 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
890 bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
891 resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
892 if (serviceInstanceMSO.getVnfs() != null) {
893 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
894 aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
895 resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
896 if (vnf.getVfModules() != null) {
897 for (VfModule vfModule : vnf.getVfModules()) {
898 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
899 Resource resource = new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false);
900 resource.setBaseVfModule(vfModule.getModelInfoVfModule().getIsBaseBoolean());
901 resourceList.add(resource);
904 if (vnf.getVolumeGroups() != null) {
905 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
906 .getVolumeGroups()) {
907 aaiResourceIds.add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
909 .add(new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
914 if (serviceInstanceMSO.getNetworks() != null) {
915 for (org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network network : serviceInstanceMSO
917 aaiResourceIds.add(new Pair<>(WorkflowType.NETWORK, network.getNetworkId()));
918 resourceList.add(new Resource(WorkflowType.NETWORK, network.getNetworkId(), false));
921 if (serviceInstanceMSO.getCollection() != null) {
922 logger.debug("found networkcollection");
924 .add(new Pair<>(WorkflowType.NETWORKCOLLECTION, serviceInstanceMSO.getCollection().getId()));
925 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
926 serviceInstanceMSO.getCollection().getId(), false));
928 if (serviceInstanceMSO.getConfigurations() != null) {
929 for (Configuration config : serviceInstanceMSO.getConfigurations()) {
930 Optional<org.onap.aai.domain.yang.Configuration> aaiConfig =
931 aaiConfigurationResources.getConfiguration(config.getConfigurationId());
932 if (aaiConfig.isPresent() && aaiConfig.get().getRelationshipList() != null) {
933 for (Relationship relationship : aaiConfig.get().getRelationshipList().getRelationship()) {
934 if (relationship.getRelatedTo().contains("vnfc")
935 || relationship.getRelatedTo().contains("vpn-binding")) {
936 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.getConfigurationId()));
938 new Resource(WorkflowType.CONFIGURATION, config.getConfigurationId(), false));
945 } catch (Exception ex) {
946 logger.error("Exception in traverseAAIService", ex);
947 buildAndThrowException(execution,
948 "Could not find existing Service Instance or related Instances to execute the request on.");
952 private void traverseAAIVnf(DelegateExecution execution, List<Resource> resourceList, String serviceId,
953 String vnfId, List<Pair<WorkflowType, String>> aaiResourceIds) {
955 ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(serviceId);
956 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
957 bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
958 resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
959 if (serviceInstanceMSO.getVnfs() != null) {
960 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
961 if (vnf.getVnfId().equals(vnfId)) {
962 aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
963 resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
964 if (vnf.getVfModules() != null) {
965 for (VfModule vfModule : vnf.getVfModules()) {
966 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
967 resourceList.add(new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false));
968 findConfigurationsInsideVfModule(execution, vnf.getVnfId(), vfModule.getVfModuleId(),
969 resourceList, aaiResourceIds);
972 if (vnf.getVolumeGroups() != null) {
973 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
974 .getVolumeGroups()) {
976 .add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
978 new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
985 } catch (Exception ex) {
986 logger.error("Exception in traverseAAIVnf", ex);
987 buildAndThrowException(execution,
988 "Could not find existing Vnf or related Instances to execute the request on.");
992 private void findConfigurationsInsideVfModule(DelegateExecution execution, String vnfId, String vfModuleId,
993 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds) {
995 org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
996 AAIResultWrapper vfModuleWrapper = new AAIResultWrapper(
997 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiVfModule));
998 Optional<Relationships> relationshipsOp;
999 relationshipsOp = vfModuleWrapper.getRelationships();
1000 if (relationshipsOp.isPresent()) {
1001 relationshipsOp = workflowActionUtils.extractRelationshipsVnfc(relationshipsOp.get());
1002 if (relationshipsOp.isPresent()) {
1003 Optional<Configuration> config =
1004 workflowActionUtils.extractRelationshipsConfiguration(relationshipsOp.get());
1005 if (config.isPresent()) {
1006 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.get().getConfigurationId()));
1008 new Resource(WorkflowType.CONFIGURATION, config.get().getConfigurationId(), false));
1012 } catch (Exception ex) {
1013 logger.error("Exception in findConfigurationsInsideVfModule", ex);
1014 buildAndThrowException(execution, "Failed to find Configuration object from the vfModule.");
1018 protected boolean traverseUserParamsService(DelegateExecution execution, List<Resource> resourceList,
1019 ServiceInstancesRequest sIRequest, String requestAction) throws IOException {
1020 boolean foundRelated = false;
1021 boolean foundVfModuleOrVG = false;
1022 String vnfCustomizationUUID = "";
1023 String vfModuleCustomizationUUID = "";
1024 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
1025 List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
1026 for (Map<String, Object> params : userParams) {
1027 if (params.containsKey(USERPARAMSERVICE)) {
1028 ObjectMapper obj = new ObjectMapper();
1029 String input = obj.writeValueAsString(params.get(USERPARAMSERVICE));
1030 Service validate = obj.readValue(input, Service.class);
1032 new Resource(WorkflowType.SERVICE, validate.getModelInfo().getModelVersionId(), false));
1033 if (validate.getResources().getVnfs() != null) {
1034 for (Vnfs vnf : validate.getResources().getVnfs()) {
1035 resourceList.add(new Resource(WorkflowType.VNF,
1036 vnf.getModelInfo().getModelCustomizationId(), false));
1037 foundRelated = true;
1038 if (vnf.getModelInfo() != null && vnf.getModelInfo().getModelCustomizationUuid() != null) {
1039 vnfCustomizationUUID = vnf.getModelInfo().getModelCustomizationUuid();
1041 if (vnf.getVfModules() != null) {
1042 for (VfModules vfModule : vnf.getVfModules()) {
1043 VfModuleCustomization vfModuleCustomization =
1044 catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
1045 vfModule.getModelInfo().getModelCustomizationUuid());
1046 if (vfModuleCustomization != null) {
1048 if (vfModuleCustomization.getVfModule() != null
1049 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
1050 && vfModuleCustomization.getVolumeHeatEnv() != null) {
1051 resourceList.add(new Resource(WorkflowType.VOLUMEGROUP,
1052 vfModuleCustomization.getModelCustomizationUUID(), false));
1053 foundRelated = true;
1054 foundVfModuleOrVG = true;
1057 if (vfModuleCustomization.getVfModule() != null
1058 && vfModuleCustomization.getVfModule().getModuleHeatTemplate() != null
1059 && vfModuleCustomization.getHeatEnvironment() != null) {
1060 foundRelated = true;
1061 foundVfModuleOrVG = true;
1062 Resource resource = new Resource(WorkflowType.VFMODULE,
1063 vfModuleCustomization.getModelCustomizationUUID(), false);
1064 if (vfModuleCustomization.getVfModule().getIsBase() != null
1065 && vfModuleCustomization.getVfModule().getIsBase()) {
1066 resource.setBaseVfModule(true);
1068 resource.setBaseVfModule(false);
1070 resourceList.add(resource);
1071 if (vfModule.getModelInfo() != null
1072 && vfModule.getModelInfo().getModelCustomizationUuid() != null) {
1073 vfModuleCustomizationUUID =
1074 vfModule.getModelInfo().getModelCustomizationUuid();
1076 if (!vnfCustomizationUUID.isEmpty()
1077 && !vfModuleCustomizationUUID.isEmpty()) {
1078 List<CvnfcConfigurationCustomization> configs =
1079 traverseCatalogDbForConfiguration(
1080 validate.getModelInfo().getModelVersionId(),
1081 vnfCustomizationUUID, vfModuleCustomizationUUID);
1082 for (CvnfcConfigurationCustomization config : configs) {
1083 Resource configResource = new Resource(WorkflowType.CONFIGURATION,
1084 config.getConfigurationResource().getModelUUID(), false);
1085 resource.setVnfCustomizationId(
1086 vnf.getModelInfo().getModelCustomizationId());
1087 resource.setVfModuleCustomizationId(
1088 vfModule.getModelInfo().getModelCustomizationId());
1089 resourceList.add(configResource);
1093 if (!foundVfModuleOrVG) {
1094 buildAndThrowException(execution,
1095 "Could not determine if vfModule was a vfModule or volume group. Heat template and Heat env are null");
1102 if (validate.getResources().getPnfs() != null) {
1103 for (Pnfs pnf : validate.getResources().getPnfs()) {
1104 resourceList.add(new Resource(WorkflowType.PNF,
1105 pnf.getModelInfo().getModelCustomizationId(), false));
1106 foundRelated = true;
1109 if (validate.getResources().getNetworks() != null) {
1110 for (Networks network : validate.getResources().getNetworks()) {
1111 resourceList.add(new Resource(WorkflowType.NETWORK,
1112 network.getModelInfo().getModelCustomizationId(), false));
1113 foundRelated = true;
1115 if (requestAction.equals(CREATEINSTANCE)) {
1116 String networkColCustId = queryCatalogDBforNetworkCollection(execution, sIRequest);
1117 if (networkColCustId != null) {
1118 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION, networkColCustId, false));
1119 foundRelated = true;
1127 return foundRelated;
1130 protected List<CvnfcConfigurationCustomization> traverseCatalogDbForConfiguration(String serviceModelUUID,
1131 String vnfCustomizationUUID, String vfModuleCustomizationUUID) {
1132 List<CvnfcConfigurationCustomization> configurations = new ArrayList<>();
1134 List<CvnfcCustomization> cvnfcCustomizations = catalogDbClient.getCvnfcCustomization(serviceModelUUID,
1135 vnfCustomizationUUID, vfModuleCustomizationUUID);
1136 for (CvnfcCustomization cvnfc : cvnfcCustomizations) {
1137 for (CvnfcConfigurationCustomization customization : cvnfc.getCvnfcConfigurationCustomization()) {
1138 if (customization.getConfigurationResource().getToscaNodeType().contains(FABRIC_CONFIGURATION)) {
1139 configurations.add(customization);
1143 logger.debug("found {} fabric configuration(s)", configurations.size());
1144 return configurations;
1145 } catch (Exception ex) {
1146 logger.error("Error in finding configurations", ex);
1147 return configurations;
1151 protected String queryCatalogDBforNetworkCollection(DelegateExecution execution,
1152 ServiceInstancesRequest sIRequest) {
1153 org.onap.so.db.catalog.beans.Service service =
1154 catalogDbClient.getServiceByID(sIRequest.getRequestDetails().getModelInfo().getModelVersionId());
1155 if (service != null) {
1156 CollectionResourceCustomization networkCollection = this.findCatalogNetworkCollection(execution, service);
1157 if (networkCollection != null) {
1158 return networkCollection.getModelCustomizationUUID();
1164 protected WorkflowResourceIds populateResourceIdsFromApiHandler(DelegateExecution execution) {
1165 return WorkflowResourceIdsUtils.getWorkflowResourceIdsFromExecution(execution);
1168 protected Resource extractResourceIdAndTypeFromUri(String uri) {
1169 Pattern patt = Pattern.compile("[vV]\\d+.*?(?:(?:/(?<type>" + SUPPORTEDTYPES
1170 + ")(?:/(?<id>[^/]+))?)(?:/(?<action>[^/]+))?(?:/resume)?)?$");
1171 Matcher m = patt.matcher(uri);
1172 boolean generated = false;
1175 logger.debug("found match on {} : {} ", uri, m);
1176 String type = m.group("type");
1177 String id = m.group("id");
1178 String action = m.group("action");
1180 throw new IllegalArgumentException("Uri could not be parsed. No type found. " + uri);
1182 if (action == null) {
1183 if (type.equals(SERVICE_INSTANCES) && (id == null || "assign".equals(id))) {
1184 id = UUID.randomUUID().toString();
1186 } else if (type.equals(VF_MODULES) && "scaleOut".equals(id)) {
1187 id = UUID.randomUUID().toString();
1191 if (action.matches(SUPPORTEDTYPES)) {
1192 id = UUID.randomUUID().toString();
1197 return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated);
1199 throw new IllegalArgumentException("Uri could not be parsed: " + uri);
1203 protected String validateResourceIdInAAI(String generatedResourceId, WorkflowType type, String instanceName,
1204 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws Exception {
1206 if ("SERVICE".equalsIgnoreCase(type.toString())) {
1207 return validateServiceResourceIdInAAI(generatedResourceId, instanceName, reqDetails);
1208 } else if ("NETWORK".equalsIgnoreCase(type.toString())) {
1209 return validateNetworkResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1210 workflowResourceIds);
1211 } else if ("VNF".equalsIgnoreCase(type.toString())) {
1212 return validateVnfResourceIdInAAI(generatedResourceId, instanceName, reqDetails, workflowResourceIds);
1213 } else if ("VFMODULE".equalsIgnoreCase(type.toString())) {
1214 return validateVfModuleResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1215 workflowResourceIds);
1216 } else if ("VOLUMEGROUP".equalsIgnoreCase(type.toString())) {
1217 return validateVolumeGroupResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1218 workflowResourceIds);
1219 } else if ("CONFIGURATION".equalsIgnoreCase(type.toString())) {
1220 return validateConfigurationResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1221 workflowResourceIds);
1223 return generatedResourceId;
1224 } catch (DuplicateNameException dne) {
1226 } catch (Exception ex) {
1227 logger.error(WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI, ex);
1228 throw new IllegalStateException(
1229 WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI);
1233 protected String convertTypeFromPlural(String type) {
1234 if (!type.matches(SUPPORTEDTYPES)) {
1237 if (type.equals(SERVICE_INSTANCES)) {
1240 return type.substring(0, 1).toUpperCase() + type.substring(1, type.length() - 1);
1245 protected List<ExecuteBuildingBlock> sortExecutionPathByObjectForVlanTagging(List<ExecuteBuildingBlock> orchFlows,
1246 String requestAction) {
1247 List<ExecuteBuildingBlock> sortedOrchFlows = new ArrayList<>();
1248 if (requestAction.equals(CREATEINSTANCE)) {
1249 for (ExecuteBuildingBlock ebb : orchFlows) {
1250 if (ebb.getBuildingBlock().getBpmnFlowName().equals("AssignNetworkBB")) {
1251 String key = ebb.getBuildingBlock().getKey();
1252 boolean isVirtualLink = Boolean.TRUE.equals(ebb.getBuildingBlock().isVirtualLink());
1253 String virtualLinkKey = ebb.getBuildingBlock().getVirtualLinkKey();
1254 sortedOrchFlows.add(ebb);
1255 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1256 if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1257 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1258 sortedOrchFlows.add(ebb2);
1261 if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1262 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1263 sortedOrchFlows.add(ebb2);
1267 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1268 if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1269 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1270 sortedOrchFlows.add(ebb2);
1273 if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1274 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1275 sortedOrchFlows.add(ebb2);
1279 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1280 || ebb.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)) {
1282 } else if (!"".equals(ebb.getBuildingBlock().getBpmnFlowName())) {
1283 sortedOrchFlows.add(ebb);
1286 } else if (requestAction.equals("deleteInstance")) {
1287 for (ExecuteBuildingBlock ebb : orchFlows) {
1288 if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeactivateNetworkBB")) {
1289 sortedOrchFlows.add(ebb);
1290 String key = ebb.getBuildingBlock().getKey();
1291 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1292 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1293 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1294 sortedOrchFlows.add(ebb2);
1298 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1299 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")
1300 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1301 sortedOrchFlows.add(ebb2);
1305 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1306 || ebb.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")) {
1308 } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) {
1309 sortedOrchFlows.add(ebb);
1313 return sortedOrchFlows;
1316 private void addBuildingBlockToExecuteBBList(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
1317 WorkflowType workflowType, OrchestrationFlow orchFlow, String requestId, String apiVersion,
1318 String resourceId, String requestAction, String vnfType, WorkflowResourceIds workflowResourceIds,
1319 RequestDetails requestDetails, boolean isVirtualLink, boolean isConfiguration) {
1321 resourceList.stream().filter(resource -> resource.getResourceType().equals(workflowType))
1322 .forEach(resource -> flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource,
1323 apiVersion, resourceId, requestAction, false, vnfType, workflowResourceIds, requestDetails,
1324 isVirtualLink, resource.getVirtualLinkKey(), null, isConfiguration)));
1327 protected List<ExecuteBuildingBlock> buildExecuteBuildingBlockList(List<OrchestrationFlow> orchFlows,
1328 List<Resource> resourceList, String requestId, String apiVersion, String resourceId, String requestAction,
1329 String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1330 boolean replaceVnf) {
1331 List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
1332 for (OrchestrationFlow orchFlow : orchFlows) {
1333 if (orchFlow.getFlowName().contains(SERVICE)) {
1335 workflowResourceIds.setServiceInstanceId(resourceId);
1337 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.SERVICE, orchFlow, requestId,
1338 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1340 } else if (orchFlow.getFlowName().contains(VNF) || (orchFlow.getFlowName().contains(CONTROLLER)
1341 && (VNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1342 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VNF, orchFlow, requestId,
1343 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1345 } else if (orchFlow.getFlowName().contains(PNF)) {
1346 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.PNF, orchFlow, requestId,
1347 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1349 } else if (orchFlow.getFlowName().contains(NETWORK)
1350 && !orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1351 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORK, orchFlow, requestId,
1352 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1354 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VIRTUAL_LINK, orchFlow,
1355 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1357 } else if (orchFlow.getFlowName().contains(VFMODULE) || (orchFlow.getFlowName().contains(CONTROLLER)
1358 && (VFMODULE).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1359 List<Resource> vfModuleResourcesSorted = null;
1360 if (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE)
1361 || requestAction.equals("activateInstance")) {
1362 vfModuleResourcesSorted = sortVfModulesByBaseFirst(resourceList.stream()
1363 .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1365 vfModuleResourcesSorted = sortVfModulesByBaseLast(resourceList.stream()
1366 .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1368 for (int i = 0; i < vfModuleResourcesSorted.size(); i++) {
1369 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, vfModuleResourcesSorted.get(i),
1370 apiVersion, resourceId, requestAction, false, vnfType, workflowResourceIds, requestDetails,
1371 false, null, null, false));
1373 } else if (orchFlow.getFlowName().contains(VOLUMEGROUP)) {
1374 if (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1375 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)) {
1376 logger.debug("Replacing workflow resource id by volume group id");
1377 resourceId = workflowResourceIds.getVolumeGroupId();
1379 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VOLUMEGROUP, orchFlow,
1380 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1382 } else if (orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1383 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORKCOLLECTION, orchFlow,
1384 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1386 } else if (orchFlow.getFlowName().contains(CONFIGURATION)) {
1387 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.CONFIGURATION, orchFlow,
1388 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1391 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, null, apiVersion, resourceId,
1392 requestAction, false, vnfType, workflowResourceIds, requestDetails, false, null, null, false));
1395 return flowsToExecute;
1398 protected ExecuteBuildingBlock buildExecuteBuildingBlock(OrchestrationFlow orchFlow, String requestId,
1399 Resource resource, String apiVersion, String resourceId, String requestAction, boolean aLaCarte,
1400 String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1401 boolean isVirtualLink, String virtualLinkKey, String vnfcName, boolean isConfiguration) {
1403 BuildingBlock buildingBlock =
1404 new BuildingBlock().setBpmnFlowName(orchFlow.getFlowName()).setMsoId(UUID.randomUUID().toString())
1405 .setIsVirtualLink(isVirtualLink).setVirtualLinkKey(virtualLinkKey)
1406 .setKey(Optional.ofNullable(resource).map(Resource::getResourceId).orElse(""));
1407 Optional.ofNullable(orchFlow.getBpmnAction()).ifPresent(action -> buildingBlock.setBpmnAction(action));
1408 Optional.ofNullable(orchFlow.getBpmnScope()).ifPresent(scope -> buildingBlock.setBpmnScope(scope));
1410 if (resource != null
1411 && (orchFlow.getFlowName().contains(VOLUMEGROUP) && (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1412 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)))) {
1413 logger.debug("Setting resourceId to volume group id for volume group flow on replace");
1414 resourceId = workflowResourceIds.getVolumeGroupId();
1417 ExecuteBuildingBlock executeBuildingBlock = new ExecuteBuildingBlock().setApiVersion(apiVersion)
1418 .setaLaCarte(aLaCarte).setRequestAction(requestAction).setResourceId(resourceId).setVnfType(vnfType)
1419 .setWorkflowResourceIds(workflowResourceIds).setRequestId(requestId).setBuildingBlock(buildingBlock)
1420 .setRequestDetails(requestDetails);
1422 if (resource != null && (isConfiguration || resource.getResourceType().equals(WorkflowType.CONFIGURATION))) {
1423 ConfigurationResourceKeys configurationResourceKeys = new ConfigurationResourceKeys();
1424 Optional.ofNullable(vnfcName).ifPresent(name -> configurationResourceKeys.setVnfcName(name));
1425 configurationResourceKeys.setCvnfcCustomizationUUID(resource.getCvnfModuleCustomizationId());
1426 configurationResourceKeys.setVfModuleCustomizationUUID(resource.getVfModuleCustomizationId());
1427 configurationResourceKeys.setVnfResourceCustomizationUUID(resource.getVnfCustomizationId());
1428 executeBuildingBlock.setConfigurationResourceKeys(configurationResourceKeys);
1430 return executeBuildingBlock;
1433 protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1434 WorkflowType resourceName, boolean aLaCarte, String cloudOwner) {
1435 return this.queryNorthBoundRequestCatalogDb(execution, requestAction, resourceName, aLaCarte, cloudOwner, "");
1438 protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1439 WorkflowType resourceName, boolean aLaCarte, String cloudOwner, String serviceType) {
1440 List<OrchestrationFlow> listToExecute = new ArrayList<>();
1441 NorthBoundRequest northBoundRequest = null;
1442 if (serviceType.equalsIgnoreCase(SERVICE_TYPE_TRANSPORT)
1443 || serviceType.equalsIgnoreCase(SERVICE_TYPE_BONDING)) {
1445 catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwnerAndServiceType(
1446 requestAction, resourceName.toString(), aLaCarte, cloudOwner, serviceType);
1448 northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1449 requestAction, resourceName.toString(), aLaCarte, cloudOwner);
1451 if (northBoundRequest == null) {
1452 northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1453 requestAction, resourceName.toString(), aLaCarte, CLOUD_OWNER);
1455 if (northBoundRequest == null) {
1456 buildAndThrowException(execution, String.format("The request: %s %s %s is not supported by GR_API.",
1457 (aLaCarte ? "AlaCarte" : "Macro"), resourceName, requestAction));
1459 if (northBoundRequest.getIsToplevelflow() != null) {
1460 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, northBoundRequest.getIsToplevelflow());
1462 List<OrchestrationFlow> flows = northBoundRequest.getOrchestrationFlowList();
1464 flows = new ArrayList<>();
1465 for (OrchestrationFlow flow : flows) {
1466 if (!flow.getFlowName().contains("BB") && !flow.getFlowName().contains("Activity")) {
1467 List<OrchestrationFlow> macroQueryFlows =
1468 catalogDbClient.getOrchestrationFlowByAction(flow.getFlowName());
1469 listToExecute.addAll(macroQueryFlows);
1471 listToExecute.add(flow);
1475 return listToExecute;
1478 protected void buildAndThrowException(DelegateExecution execution, String msg, Exception ex) {
1479 logger.error(msg, ex);
1480 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg + ex.getMessage());
1481 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg + ex.getMessage());
1484 protected void buildAndThrowException(DelegateExecution execution, String msg) {
1486 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg);
1487 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
1490 public void handleRuntimeException(DelegateExecution execution) {
1491 StringBuilder wfeExpMsg = new StringBuilder("Runtime error ");
1492 String runtimeErrorMessage;
1494 String javaExpMsg = (String) execution.getVariable("BPMN_javaExpMsg");
1495 if (javaExpMsg != null && !javaExpMsg.isEmpty()) {
1496 wfeExpMsg.append(": ").append(javaExpMsg);
1498 runtimeErrorMessage = wfeExpMsg.toString();
1499 logger.error(runtimeErrorMessage);
1500 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, runtimeErrorMessage);
1501 } catch (Exception e) {
1502 logger.error("Runtime error", e);
1503 // if runtime message was mulformed
1504 runtimeErrorMessage = "Runtime error";
1506 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, runtimeErrorMessage);
1509 protected boolean isUriResume(String uri) {
1510 return uri.endsWith("/resume");
1513 protected boolean isRequestMacroServiceResume(boolean aLaCarte, WorkflowType resourceType, String requestAction,
1514 String serviceInstanceId) {
1515 return (!aLaCarte && resourceType == WorkflowType.SERVICE
1516 && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE) || requestAction.equalsIgnoreCase(CREATEINSTANCE))
1517 && (serviceInstanceId != null && serviceInstanceId.trim().length() > 1)
1518 && (bbInputSetupUtils.getAAIServiceInstanceById(serviceInstanceId) != null));
1521 protected String validateServiceResourceIdInAAI(String generatedResourceId, String instanceName,
1522 RequestDetails reqDetails) throws DuplicateNameException, MultipleObjectsFoundException {
1523 String globalCustomerId = reqDetails.getSubscriberInfo().getGlobalSubscriberId();
1524 String serviceType = reqDetails.getRequestParameters().getSubscriptionServiceType();
1525 if (instanceName != null) {
1526 Optional<ServiceInstance> serviceInstanceAAI =
1527 bbInputSetupUtils.getAAIServiceInstanceByName(globalCustomerId, serviceType, instanceName);
1528 if (serviceInstanceAAI.isPresent()) {
1529 if (serviceInstanceAAI.get().getModelVersionId()
1530 .equalsIgnoreCase(reqDetails.getModelInfo().getModelVersionId())) {
1531 return serviceInstanceAAI.get().getServiceInstanceId();
1533 throw new DuplicateNameException(SERVICE_INSTANCE, String.format(NAME_EXISTS_WITH_DIFF_VERSION_ID,
1534 instanceName, reqDetails.getModelInfo().getModelVersionId()));
1537 ServiceInstances aaiServiceInstances =
1538 bbInputSetupUtils.getAAIServiceInstancesGloballyByName(instanceName);
1539 if (aaiServiceInstances != null) {
1540 if (aaiServiceInstances.getServiceInstance() != null
1541 && !aaiServiceInstances.getServiceInstance().isEmpty()) {
1542 if (aaiServiceInstances.getServiceInstance().size() > 1) {
1543 throw new DuplicateNameException(SERVICE_INSTANCE,
1544 String.format(NAME_EXISTS_MULTIPLE, instanceName));
1546 ServiceInstance si = aaiServiceInstances.getServiceInstance().stream().findFirst().get();
1547 Map<String, String> keys =
1548 bbInputSetupUtils.getURIKeysFromServiceInstance(si.getServiceInstanceId());
1550 throw new DuplicateNameException(SERVICE_INSTANCE,
1551 String.format(NAME_EXISTS_WITH_DIFF_COMBINATION, instanceName,
1552 keys.get("global-customer-id"), keys.get("service-type"),
1553 si.getModelVersionId()));
1559 return generatedResourceId;
1562 protected String validateNetworkResourceIdInAAI(String generatedResourceId, String instanceName,
1563 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1564 throws DuplicateNameException, MultipleObjectsFoundException {
1565 Optional<L3Network> network = bbInputSetupUtils
1566 .getRelatedNetworkByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1567 if (network.isPresent()) {
1568 if (network.get().getModelCustomizationId()
1569 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1570 return network.get().getNetworkId();
1572 throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1573 instanceName, network.get().getModelCustomizationId()));
1576 if (bbInputSetupUtils.existsAAINetworksGloballyByName(instanceName)) {
1577 throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName,
1578 workflowResourceIds.getServiceInstanceId()));
1580 return generatedResourceId;
1583 protected String validateVnfResourceIdInAAI(String generatedResourceId, String instanceName,
1584 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1585 throws DuplicateNameException, MultipleObjectsFoundException {
1586 Optional<GenericVnf> vnf = bbInputSetupUtils
1587 .getRelatedVnfByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1588 if (vnf.isPresent()) {
1589 if (vnf.get().getModelCustomizationId()
1590 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1591 return vnf.get().getVnfId();
1593 throw new DuplicateNameException("generic-vnf", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1594 instanceName, vnf.get().getModelCustomizationId()));
1597 GenericVnfs vnfs = bbInputSetupUtils.getAAIVnfsGloballyByName(instanceName);
1599 throw new DuplicateNameException("generic-vnf",
1600 String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName, vnfs.getGenericVnf().get(0).getVnfId()));
1602 return generatedResourceId;
1605 protected String validateVfModuleResourceIdInAAI(String generatedResourceId, String instanceName,
1606 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1607 GenericVnf vnf = bbInputSetupUtils.getAAIGenericVnf(workflowResourceIds.getVnfId());
1608 if (vnf != null && vnf.getVfModules() != null) {
1609 for (org.onap.aai.domain.yang.VfModule vfModule : vnf.getVfModules().getVfModule()) {
1610 if (vfModule.getVfModuleName().equalsIgnoreCase(instanceName)) {
1611 if (vfModule.getModelCustomizationId()
1612 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1613 return vfModule.getVfModuleId();
1615 throw new DuplicateNameException("vfModule",
1616 String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID, instanceName,
1617 reqDetails.getModelInfo().getModelCustomizationId()));
1622 if (bbInputSetupUtils.existsAAIVfModuleGloballyByName(instanceName)) {
1623 throw new DuplicateNameException("vfModule", instanceName);
1625 return generatedResourceId;
1628 protected String validateVolumeGroupResourceIdInAAI(String generatedResourceId, String instanceName,
1629 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1630 throws DuplicateNameException, MultipleObjectsFoundException {
1631 Optional<VolumeGroup> volumeGroup =
1632 bbInputSetupUtils.getRelatedVolumeGroupByNameFromVnf(workflowResourceIds.getVnfId(), instanceName);
1633 if (volumeGroup.isPresent()) {
1634 if (volumeGroup.get().getVfModuleModelCustomizationId()
1635 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1636 return volumeGroup.get().getVolumeGroupId();
1638 throw new DuplicateNameException("volumeGroup", volumeGroup.get().getVolumeGroupName());
1641 if (bbInputSetupUtils.existsAAIVolumeGroupGloballyByName(instanceName)) {
1642 throw new DuplicateNameException("volumeGroup", instanceName);
1644 return generatedResourceId;
1647 protected String validateConfigurationResourceIdInAAI(String generatedResourceId, String instanceName,
1648 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1649 throws DuplicateNameException, MultipleObjectsFoundException {
1650 Optional<org.onap.aai.domain.yang.Configuration> configuration =
1651 bbInputSetupUtils.getRelatedConfigurationByNameFromServiceInstance(
1652 workflowResourceIds.getServiceInstanceId(), instanceName);
1653 if (configuration.isPresent()) {
1654 if (configuration.get().getModelCustomizationId()
1655 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1656 return configuration.get().getConfigurationId();
1658 throw new DuplicateNameException("configuration", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1659 instanceName, configuration.get().getConfigurationId()));
1662 if (bbInputSetupUtils.existsAAIConfigurationGloballyByName(instanceName)) {
1663 throw new DuplicateNameException("configuration", instanceName);
1665 return generatedResourceId;
1668 private void fillExecution(DelegateExecution execution, boolean suppressRollback, String resourceId,
1669 WorkflowType resourceType) {
1670 execution.setVariable("sentSyncResponse", false);
1671 execution.setVariable("homing", false);
1672 execution.setVariable("calledHoming", false);
1673 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, true);
1674 execution.setVariable("suppressRollback", suppressRollback);
1675 execution.setVariable("resourceId", resourceId);
1676 execution.setVariable("resourceType", resourceType);
1677 execution.setVariable("resourceName", resourceType.toString());
1680 private Resource getResource(BBInputSetupUtils bbInputSetupUtils, boolean isResume, boolean alaCarte, String uri,
1682 if (!alaCarte && isResume) {
1683 logger.debug("replacing URI {}", uri);
1684 uri = bbInputSetupUtils.loadOriginalInfraActiveRequestById(requestId).getRequestUrl();
1685 logger.debug("for RESUME with original value {}", uri);
1687 return extractResourceIdAndTypeFromUri(uri);
1690 private String getResourceId(Resource resource, String requestAction, RequestDetails requestDetails,
1691 WorkflowResourceIds workflowResourceIds) throws Exception {
1692 if (resource.isGenerated() && requestAction.equalsIgnoreCase("createInstance")
1693 && requestDetails.getRequestInfo().getInstanceName() != null) {
1694 return validateResourceIdInAAI(resource.getResourceId(), resource.getResourceType(),
1695 requestDetails.getRequestInfo().getInstanceName(), requestDetails, workflowResourceIds);
1697 return resource.getResourceId();
1701 private String getServiceInstanceId(DelegateExecution execution, String resourceId, WorkflowType resourceType) {
1702 String serviceInstanceId = (String) execution.getVariable("serviceInstanceId");
1703 if ((serviceInstanceId == null || serviceInstanceId.isEmpty()) && WorkflowType.SERVICE.equals(resourceType)) {
1704 serviceInstanceId = resourceId;
1706 return serviceInstanceId;