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