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