Fix serialize DelegateExecutionImpl object bug
[so.git] / bpmn / MSOCommonBPMN / src / main / groovy / org / onap / so / bpmn / common / scripts / AbstractServiceTaskProcessor.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (c) 2019 Samsung
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.bpmn.common.scripts;
24
25 import org.camunda.bpm.engine.delegate.BpmnError
26 import org.camunda.bpm.engine.delegate.DelegateExecution
27 import org.camunda.bpm.engine.variable.VariableMap
28 import org.camunda.bpm.engine.variable.Variables
29 import org.camunda.bpm.engine.variable.Variables.SerializationDataFormats
30 import org.camunda.bpm.engine.variable.impl.value.ObjectValueImpl
31 import org.onap.so.bpmn.common.workflow.context.WorkflowCallbackResponse
32 import org.onap.so.bpmn.common.workflow.context.WorkflowContextHolder
33 import org.onap.so.bpmn.core.UrnPropertiesReader
34 import org.onap.so.bpmn.core.WorkflowException
35 import org.onap.so.client.aai.AAIResourcesClient
36 import org.springframework.web.util.UriUtils
37 import org.slf4j.Logger
38 import org.slf4j.LoggerFactory
39
40 import groovy.json.JsonSlurper
41
42 public abstract class AbstractServiceTaskProcessor implements ServiceTaskProcessor {
43         private static final Logger logger = LoggerFactory.getLogger( MsoUtils.class);
44
45         public MsoUtils utils = new MsoUtils()
46
47         /**
48          * Saves the WorkflowException in the execution to the specified variable,
49          * clearing the WorkflowException variable so the workflow can continue
50          * processing (perhaps catching another WorkflowException).
51          * @param execution the execution
52          * @return the name of the destination variable
53          */
54         public saveWorkflowException(DelegateExecution execution, String variable) {
55                 if (variable == null) {
56                         throw new NullPointerException();
57                 }
58
59                 execution.setVariable(variable, execution.getVariable("WorkflowException"))
60                 execution.setVariable("WorkflowException", null)
61         }
62
63
64         /**
65          * Validates that the request exists and that the mso-request-id variable is set.
66          * Additional required variables may be checked by specifying their names.
67          * NOTE: services requiring mso-service-instance-id must specify it explicitly!
68          * If a problem is found, buildAndThrowWorkflowException builds a WorkflowException
69          * and throws an MSOWorkflowException.  This method also sets up the log context for
70          * the workflow.
71          *
72          * @param execution the execution
73          * @return the validated request
74          */
75         public String validateRequest(DelegateExecution execution, String... requiredVariables) {
76                 ExceptionUtil exceptionUtil = new ExceptionUtil()
77                 def method = getClass().getSimpleName() + '.validateRequest(' +
78                         'execution=' + execution.getId() +
79                         ', requredVariables=' + requiredVariables +
80                         ')'
81                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
82                 logger.debug('Entered ' + method)
83
84                 String processKey = getProcessKey(execution)
85                 def prefix = execution.getVariable("prefix")
86
87                 if (prefix == null) {
88                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, processKey + " prefix is null")
89                 }
90
91                 try {
92                         def request = execution.getVariable(prefix + 'Request')
93
94                         if (request == null) {
95                                 request = execution.getVariable(processKey + 'Request')
96
97                                 if (request == null) {
98                                         request = execution.getVariable('bpmnRequest')
99                                 }
100
101                                 setVariable(execution, processKey + 'Request', null)
102                                 setVariable(execution, 'bpmnRequest', null)
103                                 setVariable(execution, prefix + 'Request', request)
104                         }
105
106                         if (request == null) {
107                                 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, processKey + " request is null")
108                         }
109
110                         // All requests must have a request ID.
111                         // Some requests (e.g. SDN-MOBILITY) do not have a service instance ID.
112
113                         String requestId = null
114                         String serviceInstanceId = null
115
116                         List<String> allRequiredVariables = new ArrayList<String>()
117                         allRequiredVariables.add("mso-request-id")
118
119                         if (requiredVariables != null) {
120                                 for (String variable : requiredVariables) {
121                                         if (!allRequiredVariables.contains(variable)) {
122                                                 allRequiredVariables.add(variable)
123                                         }
124                                 }
125                         }
126
127                         for (String variable : allRequiredVariables) {
128                                 def value = execution.getVariable(variable)
129                                 if (value == null || ((value instanceof CharSequence) && value.length() == 0)) {
130                                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, processKey +
131                                                 " request was received with no '" + variable + "' variable")
132                                 }
133
134                                 if ("mso-request-id".equals(variable)) {
135                                         requestId = (String) value
136                                 } else if ("mso-service-instance-id".equals(variable)) {
137                                         serviceInstanceId = (String) value
138                                 }
139                         }
140
141                         if (serviceInstanceId == null) {
142                                 serviceInstanceId = (String) execution.getVariable("mso-service-instance-id")
143                         }
144
145                         logger.debug('Incoming message: ' + System.lineSeparator() + request)
146                         logger.debug('Exited ' + method)
147                         return request
148                 } catch (BpmnError e) {
149                         throw e
150                 } catch (Exception e) {
151                         logger.error('Caught exception in ' + method, e)
152                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, "Invalid Message")
153                 }
154         }
155
156         /**
157          * gets vars stored in a JSON object in prefix+Request and returns as a LazyMap
158          * setting log context here too
159          * @param execution the execution
160          * @return the inputVars
161          */
162         public Map validateJSONReq(DelegateExecution execution) {
163                 def method = getClass().getSimpleName() + '.validateJSONReq(' +
164                                 'execution=' + execution.getId() +
165                                 ')'
166                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
167                 logger.debug('Entered ' + method)
168
169                 String processKey = getProcessKey(execution);
170                 def prefix = execution.getVariable("prefix")
171
172                 def request = getVariable(execution, prefix + 'Request')
173
174                 if (request == null) {
175                         request = getVariable(execution, processKey + 'Request')
176
177                         if (request == null) {
178                                 request = getVariable(execution, 'bpmnRequest')
179                         }
180                         execution.setVariable(prefix + 'Request', request)
181                 }
182
183                 def jsonSlurper = new JsonSlurper()
184                 def parsed = jsonSlurper.parseText(request)
185
186
187                 logger.debug('Incoming message: ' + System.lineSeparator() + request)
188                 logger.debug('Exited ' + method)
189                 return parsed
190
191         }
192
193         /**
194          * Sends a response to the workflow service that invoked the process.  This method
195          * may only be used by top-level processes that were directly invoked by the
196          * asynchronous workflow service.
197          * @param execution the execution
198          * @param responseCode the response code
199          * @param content the message content
200          * @throws IllegalArgumentException if the response code is invalid
201          *         by HTTP standards
202          * @throws UnsupportedOperationException if not invoked by an asynchronous,
203          *         top-level process
204          * @throws IllegalStateException if a response has already been sent
205          */
206         protected void sendWorkflowResponse(DelegateExecution execution, Object responseCode, String response) {
207                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
208                 try {
209                         String processKey = getProcessKey(execution);
210
211                         // isAsyncProcess is injected by the workflow service that started the flow
212                         if (!String.valueOf(execution.getVariable("isAsyncProcess")).equals("true")) {
213                                 throw new UnsupportedOperationException(processKey + ": " +
214                                         "sendWorkflowResponse is valid only in asynchronous workflows");
215                         }
216
217                         if (String.valueOf(execution.getVariable(processKey + "WorkflowResponseSent")).equals("true")) {
218                                         logger.debug("Sync response has already been sent for " + processKey)
219                         }else{
220
221                                 logger.debug("Building " + processKey + " response ")
222
223                                 int intResponseCode;
224
225                                 try {
226                                         intResponseCode = Integer.parseInt(String.valueOf(responseCode));
227
228                                         if (intResponseCode < 100 || intResponseCode > 599) {
229                                                 throw new NumberFormatException(String.valueOf(responseCode));
230                                         }
231                                 } catch (NumberFormatException e) {
232                                         throw new IllegalArgumentException("Process " + processKey
233                                                 + " provided an invalid HTTP response code: " + responseCode);
234                                 }
235
236                                 // Only 2XX responses are considered "Success"
237                                 String status = (intResponseCode >= 200 && intResponseCode <= 299) ?
238                                         "Success" : "Fail";
239
240                                 // TODO: Should deprecate use of processKey+Response variable for the response. Will use "WorkflowResponse" instead
241                                 execution.setVariable(processKey + "ResponseCode", String.valueOf(intResponseCode))
242                                 execution.setVariable(processKey + "Response", response);
243                                 execution.setVariable(processKey + "Status", status);
244                                 execution.setVariable("WorkflowResponse", response)
245
246                                 logger.debug("Sending response for " + processKey
247                                         + " ResponseCode=" + intResponseCode
248                                         + " Status=" + status
249                                         + " Response=\n" + response)
250
251                                 // TODO: ensure that this flow was invoked asynchronously?
252
253                                 WorkflowCallbackResponse callbackResponse = new WorkflowCallbackResponse()
254                                 callbackResponse.setStatusCode(intResponseCode)
255                                 callbackResponse.setMessage(status)
256                                 callbackResponse.setResponse(response)
257
258                                 // TODO: send this data with HTTP POST
259
260                                 WorkflowContextHolder.getInstance().processCallback(
261                                         processKey,
262                                         execution.getProcessInstanceId(),
263                                         execution.getVariable("mso-request-id"),
264                                         callbackResponse)
265
266                                 execution.setVariable(processKey + "WorkflowResponseSent", "true");
267                         }
268
269                 } catch (Exception ex) {
270                         logger.error("Unable to send workflow response to client ....", ex)
271                 }
272         }
273
274         /**
275          * Returns true if a workflow response has already been sent.
276          * @param execution the execution
277          */
278         protected boolean isWorkflowResponseSent(DelegateExecution execution) {
279                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
280                 String processKey = getProcessKey(execution);
281                 return String.valueOf(execution.getVariable(processKey + "WorkflowResponseSent")).equals("true");
282         }
283
284         /**
285          * Returns the process definition key (i.e. the process name) of the
286          * current process.
287          *
288          * @param execution the execution
289          */
290         public String getProcessKey(DelegateExecution execution) {
291                 def testKey = execution.getVariable("testProcessKey")
292                 if(testKey!=null){
293                         return testKey
294                 }
295                 return execution.getProcessEngineServices().getRepositoryService()
296                         .getProcessDefinition(execution.getProcessDefinitionId()).getKey()
297         }
298
299         /**
300          * Returns the process definition key (i.e. the process name) of the
301          * top-level process.
302          * @param execution the execution
303          */
304         public String getMainProcessKey(DelegateExecution execution) {
305                 DelegateExecution exec = execution
306
307                 while (true) {
308                         DelegateExecution parent = exec.getSuperExecution()
309
310                         if (parent == null) {
311                                 parent = exec.getParent()
312
313                                 if (parent == null) {
314                                         break
315                                 }
316                         }
317
318                         exec = parent
319                 }
320
321                 return execution.getProcessEngineServices().getRepositoryService()
322                         .getProcessDefinition(exec.getProcessDefinitionId()).getKey()
323         }
324
325         /**
326          * Gets the node for the named element from the given xml. If the element
327          * does not exist in the xml or is empty, a WorkflowException is created
328          * (and as a result, a MSOWorkflowException event is thrown).
329          *
330          * @param execution The flow's execution.
331          * @param xml Xml to search.
332          * @param elementName Name of element to search for.
333          * @return The element node, if found in the xml.
334          */
335         protected String getRequiredNodeXml(DelegateExecution execution, String xml, String elementName) {
336                 ExceptionUtil exceptionUtil = new ExceptionUtil()
337                 def element = utils.getNodeXml(xml, elementName, false)
338                 if (element.trim().isEmpty()) {
339                         def msg = 'Required element \'' + elementName + '\' is missing or empty'
340                         logger.error(msg)
341                         exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
342                 } else {
343                         return element
344                 }
345         }
346
347         /**
348          * Gets the value of the named element from the given xml. If the element
349          * does not exist in the xml or is empty, a WorkflowException is created
350          * (and as a result, a MSOWorkflowException event is thrown).
351          *
352          * @param execution The flow's execution.
353          * @param xml Xml to search.
354          * @param elementName Name of element to whose value to get.
355          * @return The non-empty value of the element, if found in the xml.
356          */
357         protected String getRequiredNodeText(DelegateExecution execution, String xml, String elementName) {
358                 ExceptionUtil exceptionUtil = new ExceptionUtil()
359                 def elementText = utils.getNodeText(xml, elementName)
360                 if ((elementText == null) || (elementText.isEmpty())) {
361                         def msg = 'Required element \'' + elementName + '\' is missing or empty'
362                         logger.error(msg)
363                         exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
364                 } else {
365                         return elementText
366                 }
367         }
368
369         /**
370          * Get the text for the specified element from the specified xml.  If
371          * the element does not exist, return the specified default value.
372          *
373          * @param xml Xml from which to get the element's text
374          * @param elementName Name of element whose text to get
375          * @param defaultValue the default value
376          * @return the element's text or the default value if the element does not
377          * exist in the given xml
378          */
379         protected String getNodeText(String xml, String elementName, String defaultValue) {
380                 def nodeText = utils.getNodeText(xml, elementName)
381                 return (nodeText == null) ? defaultValue : nodeText
382         }
383
384         /**
385          * Get the text for the specified element from the specified xml.  If
386          * the element does not exist, return an empty string.
387          *
388          * @param xml Xml from which to get the element's text.
389          * @param elementName Name of element whose text to get.
390          * @return the element's text or an empty string if the element does not
391          * exist in the given xml.
392          */
393         protected String getNodeTextForce(String xml, String elementName) {
394                 return getNodeText(xml, elementName, '');
395         }
396
397         /**
398         *Store the variable as typed with java serialization type
399         *@param execution
400         *@param name
401         *@param value
402         */
403         public void setVariable(DelegateExecution execution, String name, Object value) {
404                 VariableMap variables = Variables.createVariables()
405                 variables.putValueTyped('payload', Variables.objectValue(value)
406                 .serializationDataFormat(SerializationDataFormats.JAVA) // tells the engine to use java serialization for persisting the value
407                 .create())
408                 execution.setVariable(name,variables)
409         }
410
411         //TODO not sure how this will look in Cockpit
412
413         /**
414          * Returns the variable map
415         *@param execution
416         *@param name
417         *@return
418         **/
419         public String getVariable(DelegateExecution execution, String name) {
420                 def myObj = execution.getVariable(name)
421                 if(myObj instanceof VariableMap){
422                         VariableMap serializedObjectMap = (VariableMap) myObj
423                         ObjectValueImpl payloadObj = serializedObjectMap.getValueTyped('payload')
424                         return payloadObj.getValue()
425                 }else{
426                         return myObj
427                 }
428         }
429
430
431         /**
432          * Returns true if a value equals one of the provided set. Equality is
433          * determined by using the equals method if the value object and the
434          * object in the provided set have the same class. Otherwise, the objects
435          * are converted to strings and then compared.  Nulls are permitted for
436          * the value as well as in the provided set
437          * Example:
438          * <pre>
439          *     def statusCode = getStatusCode()
440          *     isOneOf(statusCode, 200, 201, 204)
441          * </pre>
442          * @param value the value to test
443          * @param these a set of permissable values
444          * @return true if the value is in the provided set
445          */
446         public boolean isOneOf(Object value, Object... these) {
447                 for (Object thisOne : these) {
448                         if (thisOne == null) {
449                                 if (value == null) {
450                                         return true
451                                 }
452                         } else {
453                                 if (value != null) {
454                                         if (value.getClass() == thisOne.getClass()) {
455                                                 if (value.equals(thisOne)) {
456                                                         return true
457                                                 }
458                                         } else {
459                                                 if (String.valueOf(value).equals(String.valueOf(thisOne))) {
460                                                         return true
461                                                 }
462                                         }
463                                 }
464                         }
465                 }
466                 return false
467         }
468
469         /**
470          * Sets flows success indicator variable.
471          *
472          */
473         public void setSuccessIndicator(DelegateExecution execution, boolean isSuccess) {
474                 String prefix = execution.getVariable('prefix')
475                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
476
477                 logger.debug('Entered SetSuccessIndicator Method')
478                 execution.setVariable(prefix+'SuccessIndicator', isSuccess)
479                 logger.debug('Outgoing SuccessIndicator is: ' + execution.getVariable(prefix+'SuccessIndicator') + '')
480         }
481
482         /**
483          * Sends a Error Sync Response
484          *
485          */
486         public void sendSyncError(DelegateExecution execution) {
487                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
488                 String requestId = execution.getVariable("mso-request-id")
489                 logger.debug('sendSyncError, requestId: ' + requestId)
490                 WorkflowException workflowExceptionObj = execution.getVariable("WorkflowException")
491                 if (workflowExceptionObj != null) {
492                         String errorMessage = workflowExceptionObj.getErrorMessage()
493                         def errorCode = workflowExceptionObj.getErrorCode()
494                         logger.debug('sendSyncError, requestId: '  + requestId + ' | errorMessage: ' + errorMessage + ' | errorCode: ' + errorCode)
495                         sendWorkflowResponse(execution, errorCode, errorMessage)
496                 }
497         }
498
499         /**
500          * Executes a named groovy script method in the current object
501          */
502         public void executeMethod(String methodName, Object... args) {
503
504                 if (args != null && args.size() > 0) {
505
506                         // First argument of method to call is always the execution object
507                         DelegateExecution execution = (DelegateExecution) args[0]
508
509                         def classAndMethod = getClass().getSimpleName() + '.' + methodName + '(execution=' + execution.getId() + ')'
510                         def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
511
512                         logger.debug('Entered ' + classAndMethod)
513                         logger.debug('Received parameters: ' + args)
514
515                         try{
516                                 def methodToCall = this.metaClass.getMetaMethod(methodName, args)
517                                 logger.debug('Method to call: ' + methodToCall)
518                                 methodToCall?.invoke(this, args)
519                         }
520                         catch(BpmnError bpmnError) {
521                                 logger.debug('Rethrowing BpmnError ' + bpmnError.getMessage())
522                                 throw bpmnError
523                         }
524                         catch(Exception e) {
525                                 e.printStackTrace()
526                                 logger.debug('Unexpected error encountered - ' + e.getMessage())
527                                 (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 9999, e.getMessage())
528                         }
529                         finally {
530                                 logger.debug('Exited ' + classAndMethod)
531                         }
532                 }
533         }
534
535         /**
536          *This method determines and adds the appropriate ending to come
537          *after a number (-st, -nd, -rd, or -th)
538          *
539          *@param int n
540          *
541          *@return String ending - number with suffix
542          */
543         public static String labelMaker(Object n) {
544                 Integer num
545                 if(n instanceof String){
546                         num = Integer.parseInt(n)
547                 }else{
548                         num = n
549                 }
550
551                 String ending = ""; //the end to be added to the number
552                 if(num != null){
553                 if ((num % 10 == 1) && (num != 11)) {
554                         ending = num + "st";
555                         } else if ((num % 10 == 2) && (num != 12)) {
556                         ending = num + "nd";
557                         } else if ((num % 10 == 3) && (num != 13)) {
558                         ending = num + "rd";
559                         } else {
560                         ending = num + "th";
561                 }
562                 }
563                 return ending
564         }
565
566         /**
567          * Constructs a workflow message callback URL for the specified message type and correlator.
568          * This type of callback URL is used when a workflow wants an MSO adapter (like the SDNC
569          * adapter) to call it back.  In other words, this is for callbacks internal to the MSO
570          * complex.  Use <code>createWorkflowMessageAdapterCallbackURL</code> if the callback
571          * will come from outside the MSO complex.
572          * @param messageType the message type (e.g. SDNCAResponse or VNFAResponse)
573          * @param correlator the correlator value (e.g. a request ID)
574          */
575         public String createCallbackURL(DelegateExecution execution, String messageType, String correlator) {
576                 String endpoint = UrnPropertiesReader.getVariable("mso.workflow.message.endpoint", execution)
577
578                 if (endpoint == null || endpoint.isEmpty()) {
579                         ExceptionUtil exceptionUtil = new ExceptionUtil()
580                         exceptionUtil.buildAndThrowWorkflowException(execution, 2000,
581                                 'mso:workflow:message:endpoint URN mapping is not set')
582                 }
583
584                 while (endpoint.endsWith('/')) {
585                         endpoint = endpoint.substring(0, endpoint.length()-1)
586                 }
587
588                 return endpoint +
589                         '/' + UriUtils.encodePathSegment(messageType, 'UTF-8') +
590                         '/' + UriUtils.encodePathSegment(correlator, 'UTF-8')
591         }
592
593         /**
594          *
595          * Constructs a workflow message callback URL for the specified message type and correlator.
596          * This type of callback URL is used when a workflow wants a system outside the MSO complex
597          * to call it back through the Workflow Message Adapter.
598          * @param messageType the message type (e.g. SNIROResponse)
599          * @param correlator the correlator value (e.g. a request ID)
600          */
601         public String createWorkflowMessageAdapterCallbackURL(DelegateExecution execution, String messageType, String correlator) {
602                 String endpoint = UrnPropertiesReader.getVariable("mso.adapters.workflow.message.endpoint", execution)
603
604                 if (endpoint == null || endpoint.isEmpty()) {
605                         ExceptionUtil exceptionUtil = new ExceptionUtil()
606                         exceptionUtil.buildAndThrowWorkflowException(execution, 2000,
607                                 'mso:adapters:workflow:message:endpoint URN mapping is not set')
608                 }
609
610                 while (endpoint.endsWith('/')) {
611                         endpoint = endpoint.substring(0, endpoint.length()-1)
612                 }
613
614                 return endpoint +
615                         '/' + UriUtils.encodePathSegment(messageType, 'UTF-8') +
616                         '/' + UriUtils.encodePathSegment(correlator, 'UTF-8')
617         }
618
619         public void setRollbackEnabled(DelegateExecution execution, isDebugLogEnabled) {
620
621                 // Rollback settings
622                 def prefix = execution.getVariable('prefix')
623                 def disableRollback = execution.getVariable("disableRollback")
624                 def defaultRollback = UrnPropertiesReader.getVariable("mso.rollback", execution).toBoolean()
625
626                 logger.debug('disableRollback: ' + disableRollback)
627                 logger.debug('defaultRollback: ' + defaultRollback)
628
629                 def rollbackEnabled
630
631                 if(disableRollback == null || disableRollback == '' ) {
632                         // get from default urn settings for mso_rollback
633                         disableRollback = !defaultRollback
634                         rollbackEnabled = defaultRollback
635                         logger.debug('disableRollback is null or empty!')
636                 }
637                 else {
638                         if(disableRollback == true) {
639                                 rollbackEnabled = false
640                         }
641                         else if(disableRollback == false){
642                                 rollbackEnabled = true
643                         }
644                         else {
645                                 rollbackEnabled = defaultRollback
646                         }
647                 }
648                 
649                 execution.setVariable(prefix+"backoutOnFailure", rollbackEnabled)
650                 logger.debug('rollbackEnabled (aka backoutOnFailure): ' + rollbackEnabled)
651         }
652
653         public void setBasicDBAuthHeader(DelegateExecution execution, isDebugLogEnabled) {
654                 try {
655                         String basicAuthValueDB = UrnPropertiesReader.getVariable("mso.adapters.db.auth", execution)
656                         def encodedString = utils.getBasicAuth(basicAuthValueDB, UrnPropertiesReader.getVariable("mso.msoKey", execution))
657                         execution.setVariable("BasicAuthHeaderValueDB",encodedString)
658                 } catch (IOException ex) {
659                         String dataErrorMessage = " Unable to encode Catalog DB user/password string - " + ex.getMessage()
660                         logger.debug(dataErrorMessage)
661                         (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 2500, dataErrorMessage)
662                 }
663         }
664     public AAIResourcesClient getAAIClient(){
665         return  new AAIResourcesClient();
666     }
667 }