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