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.aaiclient.client.aai.AAIObjectType
37 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper
38 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
39 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
40 import org.onap.so.constants.Defaults
41 import org.onap.logging.filter.base.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)