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