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.onap.so.logger.LoggingAnchor
26 import org.camunda.bpm.engine.delegate.BpmnError
27 import org.camunda.bpm.engine.delegate.DelegateExecution
28 import org.onap.aai.domain.yang.VolumeGroup
29 import org.onap.so.bpmn.common.scripts.AaiUtil;
30 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor;
31 import org.onap.so.bpmn.common.scripts.ExceptionUtil;
32 import org.onap.so.bpmn.common.scripts.MsoUtils
33 import org.onap.so.bpmn.common.scripts.VidUtils;
34 import org.onap.so.bpmn.core.UrnPropertiesReader
35 import org.onap.so.bpmn.core.WorkflowException
36 import org.onap.so.client.aai.AAIObjectType
37 import org.onap.so.client.aai.entities.AAIResultWrapper
38 import org.onap.so.client.aai.entities.uri.AAIResourceUri
39 import org.onap.so.client.aai.entities.uri.AAIUriFactory
40 import org.onap.so.constants.Defaults
41 import org.onap.so.logger.ErrorCode
42 import org.onap.so.logger.MessageEnum
43 import org.slf4j.Logger
44 import org.slf4j.LoggerFactory
45 import groovy.json.JsonSlurper
47 import javax.ws.rs.NotFoundException
50 * This groovy class supports the <class>DeleteVfModuleVolume.bpmn</class> process.
52 public class DeleteVfModuleVolumeInfraV1 extends AbstractServiceTaskProcessor {
53 private static final Logger logger = LoggerFactory.getLogger( DeleteVfModuleVolumeInfraV1.class);
55 private XmlParser xmlParser = new XmlParser()
57 * This method is executed during the preProcessRequest task of the <class>DeleteVfModuleVolume.bpmn</class> process.
60 public InitializeProcessVariables(DelegateExecution execution){
61 execution.setVariable('prefix', 'DELVfModVol_')
62 execution.setVariable("DELVfModVol_volumeRequest", null)
63 execution.setVariable('DELVfModVol_requestInfo', null)
64 execution.setVariable('DELVfModVol_requestId', null)
65 execution.setVariable('DELVfModVol_source', null)
66 execution.setVariable('DELVfModVol_volumeInputs', null)
67 execution.setVariable('DELVfModVol_volumeOutputs', null)
68 execution.setVariable('DELVfModVol_volumeGroupId', null)
69 execution.setVariable('DELVfModVol_vnfType', null)
70 execution.setVariable('DELVfModVol_serviceId', null)
71 execution.setVariable('DELVfModVol_cloudRegion', null)
72 execution.setVariable('DELVfModVol_cloudOwner', null)
73 execution.setVariable('DELVfModVol_tenantId', null)
74 execution.setVariable('DELVfModVol_volumeParams', null)
75 execution.setVariable('DELVfModVol_volumeGroupHeatStackId', null)
76 execution.setVariable('DELVfModVol_volumeGroupTenantId', null)
77 execution.setVariable("DELVfModVol_queryAAIVolGrpResponse", null)
78 execution.setVariable('DELVfModVol_messageId', null)
79 execution.setVariable('DELVfModVol_deleteVnfARequest', null)
80 execution.setVariable('DELVfModVol_updateInfraRequest', null)
81 execution.setVariable('DELVfModVol_CompleteMsoProcessRequest', null)
82 execution.setVariable('DELVfModVol_WorkflowException', null)
83 execution.setVariable('DELVfModVol_TransactionSuccessIndicator', false)
84 execution.setVariable("DELVfModVol_isErrorMessageException", false)
85 execution.setVariable('DELVfModVol_syncResponseSent', false)
89 * Perform initial processing, such as request validation, initialization of variables, etc.
92 public void preProcessRequest (DelegateExecution execution) {
93 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
94 preProcessRequest(execution, isDebugEnabled)
98 * This method is executed during the preProcessRequest task of the <class>DeleteVfModuleVolume.bpmn</class> process.
101 public void preProcessRequest (DelegateExecution execution, isDebugLogEnabled) {
103 InitializeProcessVariables(execution)
105 String createVolumeIncoming = validateRequest(execution)
107 // check if request is xml or json
109 def jsonSlurper = new JsonSlurper()
110 Map reqMap = jsonSlurper.parseText(createVolumeIncoming)
111 logger.debug(" Request is in JSON format.")
113 def serviceInstanceId = execution.getVariable('serviceInstanceId')
114 def volumeGroupId = execution.getVariable('volumeGroupId')
115 def vidUtils = new VidUtils(this)
116 createVolumeIncoming = vidUtils.createXmlVolumeRequest(reqMap, 'DELETE_VF_MODULE_VOL', serviceInstanceId, volumeGroupId)
117 execution.setVariable("DELVfModVol_isVidRequest", true)
119 catch(groovy.json.JsonException je) {
120 logger.debug(" Request is in XML format.")
121 // assume request is in XML format - proceed as usual to process XML request
124 String request = utils.getNodeXml(createVolumeIncoming, "volume-request").drop(38).trim().replace("tag0:","").replace(":tag0","")
125 execution.setVariable("DELVfModVol_volumeRequest", request)
127 def requestInfo = getRequiredNodeXml(execution, request, 'request-info')
128 execution.setVariable('DELVfModVol_requestInfo', requestInfo)
129 String requestId = execution.getVariable("mso-request-id")
130 if (requestId == null || requestId == "") {
131 requestId = getRequiredNodeText(execution, requestInfo, 'request-id')
133 execution.setVariable('DELVfModVol_requestId', requestId)
134 execution.setVariable('DELVfModVol_source', getNodeTextForce(requestInfo, 'source'))
136 def volumeInputs = getRequiredNodeXml(execution, request, 'volume-inputs')
137 execution.setVariable('DELVfModVol_volumeInputs', volumeInputs)
138 execution.setVariable('DELVfModVol_volumeGroupId', getRequiredNodeText(execution, volumeInputs, 'volume-group-id'))
139 execution.setVariable('DELVfModVol_vnfType', getRequiredNodeText(execution, volumeInputs, 'vnf-type'))
140 execution.setVariable('DELVfModVol_serviceId', utils.getNodeText(volumeInputs, 'service-id'))
141 execution.setVariable('DELVfModVol_tenantId', getRequiredNodeText(execution, volumeInputs, 'tenant-id'))
142 execution.setVariable('DELVfModVol_messageId', UUID.randomUUID().toString())
143 execution.setVariable('DELVfModVol_volumeOutputs', utils.getNodeXml(request, 'volume-outputs', false))
144 execution.setVariable('DELVfModVol_volumeParams', utils.getNodeXml(request, 'volume-params'))
145 execution.setVariable('DELVfModVol_cloudRegion', utils.getNodeText(request, 'aic-cloud-region'))
146 execution.setVariable('DELVfModVol_cloudOwner', utils.getNodeText(request, 'cloud-owner'))
148 setBasicDBAuthHeader(execution, isDebugLogEnabled)
150 logger.debug('Request: ' + createVolumeIncoming)
153 public void sendSyncResponse (DelegateExecution execution, isDebugEnabled) {
155 String volumeRequest = execution.getVariable("DELVfModVol_volumeRequest")
156 logger.debug(" DELVfModVol_volumeRequest - " + "\n" + volumeRequest)
157 // RESTResponse (for API Handler (APIH) Reply Task)
158 String deleteVolumeRequest =
159 """<rest:RESTResponse xmlns:rest="http://schemas.activebpel.org/REST/2007/12/01/aeREST.xsd" statusCode="200">
160 <rest:payload xmlns:rest="http://schemas.activebpel.org/REST/2007/12/01/aeREST.xsd"
161 contentType="text/xml">
164 </rest:RESTResponse>""".trim()
166 def isVidRequest = execution.getVariable('DELVfModVol_isVidRequest')
167 def syncResponse = ''
170 def serviceInstanceId = execution.getVariable('serviceInstanceId')
171 def volumeGroupId = execution.getVariable('volumeGroupId')
172 def requestId = execution.getVariable('DELVfModVol_requestId')
173 syncResponse = """{"requestReferences":{"instanceId":"${volumeGroupId}","requestId":"${requestId}"}}""".trim()
176 syncResponse = utils.formatXml(deleteVolumeRequest)
179 execution.setVariable('DELVfModVol_syncResponseSent', true)
181 sendWorkflowResponse(execution, 200, syncResponse)
185 public void sendSyncError (DelegateExecution execution, isDebugEnabled) {
186 WorkflowException we = execution.getVariable('WorkflowException')
187 def errorCode = we?.getErrorCode()
188 def errorMessage = we?.getErrorMessage()
189 //default to 400 since only invalid request will trigger this method
190 sendWorkflowResponse(execution, 400, errorMessage)
194 public void callRESTQueryAAICloudRegion (DelegateExecution execution, isDebugEnabled) {
196 String cloudRegion = execution.getVariable('DELVfModVol_cloudRegion')
198 AaiUtil aaiUtil = new AaiUtil(this)
200 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.CLOUD_REGION, Defaults.CLOUD_OWNER.toString(), cloudRegion)
201 def queryCloudRegionRequest = aaiUtil.createAaiUri(uri)
203 execution.setVariable("DELVfModVol_queryCloudRegionRequest", queryCloudRegionRequest)
205 cloudRegion = aaiUtil.getAAICloudReqion(execution, queryCloudRegionRequest, "PO", cloudRegion)
207 ExceptionUtil exceptionUtil = new ExceptionUtil()
209 if ((cloudRegion != "ERROR")) {
210 if(execution.getVariable("DELVfModVol_queryCloudRegionReturnCode") == "404"){
211 execution.setVariable("DELVfModVol_aicCloudRegion", "AAIAIC25")
213 execution.setVariable("DELVfModVol_aicCloudRegion", cloudRegion)
215 execution.setVariable("DELVfModVol_cloudRegion", cloudRegion)
216 execution.setVariable("DELVfModVol_isCloudRegionGood", true)
219 logger.debug("AAI Query Cloud Region Unsuccessful.")
220 execution.setVariable("DELVfModVol_isCloudRegionGood", false)
221 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "AAI Query Cloud Region Unsuccessful. Return Code: " + execution.getVariable("DELVfModVol_queryCloudRegionReturnCode"))
224 logger.debug(" is Cloud Region Good: " + execution.getVariable("DELVfModVol_isCloudRegionGood"))
228 * Query volume group by id
231 public void queryAAIForVolumeGroup(DelegateExecution execution, isDebugLogEnabled) {
233 ExceptionUtil exceptionUtil = new ExceptionUtil()
235 def volumeGroupId = execution.getVariable('DELVfModVol_volumeGroupId')
236 if(volumeGroupId == null) {
237 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, 'volume-group-id is not provided in the request')
238 throw new Exception('volume-group-id is not provided in the request')
240 String cloudRegion = execution.getVariable('DELVfModVol_aicCloudRegion')
243 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VOLUME_GROUP, Defaults.CLOUD_OWNER.toString(), cloudRegion, volumeGroupId)
244 AAIResultWrapper volumeGroupWrapper = getAAIClient().get(uri)
246 if (!volumeGroupWrapper.isEmpty()) {
247 Optional<VolumeGroup> volumeGroupOp = volumeGroupWrapper.asBean(VolumeGroup.class)
248 execution.setVariable("DELVfModVol_queryAAIVolGrpResponse", volumeGroupOp.get())
249 def heatStackId = volumeGroupOp.get().getHeatStackId() ?: ""
250 execution.setVariable('DELVfModVol_volumeGroupHeatStackId', heatStackId)
252 if ( volumeGroupWrapper.getRelationships().isPresent() && !volumeGroupWrapper.getRelationships().get().getRelatedAAIUris(AAIObjectType.VF_MODULE).isEmpty()) {
253 logger.debug('Volume Group ' + volumeGroupId + ' currently in use')
254 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Volume Group ${volumeGroupId} currently in use - found vf-module relationship.")
257 def volumeGroupTenantId = getTenantIdFromVolumeGroup(volumeGroupWrapper)
258 if (volumeGroupTenantId == null) {
259 logger.debug("Could not find Tenant Id element in Volume Group with Volume Group Id ${volumeGroupId}")
260 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Could not find Tenant Id element in Volume Group with Volume Group Id ${volumeGroupId}")
263 execution.setVariable('DELVfModVol_volumeGroupTenantId', volumeGroupTenantId)
264 logger.debug('Received Tenant Id ' + volumeGroupTenantId + ' from AAI for Volume Group with Volume Group Id ' + volumeGroupId)
266 logger.debug("Volume Group ${volumeGroupId} not found in AAI")
267 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Volume Group ${volumeGroupId} not found in AAI. Response code: 404")
269 }catch (BpmnError e){
271 }catch (Exception e){
272 WorkflowException aWorkflowException = exceptionUtil.MapAAIExceptionToWorkflowException(e.getMessage(), execution)
273 throw new BpmnError("MSOWorkflowException")
278 * Extract the Tenant Id from the Volume Group information returned by AAI.
280 * @param volumeGroupXml Volume Group XML returned by AAI.
281 * @return the Tenant Id extracted from the Volume Group information. 'null' is returned if
282 * the Tenant Id is missing or could not otherwise be extracted.
284 private String getTenantIdFromVolumeGroup(AAIResultWrapper wrapper) {
285 if(wrapper.getRelationships().isPresent()) {
286 List<AAIResourceUri> tenantURIList = wrapper.getRelationships().get().getRelatedAAIUris(AAIObjectType.TENANT)
287 if(!tenantURIList.isEmpty()){
288 return tenantURIList.get(0).getURIKeys().get("tenant-id")
294 private boolean hasVnfRelationship(String volumeGroupXml) {
295 def Node volumeGroupNode = xmlParser.parseText(volumeGroupXml)
296 def Node relationshipList = utils.getChildNode(volumeGroupNode, 'relationship-list')
297 if (relationshipList != null) {
298 def NodeList relationships = utils.getIdenticalChildren(relationshipList, 'relationship')
299 for (Node relationship in relationships) {
300 def Node relatedTo = utils.getChildNode(relationship, 'related-to')
301 if ((relatedTo != null) && (relatedTo.text().equals('generic-vnf'))) {
302 def Node relatedLink = utils.getChildNode(relationship, 'related-link')
303 if (relatedLink !=null && relatedLink.text() != null){
312 public void prepareVnfAdapterDeleteRequest(DelegateExecution execution, isDebugLogEnabled) {
313 def cloudRegion = execution.getVariable('DELVfModVol_cloudRegion')
314 def cloudOwner = execution.getVariable('DELVfModVol_cloudOwner')
315 def tenantId = execution.getVariable('DELVfModVol_tenantId')
316 def volumeGroupId = execution.getVariable('DELVfModVol_volumeGroupId')
317 def volumeGroupHeatStackId = execution.getVariable('DELVfModVol_volumeGroupHeatStackId')
318 def requestId = execution.getVariable('DELVfModVol_requestId')
319 def serviceId = execution.getVariable('DELVfModVol_serviceId')
321 def messageId = execution.getVariable('DELVfModVol_messageId')
322 def notificationUrl = createCallbackURL(execution, "VNFAResponse", messageId)
323 def useQualifiedHostName = UrnPropertiesReader.getVariable("mso.use.qualified.host", execution)
324 if ('true'.equals(useQualifiedHostName)) {
325 notificationUrl = utils.getQualifiedHostNameForCallback(notificationUrl)
328 String vnfAdapterRestRequest = """
329 <deleteVolumeGroupRequest>
330 <cloudSiteId>${MsoUtils.xmlEscape(cloudRegion)}</cloudSiteId>
331 <cloudOwner>${MsoUtils.xmlEscape(cloudOwner)}</cloudOwner>
332 <tenantId>${MsoUtils.xmlEscape(tenantId)}</tenantId>
333 <volumeGroupId>${MsoUtils.xmlEscape(volumeGroupId)}</volumeGroupId>
334 <volumeGroupStackId>${MsoUtils.xmlEscape(volumeGroupHeatStackId)}</volumeGroupStackId>
335 <skipAAI>true</skipAAI>
337 <requestId>${MsoUtils.xmlEscape(requestId)}</requestId>
338 <serviceInstanceId>${MsoUtils.xmlEscape(serviceId)}</serviceInstanceId>
340 <messageId>${MsoUtils.xmlEscape(messageId)}</messageId>
341 <notificationUrl>${MsoUtils.xmlEscape(notificationUrl)}</notificationUrl>
342 </deleteVolumeGroupRequest>
344 vnfAdapterRestRequest = utils.formatXml(vnfAdapterRestRequest)
345 execution.setVariable('DELVfModVol_deleteVnfARequest', vnfAdapterRestRequest)
346 logger.debug('Request for VNFAdapter Rest:\n' + vnfAdapterRestRequest)
350 public void deleteVolGrpId(DelegateExecution execution, isDebugEnabled) {
353 VolumeGroup volumeGroup = execution.getVariable("DELVfModVol_queryAAIVolGrpResponse")
354 String groupId = volumeGroup.getVolumeGroupId()
355 String cloudRegion = execution.getVariable('DELVfModVol_aicCloudRegion')
357 ExceptionUtil exceptionUtil = new ExceptionUtil()
359 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VOLUME_GROUP, Defaults.CLOUD_OWNER.toString(), cloudRegion, groupId)
360 getAAIClient().delete(uri)
361 logger.debug("Volume group $groupId deleted.")
362 }catch(NotFoundException e){
363 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Volume group $groupId not found for delete in AAI Response code: 404")
364 }catch(Exception e1){
365 WorkflowException aWorkflowException = exceptionUtil.MapAAIExceptionToWorkflowException(e1.getMessage(), execution)
366 throw new BpmnError("MSOWorkflowException")
371 public void prepareDBRequest (DelegateExecution execution, isDebugLogEnabled) {
373 WorkflowException workflowExceptionObj = execution.getVariable("WorkflowException")
374 ExceptionUtil exceptionUtil = new ExceptionUtil();
375 def requestId = execution.getVariable('DELVfModVol_requestId')
376 def volOutputs = execution.getVariable('DELVfModVol_volumeOutputs')
377 def statusMessage = "VolumeGroup successfully deleted"
379 def requestStatus = "COMPLETE"
381 if (workflowExceptionObj != null) {
382 statusMessage = (workflowExceptionObj.getErrorMessage())
383 execution.setVariable("DELVfModVol_WorkflowExceptionMessage", statusMessage)
384 execution.setVariable("DELVfModVol_WorkflowExceptionCode", workflowExceptionObj.getErrorCode())
385 requestStatus = "FAILURE"
389 String updateInfraRequest = """
390 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
391 xmlns:req="http://org.onap.so/requestsdb">
394 <req:updateInfraRequest>
395 <requestId>${MsoUtils.xmlEscape(requestId)}</requestId>
396 <lastModifiedBy>BPMN</lastModifiedBy>
397 <statusMessage>${MsoUtils.xmlEscape(statusMessage)}</statusMessage>
398 <requestStatus>${MsoUtils.xmlEscape(requestStatus)}</requestStatus>
399 <progress>${MsoUtils.xmlEscape(progress)}</progress>
400 <vnfOutputs>${MsoUtils.xmlEscape(volOutputs)}</vnfOutputs>
401 </req:updateInfraRequest>
406 updateInfraRequest = utils.formatXml(updateInfraRequest)
407 execution.setVariable('DELVfModVol_updateInfraRequest', updateInfraRequest)
408 logger.debug('Request for Update Infra Request:\n' + updateInfraRequest)
413 public void prepareCompletionHandlerRequest (DelegateExecution execution, isDebugLogEnabled) {
414 def requestId = execution.getVariable("mso-request-id")
415 def source = execution.getVariable("DELVfModVol_source")
417 String msoCompletionRequest =
418 """<aetgt:MsoCompletionRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
419 xmlns:ns="http://org.onap/so/request/types/v1">
420 <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
421 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
422 <action>DELETE</action>
423 <source>${MsoUtils.xmlEscape(source)}</source>
425 <aetgt:status-message>Volume Group has been deleted successfully.</aetgt:status-message>
426 <aetgt:mso-bpel-name>BPMN VF Module Volume action: DELETE</aetgt:mso-bpel-name>
427 </aetgt:MsoCompletionRequest>"""
429 String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest)
430 execution.setVariable('DELVfModVol_CompleteMsoProcessRequest', xmlMsoCompletionRequest)
431 logger.debug(" Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest)
437 public void prepareFalloutHandler (DelegateExecution execution) {
439 execution.setVariable("DELVfModVol_Success", false)
440 String requestId = execution.getVariable("DELVfModVol_requestId")
441 String source = execution.getVariable("DELVfModVol_source")
443 WorkflowException workflowExceptionObj = execution.getVariable("WorkflowException")
444 def errorMessage = workflowExceptionObj.getErrorMessage()
445 def errorCode = workflowExceptionObj.getErrorCode()
447 String falloutHandlerRequest =
448 """<aetgt:FalloutHandlerRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
449 xmlns:ns="http://org.onap/so/request/types/v1"
450 xmlns:wfsch="http://org.onap/so/workflow/schema/v1">
451 <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
452 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
453 <action>DELETE</action>
454 <source>${MsoUtils.xmlEscape(source)}</source>
456 <aetgt:WorkflowException>
457 <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorMessage)}</aetgt:ErrorMessage>
458 <aetgt:ErrorCode>${MsoUtils.xmlEscape(errorCode)}</aetgt:ErrorCode>
459 </aetgt:WorkflowException>
460 </aetgt:FalloutHandlerRequest>"""
463 String xmlHandlerRequest = utils.formatXml(falloutHandlerRequest)
464 logger.debug(xmlHandlerRequest)
466 execution.setVariable("DELVfModVol_FalloutHandlerRequest", xmlHandlerRequest)
467 logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
468 "Overall Error Response going to FalloutHandler", "BPMN",
469 ErrorCode.UnknownError.getValue(), "\n" + xmlHandlerRequest);
474 * Create a WorkflowException for the error case where the Tenant Id from
475 * AAI did not match the Tenant Id in the incoming request.
477 * @param execution The flow's execution instance.
479 public void handleTenantIdMismatch(DelegateExecution execution, isDebugLogEnabled) {
481 def volumeGroupId = execution.getVariable('DELVfModVol_volumeGroupId')
482 def aicCloudRegion = execution.getVariable('DELVfModVol_aicCloudRegion')
483 def tenantId = execution.getVariable('DELVfModVol_tenantId')
484 def volumeGroupTenantId = execution.getVariable('DELVfModVol_volumeGroupTenantId')
486 def String errorMessage = 'TenantId ' + tenantId + ' in incoming request does not match Tenant Id ' + volumeGroupTenantId +
487 ' retrieved from AAI for Volume Group Id ' + volumeGroupId
488 logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
489 "Error in DeleteVfModuleVolume: " + "\n" + errorMessage, "BPMN",
490 ErrorCode.UnknownError.getValue());
492 ExceptionUtil exceptionUtil = new ExceptionUtil()
493 exceptionUtil.buildWorkflowException(execution, 5000, errorMessage)