2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.so.bpmn.infrastructure.scripts;
23 import org.apache.commons.lang3.*
24 import org.camunda.bpm.engine.delegate.BpmnError
25 import org.camunda.bpm.engine.delegate.DelegateExecution
26 import org.onap.aai.domain.yang.VolumeGroup
27 import org.onap.so.bpmn.common.scripts.AaiUtil;
28 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor;
29 import org.onap.so.bpmn.common.scripts.ExceptionUtil;
30 import org.onap.so.bpmn.common.scripts.MsoUtils
31 import org.onap.so.bpmn.common.scripts.VidUtils;
32 import org.onap.so.bpmn.core.UrnPropertiesReader
33 import org.onap.so.bpmn.core.WorkflowException
34 import org.onap.so.client.aai.AAIObjectType
35 import org.onap.so.client.aai.entities.AAIResultWrapper
36 import org.onap.so.client.aai.entities.Relationships
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.MessageEnum
41 import org.onap.so.logger.MsoLogger
42 import org.springframework.web.util.UriUtils
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 MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, 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_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 msoLogger.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 msoLogger.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'))
146 setBasicDBAuthHeader(execution, isDebugLogEnabled)
148 msoLogger.debug('Request: ' + createVolumeIncoming)
151 public void sendSyncResponse (DelegateExecution execution, isDebugEnabled) {
153 String volumeRequest = execution.getVariable("DELVfModVol_volumeRequest")
154 msoLogger.debug(" DELVfModVol_volumeRequest - " + "\n" + volumeRequest)
155 // RESTResponse (for API Handler (APIH) Reply Task)
156 String deleteVolumeRequest =
157 """<rest:RESTResponse xmlns:rest="http://schemas.activebpel.org/REST/2007/12/01/aeREST.xsd" statusCode="200">
158 <rest:payload xmlns:rest="http://schemas.activebpel.org/REST/2007/12/01/aeREST.xsd"
159 contentType="text/xml">
162 </rest:RESTResponse>""".trim()
164 def isVidRequest = execution.getVariable('DELVfModVol_isVidRequest')
165 def syncResponse = ''
168 def serviceInstanceId = execution.getVariable('serviceInstanceId')
169 def volumeGroupId = execution.getVariable('volumeGroupId')
170 def requestId = execution.getVariable('DELVfModVol_requestId')
171 syncResponse = """{"requestReferences":{"instanceId":"${volumeGroupId}","requestId":"${requestId}"}}""".trim()
174 syncResponse = utils.formatXml(deleteVolumeRequest)
177 execution.setVariable('DELVfModVol_syncResponseSent', true)
179 sendWorkflowResponse(execution, 200, syncResponse)
183 public void sendSyncError (DelegateExecution execution, isDebugEnabled) {
184 WorkflowException we = execution.getVariable('WorkflowException')
185 def errorCode = we?.getErrorCode()
186 def errorMessage = we?.getErrorMessage()
187 //default to 400 since only invalid request will trigger this method
188 sendWorkflowResponse(execution, 400, errorMessage)
192 public void callRESTQueryAAICloudRegion (DelegateExecution execution, isDebugEnabled) {
194 String cloudRegion = execution.getVariable('DELVfModVol_cloudRegion')
196 AaiUtil aaiUtil = new AaiUtil(this)
198 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.CLOUD_REGION, Defaults.CLOUD_OWNER.toString(), cloudRegion)
199 def queryCloudRegionRequest = aaiUtil.createAaiUri(uri)
201 execution.setVariable("DELVfModVol_queryCloudRegionRequest", queryCloudRegionRequest)
203 cloudRegion = aaiUtil.getAAICloudReqion(execution, queryCloudRegionRequest, "PO", cloudRegion)
205 ExceptionUtil exceptionUtil = new ExceptionUtil()
207 if ((cloudRegion != "ERROR")) {
208 if(execution.getVariable("DELVfModVol_queryCloudRegionReturnCode") == "404"){
209 execution.setVariable("DELVfModVol_aicCloudRegion", "AAIAIC25")
211 execution.setVariable("DELVfModVol_aicCloudRegion", cloudRegion)
213 execution.setVariable("DELVfModVol_cloudRegion", cloudRegion)
214 execution.setVariable("DELVfModVol_isCloudRegionGood", true)
217 msoLogger.debug("AAI Query Cloud Region Unsuccessful.")
218 execution.setVariable("DELVfModVol_isCloudRegionGood", false)
219 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "AAI Query Cloud Region Unsuccessful. Return Code: " + execution.getVariable("DELVfModVol_queryCloudRegionReturnCode"))
222 msoLogger.debug(" is Cloud Region Good: " + execution.getVariable("DELVfModVol_isCloudRegionGood"))
226 * Query volume group by id
229 public void queryAAIForVolumeGroup(DelegateExecution execution, isDebugLogEnabled) {
231 ExceptionUtil exceptionUtil = new ExceptionUtil()
233 def volumeGroupId = execution.getVariable('DELVfModVol_volumeGroupId')
234 if(volumeGroupId == null) {
235 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, 'volume-group-id is not provided in the request')
236 throw new Exception('volume-group-id is not provided in the request')
238 String cloudRegion = execution.getVariable('DELVfModVol_aicCloudRegion')
241 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VOLUME_GROUP, Defaults.CLOUD_OWNER.toString(), cloudRegion, volumeGroupId)
242 AAIResultWrapper volumeGroupWrapper = getAAIClient().get(uri)
244 if (!volumeGroupWrapper.isEmpty()) {
245 Optional<VolumeGroup> volumeGroupOp = volumeGroupWrapper.asBean(VolumeGroup.class)
246 execution.setVariable("DELVfModVol_queryAAIVolGrpResponse", volumeGroupOp.get())
247 def heatStackId = volumeGroupOp.get().getHeatStackId() ?: ""
248 execution.setVariable('DELVfModVol_volumeGroupHeatStackId', heatStackId)
250 if ( volumeGroupWrapper.getRelationships().isPresent() && !volumeGroupWrapper.getRelationships().get().getRelatedAAIUris(AAIObjectType.VF_MODULE).isEmpty()) {
251 msoLogger.debug('Volume Group ' + volumeGroupId + ' currently in use')
252 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Volume Group ${volumeGroupId} currently in use - found vf-module relationship.")
255 def volumeGroupTenantId = getTenantIdFromVolumeGroup(volumeGroupWrapper)
256 if (volumeGroupTenantId == null) {
257 msoLogger.debug("Could not find Tenant Id element in Volume Group with Volume Group Id ${volumeGroupId}")
258 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Could not find Tenant Id element in Volume Group with Volume Group Id ${volumeGroupId}")
261 execution.setVariable('DELVfModVol_volumeGroupTenantId', volumeGroupTenantId)
262 msoLogger.debug('Received Tenant Id ' + volumeGroupTenantId + ' from AAI for Volume Group with Volume Group Id ' + volumeGroupId)
264 msoLogger.debug("Volume Group ${volumeGroupId} not found in AAI")
265 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Volume Group ${volumeGroupId} not found in AAI. Response code: 404")
267 }catch (BpmnError e){
269 }catch (Exception e){
270 WorkflowException aWorkflowException = exceptionUtil.MapAAIExceptionToWorkflowException(e.getMessage(), execution)
271 throw new BpmnError("MSOWorkflowException")
276 * Extract the Tenant Id from the Volume Group information returned by AAI.
278 * @param volumeGroupXml Volume Group XML returned by AAI.
279 * @return the Tenant Id extracted from the Volume Group information. 'null' is returned if
280 * the Tenant Id is missing or could not otherwise be extracted.
282 private String getTenantIdFromVolumeGroup(AAIResultWrapper wrapper) {
283 if(wrapper.getRelationships().isPresent()) {
284 List<AAIResourceUri> tenantURIList = wrapper.getRelationships().get().getRelatedAAIUris(AAIObjectType.TENANT)
285 if(!tenantURIList.isEmpty()){
286 return tenantURIList.get(0).getURIKeys().get("tenant-id")
292 private boolean hasVnfRelationship(String volumeGroupXml) {
293 def Node volumeGroupNode = xmlParser.parseText(volumeGroupXml)
294 def Node relationshipList = utils.getChildNode(volumeGroupNode, 'relationship-list')
295 if (relationshipList != null) {
296 def NodeList relationships = utils.getIdenticalChildren(relationshipList, 'relationship')
297 for (Node relationship in relationships) {
298 def Node relatedTo = utils.getChildNode(relationship, 'related-to')
299 if ((relatedTo != null) && (relatedTo.text().equals('generic-vnf'))) {
300 def Node relatedLink = utils.getChildNode(relationship, 'related-link')
301 if (relatedLink !=null && relatedLink.text() != null){
310 public void prepareVnfAdapterDeleteRequest(DelegateExecution execution, isDebugLogEnabled) {
311 def cloudRegion = execution.getVariable('DELVfModVol_cloudRegion')
312 def tenantId = execution.getVariable('DELVfModVol_tenantId')
313 def volumeGroupId = execution.getVariable('DELVfModVol_volumeGroupId')
314 def volumeGroupHeatStackId = execution.getVariable('DELVfModVol_volumeGroupHeatStackId')
315 def requestId = execution.getVariable('DELVfModVol_requestId')
316 def serviceId = execution.getVariable('DELVfModVol_serviceId')
318 def messageId = execution.getVariable('DELVfModVol_messageId')
319 def notificationUrl = createCallbackURL(execution, "VNFAResponse", messageId)
320 def useQualifiedHostName = UrnPropertiesReader.getVariable("mso.use.qualified.host", execution)
321 if ('true'.equals(useQualifiedHostName)) {
322 notificationUrl = utils.getQualifiedHostNameForCallback(notificationUrl)
325 String vnfAdapterRestRequest = """
326 <deleteVolumeGroupRequest>
327 <cloudSiteId>${MsoUtils.xmlEscape(cloudRegion)}</cloudSiteId>
328 <tenantId>${MsoUtils.xmlEscape(tenantId)}</tenantId>
329 <volumeGroupId>${MsoUtils.xmlEscape(volumeGroupId)}</volumeGroupId>
330 <volumeGroupStackId>${MsoUtils.xmlEscape(volumeGroupHeatStackId)}</volumeGroupStackId>
331 <skipAAI>true</skipAAI>
333 <requestId>${MsoUtils.xmlEscape(requestId)}</requestId>
334 <serviceInstanceId>${MsoUtils.xmlEscape(serviceId)}</serviceInstanceId>
336 <messageId>${MsoUtils.xmlEscape(messageId)}</messageId>
337 <notificationUrl>${MsoUtils.xmlEscape(notificationUrl)}</notificationUrl>
338 </deleteVolumeGroupRequest>
340 vnfAdapterRestRequest = utils.formatXml(vnfAdapterRestRequest)
341 execution.setVariable('DELVfModVol_deleteVnfARequest', vnfAdapterRestRequest)
342 msoLogger.debug('Request for VNFAdapter Rest:\n' + vnfAdapterRestRequest)
346 public void deleteVolGrpId(DelegateExecution execution, isDebugEnabled) {
349 VolumeGroup volumeGroup = execution.getVariable("DELVfModVol_queryAAIVolGrpResponse")
350 String groupId = volumeGroup.getVolumeGroupId()
351 String cloudRegion = execution.getVariable('DELVfModVol_aicCloudRegion')
353 ExceptionUtil exceptionUtil = new ExceptionUtil()
355 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VOLUME_GROUP, Defaults.CLOUD_OWNER.toString(), cloudRegion, groupId)
356 getAAIClient().delete(uri)
357 msoLogger.debug("Volume group $groupId deleted.")
358 }catch(NotFoundException e){
359 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Volume group $groupId not found for delete in AAI Response code: 404")
360 }catch(Exception e1){
361 WorkflowException aWorkflowException = exceptionUtil.MapAAIExceptionToWorkflowException(e1.getMessage(), execution)
362 throw new BpmnError("MSOWorkflowException")
367 public void prepareDBRequest (DelegateExecution execution, isDebugLogEnabled) {
369 WorkflowException workflowExceptionObj = execution.getVariable("WorkflowException")
370 ExceptionUtil exceptionUtil = new ExceptionUtil();
371 def requestId = execution.getVariable('DELVfModVol_requestId')
372 def volOutputs = execution.getVariable('DELVfModVol_volumeOutputs')
373 def statusMessage = "VolumeGroup successfully deleted"
375 def requestStatus = "COMPLETE"
377 if (workflowExceptionObj != null) {
378 statusMessage = (workflowExceptionObj.getErrorMessage())
379 execution.setVariable("DELVfModVol_WorkflowExceptionMessage", statusMessage)
380 execution.setVariable("DELVfModVol_WorkflowExceptionCode", workflowExceptionObj.getErrorCode())
381 requestStatus = "FAILURE"
385 String updateInfraRequest = """
386 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
387 xmlns:req="http://org.onap.so/requestsdb">
390 <req:updateInfraRequest>
391 <requestId>${MsoUtils.xmlEscape(requestId)}</requestId>
392 <lastModifiedBy>BPMN</lastModifiedBy>
393 <statusMessage>${MsoUtils.xmlEscape(statusMessage)}</statusMessage>
394 <requestStatus>${MsoUtils.xmlEscape(requestStatus)}</requestStatus>
395 <progress>${MsoUtils.xmlEscape(progress)}</progress>
396 <vnfOutputs>${MsoUtils.xmlEscape(volOutputs)}</vnfOutputs>
397 </req:updateInfraRequest>
402 updateInfraRequest = utils.formatXml(updateInfraRequest)
403 execution.setVariable('DELVfModVol_updateInfraRequest', updateInfraRequest)
404 msoLogger.debug('Request for Update Infra Request:\n' + updateInfraRequest)
409 public void prepareCompletionHandlerRequest (DelegateExecution execution, isDebugLogEnabled) {
410 def requestId = execution.getVariable("mso-request-id")
411 def source = execution.getVariable("DELVfModVol_source")
413 String msoCompletionRequest =
414 """<aetgt:MsoCompletionRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
415 xmlns:ns="http://org.onap/so/request/types/v1">
416 <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
417 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
418 <action>DELETE</action>
419 <source>${MsoUtils.xmlEscape(source)}</source>
421 <aetgt:status-message>Volume Group has been deleted successfully.</aetgt:status-message>
422 <aetgt:mso-bpel-name>BPMN VF Module Volume action: DELETE</aetgt:mso-bpel-name>
423 </aetgt:MsoCompletionRequest>"""
425 String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest)
426 execution.setVariable('DELVfModVol_CompleteMsoProcessRequest', xmlMsoCompletionRequest)
427 msoLogger.debug(" Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest)
433 public void prepareFalloutHandler (DelegateExecution execution, isDebugEnabled) {
435 execution.setVariable("DELVfModVol_Success", false)
436 String requestId = execution.getVariable("DELVfModVol_requestId")
437 String source = execution.getVariable("DELVfModVol_source")
439 WorkflowException workflowExceptionObj = execution.getVariable("WorkflowException")
440 def errorMessage = workflowExceptionObj.getErrorMessage()
441 def errorCode = workflowExceptionObj.getErrorCode()
443 String falloutHandlerRequest =
444 """<aetgt:FalloutHandlerRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
445 xmlns:ns="http://org.onap/so/request/types/v1"
446 xmlns:wfsch="http://org.onap/so/workflow/schema/v1">
447 <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
448 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
449 <action>DELETE</action>
450 <source>${MsoUtils.xmlEscape(source)}</source>
452 <aetgt:WorkflowException>
453 <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorMessage)}</aetgt:ErrorMessage>
454 <aetgt:ErrorCode>${MsoUtils.xmlEscape(errorCode)}</aetgt:ErrorCode>
455 </aetgt:WorkflowException>
456 </aetgt:FalloutHandlerRequest>"""
459 String xmlHandlerRequest = utils.formatXml(falloutHandlerRequest)
460 msoLogger.debug(xmlHandlerRequest)
462 execution.setVariable("DELVfModVol_FalloutHandlerRequest", xmlHandlerRequest)
463 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, " Overall Error Response going to FalloutHandler", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "\n" + xmlHandlerRequest);
469 * Create a WorkflowException for the error case where the Tenant Id from
470 * AAI did not match the Tenant Id in the incoming request.
472 * @param execution The flow's execution instance.
474 public void handleTenantIdMismatch(DelegateExecution execution, isDebugLogEnabled) {
476 def volumeGroupId = execution.getVariable('DELVfModVol_volumeGroupId')
477 def aicCloudRegion = execution.getVariable('DELVfModVol_aicCloudRegion')
478 def tenantId = execution.getVariable('DELVfModVol_tenantId')
479 def volumeGroupTenantId = execution.getVariable('DELVfModVol_volumeGroupTenantId')
481 def String errorMessage = 'TenantId ' + tenantId + ' in incoming request does not match Tenant Id ' + volumeGroupTenantId +
482 ' retrieved from AAI for Volume Group Id ' + volumeGroupId
483 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "Error in DeleteVfModuleVolume: " + "\n" + errorMessage, "BPMN", MsoLogger.getServiceName(),MsoLogger.ErrorCode.UnknownError);
485 ExceptionUtil exceptionUtil = new ExceptionUtil()
486 exceptionUtil.buildWorkflowException(execution, 5000, errorMessage)