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