005f0f3c6b021ed4b8fe4e76175b6b62a66b8652
[so.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
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
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
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=========================================================
21  */
22
23 package org.onap.so.bpmn.infrastructure.scripts
24
25 import javax.ws.rs.NotFoundException
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.aaiclient.client.aai.AAIObjectType
30 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper
31 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
32 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
33 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
34 import org.onap.logging.filter.base.ErrorCode
35 import org.onap.so.bpmn.common.scripts.AaiUtil;
36 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor;
37 import org.onap.so.bpmn.common.scripts.ExceptionUtil;
38 import org.onap.so.bpmn.common.scripts.MsoUtils
39 import org.onap.so.bpmn.common.scripts.VidUtils;
40 import org.onap.so.bpmn.core.UrnPropertiesReader
41 import org.onap.so.bpmn.core.WorkflowException
42 import org.onap.so.constants.Defaults
43 import org.onap.so.logger.LoggingAnchor
44 import org.onap.so.logger.MessageEnum
45 import org.slf4j.Logger
46 import org.slf4j.LoggerFactory
47 import groovy.json.JsonSlurper
48
49 /**
50  * This groovy class supports the <class>DeleteVfModuleVolume.bpmn</class> process.
51  */
52 public class DeleteVfModuleVolumeInfraV1 extends AbstractServiceTaskProcessor {
53     private static final Logger logger = LoggerFactory.getLogger( DeleteVfModuleVolumeInfraV1.class);
54
55         private XmlParser xmlParser = new XmlParser()
56         /**
57          * This method is executed during the preProcessRequest task of the <class>DeleteVfModuleVolume.bpmn</class> process.
58          * @param execution
59          */
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)
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                         logger.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                         logger.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                 execution.setVariable('DELVfModVol_cloudOwner', utils.getNodeText(request, 'cloud-owner'))
147
148                 setBasicDBAuthHeader(execution, isDebugLogEnabled)
149
150                 logger.debug('Request: ' + createVolumeIncoming)
151         }
152
153         public void sendSyncResponse (DelegateExecution execution, isDebugEnabled) {
154
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">
162                                 ${volumeRequest}
163                 </rest:payload>
164                        </rest:RESTResponse>""".trim()
165
166                 def isVidRequest = execution.getVariable('DELVfModVol_isVidRequest')
167                 def syncResponse = ''
168
169                 if(isVidRequest) {
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()
174                 }
175                 else {
176                         syncResponse = utils.formatXml(deleteVolumeRequest)
177                 }
178
179                 execution.setVariable('DELVfModVol_syncResponseSent', true)
180
181                 sendWorkflowResponse(execution, 200, syncResponse)
182         }
183
184
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)
191         }
192
193
194         public void callRESTQueryAAICloudRegion (DelegateExecution execution, isDebugEnabled) {
195
196                 String cloudRegion = execution.getVariable('DELVfModVol_cloudRegion')
197
198                 AaiUtil aaiUtil = new AaiUtil(this)
199
200                 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.CLOUD_REGION, Defaults.CLOUD_OWNER.toString(), cloudRegion)
201                 def queryCloudRegionRequest = aaiUtil.createAaiUri(uri)
202
203                 execution.setVariable("DELVfModVol_queryCloudRegionRequest", queryCloudRegionRequest)
204
205                 cloudRegion = aaiUtil.getAAICloudReqion(execution,  queryCloudRegionRequest, "PO", cloudRegion)
206
207                 ExceptionUtil exceptionUtil = new ExceptionUtil()
208
209                 if ((cloudRegion != "ERROR")) {
210                         if(execution.getVariable("DELVfModVol_queryCloudRegionReturnCode") == "404"){
211                                 execution.setVariable("DELVfModVol_aicCloudRegion", "AAIAIC25")
212                         }else{
213                                 execution.setVariable("DELVfModVol_aicCloudRegion", cloudRegion)
214                         }
215                         execution.setVariable("DELVfModVol_cloudRegion", cloudRegion)
216                         execution.setVariable("DELVfModVol_isCloudRegionGood", true)
217
218                 } else {
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"))
222                 }
223
224                 logger.debug(" is Cloud Region Good: " + execution.getVariable("DELVfModVol_isCloudRegionGood"))
225         }
226
227         /**
228          * Query volume group by id
229          * @param execution
230          */
231         public void queryAAIForVolumeGroup(DelegateExecution execution, isDebugLogEnabled) {
232
233                 ExceptionUtil exceptionUtil = new ExceptionUtil()
234
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')
239                 }
240                 String cloudRegion = execution.getVariable('DELVfModVol_aicCloudRegion')
241
242         try {
243             AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VOLUME_GROUP, Defaults.CLOUD_OWNER.toString(), cloudRegion, volumeGroupId)
244             AAIResultWrapper volumeGroupWrapper = getAAIClient().get(uri)
245
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)
251
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.")
255                 }
256
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}")
261                 }
262
263                 execution.setVariable('DELVfModVol_volumeGroupTenantId', volumeGroupTenantId)
264                 logger.debug('Received Tenant Id ' + volumeGroupTenantId + ' from AAI for Volume Group with Volume Group Id ' + volumeGroupId)
265             } else {
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")
268             }
269         }catch (BpmnError e){
270             throw e
271         }catch (Exception e){
272             WorkflowException aWorkflowException = exceptionUtil.MapAAIExceptionToWorkflowException(e.getMessage(), execution)
273             throw new BpmnError("MSOWorkflowException")
274         }
275         }
276
277         /**
278          * Extract the Tenant Id from the Volume Group information returned by AAI.
279          *
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.
283          */
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(AAIFluentTypeBuilder.Types.TENANT.getUriParams().tenantId)
289             }
290         }
291                 return null
292         }
293
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){
304                                                 return true
305                                         }
306                                 }
307                         }
308                 }
309                 return false
310         }
311
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')
320
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)
326                 }
327
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>
336                             <msoRequest>
337                                 <requestId>${MsoUtils.xmlEscape(requestId)}</requestId>
338                                 <serviceInstanceId>${MsoUtils.xmlEscape(serviceId)}</serviceInstanceId>
339                             </msoRequest>
340                             <messageId>${MsoUtils.xmlEscape(messageId)}</messageId>
341                             <notificationUrl>${MsoUtils.xmlEscape(notificationUrl)}</notificationUrl>
342                         </deleteVolumeGroupRequest>
343                 """
344                 vnfAdapterRestRequest = utils.formatXml(vnfAdapterRestRequest)
345                 execution.setVariable('DELVfModVol_deleteVnfARequest', vnfAdapterRestRequest)
346                 logger.debug('Request for VNFAdapter Rest:\n' + vnfAdapterRestRequest)
347         }
348
349
350         public void deleteVolGrpId(DelegateExecution execution, isDebugEnabled) {
351
352                 // get variables
353         VolumeGroup volumeGroup = execution.getVariable("DELVfModVol_queryAAIVolGrpResponse")
354                 String groupId = volumeGroup.getVolumeGroupId()
355                 String cloudRegion = execution.getVariable('DELVfModVol_aicCloudRegion')
356
357         ExceptionUtil exceptionUtil = new ExceptionUtil()
358         try {
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")
367         }
368         }
369
370
371         public void prepareDBRequest (DelegateExecution execution, isDebugLogEnabled) {
372
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"
378                 def progress = "100"
379                 def requestStatus = "COMPLETE"
380
381                 if (workflowExceptionObj != null) {
382                         statusMessage = (workflowExceptionObj.getErrorMessage())
383                         execution.setVariable("DELVfModVol_WorkflowExceptionMessage", statusMessage)
384                         execution.setVariable("DELVfModVol_WorkflowExceptionCode", workflowExceptionObj.getErrorCode())
385                         requestStatus = "FAILURE"
386                         progress = ""
387                 }
388
389                 String updateInfraRequest = """
390                         <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
391                                         xmlns:req="http://org.onap.so/requestsdb">
392                                 <soapenv:Header/>
393                                 <soapenv:Body>
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>
402                                 </soapenv:Body>
403                         </soapenv:Envelope>
404                 """
405
406                 updateInfraRequest = utils.formatXml(updateInfraRequest)
407                 execution.setVariable('DELVfModVol_updateInfraRequest', updateInfraRequest)
408                 logger.debug('Request for Update Infra Request:\n' + updateInfraRequest)
409
410         }
411
412
413         public void prepareCompletionHandlerRequest (DelegateExecution execution, isDebugLogEnabled) {
414                 def requestId = execution.getVariable("mso-request-id")
415                 def source = execution.getVariable("DELVfModVol_source")
416
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>
424                                         </request-info>
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>"""
428
429                 String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest)
430                 execution.setVariable('DELVfModVol_CompleteMsoProcessRequest', xmlMsoCompletionRequest)
431                 logger.debug(" Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest)
432
433         }
434
435
436
437         public void prepareFalloutHandler (DelegateExecution execution) {
438
439                 execution.setVariable("DELVfModVol_Success", false)
440                 String requestId = execution.getVariable("DELVfModVol_requestId")
441                 String source = execution.getVariable("DELVfModVol_source")
442
443                 WorkflowException workflowExceptionObj = execution.getVariable("WorkflowException")
444                 def errorMessage = workflowExceptionObj.getErrorMessage()
445                 def errorCode =  workflowExceptionObj.getErrorCode()
446
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>
455                                    </request-info>
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>"""
461
462                 // Format Response
463                 String xmlHandlerRequest = utils.formatXml(falloutHandlerRequest)
464                 logger.debug(xmlHandlerRequest)
465
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);
470         }
471
472
473         /**
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.
476          *
477          * @param execution The flow's execution instance.
478          */
479         public void handleTenantIdMismatch(DelegateExecution execution, isDebugLogEnabled) {
480
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')
485
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());
491
492                 ExceptionUtil exceptionUtil = new ExceptionUtil()
493                 exceptionUtil.buildWorkflowException(execution, 5000, errorMessage)
494
495         }
496
497 }