2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Modifications Copyright (c) 2019 Samsung
8 * ================================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 * ============LICENSE_END=========================================================
23 package org.onap.so.bpmn.infrastructure.scripts
25 import org.camunda.bpm.engine.delegate.BpmnError
26 import org.camunda.bpm.engine.delegate.DelegateExecution
27 import org.onap.aai.domain.yang.VolumeGroup
28 import org.onap.so.bpmn.common.scripts.AaiUtil;
29 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor;
30 import org.onap.so.bpmn.common.scripts.ExceptionUtil;
31 import org.onap.so.bpmn.common.scripts.MsoUtils
32 import org.onap.so.bpmn.common.scripts.VidUtils;
33 import org.onap.so.bpmn.core.UrnPropertiesReader
34 import org.onap.so.bpmn.core.WorkflowException
35 import org.onap.so.client.aai.AAIObjectType
36 import org.onap.so.client.aai.entities.AAIResultWrapper
37 import org.onap.so.client.aai.entities.uri.AAIResourceUri
38 import org.onap.so.client.aai.entities.uri.AAIUriFactory
39 import org.onap.so.constants.Defaults
40 import org.onap.so.logger.ErrorCode
41 import org.onap.so.logger.MessageEnum
42 import org.slf4j.Logger
43 import org.slf4j.LoggerFactory
44 import groovy.json.JsonSlurper
46 import javax.ws.rs.NotFoundException
49 * This groovy class supports the <class>DeleteVfModuleVolume.bpmn</class> process.
51 public class DeleteVfModuleVolumeInfraV1 extends AbstractServiceTaskProcessor {
52 private static final Logger logger = LoggerFactory.getLogger( DeleteVfModuleVolumeInfraV1.class);
54 private XmlParser xmlParser = new XmlParser()
56 * This method is executed during the preProcessRequest task of the <class>DeleteVfModuleVolume.bpmn</class> process.
59 public InitializeProcessVariables(DelegateExecution execution){
60 execution.setVariable('prefix', 'DELVfModVol_')
61 execution.setVariable("DELVfModVol_volumeRequest", null)
62 execution.setVariable('DELVfModVol_requestInfo', null)
63 execution.setVariable('DELVfModVol_requestId', null)
64 execution.setVariable('DELVfModVol_source', null)
65 execution.setVariable('DELVfModVol_volumeInputs', null)
66 execution.setVariable('DELVfModVol_volumeOutputs', null)
67 execution.setVariable('DELVfModVol_volumeGroupId', null)
68 execution.setVariable('DELVfModVol_vnfType', null)
69 execution.setVariable('DELVfModVol_serviceId', null)
70 execution.setVariable('DELVfModVol_cloudRegion', null)
71 execution.setVariable('DELVfModVol_cloudOwner', null)
72 execution.setVariable('DELVfModVol_tenantId', null)
73 execution.setVariable('DELVfModVol_volumeParams', null)
74 execution.setVariable('DELVfModVol_volumeGroupHeatStackId', null)
75 execution.setVariable('DELVfModVol_volumeGroupTenantId', null)
76 execution.setVariable("DELVfModVol_queryAAIVolGrpResponse", null)
77 execution.setVariable('DELVfModVol_messageId', null)
78 execution.setVariable('DELVfModVol_deleteVnfARequest', null)
79 execution.setVariable('DELVfModVol_updateInfraRequest', null)
80 execution.setVariable('DELVfModVol_CompleteMsoProcessRequest', null)
81 execution.setVariable('DELVfModVol_WorkflowException', null)
82 execution.setVariable('DELVfModVol_TransactionSuccessIndicator', false)
83 execution.setVariable("DELVfModVol_isErrorMessageException", false)
84 execution.setVariable('DELVfModVol_syncResponseSent', false)
88 * Perform initial processing, such as request validation, initialization of variables, etc.
91 public void preProcessRequest (DelegateExecution execution) {
92 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
93 preProcessRequest(execution, isDebugEnabled)
97 * This method is executed during the preProcessRequest task of the <class>DeleteVfModuleVolume.bpmn</class> process.
100 public void preProcessRequest (DelegateExecution execution, isDebugLogEnabled) {
102 InitializeProcessVariables(execution)
104 String createVolumeIncoming = validateRequest(execution)
106 // check if request is xml or json
108 def jsonSlurper = new JsonSlurper()
109 Map reqMap = jsonSlurper.parseText(createVolumeIncoming)
110 logger.debug(" Request is in JSON format.")
112 def serviceInstanceId = execution.getVariable('serviceInstanceId')
113 def volumeGroupId = execution.getVariable('volumeGroupId')
114 def vidUtils = new VidUtils(this)
115 createVolumeIncoming = vidUtils.createXmlVolumeRequest(reqMap, 'DELETE_VF_MODULE_VOL', serviceInstanceId, volumeGroupId)
116 execution.setVariable("DELVfModVol_isVidRequest", true)
118 catch(groovy.json.JsonException je) {
119 logger.debug(" Request is in XML format.")
120 // assume request is in XML format - proceed as usual to process XML request
123 String request = utils.getNodeXml(createVolumeIncoming, "volume-request").drop(38).trim().replace("tag0:","").replace(":tag0","")
124 execution.setVariable("DELVfModVol_volumeRequest", request)
126 def requestInfo = getRequiredNodeXml(execution, request, 'request-info')
127 execution.setVariable('DELVfModVol_requestInfo', requestInfo)
128 String requestId = execution.getVariable("mso-request-id")
129 if (requestId == null || requestId == "") {
130 requestId = getRequiredNodeText(execution, requestInfo, 'request-id')
132 execution.setVariable('DELVfModVol_requestId', requestId)
133 execution.setVariable('DELVfModVol_source', getNodeTextForce(requestInfo, 'source'))
135 def volumeInputs = getRequiredNodeXml(execution, request, 'volume-inputs')
136 execution.setVariable('DELVfModVol_volumeInputs', volumeInputs)
137 execution.setVariable('DELVfModVol_volumeGroupId', getRequiredNodeText(execution, volumeInputs, 'volume-group-id'))
138 execution.setVariable('DELVfModVol_vnfType', getRequiredNodeText(execution, volumeInputs, 'vnf-type'))
139 execution.setVariable('DELVfModVol_serviceId', utils.getNodeText(volumeInputs, 'service-id'))
140 execution.setVariable('DELVfModVol_tenantId', getRequiredNodeText(execution, volumeInputs, 'tenant-id'))
141 execution.setVariable('DELVfModVol_messageId', UUID.randomUUID().toString())
142 execution.setVariable('DELVfModVol_volumeOutputs', utils.getNodeXml(request, 'volume-outputs', false))
143 execution.setVariable('DELVfModVol_volumeParams', utils.getNodeXml(request, 'volume-params'))
144 execution.setVariable('DELVfModVol_cloudRegion', utils.getNodeText(request, 'aic-cloud-region'))
145 execution.setVariable('DELVfModVol_cloudOwner', utils.getNodeText(request, 'cloud-owner'))
147 setBasicDBAuthHeader(execution, isDebugLogEnabled)
149 logger.debug('Request: ' + createVolumeIncoming)
152 public void sendSyncResponse (DelegateExecution execution, isDebugEnabled) {
154 String volumeRequest = execution.getVariable("DELVfModVol_volumeRequest")
155 logger.debug(" DELVfModVol_volumeRequest - " + "\n" + volumeRequest)
156 // RESTResponse (for API Handler (APIH) Reply Task)
157 String deleteVolumeRequest =
158 """<rest:RESTResponse xmlns:rest="http://schemas.activebpel.org/REST/2007/12/01/aeREST.xsd" statusCode="200">
159 <rest:payload xmlns:rest="http://schemas.activebpel.org/REST/2007/12/01/aeREST.xsd"
160 contentType="text/xml">
163 </rest:RESTResponse>""".trim()
165 def isVidRequest = execution.getVariable('DELVfModVol_isVidRequest')
166 def syncResponse = ''
169 def serviceInstanceId = execution.getVariable('serviceInstanceId')
170 def volumeGroupId = execution.getVariable('volumeGroupId')
171 def requestId = execution.getVariable('DELVfModVol_requestId')
172 syncResponse = """{"requestReferences":{"instanceId":"${volumeGroupId}","requestId":"${requestId}"}}""".trim()
175 syncResponse = utils.formatXml(deleteVolumeRequest)
178 execution.setVariable('DELVfModVol_syncResponseSent', true)
180 sendWorkflowResponse(execution, 200, syncResponse)
184 public void sendSyncError (DelegateExecution execution, isDebugEnabled) {
185 WorkflowException we = execution.getVariable('WorkflowException')
186 def errorCode = we?.getErrorCode()
187 def errorMessage = we?.getErrorMessage()
188 //default to 400 since only invalid request will trigger this method
189 sendWorkflowResponse(execution, 400, errorMessage)
193 public void callRESTQueryAAICloudRegion (DelegateExecution execution, isDebugEnabled) {
195 String cloudRegion = execution.getVariable('DELVfModVol_cloudRegion')
197 AaiUtil aaiUtil = new AaiUtil(this)
199 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.CLOUD_REGION, Defaults.CLOUD_OWNER.toString(), cloudRegion)
200 def queryCloudRegionRequest = aaiUtil.createAaiUri(uri)
202 execution.setVariable("DELVfModVol_queryCloudRegionRequest", queryCloudRegionRequest)
204 cloudRegion = aaiUtil.getAAICloudReqion(execution, queryCloudRegionRequest, "PO", cloudRegion)
206 ExceptionUtil exceptionUtil = new ExceptionUtil()
208 if ((cloudRegion != "ERROR")) {
209 if(execution.getVariable("DELVfModVol_queryCloudRegionReturnCode") == "404"){
210 execution.setVariable("DELVfModVol_aicCloudRegion", "AAIAIC25")
212 execution.setVariable("DELVfModVol_aicCloudRegion", cloudRegion)
214 execution.setVariable("DELVfModVol_cloudRegion", cloudRegion)
215 execution.setVariable("DELVfModVol_isCloudRegionGood", true)
218 logger.debug("AAI Query Cloud Region Unsuccessful.")
219 execution.setVariable("DELVfModVol_isCloudRegionGood", false)
220 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "AAI Query Cloud Region Unsuccessful. Return Code: " + execution.getVariable("DELVfModVol_queryCloudRegionReturnCode"))
223 logger.debug(" is Cloud Region Good: " + execution.getVariable("DELVfModVol_isCloudRegionGood"))
227 * Query volume group by id
230 public void queryAAIForVolumeGroup(DelegateExecution execution, isDebugLogEnabled) {
232 ExceptionUtil exceptionUtil = new ExceptionUtil()
234 def volumeGroupId = execution.getVariable('DELVfModVol_volumeGroupId')
235 if(volumeGroupId == null) {
236 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, 'volume-group-id is not provided in the request')
237 throw new Exception('volume-group-id is not provided in the request')
239 String cloudRegion = execution.getVariable('DELVfModVol_aicCloudRegion')
242 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VOLUME_GROUP, Defaults.CLOUD_OWNER.toString(), cloudRegion, volumeGroupId)
243 AAIResultWrapper volumeGroupWrapper = getAAIClient().get(uri)
245 if (!volumeGroupWrapper.isEmpty()) {
246 Optional<VolumeGroup> volumeGroupOp = volumeGroupWrapper.asBean(VolumeGroup.class)
247 execution.setVariable("DELVfModVol_queryAAIVolGrpResponse", volumeGroupOp.get())
248 def heatStackId = volumeGroupOp.get().getHeatStackId() ?: ""
249 execution.setVariable('DELVfModVol_volumeGroupHeatStackId', heatStackId)
251 if ( volumeGroupWrapper.getRelationships().isPresent() && !volumeGroupWrapper.getRelationships().get().getRelatedAAIUris(AAIObjectType.VF_MODULE).isEmpty()) {
252 logger.debug('Volume Group ' + volumeGroupId + ' currently in use')
253 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Volume Group ${volumeGroupId} currently in use - found vf-module relationship.")
256 def volumeGroupTenantId = getTenantIdFromVolumeGroup(volumeGroupWrapper)
257 if (volumeGroupTenantId == null) {
258 logger.debug("Could not find Tenant Id element in Volume Group with Volume Group Id ${volumeGroupId}")
259 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Could not find Tenant Id element in Volume Group with Volume Group Id ${volumeGroupId}")
262 execution.setVariable('DELVfModVol_volumeGroupTenantId', volumeGroupTenantId)
263 logger.debug('Received Tenant Id ' + volumeGroupTenantId + ' from AAI for Volume Group with Volume Group Id ' + volumeGroupId)
265 logger.debug("Volume Group ${volumeGroupId} not found in AAI")
266 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Volume Group ${volumeGroupId} not found in AAI. Response code: 404")
268 }catch (BpmnError e){
270 }catch (Exception e){
271 WorkflowException aWorkflowException = exceptionUtil.MapAAIExceptionToWorkflowException(e.getMessage(), execution)
272 throw new BpmnError("MSOWorkflowException")
277 * Extract the Tenant Id from the Volume Group information returned by AAI.
279 * @param volumeGroupXml Volume Group XML returned by AAI.
280 * @return the Tenant Id extracted from the Volume Group information. 'null' is returned if
281 * the Tenant Id is missing or could not otherwise be extracted.
283 private String getTenantIdFromVolumeGroup(AAIResultWrapper wrapper) {
284 if(wrapper.getRelationships().isPresent()) {
285 List<AAIResourceUri> tenantURIList = wrapper.getRelationships().get().getRelatedAAIUris(AAIObjectType.TENANT)
286 if(!tenantURIList.isEmpty()){
287 return tenantURIList.get(0).getURIKeys().get("tenant-id")
293 private boolean hasVnfRelationship(String volumeGroupXml) {
294 def Node volumeGroupNode = xmlParser.parseText(volumeGroupXml)
295 def Node relationshipList = utils.getChildNode(volumeGroupNode, 'relationship-list')
296 if (relationshipList != null) {
297 def NodeList relationships = utils.getIdenticalChildren(relationshipList, 'relationship')
298 for (Node relationship in relationships) {
299 def Node relatedTo = utils.getChildNode(relationship, 'related-to')
300 if ((relatedTo != null) && (relatedTo.text().equals('generic-vnf'))) {
301 def Node relatedLink = utils.getChildNode(relationship, 'related-link')
302 if (relatedLink !=null && relatedLink.text() != null){
311 public void prepareVnfAdapterDeleteRequest(DelegateExecution execution, isDebugLogEnabled) {
312 def cloudRegion = execution.getVariable('DELVfModVol_cloudRegion')
313 def cloudOwner = execution.getVariable('DELVfModVol_cloudOwner')
314 def tenantId = execution.getVariable('DELVfModVol_tenantId')
315 def volumeGroupId = execution.getVariable('DELVfModVol_volumeGroupId')
316 def volumeGroupHeatStackId = execution.getVariable('DELVfModVol_volumeGroupHeatStackId')
317 def requestId = execution.getVariable('DELVfModVol_requestId')
318 def serviceId = execution.getVariable('DELVfModVol_serviceId')
320 def messageId = execution.getVariable('DELVfModVol_messageId')
321 def notificationUrl = createCallbackURL(execution, "VNFAResponse", messageId)
322 def useQualifiedHostName = UrnPropertiesReader.getVariable("mso.use.qualified.host", execution)
323 if ('true'.equals(useQualifiedHostName)) {
324 notificationUrl = utils.getQualifiedHostNameForCallback(notificationUrl)
327 String vnfAdapterRestRequest = """
328 <deleteVolumeGroupRequest>
329 <cloudSiteId>${MsoUtils.xmlEscape(cloudRegion)}</cloudSiteId>
330 <cloudOwner>${MsoUtils.xmlEscape(cloudOwner)}</cloudOwner>
331 <tenantId>${MsoUtils.xmlEscape(tenantId)}</tenantId>
332 <volumeGroupId>${MsoUtils.xmlEscape(volumeGroupId)}</volumeGroupId>
333 <volumeGroupStackId>${MsoUtils.xmlEscape(volumeGroupHeatStackId)}</volumeGroupStackId>
334 <skipAAI>true</skipAAI>
336 <requestId>${MsoUtils.xmlEscape(requestId)}</requestId>
337 <serviceInstanceId>${MsoUtils.xmlEscape(serviceId)}</serviceInstanceId>
339 <messageId>${MsoUtils.xmlEscape(messageId)}</messageId>
340 <notificationUrl>${MsoUtils.xmlEscape(notificationUrl)}</notificationUrl>
341 </deleteVolumeGroupRequest>
343 vnfAdapterRestRequest = utils.formatXml(vnfAdapterRestRequest)
344 execution.setVariable('DELVfModVol_deleteVnfARequest', vnfAdapterRestRequest)
345 logger.debug('Request for VNFAdapter Rest:\n' + vnfAdapterRestRequest)
349 public void deleteVolGrpId(DelegateExecution execution, isDebugEnabled) {
352 VolumeGroup volumeGroup = execution.getVariable("DELVfModVol_queryAAIVolGrpResponse")
353 String groupId = volumeGroup.getVolumeGroupId()
354 String cloudRegion = execution.getVariable('DELVfModVol_aicCloudRegion')
356 ExceptionUtil exceptionUtil = new ExceptionUtil()
358 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VOLUME_GROUP, Defaults.CLOUD_OWNER.toString(), cloudRegion, groupId)
359 getAAIClient().delete(uri)
360 logger.debug("Volume group $groupId deleted.")
361 }catch(NotFoundException e){
362 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Volume group $groupId not found for delete in AAI Response code: 404")
363 }catch(Exception e1){
364 WorkflowException aWorkflowException = exceptionUtil.MapAAIExceptionToWorkflowException(e1.getMessage(), execution)
365 throw new BpmnError("MSOWorkflowException")
370 public void prepareDBRequest (DelegateExecution execution, isDebugLogEnabled) {
372 WorkflowException workflowExceptionObj = execution.getVariable("WorkflowException")
373 ExceptionUtil exceptionUtil = new ExceptionUtil();
374 def requestId = execution.getVariable('DELVfModVol_requestId')
375 def volOutputs = execution.getVariable('DELVfModVol_volumeOutputs')
376 def statusMessage = "VolumeGroup successfully deleted"
378 def requestStatus = "COMPLETE"
380 if (workflowExceptionObj != null) {
381 statusMessage = (workflowExceptionObj.getErrorMessage())
382 execution.setVariable("DELVfModVol_WorkflowExceptionMessage", statusMessage)
383 execution.setVariable("DELVfModVol_WorkflowExceptionCode", workflowExceptionObj.getErrorCode())
384 requestStatus = "FAILURE"
388 String updateInfraRequest = """
389 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
390 xmlns:req="http://org.onap.so/requestsdb">
393 <req:updateInfraRequest>
394 <requestId>${MsoUtils.xmlEscape(requestId)}</requestId>
395 <lastModifiedBy>BPMN</lastModifiedBy>
396 <statusMessage>${MsoUtils.xmlEscape(statusMessage)}</statusMessage>
397 <requestStatus>${MsoUtils.xmlEscape(requestStatus)}</requestStatus>
398 <progress>${MsoUtils.xmlEscape(progress)}</progress>
399 <vnfOutputs>${MsoUtils.xmlEscape(volOutputs)}</vnfOutputs>
400 </req:updateInfraRequest>
405 updateInfraRequest = utils.formatXml(updateInfraRequest)
406 execution.setVariable('DELVfModVol_updateInfraRequest', updateInfraRequest)
407 logger.debug('Request for Update Infra Request:\n' + updateInfraRequest)
412 public void prepareCompletionHandlerRequest (DelegateExecution execution, isDebugLogEnabled) {
413 def requestId = execution.getVariable("mso-request-id")
414 def source = execution.getVariable("DELVfModVol_source")
416 String msoCompletionRequest =
417 """<aetgt:MsoCompletionRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
418 xmlns:ns="http://org.onap/so/request/types/v1">
419 <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
420 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
421 <action>DELETE</action>
422 <source>${MsoUtils.xmlEscape(source)}</source>
424 <aetgt:status-message>Volume Group has been deleted successfully.</aetgt:status-message>
425 <aetgt:mso-bpel-name>BPMN VF Module Volume action: DELETE</aetgt:mso-bpel-name>
426 </aetgt:MsoCompletionRequest>"""
428 String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest)
429 execution.setVariable('DELVfModVol_CompleteMsoProcessRequest', xmlMsoCompletionRequest)
430 logger.debug(" Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest)
436 public void prepareFalloutHandler (DelegateExecution execution) {
438 execution.setVariable("DELVfModVol_Success", false)
439 String requestId = execution.getVariable("DELVfModVol_requestId")
440 String source = execution.getVariable("DELVfModVol_source")
442 WorkflowException workflowExceptionObj = execution.getVariable("WorkflowException")
443 def errorMessage = workflowExceptionObj.getErrorMessage()
444 def errorCode = workflowExceptionObj.getErrorCode()
446 String falloutHandlerRequest =
447 """<aetgt:FalloutHandlerRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
448 xmlns:ns="http://org.onap/so/request/types/v1"
449 xmlns:wfsch="http://org.onap/so/workflow/schema/v1">
450 <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
451 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
452 <action>DELETE</action>
453 <source>${MsoUtils.xmlEscape(source)}</source>
455 <aetgt:WorkflowException>
456 <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorMessage)}</aetgt:ErrorMessage>
457 <aetgt:ErrorCode>${MsoUtils.xmlEscape(errorCode)}</aetgt:ErrorCode>
458 </aetgt:WorkflowException>
459 </aetgt:FalloutHandlerRequest>"""
462 String xmlHandlerRequest = utils.formatXml(falloutHandlerRequest)
463 logger.debug(xmlHandlerRequest)
465 execution.setVariable("DELVfModVol_FalloutHandlerRequest", xmlHandlerRequest)
466 logger.error("{} {} {} {} {}", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
467 "Overall Error Response going to FalloutHandler", "BPMN",
468 ErrorCode.UnknownError.getValue(), "\n" + xmlHandlerRequest);
473 * Create a WorkflowException for the error case where the Tenant Id from
474 * AAI did not match the Tenant Id in the incoming request.
476 * @param execution The flow's execution instance.
478 public void handleTenantIdMismatch(DelegateExecution execution, isDebugLogEnabled) {
480 def volumeGroupId = execution.getVariable('DELVfModVol_volumeGroupId')
481 def aicCloudRegion = execution.getVariable('DELVfModVol_aicCloudRegion')
482 def tenantId = execution.getVariable('DELVfModVol_tenantId')
483 def volumeGroupTenantId = execution.getVariable('DELVfModVol_volumeGroupTenantId')
485 def String errorMessage = 'TenantId ' + tenantId + ' in incoming request does not match Tenant Id ' + volumeGroupTenantId +
486 ' retrieved from AAI for Volume Group Id ' + volumeGroupId
487 logger.error("{} {} {} {}", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
488 "Error in DeleteVfModuleVolume: " + "\n" + errorMessage, "BPMN",
489 ErrorCode.UnknownError.getValue());
491 ExceptionUtil exceptionUtil = new ExceptionUtil()
492 exceptionUtil.buildWorkflowException(execution, 5000, errorMessage)