/** * Constructs an {@link LoggingTaskHandlerDecorator} instance that wraps a * created instance of the {@link WorkItemHandler} class given. This * instance will only keep the given number of {@link WorkItemExceptionInfo} * instances instead of the default 100. * * @param originalTaskHandlerClass * @param logLimit */ public LoggingTaskHandlerDecorator(Class<? extends WorkItemHandler> originalTaskHandlerClass, int logLimit) { super(originalTaskHandlerClass); initializeExceptionInfoList(logLimit); }
@Override public synchronized void handleExecuteException(Throwable cause, WorkItem workItem, WorkItemManager manager) { if (exceptionInfoList.size() == this.loggedExceptionsLimit) { exceptionInfoList.poll(); } exceptionInfoList.add(new WorkItemExceptionInfo(workItem, cause, true)); logMessage(true, workItem, cause); }
@Override public void abortWorkItem(WorkItem workItem, WorkItemManager manager) { try { originalTaskHandler.abortWorkItem(workItem, manager); } catch( RuntimeException re ) { handleAbortException(re, workItem, manager); } }
@Test public void testErrornousHandlerWithStrategyRetry() throws Exception { KieBase kbase = createKnowledgeBaseWithoutDumper("handler/BPMN2-UserTaskWithBooleanOutput.bpmn2", "handler/BPMN2-ScriptTask.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ErrornousWorkItemHandler workItemHandler = new ErrornousWorkItemHandler("ScriptTask", HandlingStrategy.RETRY); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); Map<String, Object> params = new HashMap<>(); params.put("isChecked", false); ProcessInstance processInstance = ksession.startProcess("com.sample.boolean", params); assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState()); assertProcessVarValue(processInstance, "isChecked", "true"); }
@Test public void testFormatLoggingError() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-ExceptionThrowingServiceProcess.bpmn2"); ksession = createKnowledgeSession(kbase); LoggingTaskHandlerDecorator loggingTaskHandlerWrapper = new LoggingTaskHandlerDecorator(ServiceTaskHandler.class, 2); loggingTaskHandlerWrapper.setLoggedMessageFormat("{0} - {1} - {2} - {3}"); List<InputParameter> inputParameters = new ArrayList<LoggingTaskHandlerDecorator.InputParameter>(); inputParameters.add(InputParameter.EXCEPTION_CLASS); inputParameters.add(InputParameter.WORK_ITEM_ID); inputParameters.add(InputParameter.WORK_ITEM_NAME); inputParameters.add(InputParameter.PROCESS_INSTANCE_ID); loggingTaskHandlerWrapper.setLoggedMessageInput(inputParameters); loggingTaskHandlerWrapper.setPrintStackTrace(false); ksession.getWorkItemManager().registerWorkItemHandler("Service Task", loggingTaskHandlerWrapper); Map<String, Object> params = new HashMap<String, Object>(); params.put("serviceInputItem", "exception message"); ksession.startProcess("ServiceProcess", params); ksession.startProcess("ServiceProcess", params); ksession.startProcess("ServiceProcess", params); }
@Override public void handleExecuteException(Throwable cause, WorkItem workItem, WorkItemManager manager) { if( getAndIncreaseExceptionCount(workItem.getProcessInstanceId()) < exceptionCountLimit ) { workItem.getParameters().put(this.workItemExceptionParameterName, cause); ((org.drools.core.process.instance.WorkItemManager) manager).signalEvent(this.eventType, (org.drools.core.process.instance.WorkItem) workItem, workItem.getProcessInstanceId()); } else { if( cause instanceof RuntimeException ) { throw (RuntimeException) cause; } else { throw new WorkItemHandlerRuntimeException(cause, "Signalling process instance " + workItem.getProcessInstanceId() + " with '" + this.eventType + "' resulted this exception."); } } }
@Test public void testLimitExceptionInfoList() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-ExceptionThrowingServiceProcess.bpmn2"); ksession = createKnowledgeSession(kbase); LoggingTaskHandlerDecorator loggingTaskHandlerWrapper = new LoggingTaskHandlerDecorator(ServiceTaskHandler.class, 2); loggingTaskHandlerWrapper.setPrintStackTrace(false); ksession.getWorkItemManager().registerWorkItemHandler("Service Task", loggingTaskHandlerWrapper); Map<String, Object> params = new HashMap<String, Object>(); params.put("serviceInputItem", "exception message"); ksession.startProcess("ServiceProcess", params); ksession.startProcess("ServiceProcess", params); ksession.startProcess("ServiceProcess", params); int size = loggingTaskHandlerWrapper.getWorkItemExceptionInfoList().size(); assertTrue( "WorkItemExceptionInfoList is too large: " + size, size == 2 ); }
@Test public void testErrornousHandlerWithStrategyRethrow() throws Exception { KieBase kbase = createKnowledgeBaseWithoutDumper("handler/BPMN2-UserTaskWithBooleanOutput.bpmn2", "handler/BPMN2-ScriptTask.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ErrornousWorkItemHandler workItemHandler = new ErrornousWorkItemHandler("ScriptTask", HandlingStrategy.RETHROW); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); try { Map<String, Object> params = new HashMap<>(); params.put("isChecked", false); ksession.startProcess("com.sample.boolean", params); fail("Should fail since strategy is rethrow"); } catch (WorkflowRuntimeException e) { assertEquals("On purpose", e.getCause().getMessage()); } }
@Test public void testReceiveTask() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-ReceiveTask.bpmn2"); ksession = createKnowledgeSession(kbase); ReceiveTaskHandler receiveTaskHandler = new ReceiveTaskHandler(ksession); ksession.getWorkItemManager().registerWorkItemHandler("Receive Task", receiveTaskHandler); WorkflowProcessInstance processInstance = (WorkflowProcessInstance) ksession .startProcess("ReceiveTask"); assertProcessInstanceActive(processInstance); ksession = restoreSession(ksession, true); receiveTaskHandler.setKnowledgeRuntime(ksession); receiveTaskHandler.messageReceived("HelloMessage", "Hello john!"); assertProcessInstanceFinished(processInstance, ksession); }
@Override public Map<String, WorkItemHandler> getWorkItemHandlers(RuntimeEngine runtime) { Map<String, WorkItemHandler> handlers = new HashMap<String, WorkItemHandler>(); handlers.putAll(super.getWorkItemHandlers(runtime)); handlers.put("Send Task", new SendTaskHandler()); return handlers; }
@Override public void executeWorkItem(WorkItem workItem, WorkItemManager manager) { try { originalTaskHandler.executeWorkItem(workItem, manager); } catch( Throwable cause ) { handleExecuteException(cause, workItem, manager); } }
@BeforeClass public static void setup() throws Exception { setUpDataSource(); }
@Override public void executeWorkItem(WorkItem workItem, WorkItemManager manager) { // collect message content for verification messageContent.append(workItem.getParameter("Message")); super.executeWorkItem(workItem, manager); }
@Override public void handleAbortException(Throwable cause, WorkItem workItem, WorkItemManager manager) { if( getAndIncreaseExceptionCount(workItem.getProcessInstanceId()) < exceptionCountLimit ) { workItem.getParameters().put(this.workItemExceptionParameterName, cause); ((org.drools.core.process.instance.WorkItemManager) manager).signalEvent(this.eventType, (org.drools.core.process.instance.WorkItem) workItem, workItem.getProcessInstanceId()); } }
@BeforeClass public static void setup() throws Exception { setUpDataSource(); VariableScope.setVariableStrictOption(false); WorkItemNodeInstance.setVariableStrictOption(false); }
@Test public void testErrornousHandlerWithStrategyComplete() throws Exception { KieBase kbase = createKnowledgeBaseWithoutDumper("handler/BPMN2-UserTaskWithBooleanOutput.bpmn2", "handler/BPMN2-ScriptTask.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ErrornousWorkItemHandler workItemHandler = new ErrornousWorkItemHandler("ScriptTask", HandlingStrategy.COMPLETE); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); ProcessInstance processInstance = ksession.startProcess("com.sample.boolean"); assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState()); assertProcessVarValue(processInstance, "isChecked", "true"); WorkItem handledWorkItem = workItemHandler.getWorkItem(); assertEquals(WorkItem.COMPLETED, handledWorkItem.getState()); }
@Override public synchronized void handleAbortException(Throwable cause, WorkItem workItem, WorkItemManager manager) { if (exceptionInfoList.size() == this.loggedExceptionsLimit) { exceptionInfoList.poll(); } exceptionInfoList.add(new WorkItemExceptionInfo(workItem, cause, false)); logMessage(false, workItem, cause); }
public synchronized void setLoggedExceptionInfoListSize(int loggedExceptionInfoListSize) { initializeExceptionInfoList(loggedExceptionInfoListSize); }
@Test public void testErrornousHandlerWithStrategyAbort() throws Exception { KieBase kbase = createKnowledgeBaseWithoutDumper("handler/BPMN2-UserTaskWithBooleanOutput.bpmn2", "handler/BPMN2-ScriptTask.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ErrornousWorkItemHandler workItemHandler = new ErrornousWorkItemHandler("ScriptTask", HandlingStrategy.ABORT); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); Map<String, Object> params = new HashMap<>(); params.put("isChecked", false); ProcessInstance processInstance = ksession.startProcess("com.sample.boolean", params); assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState()); assertProcessVarValue(processInstance, "isChecked", "false"); WorkItem handledWorkItem = workItemHandler.getWorkItem(); assertEquals(WorkItem.ABORTED, handledWorkItem.getState()); }
@Test public void testErrornousHandlerWithStrategyCompleteWaitState() throws Exception { KieBase kbase = createKnowledgeBaseWithoutDumper("handler/BPMN2-UserTaskWithBooleanOutput.bpmn2", "handler/BPMN2-ReceiveTask.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); TestWorkItemHandler testHandler = new TestWorkItemHandler(); ErrornousWorkItemHandler workItemHandler = new ErrornousWorkItemHandler("ReceiveTask", HandlingStrategy.COMPLETE); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); ksession.getWorkItemManager().registerWorkItemHandler("Receive Task", testHandler); ProcessInstance processInstance = ksession.startProcess("com.sample.boolean"); assertEquals(ProcessInstance.STATE_ACTIVE, processInstance.getState()); WorkItem receiveWorkItem = testHandler.getWorkItem(); Map<String, Object> results = new HashMap<>(); results.put("Message", true); ksession.getWorkItemManager().completeWorkItem(receiveWorkItem.getId(), results); assertProcessVarValue(processInstance, "isChecked", "true"); assertProcessInstanceCompleted(processInstance); }