Initial OpenECOMP MSO commit
[so.git] / bpmn / MSOGammaBPMN / src / main / groovy / com / att / bpm / scripts / UpdateVfModuleVolumeInfraV1.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * OPENECOMP - MSO
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 com.att.bpm.scripts
22
23 import groovy.json.JsonSlurper
24 import java.util.concurrent.ExecutionException;
25
26 import org.camunda.bpm.engine.delegate.BpmnError
27 import org.camunda.bpm.engine.runtime.Execution
28 import org.apache.commons.lang3.*
29 import org.springframework.web.util.UriUtils
30
31 import org.openecomp.mso.bpmn.core.WorkflowException
32 import org.openecomp.mso.rest.APIResponse
33 import org.openecomp.mso.rest.RESTClient
34 import org.openecomp.mso.rest.RESTConfig
35
36 class UpdateVfModuleVolumeInfraV1 extends VfModuleBase {
37         
38         /**
39          * Initialize the flow's variables.
40          * 
41          * @param execution The flow's execution instance.
42          */
43         private void initProcessVariables(Execution execution) {
44                 execution.setVariable('prefix', 'UPDVfModVol_')
45                 execution.setVariable('UPDVfModVol_Request', null)
46                 execution.setVariable('UPDVfModVol_requestInfo', null)
47                 execution.setVariable('UPDVfModVol_requestId', null)
48                 execution.setVariable('UPDVfModVol_source', null)
49                 execution.setVariable('UPDVfModVol_volumeInputs', null)
50                 execution.setVariable('UPDVfModVol_volumeGroupId', null)
51                 execution.setVariable('UPDVfModVol_vnfType', null)
52                 execution.setVariable('UPDVfModVol_serviceId', null)
53                 execution.setVariable('UPDVfModVol_aicCloudRegion', null)
54                 execution.setVariable('UPDVfModVol_tenantId', null)
55                 execution.setVariable('UPDVfModVol_volumeParams', null)
56                 execution.setVariable('UPDVfModVol_volumeGroupHeatStackId', null)
57                 execution.setVariable('UPDVfModVol_volumeGroupTenantId', null)
58                 execution.setVariable('UpdateVfModuleVolumeSuccessIndicator', false)
59         }
60         
61
62         /**
63          * Perform initial processing, such as request validation, initialization of variables, etc.
64          * * @param execution
65          */
66         public void preProcessRequest (Execution execution) {
67                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
68                 preProcessRequest(execution, isDebugEnabled)
69         }
70         
71         public void preProcessRequest(Execution execution, isDebugLogEnabled) {
72
73                 initProcessVariables(execution)
74                 String jsonRequest = validateRequest(execution)
75                 
76                 def request = ""
77                 
78                 try {
79                         def jsonSlurper = new JsonSlurper()
80                         Map reqMap = jsonSlurper.parseText(jsonRequest)
81                         
82                         def serviceInstanceId = execution.getVariable('serviceInstanceId')
83                         def volumeGroupId = execution.getVariable('volumeGroupId')
84                         //def vnfId = execution.getVariable('vnfId')
85                         
86                         def vidUtils = new VidUtils(this)
87                         request = vidUtils.createXmlVolumeRequest(reqMap, 'UPDATE_VF_MODULE_VOL', serviceInstanceId, volumeGroupId)
88                         
89                         execution.setVariable('UPDVfModVol_Request', request)
90                         execution.setVariable("UPDVfModVol_isVidRequest", true)
91                         
92                         //need to get persona-model-id aka model-invariantId to use later to validate vf-module relation in AAI
93                         
94                         def modelInvariantId = reqMap.requestDetails.modelInfo.modelInvariantId ?: ''
95                         execution.setVariable('UPDVfModVol_modelInvariantId', modelInvariantId)
96                 
97                         utils.log("DEBUG", "XML request:\n" + request, isDebugLogEnabled)
98                 }
99                 catch(groovy.json.JsonException je) {
100                         utils.log("DEBUG", " Request is in XML format.", isDebugLogEnabled)
101                         // assume request is in XML format - proceed as usual to process XML request
102                 }
103                 
104                 def requestId = execution.getVariable('att-mso-request-id')
105                 
106                 def requestInfo = getRequiredNodeXml(execution, request, 'request-info')
107                 execution.setVariable('UPDVfModVol_requestInfo', requestInfo)
108                 execution.setVariable('UPDVfModVol_requestId', requestId)
109                 //execution.setVariable('UPDVfModVol_requestId', getRequiredNodeText(execution, requestInfo, 'request-id'))
110                 execution.setVariable('UPDVfModVol_source', getNodeTextForce(requestInfo, 'source'))
111                 
112                 def volumeInputs = getRequiredNodeXml(execution, request, 'volume-inputs')
113                 execution.setVariable('UPDVfModVol_volumeInputs', volumeInputs)
114                 execution.setVariable('UPDVfModVol_volumeGroupId', getRequiredNodeText(execution, volumeInputs, 'volume-group-id'))
115                 execution.setVariable('UPDVfModVol_vnfType', getRequiredNodeText(execution, volumeInputs, 'vnf-type'))
116                 execution.setVariable('UPDVfModVol_vnfVersion', getRequiredNodeText(execution, volumeInputs, 'asdc-service-model-version'))
117                 execution.setVariable('UPDVfModVol_serviceId', getRequiredNodeText(execution, volumeInputs, 'service-id'))
118                 execution.setVariable('UPDVfModVol_aicCloudRegion', getRequiredNodeText(execution, volumeInputs, 'aic-cloud-region'))
119                 execution.setVariable('UPDVfModVol_tenantId', getRequiredNodeText(execution, volumeInputs, 'tenant-id'))
120
121                 def volumeParams = utils.getNodeXml(request, 'volume-params')
122                 execution.setVariable('UPDVfModVol_volumeParams', volumeParams)
123         }
124
125         /**
126          * Prepare and send the synchronous response.
127          * 
128          * @param execution The flow's execution instance.
129          */
130         public void sendSynchResponse(Execution execution, isDebugLogEnabled) {
131
132                 def requestInfo = execution.getVariable('UPDVfModVol_requestInfo')
133                 def requestId = execution.getVariable('UPDVfModVol_requestId')
134                 def source = execution.getVariable('UPDVfModVol_source')
135                 def progress = getNodeTextForce(requestInfo, 'progress')
136                 if (progress.isEmpty()) {
137                         progress = '0'
138                 }
139                 def startTime = getNodeTextForce(requestInfo, 'start-time')
140                 if (startTime.isEmpty()) {
141                         startTime = System.currentTimeMillis()
142                 }
143                 def volumeInputs = execution.getVariable('UPDVfModVol_volumeInputs')
144                 
145                 String xmlSyncResponse = """
146                         <volume-request xmlns="http://ecomp.att.com/mso/infra/vnf-request/v1">
147                                 <request-info>
148                                         <request-id>${requestId}</request-id>
149                                         <action>UPDATE_VF_MODULE_VOL</action>
150                                         <request-status>IN_PROGRESS</request-status>
151                                         <progress>${progress}</progress>
152                                         <start-time>${startTime}</start-time>
153                                         <source>${source}</source>
154                                 </request-info>
155                                 ${volumeInputs}
156                         </volume-request>
157                 """
158
159                 def syncResponse = ''
160                 def isVidRequest = execution.getVariable('UPDVfModVol_isVidRequest')
161                 
162                 if(isVidRequest) {
163                         def volumeGroupId = execution.getVariable('volumeGroupId')
164                         syncResponse = """{"requestReferences":{"instanceId":"${volumeGroupId}","requestId":"${requestId}"}}""".trim()
165                 } 
166                 else {
167                         syncResponse = utils.formatXml(xmlSyncResponse)
168                 }
169                 
170                 logDebug('Sync response: ' + syncResponse, isDebugLogEnabled)
171                 execution.setVariable('UPDVfModVol_syncResponseSent', true)
172                 sendWorkflowResponse(execution, 200, syncResponse)
173         }
174         
175         /**
176          * Prepare a Request for querying AAI for Volume Group information using the
177          * Volume Group Id and Aic Cloud Region.
178          * @param execution The flow's execution instance.
179          */
180         public void queryAAIForVolumeGroup(Execution execution, isDebugLogEnabled) {
181
182                 def volumeGroupId = execution.getVariable('UPDVfModVol_volumeGroupId')
183                 def aicCloudRegion = execution.getVariable('UPDVfModVol_aicCloudRegion')
184
185                 AaiUtil aaiUtil = new AaiUtil(this)
186                 String aaiEndpoint = aaiUtil.getCloudInfrastructureCloudRegionEndpoint(execution)
187                 String queryAAIVolumeGroupRequest = aaiEndpoint + '/' + URLEncoder.encode(aicCloudRegion, "UTF-8") + "/volume-groups/volume-group/" + UriUtils.encode(volumeGroupId, "UTF-8")
188                 
189                 utils.logAudit('Query AAI volume group by ID: ' + queryAAIVolumeGroupRequest)
190                 logDebug('Query AAI volume group by ID: ' + queryAAIVolumeGroupRequest, isDebugLogEnabled)
191                 
192                 APIResponse response = aaiUtil.executeAAIGetCall(execution, queryAAIVolumeGroupRequest)
193                 
194                 String returnCode = response.getStatusCode()
195                 String aaiResponseAsString = response.getResponseBodyAsString()
196                 aaiResponseAsString = StringEscapeUtils.unescapeXml(aaiResponseAsString)
197                 
198                 utils.logAudit("AAI query volume group by id return code: " + returnCode)
199                 utils.logAudit("AAI query volume group by id response: " + aaiResponseAsString)
200                 
201                 logDebug("AAI Volume Group return code: " + returnCode, isDebugLogEnabled)
202                 logDebug("AAI Volume Group response: " + aaiResponseAsString, isDebugLogEnabled)
203                 
204                 ExceptionUtil exceptionUtil = new ExceptionUtil()
205                 
206                 if ((returnCode == '200') || (returnCode == '204')) {
207                         
208                         execution.setVariable('UPDVfModVol_aaiVolumeGroupResponse', aaiResponseAsString)
209                         //def heatStackId = getNodeTextForce(aaiResponseAsString, 'heat-stack-id')
210                         //execution.setVariable('UPDVfModVol_volumeGroupHeatStackId', heatStackId)
211                         
212                         def volumeGroupTenantId = getTenantIdFromVolumeGroup(aaiResponseAsString)
213                         if (volumeGroupTenantId == null) {
214                                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Could not find Tenant Id element in Volume Group with Volume Group Id " + volumeGroupId
215                                         + ", AIC Cloud Region " + aicCloudRegion)
216                         }
217                         execution.setVariable('UPDVfModVol_volumeGroupTenantId', volumeGroupTenantId)
218                         logDebug("Received Tenant Id " + volumeGroupTenantId + " from AAI for Volume Group with Volume Group Id " + volumeGroupId + ", AIC Cloud Region " + aicCloudRegion, isDebugLogEnabled)
219
220                         def relatedVfModuleLink = getRelatedVfModuleRelatedLink(aaiResponseAsString)
221                         logDebug("Related VF Module link: " + relatedVfModuleLink, isDebugLogEnabled)
222                         execution.setVariable('UPDVfModVol_relatedVfModuleLink', relatedVfModuleLink)
223                         
224                 } 
225                 else if (returnCode == '404') {
226                         exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Volume Group " + volumeGroupId + " not found at AAI")
227                 } 
228                 else {
229                         WorkflowException aWorkflowException = exceptionUtil.MapAAIExceptionToWorkflowException(aaiResponseAsString, execution)
230                         throw new BpmnError("MSOWorkflowException")
231                 }
232         }
233         
234         /**
235          * Query AAI service instance
236          * @param execution
237          * @param isDebugEnabled
238          */
239         public void queryAAIForGenericVnf(Execution execution, isDebugEnabled) {
240                 
241                 def vnfId = execution.getVariable('vnfId')
242                 
243                 AaiUtil aaiUtil = new AaiUtil(this)
244                 String aaiEndpoint = aaiUtil.getNetworkGenericVnfEndpoint(execution)
245                 def String queryAAIRequest = aaiEndpoint + "/" + UriUtils.encode(vnfId, "UTF-8")
246                 
247                 utils.logAudit("AAI query generic vnf request: " + queryAAIRequest)
248                 
249                 APIResponse response = aaiUtil.executeAAIGetCall(execution, queryAAIRequest)
250                 
251                 String returnCode = response.getStatusCode()
252                 String aaiResponseAsString = response.getResponseBodyAsString()
253                 aaiResponseAsString = StringEscapeUtils.unescapeXml(aaiResponseAsString)
254                 
255                 utils.logAudit("AAI query generic vnf return code: " + returnCode)
256                 utils.logAudit("AAI query generic vnf response: " + aaiResponseAsString)
257
258                 ExceptionUtil exceptionUtil = new ExceptionUtil()
259                 
260                 if (returnCode=='200') {
261                         utils.log("DEBUG", 'Generic vnf ' + vnfId + ' found in AAI.', isDebugEnabled)
262                         execution.setVariable('UPDVfModVol_AAIQueryGenericVfnResponse', aaiResponseAsString)
263                 } else {
264                         if (returnCode=='404') {
265                                 def message = 'Generic vnf ' + vnfId + ' was not found in AAI. Return code: 404.'
266                                 utils.log("DEBUG", message, isDebugEnabled)
267                                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, message)
268                         } else {
269                                 WorkflowException aWorkflowException = exceptionUtil.MapAAIExceptionToWorkflowException(aaiResponseAsString, execution)
270                                 throw new BpmnError("MSOWorkflowException")
271                         }
272                 }
273         }
274         
275         /**
276          * Query AAI for VF Module using vf-module-id
277          * @param execution
278          * @param isDebugLogEnabled
279          */
280         public void queryAAIForVfModule(Execution execution, isDebugLogEnabled) {
281                 
282                         AaiUtil aaiUtil = new AaiUtil(this)
283                         String queryAAIVfModuleRequest = execution.getVariable('UPDVfModVol_relatedVfModuleLink')
284                         execution.setVariable('UPDVfModVol_personaModelId', '')
285                         
286                         utils.logAudit('Query AAI VF Module: ' + queryAAIVfModuleRequest)
287                         logDebug('Query AAI VF Module: ' + queryAAIVfModuleRequest, isDebugLogEnabled)
288                         
289                         APIResponse response = aaiUtil.executeAAIGetCall(execution, queryAAIVfModuleRequest)
290                         
291                         String returnCode = response.getStatusCode()
292                         String aaiResponseAsString = response.getResponseBodyAsString()
293                         aaiResponseAsString = StringEscapeUtils.unescapeXml(aaiResponseAsString)
294                         
295                         utils.logAudit("AAI query vf-module: " + returnCode)
296                         utils.logAudit("AAI query vf-module response: " + aaiResponseAsString)
297                         
298                         logDebug("AAI query vf-module:: " + returnCode, isDebugLogEnabled)
299                         logDebug("AAI query vf-module response: " + aaiResponseAsString, isDebugLogEnabled)
300                         
301                         ExceptionUtil exceptionUtil = new ExceptionUtil()
302                         
303                         if ((returnCode == '200') || (returnCode == '204')) {
304                                 def personaModelId =  utils.getNodeText1(aaiResponseAsString, 'persona-model-id')
305                                 execution.setVariable('UPDVfModVol_personaModelId', personaModelId)
306                         }
307                         else if (returnCode == '404') {
308                                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "VF Module not found at AAI")
309                         }
310                         else {
311                                 WorkflowException aWorkflowException = exceptionUtil.MapAAIExceptionToWorkflowException(aaiResponseAsString, execution)
312                                 throw new BpmnError("MSOWorkflowException")
313                         }
314                 }
315         /**
316          * 
317          */
318         public String getRelatedVfModuleRelatedLink(xml) {
319                 def list = new XmlSlurper().parseText(xml)
320                 def vfModuleRelationship = list.'**'.find { node -> node.'related-to'.text() == 'vf-module'     }
321                 return vfModuleRelationship?.'related-link'?.text() ?: ''
322         }
323         
324         /**
325          * Prepare a Request for invoking the VnfAdapterRest subflow to do
326          * a Volume Group update.
327          *
328          * @param execution The flow's execution instance.
329          */
330         public void prepVnfAdapterRest(Execution execution, isDebugLogEnabled) {
331                 
332                 def aicCloudRegion = execution.getVariable('UPDVfModVol_aicCloudRegion')
333                 def tenantId = execution.getVariable('UPDVfModVol_tenantId')
334                 def volumeGroupId = execution.getVariable('UPDVfModVol_volumeGroupId')
335                 
336                 def aaiVolumeGroupResponse = execution.getVariable('UPDVfModVol_aaiVolumeGroupResponse')
337                 def volumeGroupHeatStackId = getNodeTextForce(aaiVolumeGroupResponse, 'heat-stack-id')
338                 def volumeGroupName = getNodeTextForce(aaiVolumeGroupResponse, 'volume-group-name')
339                 
340                 def vnfType = execution.getVariable('UPDVfModVol_vnfType')
341                 def vnfVersion = execution.getVariable('UPDVfModVol_vnfVersion')
342                 
343                 def aaiGenericVnfResponse = execution.getVariable('UPDVfModVol_AAIQueryGenericVfnResponse')
344                 def vnfId = utils.getNodeText1(aaiGenericVnfResponse, 'vnf-id')
345                 def vnfName = utils.getNodeText1(aaiGenericVnfResponse, 'vnf-name')
346
347                 
348                 def volumeParamsXml = execution.getVariable('UPDVfModVol_volumeParams')
349                 def volumeGroupParams = transformVolumeParamsToEntries(volumeParamsXml)
350                 
351                 def requestId = execution.getVariable('UPDVfModVol_requestId')
352                 def serviceId = execution.getVariable('UPDVfModVol_serviceId')
353                 
354                 def messageId = execution.getVariable('att-mso-request-id') + '-' + System.currentTimeMillis()
355                 def notificationUrl = execution.getVariable("URN_mso_workflow_vnfadapter_rest_callback")
356                 def useQualifiedHostName = execution.getVariable("URN_mso_use_qualified_host")
357                 if ('true'.equals(useQualifiedHostName)) {
358                                 notificationUrl = utils.getQualifiedHostNameForCallback(notificationUrl)
359                 }
360
361                 String vnfAdapterRestRequest = """
362                         <updateVolumeGroupRequest>
363                                 <cloudSiteId>${aicCloudRegion}</cloudSiteId>
364                                 <tenantId>${tenantId}</tenantId>
365                                 <vnfId>${vnfId}</vnfId>
366                                 <vnfName>${vnfName}</vnfName>
367                                 <volumeGroupId>${volumeGroupId}</volumeGroupId>
368                                 <volumeGroupName>${volumeGroupName}</volumeGroupName>
369                                 <volumeGroupStackId>${volumeGroupHeatStackId}</volumeGroupStackId>
370                                 <vnfType>${vnfType}</vnfType>
371                                 <vnfVersion>${vnfVersion}</vnfVersion>
372                                 <vfModuleType></vfModuleType>
373                                 <volumeGroupParams>
374                                         <entry>
375                                                 <key>vnf_id</key>
376                                                 <value>${vnfId}</value>
377                                         </entry>
378                                         <entry>
379                                                 <key>vnf_name</key>
380                                                 <value>${vnfName}</value>
381                                         </entry>
382                                         <entry>
383                                                 <key>vf_module_id</key>
384                                                 <value>${volumeGroupId}</value>
385                                         </entry>
386                                         <entry>
387                                                 <key>vf_module_name</key>
388                                                 <value>${volumeGroupName}</value>
389                                         </entry>
390                                         ${volumeGroupParams}
391                             </volumeGroupParams>
392                                 <skipAAI>true</skipAAI>
393                             <msoRequest>
394                                 <requestId>${requestId}</requestId>
395                                 <serviceInstanceId>${serviceId}</serviceInstanceId>
396                             </msoRequest>
397                             <messageId>${messageId}</messageId>
398                             <notificationUrl>${notificationUrl}</notificationUrl>
399                         </updateVolumeGroupRequest>
400                 """
401                 vnfAdapterRestRequest = utils.formatXml(vnfAdapterRestRequest)
402                 execution.setVariable('UPDVfModVol_vnfAdapterRestRequest', vnfAdapterRestRequest)
403                 logDebug('Request for VNFAdapter Rest:\n' + vnfAdapterRestRequest, isDebugLogEnabled)
404         }
405         
406         /**
407          * Prepare a Request for updating the DB for this Infra request.
408          *
409          * @param execution The flow's execution instance.
410          */
411         public void prepDbInfraDbRequest(Execution execution, isDebugLogEnabled) {
412
413                 def requestId = execution.getVariable('UPDVfModVol_requestId')
414                 
415                 String updateInfraRequest = """
416                         <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
417                                         xmlns:req="http://com.att.mso/requestsdb">
418                                 <soapenv:Header/>
419                                 <soapenv:Body>
420                                         <req:updateInfraRequest>
421                                                 <requestId>${requestId}</requestId>
422                                                 <lastModifiedBy>BPEL</lastModifiedBy>
423                                                 <requestStatus>COMPLETE</requestStatus>
424                                                 <progress>100</progress>
425                                         </req:updateInfraRequest>
426                                 </soapenv:Body>
427                         </soapenv:Envelope>
428                 """
429
430                 updateInfraRequest = utils.formatXml(updateInfraRequest)
431                 execution.setVariable('UPDVfModVol_updateInfraRequest', updateInfraRequest)
432                 logDebug('Request for Update Infra Request:\n' + updateInfraRequest, isDebugLogEnabled)
433         }
434         
435         /**
436          * Build a "CompletionHandler" request.
437          * @param execution The flow's execution instance.
438          */
439         public void prepCompletionHandlerRequest(Execution execution, requestId, action, source, isDebugLogEnabled) {
440
441                 String content = """
442                 <aetgt:MsoCompletionRequest xmlns:aetgt="http://ecomp.att.com/mso/workflow/schema/v1"
443                                         xmlns:ns="http://ecomp.att.com/mso/request/types/v1">
444                         <request-info xmlns="http://ecomp.att.com/mso/infra/vnf-request/v1">
445                                 <request-id>${requestId}</request-id>
446                                 <action>CREATE</action>
447                                 <source>${source}</source>
448                         </request-info>
449                         <aetgt:mso-bpel-name>BPMN VF Module Volume action: UPDATE</aetgt:mso-bpel-name>
450                 </aetgt:MsoCompletionRequest>           
451                 """
452
453                 content = utils.formatXml(content)
454                 logDebug('Request for Completion Handler:\n' + content, isDebugLogEnabled)
455                 execution.setVariable('UPDVfModVol_CompletionHandlerRequest', content)
456         }
457         
458
459         /**
460          * Build a "FalloutHandler" request.
461          * @param execution The flow's execution instance.
462          */
463         public void prepFalloutHandler(Execution execution, isDebugLogEnabled) {
464                 
465                 def requestInfo = execution.getVariable('UPDVfModVol_requestInfo')
466                 
467                 def WorkflowException workflowException = execution.getVariable("WorkflowException")
468                 def errorResponseCode = workflowException.getErrorCode()
469                 def errorResponseMsg = workflowException.getErrorMessage()
470                 def encErrorResponseMsg = ""
471                 if (errorResponseMsg != null) {
472                         encErrorResponseMsg = errorResponseMsg.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
473                 }
474
475                 String content = """
476                         <sdncadapterworkflow:FalloutHandlerRequest xmlns:sdncadapterworkflow="http://ecomp.att.com/mso/workflow/schema/v1"
477                                         xmlns:reqtype="http://ecomp.att.com/mso/request/types/v1"
478                                         xmlns:msoservtypes="http://ecomp.att.com/mso/request/types/v1"
479                                         xmlns:structuredtypes="http://ecomp.att.com/mso/structured/types/v1">
480                                 ${requestInfo}
481                                 <sdncadapterworkflow:WorkflowException>
482                                         <sdncadapterworkflow:ErrorMessage>${encErrorResponseMsg}</sdncadapterworkflow:ErrorMessage>
483                                         <sdncadapterworkflow:ErrorCode>${errorResponseCode}</sdncadapterworkflow:ErrorCode>
484                                 </sdncadapterworkflow:WorkflowException>        
485                         </sdncadapterworkflow:FalloutHandlerRequest>
486                 """
487                 content = utils.formatXml(content)
488                 logDebug('Request for Fallout Handler:\n' + content, isDebugLogEnabled)
489                 execution.setVariable('UPDVfModVol_FalloutHandlerRequest', content)
490         }
491         
492         /**
493          * Create a WorkflowException for the error case where the Tenant Id from
494          * AAI did not match the Tenant Id in the incoming request.
495          * @param execution The flow's execution instance.
496          */
497         public void handleTenantIdMismatch(Execution execution, isDebugLogEnabled) {
498                 
499                 def volumeGroupId = execution.getVariable('UPDVfModVol_volumeGroupId')
500                 def aicCloudRegion = execution.getVariable('UPDVfModVol_aicCloudRegion')
501                 def tenantId = execution.getVariable('UPDVfModVol_tenantId')
502                 def volumeGroupTenantId = execution.getVariable('UPDVfModVol_volumeGroupTenantId')
503                 
504                 def String errorMessage = "TenantId " + tenantId + " in incoming request does not match Tenant Id " + volumeGroupTenantId +
505                         " retrieved from AAI for Volume Group Id " + volumeGroupId + ", AIC Cloud Region " + aicCloudRegion 
506                 
507                 ExceptionUtil exceptionUtil = new ExceptionUtil()
508                 logError('Error in UpdateVfModuleVol: ' + errorMessage)
509                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, errorMessage)
510         }
511         
512         /**
513          * Create a WorkflowException for the error case where the Personal Model Id from
514          * AAI did not match the model invariant ID in the incoming request.
515          * @param execution The flow's execution instance.
516          */
517         public void handlePersonaModelIdMismatch(Execution execution, isDebugLogEnabled) {
518                 
519                 def modelInvariantId = execution.getVariable('UPDVfModVol_modelInvariantId')
520                 def personaModelId = execution.getVariable('UPDVfModVol_personaModelId')
521                 
522                 def String errorMessage = "Model Invariant ID " + modelInvariantId + " in incoming request does not match persona model ID " + personaModelId +
523                         " retrieved from AAI for Volume Group Id "
524                 
525                 ExceptionUtil exceptionUtil = new ExceptionUtil()
526                 logError('Error in UpdateVfModuleVol: ' + errorMessage)
527                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, errorMessage)
528         }
529         
530 }