20ced720028172871ca924213e088060a0f0fb11
[so.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.so.bpmn.infrastructure.scripts;
22
23 import static org.apache.commons.lang3.StringUtils.*;
24
25 import javax.ws.rs.NotFoundException
26
27 import org.apache.commons.lang3.*
28 import org.camunda.bpm.engine.delegate.BpmnError
29 import org.camunda.bpm.engine.delegate.DelegateExecution
30 import org.json.JSONArray
31 import org.json.JSONObject
32 import org.onap.aai.domain.yang.ServiceInstance
33 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
34 import org.onap.so.bpmn.common.scripts.ExceptionUtil
35 import org.onap.so.bpmn.common.scripts.MsoUtils
36 import org.onap.so.bpmn.core.WorkflowException
37 import org.onap.so.bpmn.core.domain.Resource
38 import org.onap.so.bpmn.core.json.JsonUtils
39 import org.onap.so.client.aai.AAIObjectType
40 import org.onap.so.client.aai.AAIResourcesClient
41 import org.onap.so.client.aai.entities.AAIResultWrapper
42 import org.onap.so.client.aai.entities.uri.AAIResourceUri
43 import org.onap.so.client.aai.entities.uri.AAIUriFactory
44 import org.springframework.web.util.UriUtils
45
46 import groovy.json.*
47
48 /**
49  * This groovy class supports the <class>UpdateCustomE2EServiceInstance.bpmn</class> process.
50  * AlaCarte flow for 1702 ServiceInstance Update
51  *
52  */
53 public class UpdateCustomE2EServiceInstance extends AbstractServiceTaskProcessor {
54         String Prefix="UPDSI_"
55         ExceptionUtil exceptionUtil = new ExceptionUtil()
56         JsonUtils jsonUtil = new JsonUtils()
57
58
59         public void preProcessRequest (DelegateExecution execution) {
60                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
61                 execution.setVariable("prefix",Prefix)
62                 String msg = ""
63                 utils.log("INFO", " *** preProcessRequest() *** ", isDebugEnabled)
64
65                 try {
66
67                         String siRequest = execution.getVariable("bpmnRequest")
68                         utils.logAudit(siRequest)
69
70                         String requestId = execution.getVariable("mso-request-id")
71                         execution.setVariable("msoRequestId", requestId)
72                         utils.log("INFO", "Input Request:" + siRequest + " reqId:" + requestId, isDebugEnabled)
73
74                         String serviceInstanceId = execution.getVariable("serviceInstanceId")
75                         if (isBlank(serviceInstanceId)) {
76                                 msg = "Input serviceInstanceId' is null"
77                                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
78                         }
79
80                         //subscriberInfo for aai
81                         String globalSubscriberId = jsonUtil.getJsonValue(siRequest, "requestDetails.subscriberInfo.globalSubscriberId")
82                         if (isBlank(globalSubscriberId)) {
83                                 msg = "Input globalSubscriberId' is null"
84                                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
85                         } else {
86                                 execution.setVariable("globalSubscriberId", globalSubscriberId)
87                         }
88
89                         //requestDetails
90                         execution.setVariable("source", jsonUtil.getJsonValue(siRequest, "requestDetails.requestInfo.source"))
91                         execution.setVariable("serviceInstanceName", jsonUtil.getJsonValue(siRequest, "requestDetails.requestInfo.instanceName"))
92                         execution.setVariable("disableRollback", jsonUtil.getJsonValue(siRequest, "requestDetails.requestInfo.suppressRollback"))
93                         String productFamilyId = jsonUtil.getJsonValue(siRequest, "requestDetails.requestInfo.productFamilyId")
94                         if (isBlank(productFamilyId))
95                         {
96                                 msg = "Input productFamilyId is null"
97                                 utils.log("INFO", msg, isDebugEnabled)
98                         } else {
99                                 execution.setVariable("productFamilyId", productFamilyId)
100                         }
101
102                          //user params
103                  String userParams = jsonUtil.getJsonValue(siRequest, "requestDetails.requestParameters.userParams")
104              utils.log("INFO", "userParams:" + userParams, isDebugEnabled)
105                  List<String> paramList = jsonUtil.StringArrayToList(execution, userParams)
106                  String uuiRequest = jsonUtil.getJsonValue(paramList.get(0), "UUIRequest")
107                         if (isBlank(uuiRequest)) {
108                                 msg = "Input uuiRequest is null"
109                                 utils.log("INFO", msg, isDebugEnabled)
110                                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
111                         } else
112                         {
113                                 execution.setVariable("uuiRequest", uuiRequest)
114                         }
115
116                         utils.log("INFO", "uuiRequest:\n" + uuiRequest,  isDebugEnabled)
117
118                         //serviceType for aai
119                         String serviceType = jsonUtil.getJsonValue(uuiRequest, "service.serviceType")
120                         if (isBlank(serviceType)) {
121                                 msg = "Input serviceType is null"
122                                 utils.log("INFO", msg, isDebugEnabled)
123                                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
124                         } else {
125                                 execution.setVariable("serviceType", serviceType)
126                         }
127
128                         // target model info
129                         String modelInvariantUuid = jsonUtil.getJsonValue(uuiRequest, "service.serviceInvariantUuid")
130                         utils.log("INFO","modelInvariantUuid: " + modelInvariantUuid, isDebugEnabled)
131                         execution.setVariable("modelInvariantUuid", modelInvariantUuid)
132                         execution.setVariable("model-invariant-id-target", modelInvariantUuid)
133
134                         String modelUuid = jsonUtil.getJsonValue(uuiRequest, "service.serviceUuid")
135                         utils.log("INFO","modelUuid: " + modelUuid, isDebugEnabled)
136                         execution.setVariable("modelUuid", modelUuid)
137                         execution.setVariable("model-version-id-target", modelUuid)
138
139                         String serviceModelName = jsonUtil.getJsonValue(uuiRequest, "service.parameters.templateName")
140                         utils.log("INFO","serviceModelName: " + serviceModelName, isDebugEnabled)
141                         if(serviceModelName == null) {
142                                 serviceModelName = ""
143                         }
144                         execution.setVariable("serviceModelName", serviceModelName)
145
146                         //operationId
147                         String operationId = jsonUtil.getJsonValue(siRequest, "operationId")
148                         if (isBlank(operationId)) {
149                                 operationId = UUID.randomUUID().toString()
150                          }
151                         execution.setVariable("operationId", operationId)
152                         execution.setVariable("operationType", "update")
153                         execution.setVariable("hasResourcetoUpdate", false)
154
155                         execution.setVariable("URN_mso_adapters_openecomp_db_endpoint","http://mso.mso.testlab.openecomp.org:8080/dbadapters/RequestsDbAdapter")
156
157                 } catch (BpmnError e) {
158                         throw e;
159                 } catch (Exception ex){
160                         msg = "Exception in preProcessRequest " + ex.getMessage()
161                         utils.log("INFO", msg, isDebugEnabled)
162                         exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
163                 }
164                 utils.log("INFO"," ***** Exit preProcessRequest *****",  isDebugEnabled)
165         }
166
167         /**
168          * Gets the service instance and its relationships from aai
169          */
170         public void getServiceInstance(DelegateExecution execution) {
171                 try {
172                         String serviceInstanceId = execution.getVariable('serviceInstanceId')
173                         String globalSubscriberId = execution.getVariable('globalSubscriberId')
174                         String serviceType = execution.getVariable('serviceType')
175
176                         AAIResourcesClient resourceClient = new AAIResourcesClient()
177                         AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, globalSubscriberId, serviceType, serviceInstanceId)
178                         AAIResultWrapper wrapper = resourceClient.get(serviceInstanceUri, NotFoundException.class)
179
180                         Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class)
181                         execution.setVariable("serviceInstanceName", si.get().getServiceInstanceName())
182                         execution.setVariable("model-invariant-id-original", si.get().getModelInvariantId())
183                         execution.setVariable("model-version-id-original", si.get().getModelVersionId())
184
185                         JSONObject ob = new JSONObject(wrapper.getJson())
186                         JSONArray ar = ob.getJSONObject("relationship-list").getJSONArray("relationship")
187
188                         execution.setVariable("serviceRelationShip", ar.toString())
189
190
191                 }catch(BpmnError e) {
192                         throw e;
193                 }catch(NotFoundException e) {
194                         exceptionUtil.buildAndThrowWorkflowException(execution, 404, "Service-instance does not exist AAI")
195                 }catch(Exception ex) {
196                         String msg = "Internal Error in getServiceInstance: " + ex.getMessage()
197                         exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
198                 }
199         }
200
201         public void preCompareModelVersions(DelegateExecution execution) {
202                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
203         }
204
205         public void postCompareModelVersions(DelegateExecution execution) {
206                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
207                 utils.log("DEBUG", " ======== STARTED postCompareModelVersions Process ======== ", isDebugEnabled)
208
209                 def hasResourcetoUpdate = false
210                 def hasResourcetoAdd = false
211                 def hasResourcetoDelete = false
212                 List<Resource> addResourceList =  execution.getVariable("addResourceList")
213                 List<Resource> delResourceList =  execution.getVariable("delResourceList")
214
215                 if(addResourceList != null && !addResourceList.isEmpty()) {
216                         hasResourcetoAdd = true
217                 }
218
219                 if(delResourceList != null && !delResourceList.isEmpty()) {
220                         hasResourcetoDelete = true
221                 }
222
223                 hasResourcetoUpdate = hasResourcetoAdd || hasResourcetoDelete
224                 execution.setVariable("hasResourcetoUpdate", hasResourcetoUpdate)
225
226                 utils.log("DEBUG", "======== COMPLETED postCompareModelVersions Process ======== ", isDebugEnabled)
227         }
228
229         /**
230          * Init the service Operation Status
231          */
232         public void prepareInitServiceOperationStatus(DelegateExecution execution){
233                 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
234                 utils.log("DEBUG", " ======== STARTED prepareInitServiceOperationStatus Process ======== ", isDebugEnabled)
235                 try{
236                         String serviceId = execution.getVariable("serviceInstanceId")
237                         String operationId = execution.getVariable("operationId")
238                         String operationType = execution.getVariable("operationType")
239                         String userId = ""
240                         String result = "processing"
241                         String progress = "0"
242                         String reason = ""
243                         String operationContent = "Prepare service updating"
244                         utils.log("DEBUG", "Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId, isDebugEnabled)
245                         serviceId = UriUtils.encode(serviceId,"UTF-8")
246                         execution.setVariable("serviceInstanceId", serviceId)
247                         execution.setVariable("operationId", operationId)
248                         execution.setVariable("operationType", operationType)
249
250                         def dbAdapterEndpoint = execution.getVariable("URN_mso_adapters_openecomp_db_endpoint")
251                         execution.setVariable("CVFMI_dbAdapterEndpoint", dbAdapterEndpoint)
252                         utils.log("DEBUG", "DB Adapter Endpoint is: " + dbAdapterEndpoint, isDebugEnabled)
253
254                         String payload =
255                                 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
256                         xmlns:ns="http://org.onap.so/requestsdb">
257                         <soapenv:Header/>
258                         <soapenv:Body>
259                             <ns:updateServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
260                             <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
261                             <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
262                             <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
263                             <userId>${MsoUtils.xmlEscape(userId)}</userId>
264                             <result>${MsoUtils.xmlEscape(result)}</result>
265                             <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
266                             <progress>${MsoUtils.xmlEscape(progress)}</progress>
267                             <reason>${MsoUtils.xmlEscape(reason)}</reason>
268                         </ns:updateServiceOperationStatus>
269                     </soapenv:Body>
270                 </soapenv:Envelope>"""
271
272                         payload = utils.formatXml(payload)
273                         execution.setVariable("CVFMI_updateServiceOperStatusRequest", payload)
274                         utils.log("DEBUG", "Outgoing updateServiceOperStatusRequest: \n" + payload, isDebugEnabled)
275                         utils.logAudit("CreateVfModuleInfra Outgoing updateServiceOperStatusRequest Request: " + payload)
276
277                 }catch(Exception e){
278                         utils.log("ERROR", "Exception Occured Processing prepareInitServiceOperationStatus. Exception is:\n" + e, isDebugEnabled)
279                         execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during prepareInitServiceOperationStatus Method:\n" + e.getMessage())
280                 }
281                 utils.log("DEBUG", "======== COMPLETED prepareInitServiceOperationStatus Process ======== ", isDebugEnabled)
282         }
283
284         /**
285          * Update the service Operation Status
286          */
287         public void preUpdateServiceOperationStatus(DelegateExecution execution){
288                 def method = getClass().getSimpleName() + '.preUpdateServiceOperationStatus(' +'execution=' + execution.getId() +')'
289                 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
290                 utils.log("INFO","Entered " + method, isDebugEnabled)
291
292                 try{
293                         String serviceId = execution.getVariable("serviceInstanceId")
294                         String operationId = execution.getVariable("operationId")
295                         String operationType = execution.getVariable("operationType")
296                         String serviceName = execution.getVariable("serviceInstanceName")
297                         String result = execution.getVariable("operationResult")
298                         String progress = execution.getVariable("progress")
299                         String reason = execution.getVariable("operationReason")
300                         String userId = ""
301                         utils.log("INFO", "progress: " + progress , isDebugEnabled)
302
303                         String operationContent = "Prepare service : " + execution.getVariable("operationStatus")
304
305                         utils.log("INFO", "Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId, isDebugEnabled)
306                         serviceId = UriUtils.encode(serviceId,"UTF-8")
307                         execution.setVariable("serviceInstanceId", serviceId)
308                         execution.setVariable("operationId", operationId)
309                         execution.setVariable("operationType", operationType)
310
311                         def dbAdapterEndpoint = "http://mso.mso.testlab.openecomp.org:8080/dbadapters/RequestsDbAdapter"
312                         execution.setVariable("CVFMI_dbAdapterEndpoint", dbAdapterEndpoint)
313                         utils.log("INFO", "DB Adapter Endpoint is: " + dbAdapterEndpoint, isDebugEnabled)
314
315                         execution.setVariable("URN_mso_openecomp_adapters_db_endpoint","http://mso.mso.testlab.openecomp.org:8080/dbadapters/RequestsDbAdapter")
316                         String payload =
317                                 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
318                         xmlns:ns="http://org.onap.so/requestsdb">
319                         <soapenv:Header/>
320                         <soapenv:Body>
321                             <ns:updateServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
322                             <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
323                             <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
324                             <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
325                             <userId>${MsoUtils.xmlEscape(userId)}</userId>
326                             <result>${MsoUtils.xmlEscape(result)}</result>
327                             <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
328                             <progress>${MsoUtils.xmlEscape(progress)}</progress>
329                             <reason>${MsoUtils.xmlEscape(reason)}</reason>
330                         </ns:updateServiceOperationStatus>
331                     </soapenv:Body>
332                 </soapenv:Envelope>"""
333
334                         payload = utils.formatXml(payload)
335                         execution.setVariable("CVFMI_updateServiceOperStatusRequest", payload)
336                         utils.log("INFO", "Outgoing preUpdateServiceOperationStatus: \n" + payload, isDebugEnabled)
337
338
339                 }catch(Exception e){
340                         utils.log("ERROR", "Exception Occured Processing preUpdateServiceOperationStatus. Exception is:\n" + e, isDebugEnabled)
341                         execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during preUpdateServiceOperationStatus Method:\n" + e.getMessage())
342                 }
343                 utils.log("INFO", "======== COMPLETED preUpdateServiceOperationStatus Process ======== ", isDebugEnabled)
344                 utils.log("INFO", "Exited " + method, isDebugEnabled)
345         }
346
347         public void sendSyncResponse (DelegateExecution execution) {
348                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
349                 utils.log("INFO", " *** sendSyncResponse *** ", isDebugEnabled)
350
351                 try {
352                         String operationId = execution.getVariable("operationId")
353                         def hasResourcetoUpdate = execution.getVariable("hasResourcetoUpdate")
354
355                         String updateServiceResp = ""
356                         if(hasResourcetoUpdate) {
357                                 // RESTResponse for API Handler (APIH) Reply Task
358                                 updateServiceResp = """{"operationId":"${operationId}"}""".trim()
359                         }
360                         else {
361                                 updateServiceResp =  """{"OperationResult":"No Resource to Add or Delete or Service Instance not found in AAI."}"""
362                         }
363
364                         utils.log("INFO", " sendSyncResponse to APIH:" + "\n" + updateServiceResp, isDebugEnabled)
365                         sendWorkflowResponse(execution, 202, updateServiceResp)
366                         execution.setVariable("sentSyncResponse", true)
367
368                 } catch (Exception ex) {
369                         String msg = "Exceptuion in sendSyncResponse:" + ex.getMessage()
370                         utils.log("INFO", msg, isDebugEnabled)
371                         exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
372                 }
373                 utils.log("INFO"," ***** Exit sendSyncResopnse *****",  isDebugEnabled)
374         }
375
376         public void sendSyncError (DelegateExecution execution) {
377                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
378                 utils.log("INFO", " *** sendSyncError *** ", isDebugEnabled)
379
380                 try {
381                         String errorMessage = ""
382                         int errorCode = 7000
383                         if (execution.getVariable("WorkflowException") instanceof WorkflowException) {
384                                 WorkflowException wfe = execution.getVariable("WorkflowException")
385                                 errorMessage = wfe.getErrorMessage()
386                                 errorCode = wfe.getErrorCode()
387                         } else {
388                                 errorMessage = "Sending Sync Error."
389                         }
390
391                         String buildworkflowException =
392                                         """<aetgt:WorkflowException xmlns:aetgt="http://org.onap/so/workflow/schema/v1">
393                                         <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorMessage)}</aetgt:ErrorMessage>
394                                         <aetgt:ErrorCode>${MsoUtils.xmlEscape(errorCode)}</aetgt:ErrorCode>
395                                    </aetgt:WorkflowException>"""
396
397                         utils.logAudit(buildworkflowException)
398                         sendWorkflowResponse(execution, 500, buildworkflowException)
399
400                 } catch (Exception ex) {
401                         utils.log("INFO", " Sending Sync Error Activity Failed. " + "\n" + ex.getMessage(), isDebugEnabled)
402                 }
403
404         }
405
406         public void prepareCompletionRequest (DelegateExecution execution) {
407                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
408                 utils.log("INFO", " *** prepareCompletion *** ", isDebugEnabled)
409
410                 try {
411                         String requestId = execution.getVariable("msoRequestId")
412                         String serviceInstanceId = execution.getVariable("serviceInstanceId")
413                         String source = execution.getVariable("source")
414
415                         String msoCompletionRequest =
416                                         """<aetgt:MsoCompletionRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
417                                                                 xmlns:ns="http://org.onap/so/request/types/v1">
418                                                 <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
419                                                         <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
420                                                         <action>UPDATE</action>
421                                                         <source>${MsoUtils.xmlEscape(source)}</source>
422                                                 </request-info>
423                                                 <status-message>Service Instance was updated successfully.</status-message>
424                                                 <serviceInstanceId>${MsoUtils.xmlEscape(serviceInstanceId)}</serviceInstanceId>
425                                                 <mso-bpel-name>UpdateCustomE2EServiceInstance</mso-bpel-name>
426                                         </aetgt:MsoCompletionRequest>"""
427
428                         // Format Response
429                         String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest)
430
431                         execution.setVariable("completionRequest", xmlMsoCompletionRequest)
432                         utils.log("INFO", " Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest, isDebugEnabled)
433
434                 } catch (Exception ex) {
435                         String msg = " Exception in prepareCompletion:" + ex.getMessage()
436                         utils.log("INFO", msg, isDebugEnabled)
437                         exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
438                 }
439                 utils.log("INFO", "*** Exit prepareCompletionRequest ***", isDebugEnabled)
440         }
441
442         public void prepareFalloutRequest(DelegateExecution execution){
443                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
444                 utils.log("INFO", " *** prepareFalloutRequest *** ", isDebugEnabled)
445
446                 try {
447                         WorkflowException wfex = execution.getVariable("WorkflowException")
448                         utils.log("INFO", " Input Workflow Exception: " + wfex.toString(), isDebugEnabled)
449                         String requestId = execution.getVariable("msoRequestId")
450                         String source = execution.getVariable("source")
451                         String requestInfo =
452                                         """<request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
453                                         <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
454                                         <action>UPDATE</action>
455                                         <source>${MsoUtils.xmlEscape(source)}</source>
456                                    </request-info>"""
457
458                         String falloutRequest = exceptionUtil.processMainflowsBPMNException(execution, requestInfo)
459                         execution.setVariable("falloutRequest", falloutRequest)
460                 } catch (Exception ex) {
461                         utils.log("INFO", "Exception prepareFalloutRequest:" + ex.getMessage(), isDebugEnabled)
462                         String errorException = "  Bpmn error encountered in UpdateCustomE2EServiceInstance flow. FalloutHandlerRequest,  buildErrorResponse() - " + ex.getMessage()
463                         String requestId = execution.getVariable("msoRequestId")
464                         String falloutRequest =
465                                         """<aetgt:FalloutHandlerRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
466                                                                      xmlns:ns="http://org.onap/so/request/types/v1"
467                                                                      xmlns:wfsch="http://org.onap/so/workflow/schema/v1">
468                                            <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
469                                               <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
470                                               <action>UPDATE</action>
471                                               <source>UUI</source>
472                                            </request-info>
473                                                 <aetgt:WorkflowException xmlns:aetgt="http://org.onap/so/workflow/schema/v1">
474                                                         <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorException)}</aetgt:ErrorMessage>
475                                                         <aetgt:ErrorCode>7000</aetgt:ErrorCode>
476                                                 </aetgt:WorkflowException>
477                                         </aetgt:FalloutHandlerRequest>"""
478
479                         execution.setVariable("falloutRequest", falloutRequest)
480                 }
481                 utils.log("INFO", "*** Exit prepareFalloutRequest ***", isDebugEnabled)
482         }
483 }