ba8761493763daa295714df390af9bbafb13298b
[so.git] / bpmn / so-bpmn-infrastructure-common / src / main / groovy / org / onap / so / bpmn / infrastructure / scripts / CreateSliceService.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  # Copyright (c) 2020, CMCC Technologies Co., Ltd.
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 org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
24 import org.onap.so.serviceinstancebeans.Service
25
26 import static org.apache.commons.lang3.StringUtils.*
27 import org.camunda.bpm.engine.delegate.BpmnError
28 import org.camunda.bpm.engine.delegate.DelegateExecution
29 import org.onap.aai.domain.yang.ServiceInstance
30 import org.onap.aaiclient.client.aai.AAIResourcesClient
31 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
32 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
33 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
34 import org.onap.logging.filter.base.ErrorCode
35 import org.onap.so.beans.nsmf.SliceTaskParams
36 import org.onap.so.beans.nsmf.SliceTaskParamsAdapter
37 import org.onap.so.beans.nsmf.oof.TemplateInfo
38 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
39 import org.onap.so.bpmn.common.scripts.ExceptionUtil
40 import org.onap.so.bpmn.common.scripts.MsoUtils
41 import org.onap.so.bpmn.common.scripts.NssmfAdapterUtils
42 import org.onap.so.bpmn.common.scripts.OofUtils
43 import org.onap.so.bpmn.core.UrnPropertiesReader
44 import org.onap.so.bpmn.core.json.JsonUtils
45 import org.onap.so.db.request.beans.OrchestrationTask
46 import org.onap.so.logger.LoggingAnchor
47 import org.onap.so.logger.MessageEnum
48 import org.slf4j.Logger
49 import org.slf4j.LoggerFactory
50 import org.springframework.web.util.UriUtils
51 import com.fasterxml.jackson.databind.ObjectMapper
52 import groovy.json.JsonSlurper
53
54 public class CreateSliceService extends AbstractServiceTaskProcessor {
55     String Prefix = "CRESS_"
56
57     ExceptionUtil exceptionUtil = new ExceptionUtil()
58
59     JsonUtils jsonUtil = new JsonUtils()
60
61     JsonSlurper jsonSlurper = new JsonSlurper()
62
63     ObjectMapper objectMapper = new ObjectMapper()
64
65     OofUtils oofUtils = new OofUtils()
66
67     AAIResourcesClient client = getAAIClient()
68
69     private static final Logger logger = LoggerFactory.getLogger(CreateSliceService.class)
70
71     public void preProcessRequest(DelegateExecution execution) {
72         logger.debug("Start preProcessRequest")
73         execution.setVariable("prefix", Prefix)
74         String msg = ""
75
76         try {
77             String ssRequest = execution.getVariable("bpmnRequest")
78             logger.debug(ssRequest)
79
80             String requestId = execution.getVariable("mso-request-id")
81             execution.setVariable("msoRequestId", requestId)
82             logger.debug("Input Request:" + ssRequest + " reqId:" + requestId)
83
84             String serviceInstanceId = execution.getVariable("serviceInstanceId")
85             if (isBlank(serviceInstanceId)) {
86                 serviceInstanceId = UUID.randomUUID().toString()
87             }
88
89             String operationId = UUID.randomUUID().toString()
90             execution.setVariable("operationId", operationId)
91
92             logger.debug("Generated new Service Instance:" + serviceInstanceId)
93             serviceInstanceId = UriUtils.encode(serviceInstanceId, "UTF-8")
94             execution.setVariable("serviceInstanceId", serviceInstanceId)
95
96             //subscriberInfo
97             String globalSubscriberId = jsonUtil.getJsonValue(ssRequest, "requestDetails.subscriberInfo.globalSubscriberId")
98             if (isBlank(globalSubscriberId)) {
99                 msg = "Input globalSubscriberId' is null"
100                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
101             } else {
102                 execution.setVariable("globalSubscriberId", globalSubscriberId)
103             }
104
105             //requestInfo
106             execution.setVariable("source", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.source"))
107             execution.setVariable("serviceInstanceName", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.instanceName"))
108             execution.setVariable("disableRollback", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.suppressRollback"))
109             String productFamilyId = jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.productFamilyId")
110             if (isBlank(productFamilyId)) {
111                 msg = "Input productFamilyId is null"
112                 logger.debug(msg)
113                 //exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
114             } else {
115                 execution.setVariable("productFamilyId", productFamilyId)
116             }
117
118             //modelInfo
119             String serviceModelInfo = jsonUtil.getJsonValue(ssRequest, "requestDetails.modelInfo")
120             if (isBlank(serviceModelInfo)) {
121                 msg = "Input serviceModelInfo is null"
122                 logger.debug(msg)
123                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
124             } else {
125                 execution.setVariable("serviceModelInfo", serviceModelInfo)
126             }
127
128             logger.debug("modelInfo: " + serviceModelInfo)
129
130 //            //requestParameters
131 //            String subscriptionServiceType = jsonUtil.getJsonValue(ssRequest, "requestDetails.requestParameters.subscriptionServiceType")
132 //            if (isBlank(subscriptionServiceType)) {
133 //                msg = "Input subscriptionServiceType is null"
134 //                logger.debug(msg)
135 //                exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
136 //            } else {
137 //                subscriptionServiceType = "5G"
138 //                execution.setVariable("subscriptionServiceType", subscriptionServiceType)
139 //            }
140 //            logger.debug("subscriptionServiceType: " + subscriptionServiceType)
141
142             /*
143             * Extracting User Parameters from incoming Request and converting into a Map
144             */
145             Map reqMap = jsonSlurper.parseText(ssRequest) as Map
146
147             //InputParams
148             def userParamsList = reqMap.requestDetails?.requestParameters?.userParams
149
150             Map<String, String> inputMap = [:]
151             if (userParamsList) {
152                 for (def i = 0; i < userParamsList.size(); i++) {
153                     def userParams1 = userParamsList.get(i)
154                     userParams1.each { param -> inputMap.put(param.key, param.value) }
155                 }
156             }
157
158             logger.debug("User Input Parameters map: " + inputMap.toString())
159             String uuiRequest = inputMap.get("UUIRequest")
160             Map uuiReqMap = jsonSlurper.parseText(uuiRequest) as Map
161             Map<String, Object> serviceObject = (Map<String, Object>) uuiReqMap.get("service")
162             Map<String, Object> parameterObject = (Map<String, Object>) serviceObject.get("parameters")
163             Map<String, Object> requestInputs = (Map<String, Object>) parameterObject.get("requestInputs")
164
165             def serviceProfile = [:]
166             for(entry in requestInputs) {
167                 serviceProfile[entry.key] = entry.value
168             }
169
170             execution.setVariable("serviceInputParams", inputMap)
171             execution.setVariable("uuiRequest", uuiRequest)
172             execution.setVariable("serviceProfile", serviceProfile)
173             execution.setVariable("subscriptionServiceType", serviceObject.get("serviceType"))
174
175             //TODO
176             //execution.setVariable("serviceInputParams", jsonUtil.getJsonValue(siRequest, "requestDetails.requestParameters.userParams"))
177             //execution.setVariable("failExists", true)
178
179         } catch (BpmnError e) {
180             throw e
181         } catch (Exception ex) {
182             msg = "Exception in preProcessRequest " + ex.getMessage()
183             logger.debug(msg)
184             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
185         }
186         logger.debug("Finish preProcessRequest")
187     }
188
189     /**
190      *
191      * @param execution
192      */
193     public void prepareInitServiceOperationStatus(DelegateExecution execution) {
194         logger.debug("Start prepareInitServiceOperationStatus")
195         try{
196             String serviceId = execution.getVariable("serviceInstanceId")
197             String operationId = execution.getVariable("operationId")
198             String operationType = "CREATE"
199             String userId = execution.getVariable("globalSubscriberId")
200             String result = "processing"
201             String progress = "0"
202             String reason = ""
203             String operationContent = "Prepare service creation"
204             logger.debug("Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId)
205             serviceId = UriUtils.encode(serviceId,"UTF-8")
206             execution.setVariable("serviceInstanceId", serviceId)
207             execution.setVariable("operationType", operationType)
208
209             def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint",execution)
210             execution.setVariable("CSSOS_dbAdapterEndpoint", dbAdapterEndpoint)
211             logger.debug("DB Adapter Endpoint is: " + dbAdapterEndpoint)
212             def dbAdapterAuth = UrnPropertiesReader.getVariable("mso.requestDb.auth")
213             Map<String, String> CSSOS_headerMap = [:]
214             CSSOS_headerMap.put("content-type", "application/soap+xml")
215             CSSOS_headerMap.put("Authorization", dbAdapterAuth)
216             execution.setVariable("CSSOS_headerMap", CSSOS_headerMap)
217             logger.debug("DB Adapter Header is: " + CSSOS_headerMap)
218
219             String payload =
220                     """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
221                         xmlns:ns="http://org.onap.so/requestsdb">
222                         <soapenv:Header/>
223                         <soapenv:Body>
224                             <ns:initServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
225                             <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
226                             <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
227                             <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
228                             <userId>${MsoUtils.xmlEscape(userId)}</userId>
229                             <result>${MsoUtils.xmlEscape(result)}</result>
230                             <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
231                             <progress>${MsoUtils.xmlEscape(progress)}</progress>
232                             <reason>${MsoUtils.xmlEscape(reason)}</reason>
233                         </ns:initServiceOperationStatus>
234                     </soapenv:Body>
235                 </soapenv:Envelope>"""
236
237             payload = utils.formatXml(payload)
238             execution.setVariable("CSSOS_updateServiceOperStatusRequest", payload)
239             logger.debug("Outgoing updateServiceOperStatusRequest: \n" + payload)
240         }catch(Exception e){
241             logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
242                     "Exception Occured Processing prepareInitServiceOperationStatus.", "BPMN",
243                     ErrorCode.UnknownError.getValue(), "Exception is:\n" + e)
244         }
245         logger.debug("Finish prepareInitServiceOperationStatus")
246     }
247
248     /**
249      * prepare create OrchestrationTask
250      * @param execution
251      */
252     public void prepareCreateOrchestrationTask(DelegateExecution execution) {
253         logger.debug("Start createOrchestrationTask")
254         String taskId = execution.getBusinessKey()
255         execution.setVariable("orchestrationTaskId", taskId)
256         logger.debug("BusinessKey: " + taskId)
257         String serviceInstanceId = execution.getVariable("serviceInstanceId")
258         String serviceInstanceName = execution.getVariable("serviceInstanceName")
259         String taskName = "SliceServiceTask"
260         String taskStatus = "Planning"
261         String isManual = "false"
262         String requestMethod = "POST"
263         execution.setVariable("CSSOT_taskId", taskId)
264         execution.setVariable("CSSOT_name", taskName)
265         execution.setVariable("CSSOT_status", taskStatus)
266         execution.setVariable("CSSOT_isManual", isManual)
267         execution.setVariable("CSSOT_requestMethod", requestMethod)
268
269         Map<String, Object> serviceProfile = execution.getVariable("serviceProfile") as Map<String, Object>
270
271         SliceTaskParamsAdapter sliceTaskParams = new SliceTaskParamsAdapter()
272         sliceTaskParams.setServiceId(serviceInstanceId)
273         sliceTaskParams.setServiceName(serviceInstanceName)
274         sliceTaskParams.setServiceProfile(serviceProfile)
275
276         execution.setVariable("sliceTaskParams", sliceTaskParams)
277
278         execution.setVariable("CSSOT_paramJson", objectMapper.writeValueAsString(sliceTaskParams))
279
280         logger.debug("Finish createOrchestrationTask")
281     }
282
283     /**
284      *  send sync response to csmf
285      * @param execution
286      */
287     public void sendSyncResponse(DelegateExecution execution) {
288         logger.debug("Start sendSyncResponse")
289         try {
290             String operationId = execution.getVariable("operationId")
291             String serviceInstanceId = execution.getVariable("serviceInstanceId")
292             // RESTResponse for API Handler (APIH) Reply Task
293             String createServiceRestRequest = """
294                 {
295                    "service": {
296                         "serviceId":"${serviceInstanceId}",
297                         "operationId":"${operationId}"
298                    }
299                 }
300                 """.trim()
301
302             logger.debug("sendSyncResponse to APIH:" + "\n" + createServiceRestRequest)
303             sendWorkflowResponse(execution, 202, createServiceRestRequest)
304             execution.setVariable("sentSyncResponse", true)
305         } catch (Exception e) {
306             String msg = "Exceptuion in sendSyncResponse:" + e.getMessage()
307             logger.debug(msg)
308             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
309         }
310         logger.debug("Finish sendSyncResponse")
311     }
312
313     public void prepareSelectNSTRequest(DelegateExecution execution) {
314         logger.debug("Start prepareSelectNSTRequest")
315         String requestId = execution.getVariable("msoRequestId")
316         String messageType = "NSTSelectionResponse"
317         execution.setVariable("nstSelectionUrl", "/api/oof/v1/selection/nst")
318         execution.setVariable("nstSelection_messageType", messageType)
319         execution.setVariable("nstSelection_correlator", requestId)
320         String timeout = UrnPropertiesReader.getVariable("mso.adapters.oof.timeout", execution);
321         execution.setVariable("nstSelection_timeout", timeout)
322
323         Map<String, Object> serviceProfile = execution.getVariable("serviceProfile") as Map<String, Object>
324         serviceProfile.remove("profileId")
325         String oofRequest = oofUtils.buildSelectNSTRequest(requestId, messageType, serviceProfile)
326         execution.setVariable("nstSelection_oofRequest", oofRequest)
327         logger.debug("Finish prepareSelectNSTRequest")
328
329     }
330
331     /**
332      * process async response of oof, put the {@solutions} at {@nstSolution}
333      * @param execution
334      */
335     public void processNSTSolutions(DelegateExecution execution) {
336         Map<String, Object> nstSolution
337         try {
338             logger.debug("Start processing NSTSolutions")
339             Map<String, Object> resMap =
340                     objectMapper.readValue(execution.getVariable("nstSelection_oofResponse") as String,
341                             Map.class)
342
343             List<Map<String, Object>> nstSolutions = (List<Map<String, Object>>) resMap.get("solutions")
344             nstSolution = nstSolutions.get(0)
345             execution.setVariable("nstSolution", nstSolution)
346
347             //set nst info into sliceTaskParams
348             SliceTaskParamsAdapter sliceTaskParams =
349                     execution.getVariable("sliceTaskParams") as SliceTaskParamsAdapter
350             TemplateInfo nstInfo = new TemplateInfo()
351             nstInfo.setUUID(nstSolution.get("UUID") as String)
352             nstInfo.setInvariantUUID(nstSolution.get("invariantUUID") as String)
353             nstInfo.setName(nstSolution.get("NSTName") as String)
354
355             sliceTaskParams.setNSTInfo(nstInfo)
356             sliceTaskParams.setNstId(nstSolution.get("UUID") as String)
357             sliceTaskParams.setNstName(nstSolution.get("NSTName") as String)
358
359             execution.setVariable("sliceTaskParams", sliceTaskParams)
360
361         } catch (Exception ex) {
362             logger.debug( "Failed to get NST solution suggested by OOF.")
363             exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Failed to get NST solution suggested by OOF.")
364         }
365
366     }
367
368     public void prepareUpdateOrchestrationTask(DelegateExecution execution) {
369         logger.debug("Start prepareUpdateOrchestrationTask")
370         String requestMethod = "PUT"
371         String taskStatus = execution.getVariable("taskStatus")
372         SliceTaskParamsAdapter sliceTaskParams =
373                 execution.getVariable("sliceTaskParams") as SliceTaskParamsAdapter
374
375         execution.setVariable("CSSOT_status", taskStatus)
376         execution.setVariable("CSSOT_paramJson", objectMapper.writeValueAsString(sliceTaskParams))
377         execution.setVariable("CSSOT_requestMethod", requestMethod)
378         logger.debug("Finish prepareUpdateOrchestrationTask")
379     }
380
381
382     public void prepareGetUserOptions(DelegateExecution execution) {
383         logger.debug("Start prepareGetUserOptions")
384         String requestMethod = "GET"
385         execution.setVariable("taskAction", "commit")
386         String taskAction = execution.getVariable("taskAction")
387         logger.debug("task action is: " + taskAction)
388         if (!"commit".equals(taskAction) && !"abort".equals(taskAction)) {
389             String msg = "Unknown task action: " + taskAction
390             logger.debug(msg)
391             exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
392         }
393         execution.setVariable("CSSOT_requestMethod", requestMethod)
394         logger.debug("Finish prepareGetUserOptions")
395     }
396
397     public void processUserOptions(DelegateExecution execution) {
398         logger.debug("Start processUserOptions")
399         String response = execution.getVariable("CSSOT_dbResponse")
400         OrchestrationTask orchestrationTask = objectMapper.readValue(response, OrchestrationTask.class)
401         String paramJson = orchestrationTask.getParams()
402         logger.debug("paramJson: " + paramJson)
403
404         SliceTaskParamsAdapter sliceTaskParams = objectMapper.readValue(paramJson, SliceTaskParamsAdapter.class)
405
406         execution.setVariable("sliceTaskParams", sliceTaskParams)
407         logger.debug("Finish processUserOptions")
408     }
409
410     public void updateAAIOrchStatus(DelegateExecution execution) {
411         logger.debug("Start updateAAIOrchStatus")
412         String serviceInstanceId = execution.getVariable("serviceInstanceId")
413         String orchStatus = execution.getVariable("orchestrationStatus")
414
415         try {
416             ServiceInstance si = new ServiceInstance()
417             si.setOrchestrationStatus(orchStatus)
418
419             AAIResourceUri uri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(serviceInstanceId))
420             client.update(uri, si)
421         } catch (BpmnError e) {
422             throw e
423         } catch (Exception ex) {
424             String msg = "Exception in CreateSliceService.updateAAIOrchStatus " + ex.getMessage()
425             logger.info(msg)
426             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
427         }
428
429         logger.debug("Finish updateAAIOrchStatus")
430     }
431
432     public void prepareUpdateServiceOperationStatus(DelegateExecution execution) {
433         logger.debug("Start preUpdateServiceOperationStatus")
434         try{
435             String serviceId = execution.getVariable("serviceInstanceId")
436             String operationId = execution.getVariable("operationId")
437             String operationType = execution.getVariable("operationType")
438             String userId = execution.getVariable("globalSubscriberId")
439             String result = execution.getVariable("operationResult")
440             String progress = execution.getVariable("operationProgress")
441             String reason = execution.getVariable("operationReason")
442             String operationContent = "service: " + result + " progress: " + progress
443
444             String payload =
445                     """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
446                         xmlns:ns="http://org.onap.so/requestsdb">
447                         <soapenv:Header/>
448                         <soapenv:Body>
449                             <ns:initServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
450                             <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
451                             <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
452                             <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
453                             <userId>${MsoUtils.xmlEscape(userId)}</userId>
454                             <result>${MsoUtils.xmlEscape(result)}</result>
455                             <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
456                             <progress>${MsoUtils.xmlEscape(progress)}</progress>
457                             <reason>${MsoUtils.xmlEscape(reason)}</reason>
458                         </ns:initServiceOperationStatus>
459                     </soapenv:Body>
460                 </soapenv:Envelope>"""
461
462             payload = utils.formatXml(payload)
463             execution.setVariable("CSSOS_updateServiceOperStatusRequest", payload)
464             logger.debug("Outgoing updateServiceOperStatusRequest: \n" + payload)
465
466         }catch(Exception e){
467             logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
468                     "Exception Occured Processing preUpdateServiceOperationStatus.", "BPMN",
469                     ErrorCode.UnknownError.getValue(), "Exception is:\n" + e.getMessage())
470         }
471         logger.debug("Finish preUpdateServiceOperationStatus")
472     }
473
474
475
476     public void prepareCompletionRequest (DelegateExecution execution) {
477         logger.trace("Start prepareCompletionRequest")
478         try {
479             String requestId = execution.getVariable("msoRequestId")
480             String serviceInstanceId = execution.getVariable("serviceInstanceId")
481             String source = execution.getVariable("source")
482
483             String msoCompletionRequest =
484                     """<aetgt:MsoCompletionRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
485                                 xmlns:ns="http://org.onap/so/request/types/v1">
486                         <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
487                             <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
488                             <action>CREATE</action>
489                             <source>${MsoUtils.xmlEscape(source)}</source>
490                         </request-info>
491                         <status-message>Service Instance was created successfully.</status-message>
492                         <serviceInstanceId>${MsoUtils.xmlEscape(serviceInstanceId)}</serviceInstanceId>
493                         <mso-bpel-name>CreateGenericALaCarteServiceInstance</mso-bpel-name>
494                     </aetgt:MsoCompletionRequest>"""
495
496             // Format Response
497             String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest)
498
499             execution.setVariable("completionRequest", xmlMsoCompletionRequest)
500             logger.debug("Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest)
501
502         } catch (Exception ex) {
503             String msg = " Exception in prepareCompletion:" + ex.getMessage()
504             logger.debug(msg)
505             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
506         }
507         logger.trace("Finish prepareCompletionRequest")
508     }
509
510 }
511