0f9a0ad29226544a4f53a74531de4f66cd5e3216
[so.git] / bpmn / so-bpmn-infrastructure-common / src / main / groovy / org / onap / so / bpmn / infrastructure / scripts / UpdateVfModuleVolume.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
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 org.onap.so.bpmn.infrastructure.scripts
22
23 import org.apache.commons.lang3.*
24 import org.camunda.bpm.engine.delegate.BpmnError
25 import org.camunda.bpm.engine.delegate.DelegateExecution
26 import org.onap.so.bpmn.common.scripts.AaiUtil
27 import org.onap.so.bpmn.common.scripts.ExceptionUtil
28 import org.onap.so.bpmn.common.scripts.MsoUtils
29 import org.onap.so.bpmn.common.scripts.VfModuleBase
30 import org.onap.so.bpmn.core.UrnPropertiesReader;
31 import org.onap.so.bpmn.core.WorkflowException
32 import org.onap.so.client.aai.AAIObjectType
33 import org.onap.so.client.aai.entities.uri.AAIResourceUri
34 import org.onap.so.client.aai.entities.uri.AAIUriFactory
35 import org.onap.so.constants.Defaults
36 import org.onap.so.logger.MessageEnum
37 import org.onap.so.logger.MsoLogger
38 import org.onap.so.rest.APIResponse
39
40 class UpdateVfModuleVolume extends VfModuleBase {
41         private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, UpdateVfModuleVolume.class);
42         
43         ExceptionUtil exceptionUtil = new ExceptionUtil()
44
45         /**
46          * Initialize the flow's variables.
47          *
48          * @param execution The flow's execution instance.
49          */
50         private void initProcessVariables(DelegateExecution execution) {
51                 execution.setVariable('prefix', 'UPDVfModVol_')
52                 execution.setVariable('UPDVfModVol_Request', null)
53                 execution.setVariable('UPDVfModVol_requestInfo', null)
54                 execution.setVariable('UPDVfModVol_requestId', null)
55                 execution.setVariable('UPDVfModVol_source', null)
56                 execution.setVariable('UPDVfModVol_volumeInputs', null)
57                 execution.setVariable('UPDVfModVol_volumeGroupId', null)
58                 execution.setVariable('UPDVfModVol_vnfType', null)
59                 execution.setVariable('UPDVfModVol_serviceId', null)
60                 execution.setVariable('UPDVfModVol_aicCloudRegion', null)
61                 execution.setVariable('UPDVfModVol_tenantId', null)
62                 execution.setVariable('UPDVfModVol_volumeParams', null)
63                 execution.setVariable('UPDVfModVol_volumeGroupHeatStackId', null)
64                 execution.setVariable('UPDVfModVol_volumeGroupTenantId', null)
65                 execution.setVariable('UpdateVfModuleVolumeSuccessIndicator', false)
66         }
67
68         /**
69          * Check for missing elements in the received request.
70          *
71          * @param execution The flow's execution instance.
72          */
73         @Override
74         public void preProcessRequest(DelegateExecution execution) {
75                 def method = getClass().getSimpleName() + '.preProcessRequest(' +
76                         'execution=' + execution.getId() +
77                         ')'
78
79                 msoLogger.trace('Entered ' + method)
80
81                 try {
82                         initProcessVariables(execution)
83                         String request = validateRequest(execution)
84
85                         def requestInfo = getRequiredNodeXml(execution, request, 'request-info')
86                         execution.setVariable('UPDVfModVol_requestInfo', requestInfo)
87                         execution.setVariable('UPDVfModVol_requestId', getRequiredNodeText(execution, requestInfo, 'request-id'))
88                         execution.setVariable('UPDVfModVol_source', getNodeTextForce(requestInfo, 'source'))
89
90                         def volumeInputs = getRequiredNodeXml(execution, request, 'volume-inputs')
91                         execution.setVariable('UPDVfModVol_volumeInputs', volumeInputs)
92                         execution.setVariable('UPDVfModVol_volumeGroupId', getRequiredNodeText(execution, volumeInputs, 'volume-group-id'))
93                         execution.setVariable('UPDVfModVol_vnfType', getRequiredNodeText(execution, volumeInputs, 'vnf-type'))
94                         execution.setVariable('UPDVfModVol_serviceId', getRequiredNodeText(execution, volumeInputs, 'service-id'))
95                         execution.setVariable('UPDVfModVol_aicCloudRegion', getRequiredNodeText(execution, volumeInputs, 'aic-cloud-region'))
96                         execution.setVariable('UPDVfModVol_tenantId', getRequiredNodeText(execution, volumeInputs, 'tenant-id'))
97
98                         def volumeParams = utils.getNodeXml(request, 'volume-params')
99                         execution.setVariable('UPDVfModVol_volumeParams', volumeParams)
100
101                         msoLogger.trace('Exited ' + method)
102                         msoLogger.debug("UpdateVfModuleVolume request: " + request)
103                 } catch (BpmnError bpmnError) {
104                         throw bpmnError
105                 } catch (Exception e) {
106                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
107                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in preProcessRequest(): ' + e.getMessage())
108                 }
109         }
110
111         /**
112          * Prepare and send the synchronous response.
113          *
114          * @param execution The flow's execution instance.
115          */
116         public void sendSynchResponse(DelegateExecution execution) {
117                 def method = getClass().getSimpleName() + '.sendSynchResponse(' +
118                         'execution=' + execution.getId() +
119                         ')'
120
121                 msoLogger.trace('Entered ' + method)
122
123                 try {
124                         def requestInfo = execution.getVariable('UPDVfModVol_requestInfo')
125                         def requestId = execution.getVariable('UPDVfModVol_requestId')
126                         def source = execution.getVariable('UPDVfModVol_source')
127                         def progress = getNodeTextForce(requestInfo, 'progress')
128                         if (progress.isEmpty()) {
129                                 progress = '0'
130                         }
131                         def startTime = getNodeTextForce(requestInfo, 'start-time')
132                         if (startTime.isEmpty()) {
133                                 startTime = System.currentTimeMillis()
134                         }
135                         def volumeInputs = execution.getVariable('UPDVfModVol_volumeInputs')
136
137                         String synchResponse = """
138                                 <volume-request xmlns="http://org.onap/so/infra/vnf-request/v1">
139                                         <request-info>
140                                                 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
141                                                 <action>UPDATE_VF_MODULE_VOL</action>
142                                                 <request-status>IN_PROGRESS</request-status>
143                                                 <progress>${MsoUtils.xmlEscape(progress)}</progress>
144                                                 <start-time>${MsoUtils.xmlEscape(startTime)}</start-time>
145                                                 <source>${MsoUtils.xmlEscape(source)}</source>
146                                         </request-info>
147                                         ${volumeInputs}
148                                 </volume-request>
149                         """
150
151                         synchResponse = utils.formatXml(synchResponse)
152                         sendWorkflowResponse(execution, 200, synchResponse)
153                         msoLogger.debug("UpdateVfModuleVolume Synch Response: " + synchResponse)
154                 } catch (BpmnError e) {
155                         throw e;
156                 } catch (Exception e) {
157                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
158                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in sendSynchResponse(): ' + e.getMessage())
159                 }
160         }
161
162         /**
163          * Prepare a Request for querying AAI for Volume Group information using the
164          * Volume Group Id and Aic Cloud Region.
165          *
166          * @param execution The flow's execution instance.
167          */
168         public void queryAAIForVolumeGroup(DelegateExecution execution) {
169                 def method = getClass().getSimpleName() + '.queryAAIForVolumeGroup(' +
170                         'execution=' + execution.getId() +
171                         ')'
172
173                 msoLogger.trace('Entered ' + method)
174
175                 try {
176                         def volumeGroupId = execution.getVariable('UPDVfModVol_volumeGroupId')
177                         def aicCloudRegion = execution.getVariable('UPDVfModVol_aicCloudRegion')
178                         
179                         AaiUtil aaiUtil = new AaiUtil(this)
180                         AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VOLUME_GROUP, Defaults.CLOUD_OWNER.toString(), aicCloudRegion, volumeGroupId)
181                         String endPoint = aaiUtil.createAaiUri(uri)
182                         
183
184                         msoLogger.debug('Sending GET to AAI endpoint \'' + endPoint + '\'')
185                         msoLogger.debug("UpdateVfModuleVolume sending GET for quering AAI endpoint: " + endPoint)
186
187                         APIResponse response = aaiUtil.executeAAIGetCall(execution, endPoint)
188                         def int statusCode = response.getStatusCode()
189                         def responseData = response.getResponseBodyAsString()
190                         msoLogger.debug('Response code:' + statusCode)
191                         msoLogger.debug('Response:' + System.lineSeparator() + responseData)
192                         msoLogger.debug("UpdateVfModuleVolume response data: " + responseData)
193
194                         def volumeGroup = responseData
195                         def heatStackId = getNodeTextForce(volumeGroup, 'heat-stack-id')
196                         execution.setVariable('UPDVfModVol_volumeGroupHeatStackId', heatStackId)
197                         if ((statusCode == 200) || (statusCode == 204)) {
198                                 def volumeGroupTenantId = getTenantIdFromVolumeGroup(volumeGroup)
199                                 if (volumeGroupTenantId == null) {
200                                         throw new Exception('Could not find Tenant Id element in Volume Group with Volume Group Id \'' + volumeGroupId + '\''
201                                                 + '\', AIC Cloud Region \'' + aicCloudRegion + '\'')
202                                 }
203                                 execution.setVariable('UPDVfModVol_volumeGroupTenantId', volumeGroupTenantId)
204                                 msoLogger.debug('Received Tenant Id \'' + volumeGroupTenantId + '\' from AAI for Volume Group with Volume Group Id \'' + volumeGroupId + '\''
205                                         + '\', AIC Cloud Region \'' + aicCloudRegion + '\'')
206                         } else if (statusCode == 404) {
207                                 throw new Exception('Volume Group \'' + volumeGroupId + '\' not found at AAI')
208                         } else {
209                                 throw new Exception('Bad status code ' + statusCode + ' received from AAI; Response data: ' + responseData)
210                         }
211
212                         msoLogger.trace('Exited ' + method)
213                 } catch (BpmnError e) {
214                         throw e;
215                 } catch (Exception e) {
216                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
217                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in queryAAIForVolumeGroup(): ' + e.getMessage())
218                 }
219         }
220
221         /**
222          * Prepare a Request for invoking the VnfAdapterRest subflow to do
223          * a Volume Group update.
224          *
225          * @param execution The flow's execution instance.
226          */
227         public void prepVnfAdapterRest(DelegateExecution execution) {
228                 def method = getClass().getSimpleName() + '.prepVnfAdapterRest(' +
229                         'execution=' + execution.getId() +
230                         ')'
231
232                 msoLogger.trace('Entered ' + method)
233
234                 try {
235                         def aicCloudRegion = execution.getVariable('UPDVfModVol_aicCloudRegion')
236                         def tenantId = execution.getVariable('UPDVfModVol_tenantId')
237                         def volumeGroupId = execution.getVariable('UPDVfModVol_volumeGroupId')
238                         def volumeGroupHeatStackId = execution.getVariable('UPDVfModVol_volumeGroupHeatStackId')
239                         def vnfType = execution.getVariable('UPDVfModVol_vnfType')
240
241                         def volumeParamsXml = execution.getVariable('UPDVfModVol_volumeParams')
242                         def volumeGroupParams = transformParamsToEntries(volumeParamsXml)
243
244                         def requestId = execution.getVariable('UPDVfModVol_requestId')
245                         def serviceId = execution.getVariable('UPDVfModVol_serviceId')
246
247                         def messageId = execution.getVariable('mso-request-id') + '-' + System.currentTimeMillis()
248                         def notificationUrl = createCallbackURL(execution, "VNFAResponse", messageId)
249                         def useQualifiedHostName = UrnPropertiesReader.getVariable("mso.use.qualified.host",execution)
250                         if ('true'.equals(useQualifiedHostName)) {
251                                         notificationUrl = utils.getQualifiedHostNameForCallback(notificationUrl)
252                         }
253
254                         String vnfAdapterRestRequest = """
255                                 <updateVolumeGroupRequest>
256                                         <cloudSiteId>${MsoUtils.xmlEscape(aicCloudRegion)}</cloudSiteId>
257                                         <tenantId>${MsoUtils.xmlEscape(tenantId)}</tenantId>
258                                         <volumeGroupId>${MsoUtils.xmlEscape(volumeGroupId)}</volumeGroupId>
259                                         <volumeGroupStackId>${MsoUtils.xmlEscape(volumeGroupHeatStackId)}</volumeGroupStackId>
260                                         <vnfType>${MsoUtils.xmlEscape(vnfType)}</vnfType>
261                                         <vnfVersion></vnfVersion>
262                                         <vfModuleType></vfModuleType>
263                                         <volumeGroupParams>
264                                                 ${volumeGroupParams}
265                                     </volumeGroupParams>
266                                         <skipAAI>true</skipAAI>
267                                     <msoRequest>
268                                         <requestId>${MsoUtils.xmlEscape(requestId)}</requestId>
269                                         <serviceInstanceId>${MsoUtils.xmlEscape(serviceId)}</serviceInstanceId>
270                                     </msoRequest>
271                                     <messageId>${MsoUtils.xmlEscape(messageId)}</messageId>
272                                     <notificationUrl>${MsoUtils.xmlEscape(notificationUrl)}</notificationUrl>
273                                 </updateVolumeGroupRequest>
274                         """
275                         vnfAdapterRestRequest = utils.formatXml(vnfAdapterRestRequest)
276                         execution.setVariable('UPDVfModVol_vnfAdapterRestRequest', vnfAdapterRestRequest)
277                         msoLogger.debug('Request for VNFAdapter Rest:\n' + vnfAdapterRestRequest)
278
279                         msoLogger.debug("UpdateVfModuleVolume Request for VNFAdapter Rest: " + vnfAdapterRestRequest)
280                         msoLogger.trace('Exited ' + method)
281                 } catch (BpmnError e) {
282                         throw e;
283                 } catch (Exception e) {
284                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
285                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in prepVnfAdapterRest(): ' + e.getMessage())
286                 }
287         }
288
289         /**
290          * Prepare a Request for updating the DB for this Infra request.
291          *
292          * @param execution The flow's execution instance.
293          */
294         public void prepDbInfraDbRequest(DelegateExecution execution) {
295                 def method = getClass().getSimpleName() + '.prepDbInfraDbRequest(' +
296                         'execution=' + execution.getId() +
297                         ')'
298
299                 msoLogger.trace('Entered ' + method)
300
301                 try {
302                         def requestId = execution.getVariable('UPDVfMod_requestId')
303
304                         String updateInfraRequest = """
305                                 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
306                                                 xmlns:req="http://org.onap.so/requestsdb">
307                                         <soapenv:Header/>
308                                         <soapenv:Body>
309                                                 <req:updateInfraRequest>
310                                                         <requestId>${MsoUtils.xmlEscape(requestId)}</requestId>
311                                                         <lastModifiedBy>BPEL</lastModifiedBy>
312                                                         <requestStatus>COMPLETE</requestStatus>
313                                                         <progress>100</progress>
314                                                 </req:updateInfraRequest>
315                                         </soapenv:Body>
316                                 </soapenv:Envelope>
317                         """
318
319                         updateInfraRequest = utils.formatXml(updateInfraRequest)
320                         execution.setVariable('UPDVfModVol_updateInfraRequest', updateInfraRequest)
321                         msoLogger.debug('Request for Update Infra Request:\n' + updateInfraRequest)
322
323                         msoLogger.debug("UpdateVfModuleVolume Request for Updating DB for Infra: " + updateInfraRequest)
324                         msoLogger.trace('Exited ' + method)
325                 } catch (BpmnError e) {
326                         throw e;
327                 } catch (Exception e) {
328                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
329                         exceptionUtil.buildWorkflowException(execution, 1002, 'Error in prepDbInfraDbRequest(): ' + e.getMessage())
330                 }
331         }
332
333         /**
334          * Build a "CompletionHandler" request.
335          *
336          * @param execution The flow's execution instance.
337          */
338         public void prepCompletionHandlerRequest(DelegateExecution execution) {
339                 def method = getClass().getSimpleName() + '.prepCompletionHandlerRequest(' +
340                         'execution=' + execution.getId() +
341                         ')'
342
343                 msoLogger.trace('Entered ' + method)
344
345                 try {
346                         def requestInfo = execution.getVariable('UPDVfModVol_requestInfo')
347
348                         String content = """
349                                 <sdncadapterworkflow:MsoCompletionRequest xmlns:sdncadapterworkflow="http://org.onap/so/workflow/schema/v1"
350                                                 xmlns:reqtype="http://org.onap/so/request/types/v1">
351                                         ${requestInfo}
352                                         <sdncadapterworkflow:mso-bpel-name>MSO_ACTIVATE_BPEL</sdncadapterworkflow:mso-bpel-name>
353                                 </sdncadapterworkflow:MsoCompletionRequest>
354                         """
355
356                         content = utils.formatXml(content)
357                         msoLogger.debug('Request for Completion Handler:\n' + content)
358                         msoLogger.debug("UpdateVfModuleVolume Completion Handler request: " + content)
359                         execution.setVariable('UPDVfModVol_CompletionHandlerRequest', content)
360
361                         msoLogger.trace('Exited ' + method)
362                 } catch (BpmnError e) {
363                         throw e;
364                 } catch (Exception e) {
365                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
366                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in prepCompletionHandlerRequest(): ' + e.getMessage())
367                 }
368         }
369
370         /**
371          * Build a "FalloutHandler" request.
372          *
373          * @param execution The flow's execution instance.
374          */
375         public void prepFalloutHandler(DelegateExecution execution) {
376                 def method = getClass().getSimpleName() + '.prepFalloutHandler(' +
377                         'execution=' + execution.getId() +
378                         ')'
379
380                 msoLogger.trace('Entered ' + method)
381
382                 try {
383                         def requestInfo = execution.getVariable('UPDVfModVol_requestInfo')
384
385                         def WorkflowException workflowException = execution.getVariable("WorkflowException")
386                         def errorResponseCode = workflowException.getErrorCode()
387                         def errorResponseMsg = workflowException.getErrorMessage()
388                         def encErrorResponseMsg = ""
389                         if (errorResponseMsg != null) {
390                                 encErrorResponseMsg = errorResponseMsg
391                         }
392
393                         String content = """
394                                 <sdncadapterworkflow:FalloutHandlerRequest xmlns:sdncadapterworkflow="http://org.onap/so/workflow/schema/v1"
395                                                 xmlns:reqtype="http://org.onap/so/request/types/v1"
396                                                 xmlns:msoservtypes="http://org.onap/so/request/types/v1"
397                                                 xmlns:structuredtypes="http://org.onap/so/structured/types/v1">
398                                         ${requestInfo}
399                                         <sdncadapterworkflow:WorkflowException>
400                                                 <sdncadapterworkflow:ErrorMessage>${MsoUtils.xmlEscape(encErrorResponseMsg)}</sdncadapterworkflow:ErrorMessage>
401                                                 <sdncadapterworkflow:ErrorCode>${MsoUtils.xmlEscape(errorResponseCode)}</sdncadapterworkflow:ErrorCode>
402                                         </sdncadapterworkflow:WorkflowException>
403                                 </sdncadapterworkflow:FalloutHandlerRequest>
404                         """
405                         content = utils.formatXml(content)
406                         msoLogger.debug('Request for Fallout Handler:\n' + content)
407                         msoLogger.debug("UpdateVfModuleVolume Fallout request: " + content)
408                         execution.setVariable('UPDVfModVol_FalloutHandlerRequest', content)
409
410                         msoLogger.trace('Exited ' + method)
411                 } catch (BpmnError e) {
412                         throw e;
413                 } catch (Exception e) {
414                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
415                         exceptionUtil.buildWorkflowException(execution, 1002, 'Error in prepFalloutHandler(): ' + e.getMessage())
416                 }
417         }
418
419         /**
420          * Create a WorkflowException for the error case where the Tenant Id from
421          * AAI did not match the Tenant Id in the incoming request.
422          *
423          * @param execution The flow's execution instance.
424          */
425         public void handleTenantIdMismatch(DelegateExecution execution) {
426                 def method = getClass().getSimpleName() + '.handleTenantIdMismatch(' +
427                         'execution=' + execution.getId() +
428                         ')'
429
430                 msoLogger.trace('Entered ' + method)
431
432                 String processKey = getProcessKey(execution);
433                 def volumeGroupId = execution.getVariable('UPDVfModVol_volumeGroupId')
434                 def aicCloudRegion = execution.getVariable('UPDVfModVol_aicCloudRegion')
435                 def tenantId = execution.getVariable('UPDVfModVol_tenantId')
436                 def volumeGroupTenantId = execution.getVariable('UPDVfModVol_volumeGroupTenantId')
437
438                 def String errorMessage = 'TenantId \'' + tenantId + '\' in incoming request does not match Tenant Id \'' + volumeGroupTenantId +
439                         '\' retrieved from AAI for Volume Group Id \'' + volumeGroupId + '\', AIC Cloud Region \'' + aicCloudRegion + '\''
440
441                 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Error in UpdateVfModuleVol: ' + errorMessage, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception");
442
443                 WorkflowException exception = new WorkflowException(processKey, 5000, errorMessage);
444                 execution.setVariable("WorkflowException", exception);
445
446                 msoLogger.trace('Exited ' + method)
447                 msoLogger.debug("UpdateVfModuleVolume workflowException in Tenant Mismatch: " + errorMessage)
448         }
449 }