Springboot 2.0 upgrade
[so.git] / bpmn / so-bpmn-infrastructure-common / src / main / groovy / org / onap / so / bpmn / infrastructure / scripts / DeleteVfModuleVolumeInfraV1.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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=========================================================
19  */
20
21 package org.onap.so.bpmn.infrastructure.scripts;
22
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.onap.so.rest.APIResponse
43 import org.springframework.web.util.UriUtils
44
45
46 import groovy.json.JsonSlurper
47
48 import javax.ws.rs.NotFoundException
49
50 /**
51  * This groovy class supports the <class>DeleteVfModuleVolume.bpmn</class> process.
52  */
53 public class DeleteVfModuleVolumeInfraV1 extends AbstractServiceTaskProcessor {
54         private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, DeleteVfModuleVolumeInfraV1.class);
55
56         private XmlParser xmlParser = new XmlParser()
57         /**
58          * This method is executed during the preProcessRequest task of the <class>DeleteVfModuleVolume.bpmn</class> process.
59          * @param execution
60          */
61         public InitializeProcessVariables(DelegateExecution execution){
62                 execution.setVariable('prefix', 'DELVfModVol_')
63                 execution.setVariable("DELVfModVol_volumeRequest", null)
64                 execution.setVariable('DELVfModVol_requestInfo', null)
65                 execution.setVariable('DELVfModVol_requestId', null)
66                 execution.setVariable('DELVfModVol_source', null)
67                 execution.setVariable('DELVfModVol_volumeInputs', null)
68                 execution.setVariable('DELVfModVol_volumeOutputs', null)
69                 execution.setVariable('DELVfModVol_volumeGroupId', null)
70                 execution.setVariable('DELVfModVol_vnfType', null)
71                 execution.setVariable('DELVfModVol_serviceId', null)
72                 execution.setVariable('DELVfModVol_cloudRegion', 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)
86         }
87
88         /**
89          * Perform initial processing, such as request validation, initialization of variables, etc.
90          * * @param execution
91          */
92         public void preProcessRequest (DelegateExecution execution) {
93                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
94                 preProcessRequest(execution, isDebugEnabled)
95         }
96
97         /**
98          * This method is executed during the preProcessRequest task of the <class>DeleteVfModuleVolume.bpmn</class> process.
99          * @param execution
100          */
101         public void preProcessRequest (DelegateExecution execution, isDebugLogEnabled) {
102
103                 InitializeProcessVariables(execution)
104
105                 String createVolumeIncoming = validateRequest(execution)
106
107                 // check if request is xml or json
108                 try {
109                         def jsonSlurper = new JsonSlurper()
110                         Map reqMap = jsonSlurper.parseText(createVolumeIncoming)
111                         msoLogger.debug(" Request is in JSON format.")
112
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)
118                 }
119                 catch(groovy.json.JsonException je) {
120                         msoLogger.debug(" Request is in XML format.")
121                         // assume request is in XML format - proceed as usual to process XML request
122                 }
123
124                 String request = utils.getNodeXml(createVolumeIncoming, "volume-request").drop(38).trim().replace("tag0:","").replace(":tag0","")
125                 execution.setVariable("DELVfModVol_volumeRequest", request)
126
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')
132                 }
133                 execution.setVariable('DELVfModVol_requestId', requestId)
134                 execution.setVariable('DELVfModVol_source', getNodeTextForce(requestInfo, 'source'))
135
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
147                 setBasicDBAuthHeader(execution, isDebugLogEnabled)
148
149                 msoLogger.debug('Request: ' + createVolumeIncoming)
150         }
151
152         public void sendSyncResponse (DelegateExecution execution, isDebugEnabled) {
153
154                 String volumeRequest = execution.getVariable("DELVfModVol_volumeRequest")
155                 msoLogger.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">
161                                 ${volumeRequest}
162                 </rest:payload>
163                        </rest:RESTResponse>""".trim()
164
165                 def isVidRequest = execution.getVariable('DELVfModVol_isVidRequest')
166                 def syncResponse = ''
167
168                 if(isVidRequest) {
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()
173                 }
174                 else {
175                         syncResponse = utils.formatXml(deleteVolumeRequest)
176                 }
177
178                 execution.setVariable('DELVfModVol_syncResponseSent', true)
179
180                 sendWorkflowResponse(execution, 200, syncResponse)
181         }
182
183
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)
190         }
191
192
193         public void callRESTQueryAAICloudRegion (DelegateExecution execution, isDebugEnabled) {
194
195                 String cloudRegion = execution.getVariable('DELVfModVol_cloudRegion')
196
197                 AaiUtil aaiUtil = new AaiUtil(this)
198
199                 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.CLOUD_REGION, Defaults.CLOUD_OWNER.toString(), cloudRegion)
200                 def queryCloudRegionRequest = aaiUtil.createAaiUri(uri)
201
202                 execution.setVariable("DELVfModVol_queryCloudRegionRequest", queryCloudRegionRequest)
203
204                 cloudRegion = aaiUtil.getAAICloudReqion(execution,  queryCloudRegionRequest, "PO", cloudRegion)
205
206                 ExceptionUtil exceptionUtil = new ExceptionUtil()
207
208                 if ((cloudRegion != "ERROR")) {
209                         if(execution.getVariable("DELVfModVol_queryCloudRegionReturnCode") == "404"){
210                                 execution.setVariable("DELVfModVol_aicCloudRegion", "AAIAIC25")
211                         }else{
212                                 execution.setVariable("DELVfModVol_aicCloudRegion", cloudRegion)
213                         }
214                         execution.setVariable("DELVfModVol_cloudRegion", cloudRegion)
215                         execution.setVariable("DELVfModVol_isCloudRegionGood", true)
216
217                 } else {
218                         msoLogger.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"))
221                 }
222
223                 msoLogger.debug(" is Cloud Region Good: " + execution.getVariable("DELVfModVol_isCloudRegionGood"))
224         }
225
226         /**
227          * Query volume group by id
228          * @param execution
229          */
230         public void queryAAIForVolumeGroup(DelegateExecution execution, isDebugLogEnabled) {
231
232                 ExceptionUtil exceptionUtil = new ExceptionUtil()
233
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')
238                 }
239                 String cloudRegion = execution.getVariable('DELVfModVol_aicCloudRegion')
240
241         try {
242             AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VOLUME_GROUP, Defaults.CLOUD_OWNER.toString(), cloudRegion, volumeGroupId)
243             AAIResultWrapper volumeGroupWrapper = getAAIClient().get(uri)
244
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)
250
251                 if ( volumeGroupWrapper.getRelationships().isPresent() && !volumeGroupWrapper.getRelationships().get().getRelatedAAIUris(AAIObjectType.VF_MODULE).isEmpty()) {
252                     msoLogger.debug('Volume Group ' + volumeGroupId + ' currently in use')
253                     exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Volume Group ${volumeGroupId} currently in use - found vf-module relationship.")
254                 }
255
256                 def volumeGroupTenantId = getTenantIdFromVolumeGroup(volumeGroupWrapper)
257                 if (volumeGroupTenantId == null) {
258                     msoLogger.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}")
260                 }
261
262                 execution.setVariable('DELVfModVol_volumeGroupTenantId', volumeGroupTenantId)
263                 msoLogger.debug('Received Tenant Id ' + volumeGroupTenantId + ' from AAI for Volume Group with Volume Group Id ' + volumeGroupId)
264             } else {
265                 msoLogger.debug("Volume Group ${volumeGroupId} not found in AAI")
266                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Volume Group ${volumeGroupId} not found in AAI. Response code: 404")
267             }
268         }catch (BpmnError e){
269             throw e
270         }catch (Exception e){
271             WorkflowException aWorkflowException = exceptionUtil.MapAAIExceptionToWorkflowException(e.getMessage(), execution)
272             throw new BpmnError("MSOWorkflowException")
273         }
274         }
275
276         /**
277          * Extract the Tenant Id from the Volume Group information returned by AAI.
278          *
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.
282          */
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")
288             }
289         }
290                 return null
291         }
292
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){
303                                                 return true
304                                         }
305                                 }
306                         }
307                 }
308                 return false
309         }
310
311         public void prepareVnfAdapterDeleteRequest(DelegateExecution execution, isDebugLogEnabled) {
312                 def cloudRegion = execution.getVariable('DELVfModVol_cloudRegion')
313                 def tenantId = execution.getVariable('DELVfModVol_tenantId')
314                 def volumeGroupId = execution.getVariable('DELVfModVol_volumeGroupId')
315                 def volumeGroupHeatStackId = execution.getVariable('DELVfModVol_volumeGroupHeatStackId')
316                 def requestId = execution.getVariable('DELVfModVol_requestId')
317                 def serviceId = execution.getVariable('DELVfModVol_serviceId')
318
319                 def messageId = execution.getVariable('DELVfModVol_messageId')
320                 def notificationUrl = createCallbackURL(execution, "VNFAResponse", messageId)
321                 def useQualifiedHostName = UrnPropertiesReader.getVariable("mso.use.qualified.host", execution)
322                 if ('true'.equals(useQualifiedHostName)) {
323                                 notificationUrl = utils.getQualifiedHostNameForCallback(notificationUrl)
324                 }
325
326                 String vnfAdapterRestRequest = """
327                         <deleteVolumeGroupRequest>
328                                 <cloudSiteId>${MsoUtils.xmlEscape(cloudRegion)}</cloudSiteId>
329                                 <tenantId>${MsoUtils.xmlEscape(tenantId)}</tenantId>
330                                 <volumeGroupId>${MsoUtils.xmlEscape(volumeGroupId)}</volumeGroupId>
331                                 <volumeGroupStackId>${MsoUtils.xmlEscape(volumeGroupHeatStackId)}</volumeGroupStackId>
332                                 <skipAAI>true</skipAAI>
333                             <msoRequest>
334                                 <requestId>${MsoUtils.xmlEscape(requestId)}</requestId>
335                                 <serviceInstanceId>${MsoUtils.xmlEscape(serviceId)}</serviceInstanceId>
336                             </msoRequest>
337                             <messageId>${MsoUtils.xmlEscape(messageId)}</messageId>
338                             <notificationUrl>${MsoUtils.xmlEscape(notificationUrl)}</notificationUrl>
339                         </deleteVolumeGroupRequest>
340                 """
341                 vnfAdapterRestRequest = utils.formatXml(vnfAdapterRestRequest)
342                 execution.setVariable('DELVfModVol_deleteVnfARequest', vnfAdapterRestRequest)
343                 msoLogger.debug('Request for VNFAdapter Rest:\n' + vnfAdapterRestRequest)
344         }
345
346
347         public void deleteVolGrpId(DelegateExecution execution, isDebugEnabled) {
348
349                 // get variables
350         VolumeGroup volumeGroup = execution.getVariable("DELVfModVol_queryAAIVolGrpResponse")
351                 String groupId = volumeGroup.getVolumeGroupId()
352                 String cloudRegion = execution.getVariable('DELVfModVol_aicCloudRegion')
353
354         ExceptionUtil exceptionUtil = new ExceptionUtil()
355         try {
356             AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VOLUME_GROUP, Defaults.CLOUD_OWNER.toString(), cloudRegion, groupId)
357             getAAIClient().delete(uri)
358             msoLogger.debug("Volume group $groupId deleted.")
359         }catch(NotFoundException e){
360             exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Volume group $groupId not found for delete in AAI Response code: 404")
361         }catch(Exception e1){
362             WorkflowException aWorkflowException = exceptionUtil.MapAAIExceptionToWorkflowException(e1.getMessage(), execution)
363             throw new BpmnError("MSOWorkflowException")
364         }
365         }
366
367
368         public void prepareDBRequest (DelegateExecution execution, isDebugLogEnabled) {
369
370                 WorkflowException workflowExceptionObj = execution.getVariable("WorkflowException")
371                 ExceptionUtil exceptionUtil = new ExceptionUtil();
372                 def requestId = execution.getVariable('DELVfModVol_requestId')
373                 def volOutputs = execution.getVariable('DELVfModVol_volumeOutputs')
374                 def statusMessage = "VolumeGroup successfully deleted"
375                 def progress = "100"
376                 def requestStatus = "COMPLETE"
377
378                 if (workflowExceptionObj != null) {
379                         statusMessage = (workflowExceptionObj.getErrorMessage())
380                         execution.setVariable("DELVfModVol_WorkflowExceptionMessage", statusMessage)
381                         execution.setVariable("DELVfModVol_WorkflowExceptionCode", workflowExceptionObj.getErrorCode())
382                         requestStatus = "FAILURE"
383                         progress = ""
384                 }
385
386                 String updateInfraRequest = """
387                         <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
388                                         xmlns:req="http://org.onap.so/requestsdb">
389                                 <soapenv:Header/>
390                                 <soapenv:Body>
391                                         <req:updateInfraRequest>
392                                                 <requestId>${MsoUtils.xmlEscape(requestId)}</requestId>
393                                                 <lastModifiedBy>BPMN</lastModifiedBy>
394                                                 <statusMessage>${MsoUtils.xmlEscape(statusMessage)}</statusMessage>
395                                                 <requestStatus>${MsoUtils.xmlEscape(requestStatus)}</requestStatus>
396                                                 <progress>${MsoUtils.xmlEscape(progress)}</progress>
397                                                 <vnfOutputs>${MsoUtils.xmlEscape(volOutputs)}</vnfOutputs>
398                                         </req:updateInfraRequest>
399                                 </soapenv:Body>
400                         </soapenv:Envelope>
401                 """
402
403                 updateInfraRequest = utils.formatXml(updateInfraRequest)
404                 execution.setVariable('DELVfModVol_updateInfraRequest', updateInfraRequest)
405                 msoLogger.debug('Request for Update Infra Request:\n' + updateInfraRequest)
406
407         }
408
409
410         public void prepareCompletionHandlerRequest (DelegateExecution execution, isDebugLogEnabled) {
411                 def requestId = execution.getVariable("mso-request-id")
412                 def source = execution.getVariable("DELVfModVol_source")
413
414                 String msoCompletionRequest =
415                         """<aetgt:MsoCompletionRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
416                                                         xmlns:ns="http://org.onap/so/request/types/v1">
417                                         <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
418                                                 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
419                                                 <action>DELETE</action>
420                                                 <source>${MsoUtils.xmlEscape(source)}</source>
421                                         </request-info>
422                                         <aetgt:status-message>Volume Group has been deleted successfully.</aetgt:status-message>
423                                         <aetgt:mso-bpel-name>BPMN VF Module Volume action: DELETE</aetgt:mso-bpel-name>
424                                 </aetgt:MsoCompletionRequest>"""
425
426                 String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest)
427                 execution.setVariable('DELVfModVol_CompleteMsoProcessRequest', xmlMsoCompletionRequest)
428                 msoLogger.debug(" Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest)
429
430         }
431
432
433
434         public void prepareFalloutHandler (DelegateExecution execution, isDebugEnabled) {
435
436                 execution.setVariable("DELVfModVol_Success", false)
437                 String requestId = execution.getVariable("DELVfModVol_requestId")
438                 String source = execution.getVariable("DELVfModVol_source")
439
440                 WorkflowException workflowExceptionObj = execution.getVariable("WorkflowException")
441                 def errorMessage = workflowExceptionObj.getErrorMessage()
442                 def errorCode =  workflowExceptionObj.getErrorCode()
443
444                 String falloutHandlerRequest =
445                     """<aetgt:FalloutHandlerRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
446                                                              xmlns:ns="http://org.onap/so/request/types/v1"
447                                                              xmlns:wfsch="http://org.onap/so/workflow/schema/v1">
448                                    <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
449                                       <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
450                                       <action>DELETE</action>
451                                       <source>${MsoUtils.xmlEscape(source)}</source>
452                                    </request-info>
453                                         <aetgt:WorkflowException>
454                                       <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorMessage)}</aetgt:ErrorMessage>
455                                       <aetgt:ErrorCode>${MsoUtils.xmlEscape(errorCode)}</aetgt:ErrorCode>
456                                         </aetgt:WorkflowException>
457                                 </aetgt:FalloutHandlerRequest>"""
458
459                 // Format Response
460                 String xmlHandlerRequest = utils.formatXml(falloutHandlerRequest)
461                 msoLogger.debug(xmlHandlerRequest)
462
463                 execution.setVariable("DELVfModVol_FalloutHandlerRequest", xmlHandlerRequest)
464                 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "  Overall Error Response going to FalloutHandler", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "\n" + xmlHandlerRequest);
465
466         }
467
468
469         /**
470          * Create a WorkflowException for the error case where the Tenant Id from
471          * AAI did not match the Tenant Id in the incoming request.
472          *
473          * @param execution The flow's execution instance.
474          */
475         public void handleTenantIdMismatch(DelegateExecution execution, isDebugLogEnabled) {
476
477                 def volumeGroupId = execution.getVariable('DELVfModVol_volumeGroupId')
478                 def aicCloudRegion = execution.getVariable('DELVfModVol_aicCloudRegion')
479                 def tenantId = execution.getVariable('DELVfModVol_tenantId')
480                 def volumeGroupTenantId = execution.getVariable('DELVfModVol_volumeGroupTenantId')
481
482                 def String errorMessage = 'TenantId ' + tenantId + ' in incoming request does not match Tenant Id ' + volumeGroupTenantId +
483                         ' retrieved from AAI for Volume Group Id ' + volumeGroupId
484                 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "Error in DeleteVfModuleVolume: " + "\n" + errorMessage, "BPMN", MsoLogger.getServiceName(),MsoLogger.ErrorCode.UnknownError);
485
486                 ExceptionUtil exceptionUtil = new ExceptionUtil()
487                 exceptionUtil.buildWorkflowException(execution, 5000, errorMessage)
488
489         }
490
491 }