/** * Copyright 2010 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jbpm.bpmn2; import java.io.ByteArrayInputStream; import java.io.File; import java.io.StringReader; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.parsers.DocumentBuilderFactory; import org.drools.core.util.IoUtils; import org.jbpm.bpmn2.handler.ReceiveTaskHandler; import org.jbpm.bpmn2.handler.SendTaskHandler; import org.jbpm.bpmn2.handler.ServiceTaskHandler; import org.jbpm.bpmn2.handler.SignallingTaskHandlerDecorator; import org.jbpm.bpmn2.objects.ExceptionService; import org.jbpm.bpmn2.objects.Person; import org.jbpm.bpmn2.objects.TestWorkItemHandler; import org.jbpm.process.audit.JPAAuditLogService; import org.jbpm.process.audit.VariableInstanceLog; import org.jbpm.process.instance.impl.demo.DoNothingWorkItemHandler; import org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler; import org.jbpm.test.util.CountDownProcessEventListener; import org.junit.After; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import org.kie.api.KieBase; import org.kie.api.event.process.DefaultProcessEventListener; import org.kie.api.event.process.ProcessStartedEvent; import org.kie.api.io.Resource; import org.kie.api.io.ResourceType; import org.kie.api.runtime.KieSession; import org.kie.api.runtime.process.ProcessInstance; import org.kie.api.runtime.process.WorkItem; import org.kie.api.runtime.process.WorkflowProcessInstance; import org.kie.internal.KnowledgeBase; import org.kie.internal.KnowledgeBaseFactory; import org.kie.internal.builder.KnowledgeBuilder; import org.kie.internal.builder.KnowledgeBuilderError; import org.kie.internal.builder.KnowledgeBuilderFactory; import org.kie.internal.io.ResourceFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; @RunWith(Parameterized.class) public class StandaloneBPMNProcessTest extends JbpmBpmn2TestCase { private static final Logger logger = LoggerFactory.getLogger(StandaloneBPMNProcessTest.class); @Parameters public static Collection<Object[]> persistence() { Object[][] data = new Object[][] { { false, false }, { true, false }, { true, true } }; return Arrays.asList(data); } public StandaloneBPMNProcessTest(boolean persistence, boolean locking) { super(persistence, locking); } @BeforeClass public static void setup() throws Exception { setUpDataSource(); } @After public void tearDown() { KnowledgeBaseFactory.setKnowledgeBaseServiceFactory(null); } /** * Tests */ @Test public void testMinimalProcess() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-MinimalProcess.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ProcessInstance processInstance = ksession.startProcess("Minimal"); assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED); } @Test public void testMinimalProcessWithGraphical() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-MinimalProcessWithGraphical.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ProcessInstance processInstance = ksession.startProcess("Minimal"); assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED); } @Test public void testMinimalProcessWithDIGraphical() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-MinimalProcessWithDIGraphical.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ProcessInstance processInstance = ksession.startProcess("Minimal"); assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED); } @Test public void testCompositeProcessWithDIGraphical() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-CompositeProcessWithDIGraphical.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ProcessInstance processInstance = ksession.startProcess("Composite"); assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED); } @Test public void testScriptTask() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-ScriptTask.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ProcessInstance processInstance = ksession.startProcess("ScriptTask"); assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED); } @Test public void testDataObject() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-DataObject.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); Map<String, Object> params = new HashMap<String, Object>(); params.put("employee", "UserId-12345"); ProcessInstance processInstance = ksession.startProcess("Evaluation", params); assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED); } @Test public void testEvaluationProcess() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-EvaluationProcess.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("RegisterRequest", new SystemOutWorkItemHandler()); Map<String, Object> params = new HashMap<String, Object>(); params.put("employee", "UserId-12345"); ProcessInstance processInstance = ksession.startProcess("Evaluation", params); assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED); } @Test public void testEvaluationProcess2() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-EvaluationProcess2.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", new SystemOutWorkItemHandler()); Map<String, Object> params = new HashMap<String, Object>(); params.put("employee", "UserId-12345"); ProcessInstance processInstance = ksession.startProcess("com.sample.evaluation", params); assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED); } @Test public void testEvaluationProcess3() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-EvaluationProcess3.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("RegisterRequest", new SystemOutWorkItemHandler()); Map<String, Object> params = new HashMap<String, Object>(); params.put("employee", "john2"); ProcessInstance processInstance = ksession.startProcess("Evaluation", params); assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED); } @Test public void testUserTask() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-UserTask.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); Map<String, Object> params = new HashMap<String, Object>(); String varId = "s"; String varValue = "initialValue"; params.put(varId, varValue); ProcessInstance processInstance = ksession.startProcess("UserTask", params); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); // Test jbpm-audit findVariableInstancesByName* methods if( isPersistence() ) { List<VariableInstanceLog> varLogs = logService.findVariableInstancesByName(varId, true); assertTrue( ! varLogs.isEmpty() ); for( VariableInstanceLog varLog : varLogs ) { assertEquals( varId, varLog.getVariableId()); } varLogs = logService.findVariableInstancesByNameAndValue( varId, varValue, true); assertTrue( ! varLogs.isEmpty() ); for( VariableInstanceLog varLog : varLogs ) { assertEquals( varId, varLog.getVariableId()); assertEquals( varValue, varLog.getValue() ); } } ksession = restoreSession(ksession, true); WorkItem workItem = workItemHandler.getWorkItem(); assertNotNull(workItem); assertEquals("john", workItem.getParameter("ActorId")); ksession.getWorkItemManager().completeWorkItem(workItem.getId(), null); assertProcessInstanceCompleted(processInstance.getId(), ksession); } @Test public void testLane() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-Lane.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); ProcessInstance processInstance = ksession.startProcess("UserTask"); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); ksession = restoreSession(ksession, true); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); WorkItem workItem = workItemHandler.getWorkItem(); assertNotNull(workItem); assertEquals("john", workItem.getParameter("ActorId")); Map<String, Object> results = new HashMap<String, Object>(); results.put("ActorId", "mary"); ksession.getWorkItemManager().completeWorkItem(workItem.getId(), results); ksession = restoreSession(ksession, true); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); workItem = workItemHandler.getWorkItem(); assertNotNull(workItem); assertEquals("mary", workItem.getParameter("SwimlaneActorId")); ksession.getWorkItemManager().completeWorkItem(workItem.getId(), null); assertProcessInstanceCompleted(processInstance.getId(), ksession); } @Test public void testExclusiveSplit() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-ExclusiveSplit.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Email", new SystemOutWorkItemHandler()); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", "First"); params.put("y", "Second"); ProcessInstance processInstance = ksession.startProcess("com.sample.test", params); assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED); } @Test public void testExclusiveSplitDefault() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-ExclusiveSplitDefault.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Email", new SystemOutWorkItemHandler()); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", "NotFirst"); params.put("y", "Second"); ProcessInstance processInstance = ksession.startProcess("com.sample.test", params); assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED); } @Test public void testInclusiveSplit() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-InclusiveSplit.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", 15); ProcessInstance processInstance = ksession.startProcess("com.sample.test", params); assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED); } @Test public void testInclusiveSplitDefault() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-InclusiveSplitDefault.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", -5); ProcessInstance processInstance = ksession.startProcess("com.sample.test", params); assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED); } @Test @Ignore public void testExclusiveSplitXPath() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-ExclusiveSplitXPath.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Email", new SystemOutWorkItemHandler()); Document document = DocumentBuilderFactory .newInstance() .newDocumentBuilder() .parse(new ByteArrayInputStream( "<myDocument><chapter1>BlaBla</chapter1><chapter2>MoreBlaBla</chapter2></myDocument>".getBytes())); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", document); params.put("y", "SomeString"); ProcessInstance processInstance = ksession.startProcess("com.sample.test", params); assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED); } @Test public void testEventBasedSplit() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-EventBasedSplit.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); // Yes ProcessInstance processInstance = ksession.startProcess("com.sample.test"); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); ksession = restoreSession(ksession, true); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); ksession.signalEvent("Yes", "YesValue", processInstance.getId()); assertProcessInstanceCompleted(processInstance.getId(), ksession); // No processInstance = ksession.startProcess("com.sample.test"); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); ksession = restoreSession(ksession, true); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); ksession.signalEvent("No", "NoValue", processInstance.getId()); assertProcessInstanceCompleted(processInstance.getId(), ksession); } @Test public void testEventBasedSplitBefore() throws Exception { // signaling before the split is reached should have no effect KieBase kbase = createKnowledgeBase("BPMN2-EventBasedSplit.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new DoNothingWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new DoNothingWorkItemHandler()); // Yes ProcessInstance processInstance = ksession.startProcess("com.sample.test"); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); ksession = restoreSession(ksession, true); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new DoNothingWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new DoNothingWorkItemHandler()); ksession.signalEvent("Yes", "YesValue", processInstance.getId()); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); // No processInstance = ksession.startProcess("com.sample.test"); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); ksession = restoreSession(ksession, true); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new DoNothingWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new DoNothingWorkItemHandler()); ksession.signalEvent("No", "NoValue", processInstance.getId()); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); } @Test public void testEventBasedSplitAfter() throws Exception { // signaling the other alternative after one has been selected should // have no effect KieBase kbase = createKnowledgeBase("BPMN2-EventBasedSplit.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new DoNothingWorkItemHandler()); // Yes ProcessInstance processInstance = ksession.startProcess("com.sample.test"); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); ksession = restoreSession(ksession, true); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new DoNothingWorkItemHandler()); ksession.signalEvent("Yes", "YesValue", processInstance.getId()); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); ksession = restoreSession(ksession, true); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new DoNothingWorkItemHandler()); // No ksession.signalEvent("No", "NoValue", processInstance.getId()); } @Test(timeout=10000) public void testEventBasedSplit2() throws Exception { CountDownProcessEventListener countDownListener = new CountDownProcessEventListener("timer", 2); KieBase kbase = createKnowledgeBase("BPMN2-EventBasedSplit2.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.addEventListener(countDownListener); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); // Yes ProcessInstance processInstance = ksession.startProcess("com.sample.test"); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); ksession = restoreSession(ksession, true); ksession.addEventListener(countDownListener); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); ksession.signalEvent("Yes", "YesValue", processInstance.getId()); assertProcessInstanceCompleted(processInstance.getId(), ksession); ksession = restoreSession(ksession, true); ksession.addEventListener(countDownListener); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); ksession = restoreSession(ksession, true); ksession.addEventListener(countDownListener); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); // Timer processInstance = ksession.startProcess("com.sample.test"); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); countDownListener.waitTillCompleted(); ksession = restoreSession(ksession, true); ksession.addEventListener(countDownListener); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); assertProcessInstanceCompleted(processInstance.getId(), ksession); } @Test @Ignore("process does not complete") public void testEventBasedSplit3() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-EventBasedSplit3.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); Person jack = new Person(); jack.setName("Jack"); // Yes ProcessInstance processInstance = ksession.startProcess("com.sample.test"); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); ksession = restoreSession(ksession); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); ksession.signalEvent("Yes", "YesValue", processInstance.getId()); assertProcessInstanceCompleted(processInstance.getId(), ksession); // Condition processInstance = ksession.startProcess("com.sample.test"); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); ksession = restoreSession(ksession); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); ksession.insert(jack); assertProcessInstanceCompleted(processInstance.getId(), ksession); } @Test public void testEventBasedSplit4() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-EventBasedSplit4.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); // Yes ProcessInstance processInstance = ksession.startProcess("com.sample.test"); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); ksession = restoreSession(ksession, true); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); ksession.signalEvent("Message-YesMessage", "YesValue", processInstance.getId()); assertProcessInstanceCompleted(processInstance.getId(), ksession); ksession = restoreSession(ksession, true); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); // No processInstance = ksession.startProcess("com.sample.test"); ksession.signalEvent("Message-NoMessage", "NoValue", processInstance.getId()); assertProcessInstanceCompleted(processInstance.getId(), ksession); } @Test public void testEventBasedSplit5() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-EventBasedSplit5.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); ReceiveTaskHandler receiveTaskHandler = new ReceiveTaskHandler(ksession); ksession.getWorkItemManager().registerWorkItemHandler("Receive Task", receiveTaskHandler); // Yes ProcessInstance processInstance = ksession.startProcess("com.sample.test"); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); ksession = restoreSession(ksession, true); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); receiveTaskHandler.setKnowledgeRuntime(ksession); ksession.getWorkItemManager().registerWorkItemHandler("Receive Task", receiveTaskHandler); receiveTaskHandler.messageReceived("YesMessage", "YesValue"); assertProcessInstanceCompleted(processInstance.getId(), ksession); receiveTaskHandler.messageReceived("NoMessage", "NoValue"); ksession = restoreSession(ksession, true); ksession.getWorkItemManager().registerWorkItemHandler("Email1", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("Email2", new SystemOutWorkItemHandler()); receiveTaskHandler.setKnowledgeRuntime(ksession); ksession.getWorkItemManager().registerWorkItemHandler("Receive Task", receiveTaskHandler); // No processInstance = ksession.startProcess("com.sample.test"); receiveTaskHandler.messageReceived("NoMessage", "NoValue"); assertProcessInstanceCompleted(processInstance.getId(), ksession); receiveTaskHandler.messageReceived("YesMessage", "YesValue"); } @Test public void testCallActivity() throws Exception { KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); kbuilder.add(ResourceFactory.newClassPathResource("BPMN2-CallActivity.bpmn2"), ResourceType.BPMN2); kbuilder.add(ResourceFactory.newClassPathResource("BPMN2-CallActivitySubProcess.bpmn2"), ResourceType.BPMN2); if (!kbuilder.getErrors().isEmpty()) { for (KnowledgeBuilderError error : kbuilder.getErrors()) { logger.error("{}", error); } throw new IllegalArgumentException("Errors while parsing knowledge base"); } KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); kbase.addKnowledgePackages(kbuilder.getKnowledgePackages()); KieSession ksession = createKnowledgeSession(kbase); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", "oldValue"); ProcessInstance processInstance = ksession.startProcess("ParentProcess", params); assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED); assertEquals("new value", ((WorkflowProcessInstance) processInstance).getVariable("y")); } @Test public void testSubProcess() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-SubProcess.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ProcessInstance processInstance = ksession.startProcess("SubProcess"); assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED); } @Test public void testMultiInstanceLoopCharacteristicsProcess() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-MultiInstanceLoopCharacteristicsProcess.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); Map<String, Object> params = new HashMap<String, Object>(); List<String> myList = new ArrayList<String>(); myList.add("First Item"); myList.add("Second Item"); params.put("list", myList); ProcessInstance processInstance = ksession.startProcess("MultiInstanceLoopCharacteristicsProcess", params); assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED); } @Test public void testErrorBoundaryEvent() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-ErrorBoundaryEventInterrupting.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("MyTask", new DoNothingWorkItemHandler()); ProcessInstance processInstance = ksession.startProcess("ErrorBoundaryEvent"); assertProcessInstanceCompleted(processInstance.getId(), ksession); } @Test(timeout=10000) public void testTimerBoundaryEvent() throws Exception { CountDownProcessEventListener countDownListener = new CountDownProcessEventListener("TimerEvent", 1); KieBase kbase = createKnowledgeBase("BPMN2-TimerBoundaryEventDuration.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.addEventListener(countDownListener); ksession.getWorkItemManager().registerWorkItemHandler("MyTask", new DoNothingWorkItemHandler()); ProcessInstance processInstance = ksession.startProcess("TimerBoundaryEvent"); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); countDownListener.waitTillCompleted(); assertProcessInstanceCompleted(processInstance.getId(), ksession); } @Test(timeout=10000) public void testTimerBoundaryEventInterrupting() throws Exception { CountDownProcessEventListener countDownListener = new CountDownProcessEventListener("TimerEvent", 1); KieBase kbase = createKnowledgeBase("BPMN2-TimerBoundaryEventInterrupting.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.addEventListener(countDownListener); ksession.getWorkItemManager().registerWorkItemHandler("MyTask", new DoNothingWorkItemHandler()); ProcessInstance processInstance = ksession.startProcess("TimerBoundaryEvent"); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); countDownListener.waitTillCompleted(); assertProcessInstanceCompleted(processInstance.getId(), ksession); } @Test @Ignore("Process does not complete.") public void testAdHocSubProcess() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-AdHocSubProcess.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); ProcessInstance processInstance = ksession.startProcess("AdHocSubProcess"); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); WorkItem workItem = workItemHandler.getWorkItem(); assertNull(workItem); ksession = restoreSession(ksession); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); ksession.fireAllRules(); ksession.signalEvent("Hello2", null, processInstance.getId()); workItem = workItemHandler.getWorkItem(); assertNotNull(workItem); ksession = restoreSession(ksession); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); ksession.getWorkItemManager().completeWorkItem(workItem.getId(), null); assertProcessInstanceCompleted(processInstance.getId(), ksession); } @Test @Ignore("Process does not complete.") public void testAdHocSubProcessAutoComplete() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-AdHocSubProcessAutoComplete.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); ProcessInstance processInstance = ksession.startProcess("AdHocSubProcess"); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); WorkItem workItem = workItemHandler.getWorkItem(); assertNull(workItem); ksession = restoreSession(ksession); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); ksession.fireAllRules(); workItem = workItemHandler.getWorkItem(); assertNotNull("WorkItem should not be null.", workItem); ksession = restoreSession(ksession); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); ksession.getWorkItemManager().completeWorkItem(workItem.getId(), null); assertProcessInstanceCompleted(processInstance.getId(), ksession); } @Test public void testIntermediateCatchEventSignal() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-IntermediateCatchEventSignal.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", new SystemOutWorkItemHandler()); ProcessInstance processInstance = ksession.startProcess("IntermediateCatchEvent"); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); ksession = restoreSession(ksession, true); // now signal process instance ksession.signalEvent("MyMessage", "SomeValue", processInstance.getId()); assertProcessInstanceCompleted(processInstance.getId(), ksession); } @Test public void testIntermediateCatchEventMessage() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-IntermediateCatchEventMessage.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", new SystemOutWorkItemHandler()); ProcessInstance processInstance = ksession.startProcess("IntermediateCatchEvent"); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); ksession = restoreSession(ksession, true); // now signal process instance ksession.signalEvent("Message-HelloMessage", "SomeValue", processInstance.getId()); assertProcessInstanceCompleted(processInstance.getId(), ksession); } @Test(timeout=10000) public void testIntermediateCatchEventTimer() throws Exception { CountDownProcessEventListener countDownListener = new CountDownProcessEventListener("timer", 1); KieBase kbase = createKnowledgeBase("BPMN2-IntermediateCatchEventTimerDuration.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.addEventListener(countDownListener); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", new DoNothingWorkItemHandler()); ProcessInstance processInstance = ksession.startProcess("IntermediateCatchEvent"); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); // now wait for 1 second for timer to trigger countDownListener.waitTillCompleted(); ksession = restoreSession(ksession, true); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", new DoNothingWorkItemHandler()); assertProcessInstanceCompleted(processInstance.getId(), ksession); } @Test @Ignore("process does not complete") public void testIntermediateCatchEventCondition() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-IntermediateCatchEventCondition.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ProcessInstance processInstance = ksession.startProcess("IntermediateCatchEvent"); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); ksession = restoreSession(ksession); // now activate condition Person person = new Person(); person.setName("Jack"); ksession.insert(person); assertProcessInstanceCompleted(processInstance.getId(), ksession); } @Test public void testErrorEndEventProcess() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-ErrorEndEvent.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ProcessInstance processInstance = ksession.startProcess("ErrorEndEvent"); assertProcessInstanceAborted(processInstance.getId(), ksession); } @Test public void testServiceTask() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-ServiceProcess.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Service Task", new ServiceTaskHandler()); Map<String, Object> params = new HashMap<String, Object>(); params.put("s", "john"); WorkflowProcessInstance processInstance = (WorkflowProcessInstance) ksession.startProcess("ServiceProcess", params); assertProcessInstanceCompleted(processInstance.getId(), ksession); assertEquals("Hello john!", processInstance.getVariable("s")); } @Test public void testSendTask() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-SendTask.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Send Task", new SendTaskHandler()); Map<String, Object> params = new HashMap<String, Object>(); params.put("s", "john"); WorkflowProcessInstance processInstance = (WorkflowProcessInstance) ksession.startProcess("SendTask", params); assertProcessInstanceCompleted(processInstance.getId(), ksession); } @Test public void testReceiveTask() throws Exception { KieBase kbase = createKnowledgeBaseWithoutDumper("BPMN2-ReceiveTask.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ReceiveTaskHandler receiveTaskHandler = new ReceiveTaskHandler(ksession); ksession.getWorkItemManager().registerWorkItemHandler("Receive Task", receiveTaskHandler); WorkflowProcessInstance processInstance = (WorkflowProcessInstance) ksession.startProcess("ReceiveTask"); assertEquals(ProcessInstance.STATE_ACTIVE, processInstance.getState()); ksession = restoreSession(ksession); receiveTaskHandler.messageReceived("HelloMessage", "Hello john!"); assertProcessInstanceCompleted(processInstance.getId(), ksession); } @Test @Ignore("bpmn does not compile") public void testConditionalStart() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-ConditionalStart.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); Person person = new Person(); person.setName("jack"); ksession.insert(person); ksession.fireAllRules(); person = new Person(); person.setName("john"); ksession.insert(person); ksession.fireAllRules(); } @Test(timeout=10000) public void testTimerStart() throws Exception { CountDownProcessEventListener countDownListener = new CountDownProcessEventListener("StartProcess", 5); KieBase kbase = createKnowledgeBase("BPMN2-TimerStart.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.addEventListener(countDownListener); final List<Long> list = new ArrayList<Long>(); ksession.addEventListener(new DefaultProcessEventListener() { public void beforeProcessStarted(ProcessStartedEvent event) { list.add(event.getProcessInstance().getId()); } }); assertEquals(0, list.size()); countDownListener.waitTillCompleted(); assertEquals(5, list.size()); } @Test public void testSignalStart() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-SignalStart.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); final List<Long> list = new ArrayList<Long>(); ksession.addEventListener(new DefaultProcessEventListener() { public void afterProcessStarted(ProcessStartedEvent event) { list.add(event.getProcessInstance().getId()); } }); ksession.signalEvent("MySignal", "NewValue"); assertEquals(1, list.size()); } @Test public void testSignalEnd() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-SignalEndEvent.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", "MyValue"); ksession.startProcess("SignalEndEvent", params); } @Test public void testMessageStart() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-MessageStart.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); final List<Long> list = new ArrayList<Long>(); ksession.addEventListener(new DefaultProcessEventListener() { public void afterProcessStarted(ProcessStartedEvent event) { list.add(event.getProcessInstance().getId()); } }); ksession.signalEvent("Message-HelloMessage", "NewValue"); assertEquals(1, list.size()); } @Test public void testMessageEnd() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-MessageEndEvent.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Send Task", new SendTaskHandler()); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", "MyValue"); ProcessInstance processInstance = ksession.startProcess("MessageEndEvent", params); assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState()); } @Test public void testMessageIntermediateThrow() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-IntermediateThrowEventMessage.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Send Task", new SendTaskHandler()); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", "MyValue"); ProcessInstance processInstance = ksession.startProcess("MessageIntermediateEvent", params); assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState()); } @Test public void testSignalIntermediateThrow() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-IntermediateThrowEventSignal.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", "MyValue"); ProcessInstance processInstance = ksession.startProcess("SignalIntermediateEvent", params); assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState()); } @Test public void testNoneIntermediateThrow() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-IntermediateThrowEventNone.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ProcessInstance processInstance = ksession.startProcess("NoneIntermediateEvent", null); assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState()); } @Test public void testErrorSignallingExceptionServiceTask() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-ExceptionServiceProcess-ErrorSignalling.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); runTestErrorSignallingExceptionServiceTask(ksession); } public static void runTestErrorSignallingExceptionServiceTask(KieSession ksession) throws Exception { // Setup String eventType = "Error-code"; SignallingTaskHandlerDecorator signallingTaskWrapper = new SignallingTaskHandlerDecorator(ServiceTaskHandler.class, eventType); signallingTaskWrapper.setWorkItemExceptionParameterName(ExceptionService.exceptionParameterName); ksession.getWorkItemManager().registerWorkItemHandler("Service Task", signallingTaskWrapper); Object [] caughtEventObjectHolder = new Object[1]; caughtEventObjectHolder[0] = null; ExceptionService.setCaughtEventObjectHolder(caughtEventObjectHolder); TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); // Start process Map<String, Object> params = new HashMap<String, Object>(); String input = "this is my service input"; params.put("serviceInputItem", input ); ProcessInstance processInstance = ksession.startProcess("ServiceProcess", params); assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE); WorkItem workItem = workItemHandler.getWorkItem(); assertNotNull(workItem); ksession.getWorkItemManager().completeWorkItem(workItem.getId(), null); // Check that event was passed to Event SubProcess (and grabbed by WorkItemHandler); assertTrue( "Event was not passed to Event Subprocess", caughtEventObjectHolder[0] != null && caughtEventObjectHolder[0] instanceof WorkItem ); workItem = (WorkItem) caughtEventObjectHolder[0]; Object throwObj = workItem.getParameter(ExceptionService.exceptionParameterName); assertTrue( "WorkItem doesn't contain Throwable", throwObj instanceof Throwable ); assertTrue("Exception message does not match service input.", ((Throwable) throwObj).getMessage().endsWith(input) ); // Complete process processInstance = ksession.getProcessInstance(processInstance.getId()); assertTrue( "Process instance has not been aborted.", processInstance == null || processInstance.getState() == ProcessInstance.STATE_ABORTED ); } @Test public void testSignallingExceptionServiceTask() throws Exception { // dump/reread functionality seems to work for this test // .. but I'm pretty sure that's more coincidence than design (mriet, 2013-03-06) KieBase kbase = createKnowledgeBase("BPMN2-ExceptionServiceProcess-Signalling.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); runTestSignallingExceptionServiceTask(ksession); } @Test public void testXXEProcessVulnerability() throws Exception { Resource processResource = ResourceFactory.newClassPathResource("xxe-protection/BPMN2-XXE-Process.bpmn2"); File dtdFile = new File("src/test/resources/xxe-protection/external.dtd"); assertTrue(dtdFile.exists()); String dtdContent = IoUtils.readFileAsString(dtdFile); dtdContent = dtdContent.replaceAll("@@PATH@@", dtdFile.getParentFile().getAbsolutePath()); IoUtils.write(dtdFile, dtdContent.getBytes("UTF-8")); byte[] data = IoUtils.readBytesFromInputStream(processResource.getInputStream()); String processAsString = new String(data, "UTF-8"); // replace place holders with actual paths File testFiles = new File("src/test/resources/xxe-protection"); assertTrue(testFiles.exists()); String path = testFiles.getAbsolutePath(); processAsString = processAsString.replaceAll("@@PATH@@", path); Resource resource = ResourceFactory.newReaderResource(new StringReader(processAsString)); resource.setSourcePath(processResource.getSourcePath()); resource.setTargetPath(processResource.getTargetPath()); KieBase kbase = createKnowledgeBaseFromResources(resource); KieSession ksession = createKnowledgeSession(kbase); ProcessInstance processInstance = ksession.startProcess("async-examples.bp1"); String var1 = getProcessVarValue(processInstance, "testScript1"); String var2 = getProcessVarValue(processInstance, "testScript2"); assertNull(var1); assertNull(var2); assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED); } public static void runTestSignallingExceptionServiceTask(KieSession ksession) throws Exception { // Setup String eventType = "exception-signal"; SignallingTaskHandlerDecorator signallingTaskWrapper = new SignallingTaskHandlerDecorator(ServiceTaskHandler.class, eventType); signallingTaskWrapper.setWorkItemExceptionParameterName(ExceptionService.exceptionParameterName); ksession.getWorkItemManager().registerWorkItemHandler("Service Task", signallingTaskWrapper); Object [] caughtEventObjectHolder = new Object[1]; caughtEventObjectHolder[0] = null; ExceptionService.setCaughtEventObjectHolder(caughtEventObjectHolder); // Start process Map<String, Object> params = new HashMap<String, Object>(); String input = "this is my service input"; params.put("serviceInputItem", input ); ProcessInstance processInstance = ksession.startProcess("ServiceProcess", params); // Check that event was passed to Event SubProcess (and grabbed by WorkItemHandler); assertTrue( "Event was not passed to Event Subprocess", caughtEventObjectHolder[0] != null && caughtEventObjectHolder[0] instanceof WorkItem ); WorkItem workItem = (WorkItem) caughtEventObjectHolder[0]; Object throwObj = workItem.getParameter(ExceptionService.exceptionParameterName); assertTrue( "WorkItem doesn't contain Throwable", throwObj instanceof Throwable ); assertTrue("Exception message does not match service input.", ((Throwable) throwObj).getMessage().endsWith(input) ); // Complete process assertEquals( "Process instance is not active.", ProcessInstance.STATE_ACTIVE, processInstance.getState() ); ksession.getWorkItemManager().completeWorkItem(workItem.getId(), null); processInstance = ksession.getProcessInstance(processInstance.getId()); if( processInstance != null ) { assertEquals( "Process instance is not completed.", ProcessInstance.STATE_COMPLETED, processInstance.getState() ); } // otherwise, persistence use => processInstance == null => process is completed } }