9fa488f8a7ed2c9eb638b620c98922b9837fa66d
[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 org.onap.so.logger.LoggingAnchor
26 import org.camunda.bpm.engine.delegate.BpmnError
27 import org.camunda.bpm.engine.delegate.DelegateExecution
28 import org.onap.aai.domain.yang.VolumeGroup
29 import org.onap.so.bpmn.common.scripts.AaiUtil;
30 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor;
31 import org.onap.so.bpmn.common.scripts.ExceptionUtil;
32 import org.onap.so.bpmn.common.scripts.MsoUtils
33 import org.onap.so.bpmn.common.scripts.VidUtils;
34 import org.onap.so.bpmn.core.UrnPropertiesReader
35 import org.onap.so.bpmn.core.WorkflowException
36 import org.onap.so.client.aai.AAIObjectType
37 import org.onap.so.client.aai.entities.AAIResultWrapper
38 import org.onap.so.client.aai.entities.uri.AAIResourceUri
39 import org.onap.so.client.aai.entities.uri.AAIUriFactory
40 import org.onap.so.constants.Defaults
41 import org.onap.so.logger.ErrorCode
42 import org.onap.so.logger.MessageEnum
43 import org.slf4j.Logger
44 import org.slf4j.LoggerFactory
45 import groovy.json.JsonSlurper
46
47 import javax.ws.rs.NotFoundException
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("tenant-id")
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 }