/* Copyright 2013 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 org.drools.core.command.impl.ExecutableCommand; import org.drools.core.command.impl.RegistryContext; import org.jbpm.bpmn2.objects.TestWorkItemHandler; import org.jbpm.process.core.context.variable.VariableScope; import org.jbpm.process.instance.context.variable.VariableScopeInstance; import org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler; import org.jbpm.test.util.CountDownProcessEventListener; import org.jbpm.workflow.instance.impl.NodeInstanceImpl; import org.jbpm.workflow.instance.impl.WorkflowProcessInstanceImpl; import org.jbpm.workflow.instance.node.CompositeContextNodeInstance; import org.jbpm.workflow.instance.node.ForEachNodeInstance; import org.jbpm.workflow.instance.node.ForEachNodeInstance.ForEachJoinNodeInstance; import org.junit.After; import org.junit.BeforeClass; 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.ProcessNodeTriggeredEvent; import org.kie.api.event.process.ProcessStartedEvent; import org.kie.api.runtime.KieSession; import org.kie.api.runtime.process.NodeInstance; import org.kie.api.runtime.process.ProcessInstance; import org.kie.api.runtime.process.WorkItem; import org.kie.api.runtime.process.WorkItemManager; import org.kie.api.runtime.process.WorkflowProcessInstance; import org.kie.api.runtime.Context; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import javax.xml.parsers.DocumentBuilderFactory; import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @RunWith(Parameterized.class) public class FlowTest extends JbpmBpmn2TestCase { @Parameters public static Collection<Object[]> persistence() { Object[][] data = new Object[][] { { false }, { true } }; return Arrays.asList(data); }; private static final Logger logger = LoggerFactory.getLogger(FlowTest.class); private KieSession ksession; public FlowTest(boolean persistence) { super(persistence); } @BeforeClass public static void setup() throws Exception { setUpDataSource(); VariableScope.setVariableStrictOption(true); } @After public void dispose() { if (ksession != null) { ksession.dispose(); ksession = null; } } @After public void clearProperties() { System.clearProperty("jbpm.enable.multi.con"); } @Test public void testExclusiveSplitWithNoConditions() throws Exception { try { createKnowledgeBaseWithoutDumper("BPMN2-ExclusiveGatewayWithNoConditionsDefined.bpmn2"); fail("Should fail as XOR gateway does not have conditions defined"); } catch (RuntimeException e) { assertTrue(e.getMessage().indexOf("does not have a constraint for Connection") != -1); } } @Test public void testExclusiveSplit() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-ExclusiveSplit.bpmn2"); 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); assertProcessInstanceCompleted(processInstance); } @Test public void testExclusiveSplitXPathAdvanced() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-ExclusiveSplitXPath-advanced.bpmn2"); ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Email", new SystemOutWorkItemHandler()); Map<String, Object> params = new HashMap<String, Object>(); Document doc = DocumentBuilderFactory.newInstance() .newDocumentBuilder().newDocument(); Element hi = doc.createElement("hi"); Element ho = doc.createElement("ho"); hi.appendChild(ho); Attr attr = doc.createAttribute("value"); ho.setAttributeNode(attr); attr.setValue("a"); params.put("x", hi); params.put("y", "Second"); ProcessInstance processInstance = ksession.startProcess( "com.sample.test", params); assertProcessInstanceCompleted(processInstance); } @Test public void testExclusiveSplitXPathAdvanced2() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-ExclusiveSplitXPath-advanced-vars-not-signaled.bpmn2"); ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Email", new SystemOutWorkItemHandler()); Map<String, Object> params = new HashMap<String, Object>(); Document doc = DocumentBuilderFactory.newInstance() .newDocumentBuilder().newDocument(); Element hi = doc.createElement("hi"); Element ho = doc.createElement("ho"); hi.appendChild(ho); Attr attr = doc.createAttribute("value"); ho.setAttributeNode(attr); attr.setValue("a"); params.put("x", hi); params.put("y", "Second"); ProcessInstance processInstance = ksession.startProcess( "com.sample.test", params); assertProcessInstanceCompleted(processInstance); } @Test public void testExclusiveSplitXPathAdvancedWithVars() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-ExclusiveSplitXPath-advanced-with-vars.bpmn2"); ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Email", new SystemOutWorkItemHandler()); Map<String, Object> params = new HashMap<String, Object>(); Document doc = DocumentBuilderFactory.newInstance() .newDocumentBuilder().newDocument(); Element hi = doc.createElement("hi"); Element ho = doc.createElement("ho"); hi.appendChild(ho); Attr attr = doc.createAttribute("value"); ho.setAttributeNode(attr); attr.setValue("a"); params.put("x", hi); params.put("y", "Second"); ProcessInstance processInstance = ksession.startProcess( "com.sample.test", params); assertProcessInstanceCompleted(processInstance); } @Test public void testExclusiveSplitPriority() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-ExclusiveSplitPriority.bpmn2"); 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); assertProcessInstanceCompleted(processInstance); } @Test public void testExclusiveSplitDefault() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-ExclusiveSplitDefault.bpmn2"); 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); assertProcessInstanceCompleted(processInstance); } @Test public void testExclusiveXORGateway() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-gatewayTest.bpmn2"); ksession = createKnowledgeSession(kbase); Document document = DocumentBuilderFactory .newInstance() .newDocumentBuilder() .parse(new ByteArrayInputStream( "<instanceMetadata><user approved=\"false\" /></instanceMetadata>" .getBytes())); Map<String, Object> params = new HashMap<String, Object>(); params.put("instanceMetadata", document); params.put( "startMessage", DocumentBuilderFactory .newInstance() .newDocumentBuilder() .parse(new ByteArrayInputStream( "<task subject='foobar2'/>".getBytes())) .getFirstChild()); ProcessInstance processInstance = ksession.startProcess("process", params); assertProcessInstanceCompleted(processInstance); } @Test public void testInclusiveSplit() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-InclusiveSplit.bpmn2"); ksession = createKnowledgeSession(kbase); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", 15); ProcessInstance processInstance = ksession.startProcess( "com.sample.test", params); assertProcessInstanceCompleted(processInstance); } @Test public void testInclusiveSplitDefaultConnection() throws Exception { KieBase kbase = createKnowledgeBaseWithoutDumper("BPMN2-InclusiveGatewayWithDefault.bpmn2"); ksession = createKnowledgeSession(kbase); Map<String, Object> params = new HashMap<String, Object>(); params.put("test", "c"); ProcessInstance processInstance = ksession.startProcess("InclusiveGatewayWithDefault", params); assertProcessInstanceCompleted(processInstance); } @Test public void testInclusiveSplitAndJoin() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-InclusiveSplitAndJoin.bpmn2"); ksession = createKnowledgeSession(kbase); TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", 15); ProcessInstance processInstance = ksession.startProcess( "com.sample.test", params); List<WorkItem> activeWorkItems = workItemHandler.getWorkItems(); assertEquals(2, activeWorkItems.size()); ksession = restoreSession(ksession, true); for (WorkItem wi : activeWorkItems) { ksession.getWorkItemManager().completeWorkItem(wi.getId(), null); } assertProcessInstanceFinished(processInstance, ksession); } @Test public void testInclusiveSplitAndJoinLoop() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-InclusiveSplitAndJoinLoop.bpmn2"); ksession = createKnowledgeSession(kbase); TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", 21); ProcessInstance processInstance = ksession.startProcess( "com.sample.test", params); List<WorkItem> activeWorkItems = workItemHandler.getWorkItems(); assertEquals(3, activeWorkItems.size()); ksession = restoreSession(ksession, true); for (WorkItem wi : activeWorkItems) { ksession.getWorkItemManager().completeWorkItem(wi.getId(), null); } assertProcessInstanceFinished(processInstance, ksession); } @Test public void testInclusiveSplitAndJoinLoop2() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-InclusiveSplitAndJoinLoop2.bpmn2"); ksession = createKnowledgeSession(kbase); TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", 21); ProcessInstance processInstance = ksession.startProcess( "com.sample.test", params); List<WorkItem> activeWorkItems = workItemHandler.getWorkItems(); assertEquals(3, activeWorkItems.size()); ksession = restoreSession(ksession, true); for (WorkItem wi : activeWorkItems) { ksession.getWorkItemManager().completeWorkItem(wi.getId(), null); } assertProcessInstanceFinished(processInstance, ksession); } @Test public void testInclusiveSplitAndJoinNested() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-InclusiveSplitAndJoinNested.bpmn2"); ksession = createKnowledgeSession(kbase); TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", 15); ProcessInstance processInstance = ksession.startProcess( "com.sample.test", params); List<WorkItem> activeWorkItems = workItemHandler.getWorkItems(); assertEquals(2, activeWorkItems.size()); ksession = restoreSession(ksession, true); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); for (WorkItem wi : activeWorkItems) { ksession.getWorkItemManager().completeWorkItem(wi.getId(), null); } activeWorkItems = workItemHandler.getWorkItems(); assertEquals(2, activeWorkItems.size()); ksession = restoreSession(ksession, true); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); for (WorkItem wi : activeWorkItems) { ksession.getWorkItemManager().completeWorkItem(wi.getId(), null); } assertProcessInstanceFinished(processInstance, ksession); } @Test public void testInclusiveSplitAndJoinEmbedded() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-InclusiveSplitAndJoinEmbedded.bpmn2"); ksession = createKnowledgeSession(kbase); TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", 15); ProcessInstance processInstance = ksession.startProcess( "com.sample.test", params); List<WorkItem> activeWorkItems = workItemHandler.getWorkItems(); assertEquals(2, activeWorkItems.size()); ksession = restoreSession(ksession, true); for (WorkItem wi : activeWorkItems) { ksession.getWorkItemManager().completeWorkItem(wi.getId(), null); } assertProcessInstanceFinished(processInstance, ksession); } @Test public void testInclusiveSplitAndJoinWithParallel() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-InclusiveSplitAndJoinWithParallel.bpmn2"); ksession = createKnowledgeSession(kbase); TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", 25); ProcessInstance processInstance = ksession.startProcess( "com.sample.test", params); List<WorkItem> activeWorkItems = workItemHandler.getWorkItems(); assertEquals(4, activeWorkItems.size()); ksession = restoreSession(ksession, true); for (WorkItem wi : activeWorkItems) { ksession.getWorkItemManager().completeWorkItem(wi.getId(), null); } assertProcessInstanceFinished(processInstance, ksession); } @Test public void testInclusiveSplitAndJoinWithEnd() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-InclusiveSplitAndJoinWithEnd.bpmn2"); ksession = createKnowledgeSession(kbase); TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", 25); ProcessInstance processInstance = ksession.startProcess( "com.sample.test", params); List<WorkItem> activeWorkItems = workItemHandler.getWorkItems(); assertEquals(3, activeWorkItems.size()); ksession = restoreSession(ksession, true); for (int i = 0; i < 2; i++) { ksession.getWorkItemManager().completeWorkItem( activeWorkItems.get(i).getId(), null); } assertProcessInstanceActive(processInstance); ksession.getWorkItemManager().completeWorkItem( activeWorkItems.get(2).getId(), null); assertProcessInstanceFinished(processInstance, ksession); } @Test(timeout=10000) public void testInclusiveSplitAndJoinWithTimer() throws Exception { CountDownProcessEventListener countDownListener = new CountDownProcessEventListener("timer", 2); KieBase kbase = createKnowledgeBase("BPMN2-InclusiveSplitAndJoinWithTimer.bpmn2"); ksession = createKnowledgeSession(kbase); ksession.addEventListener(countDownListener); TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", 15); ProcessInstance processInstance = ksession.startProcess( "com.sample.test", params); List<WorkItem> activeWorkItems = workItemHandler.getWorkItems(); assertEquals(1, activeWorkItems.size()); ksession.getWorkItemManager().completeWorkItem( activeWorkItems.get(0).getId(), null); countDownListener.waitTillCompleted(); assertProcessInstanceActive(processInstance); activeWorkItems = workItemHandler.getWorkItems(); assertEquals(2, activeWorkItems.size()); ksession.getWorkItemManager().completeWorkItem( activeWorkItems.get(0).getId(), null); assertProcessInstanceActive(processInstance); ksession.getWorkItemManager().completeWorkItem( activeWorkItems.get(1).getId(), null); assertProcessInstanceFinished(processInstance, ksession); } @Test public void testInclusiveSplitAndJoinExtraPath() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-InclusiveSplitAndJoinExtraPath.bpmn2"); ksession = createKnowledgeSession(kbase); TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", 25); ProcessInstance processInstance = ksession.startProcess( "com.sample.test", params); ksession.signalEvent("signal", null); List<WorkItem> activeWorkItems = workItemHandler.getWorkItems(); assertEquals(4, activeWorkItems.size()); ksession = restoreSession(ksession, true); for (int i = 0; i < 3; i++) { ksession.getWorkItemManager().completeWorkItem( activeWorkItems.get(i).getId(), null); } assertProcessInstanceActive(processInstance); ksession.getWorkItemManager().completeWorkItem( activeWorkItems.get(3).getId(), null); assertProcessInstanceFinished(processInstance, ksession); } @Test public void testInclusiveSplitDefault() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-InclusiveSplitDefault.bpmn2"); ksession = createKnowledgeSession(kbase); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", -5); ProcessInstance processInstance = ksession.startProcess( "com.sample.test", params); assertProcessInstanceCompleted(processInstance); } @Test public void testInclusiveParallelExclusiveSplitNoLoop() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-InclusiveNestedInParallelNestedInExclusive.bpmn2"); ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("testWI", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("testWI2", new SystemOutWorkItemHandler() { @Override public void executeWorkItem(WorkItem workItem, WorkItemManager manager) { Integer x = (Integer) workItem.getParameter("input1"); x++; Map<String, Object> results = new HashMap<String, Object>(); results.put("output1", x); manager.completeWorkItem(workItem.getId(), results); } }); final Map<String, Integer> nodeInstanceExecutionCounter = new HashMap<String, Integer>(); ksession.addEventListener(new DefaultProcessEventListener(){ @Override public void beforeNodeTriggered(ProcessNodeTriggeredEvent event) { logger.info(event.getNodeInstance().getNodeName()); Integer value = nodeInstanceExecutionCounter.get(event.getNodeInstance().getNodeName()); if (value == null) { value = new Integer(0); } value++; nodeInstanceExecutionCounter.put(event.getNodeInstance().getNodeName(), value); } }); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", 0); ProcessInstance processInstance = ksession.startProcess("Process_1", params); assertProcessInstanceCompleted(processInstance); assertEquals(12, nodeInstanceExecutionCounter.size()); assertEquals(1, (int)nodeInstanceExecutionCounter.get("Start")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("XORGateway-converging")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("ANDGateway-diverging")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("ORGateway-diverging")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("testWI3")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("testWI2")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("ORGateway-converging")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("Script")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("XORGateway-diverging")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("ANDGateway-converging")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("testWI6")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("End")); } @Test public void testInclusiveParallelExclusiveSplitLoop() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-InclusiveNestedInParallelNestedInExclusive.bpmn2"); ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("testWI", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("testWI2", new SystemOutWorkItemHandler() { @Override public void executeWorkItem(WorkItem workItem, WorkItemManager manager) { Integer x = (Integer) workItem.getParameter("input1"); x++; Map<String, Object> results = new HashMap<String, Object>(); results.put("output1", x); manager.completeWorkItem(workItem.getId(), results); } }); final Map<String, Integer> nodeInstanceExecutionCounter = new HashMap<String, Integer>(); ksession.addEventListener(new DefaultProcessEventListener(){ @Override public void beforeNodeTriggered(ProcessNodeTriggeredEvent event) { Integer value = nodeInstanceExecutionCounter.get(event.getNodeInstance().getNodeName()); if (value == null) { value = new Integer(0); } value++; nodeInstanceExecutionCounter.put(event.getNodeInstance().getNodeName(), value); } }); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", -1); ProcessInstance processInstance = ksession.startProcess("Process_1", params); assertProcessInstanceCompleted(processInstance); assertEquals(12, nodeInstanceExecutionCounter.size()); assertEquals(1, (int)nodeInstanceExecutionCounter.get("Start")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("XORGateway-converging")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("ANDGateway-diverging")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("ORGateway-diverging")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("testWI3")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("testWI2")); assertEquals(4, (int)nodeInstanceExecutionCounter.get("ORGateway-converging")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("Script")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("XORGateway-diverging")); assertEquals(4, (int)nodeInstanceExecutionCounter.get("ANDGateway-converging")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("testWI6")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("End")); } @Test public void testInclusiveParallelExclusiveSplitNoLoopAsync() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-InclusiveNestedInParallelNestedInExclusive.bpmn2"); ksession = createKnowledgeSession(kbase); TestWorkItemHandler handler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("testWI", handler); ksession.getWorkItemManager().registerWorkItemHandler("testWI2", new SystemOutWorkItemHandler() { @Override public void executeWorkItem(WorkItem workItem, WorkItemManager manager) { Integer x = (Integer) workItem.getParameter("input1"); x++; Map<String, Object> results = new HashMap<String, Object>(); results.put("output1", x); manager.completeWorkItem(workItem.getId(), results); } }); final Map<String, Integer> nodeInstanceExecutionCounter = new HashMap<String, Integer>(); ksession.addEventListener(new DefaultProcessEventListener(){ @Override public void beforeNodeTriggered(ProcessNodeTriggeredEvent event) { Integer value = nodeInstanceExecutionCounter.get(event.getNodeInstance().getNodeName()); if (value == null) { value = new Integer(0); } value++; nodeInstanceExecutionCounter.put(event.getNodeInstance().getNodeName(), value); } }); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", 0); ProcessInstance processInstance = ksession.startProcess("Process_1", params); assertProcessInstanceActive(processInstance); List<WorkItem> workItems = handler.getWorkItems(); assertNotNull(workItems); assertEquals(2, workItems.size()); // complete work items within OR gateway for (WorkItem workItem : workItems) { ksession.getWorkItemManager().completeWorkItem(workItem.getId(), null); } assertProcessInstanceActive(processInstance); workItems = handler.getWorkItems(); assertNotNull(workItems); assertEquals(1, workItems.size()); // complete last workitem after AND gateway for (WorkItem workItem : workItems) { ksession.getWorkItemManager().completeWorkItem(workItem.getId(), null); } assertProcessInstanceCompleted(processInstance); assertEquals(12, nodeInstanceExecutionCounter.size()); assertEquals(1, (int)nodeInstanceExecutionCounter.get("Start")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("XORGateway-converging")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("ANDGateway-diverging")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("ORGateway-diverging")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("testWI3")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("testWI2")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("ORGateway-converging")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("Script")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("XORGateway-diverging")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("ANDGateway-converging")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("testWI6")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("End")); } @Test public void testInclusiveParallelExclusiveSplitLoopAsync() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-InclusiveNestedInParallelNestedInExclusive.bpmn2"); ksession = createKnowledgeSession(kbase); TestWorkItemHandler handler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("testWI", handler); ksession.getWorkItemManager().registerWorkItemHandler("testWI2", new SystemOutWorkItemHandler() { @Override public void executeWorkItem(WorkItem workItem, WorkItemManager manager) { Integer x = (Integer) workItem.getParameter("input1"); x++; Map<String, Object> results = new HashMap<String, Object>(); results.put("output1", x); manager.completeWorkItem(workItem.getId(), results); } }); final Map<String, Integer> nodeInstanceExecutionCounter = new HashMap<String, Integer>(); ksession.addEventListener(new DefaultProcessEventListener(){ @Override public void beforeNodeTriggered(ProcessNodeTriggeredEvent event) { Integer value = nodeInstanceExecutionCounter.get(event.getNodeInstance().getNodeName()); if (value == null) { value = new Integer(0); } value++; nodeInstanceExecutionCounter.put(event.getNodeInstance().getNodeName(), value); } }); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", -1); ProcessInstance processInstance = ksession.startProcess("Process_1", params); assertProcessInstanceActive(processInstance); List<WorkItem> workItems = handler.getWorkItems(); assertNotNull(workItems); assertEquals(2, workItems.size()); // complete work items within OR gateway for (WorkItem workItem : workItems) { ksession.getWorkItemManager().completeWorkItem(workItem.getId(), null); } assertProcessInstanceActive(processInstance); workItems = handler.getWorkItems(); assertNotNull(workItems); assertEquals(2, workItems.size()); // complete work items within OR gateway for (WorkItem workItem : workItems) { ksession.getWorkItemManager().completeWorkItem(workItem.getId(), null); } assertProcessInstanceActive(processInstance); workItems = handler.getWorkItems(); assertNotNull(workItems); assertEquals(1, workItems.size()); // complete last workitem after AND gateway for (WorkItem workItem : workItems) { ksession.getWorkItemManager().completeWorkItem(workItem.getId(), null); } assertProcessInstanceCompleted(processInstance); assertEquals(12, nodeInstanceExecutionCounter.size()); assertEquals(1, (int)nodeInstanceExecutionCounter.get("Start")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("XORGateway-converging")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("ANDGateway-diverging")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("ORGateway-diverging")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("testWI3")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("testWI2")); assertEquals(4, (int)nodeInstanceExecutionCounter.get("ORGateway-converging")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("Script")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("XORGateway-diverging")); assertEquals(4, (int)nodeInstanceExecutionCounter.get("ANDGateway-converging")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("testWI6")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("End")); } @Test public void testInclusiveSplitNested() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-InclusiveGatewayNested.bpmn2"); ksession = createKnowledgeSession(kbase); TestWorkItemHandler handler = new TestWorkItemHandler(); TestWorkItemHandler handler2 = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("testWI", handler); ksession.getWorkItemManager().registerWorkItemHandler("testWI2", handler2); Map<String, Object> params = new HashMap<String, Object>(); ProcessInstance processInstance = ksession.startProcess("Process_1", params); assertProcessInstanceActive(processInstance); ksession.getWorkItemManager().completeWorkItem(handler.getWorkItem().getId(), null); ksession.getWorkItemManager().completeWorkItem(handler2.getWorkItem().getId(), null); assertProcessInstanceActive(processInstance); List<WorkItem> workItems = handler.getWorkItems(); assertNotNull(workItems); assertEquals(2, workItems.size()); for (WorkItem wi : workItems) { assertProcessInstanceActive(processInstance); ksession.getWorkItemManager().completeWorkItem(wi.getId(), null); } assertProcessInstanceActive(processInstance); ksession.getWorkItemManager().completeWorkItem(handler.getWorkItem().getId(), null); assertProcessInstanceCompleted(processInstance); } @Test public void testInclusiveSplitWithLoopInside() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-InclusiveGatewayWithLoopInside.bpmn2"); ksession = createKnowledgeSession(kbase); final Map<String, Integer> nodeInstanceExecutionCounter = new HashMap<String, Integer>(); ksession.addEventListener(new DefaultProcessEventListener(){ @Override public void beforeNodeTriggered(ProcessNodeTriggeredEvent event) { logger.info("{} {}", event.getNodeInstance().getNodeName(), ((NodeInstanceImpl) event.getNodeInstance()).getLevel()); Integer value = nodeInstanceExecutionCounter.get(event.getNodeInstance().getNodeName()); if (value == null) { value = new Integer(0); } value++; nodeInstanceExecutionCounter.put(event.getNodeInstance().getNodeName(), value); } }); TestWorkItemHandler handler = new TestWorkItemHandler(); TestWorkItemHandler handler2 = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("testWI", handler); ksession.getWorkItemManager().registerWorkItemHandler("testWI2", handler2); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", -1); ProcessInstance processInstance = ksession.startProcess("Process_1", params); assertProcessInstanceActive(processInstance); List<WorkItem> workItems = handler.getWorkItems(); assertNotNull(workItems); assertEquals(2, workItems.size()); for (WorkItem wi : workItems) { assertProcessInstanceActive(processInstance); ksession.getWorkItemManager().completeWorkItem(wi.getId(), null); } assertProcessInstanceActive(processInstance); ksession.getWorkItemManager().completeWorkItem(handler2.getWorkItem().getId(), null); assertProcessInstanceActive(processInstance); ksession.getWorkItemManager().completeWorkItem(handler2.getWorkItem().getId(), null); assertProcessInstanceActive(processInstance); ksession.getWorkItemManager().completeWorkItem(handler.getWorkItem().getId(), null); assertProcessInstanceCompleted(processInstance); assertEquals(10, nodeInstanceExecutionCounter.size()); assertEquals(1, (int)nodeInstanceExecutionCounter.get("Start")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("OR diverging")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("tareaWorkflow3")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("tareaWorkflow2")); assertEquals(3, (int)nodeInstanceExecutionCounter.get("OR converging")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("tareaWorkflow6")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("Script")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("XOR diverging")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("XOR converging")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("End")); } @Test public void testInclusiveSplitWithLoopInsideSubprocess() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-InclusiveGatewayWithLoopInsideSubprocess.bpmn2"); ksession = createKnowledgeSession(kbase); final Map<String, Integer> nodeInstanceExecutionCounter = new HashMap<String, Integer>(); ksession.addEventListener(new DefaultProcessEventListener(){ @Override public void beforeNodeTriggered(ProcessNodeTriggeredEvent event) { logger.info("{} {}", event.getNodeInstance().getNodeName(), ((NodeInstanceImpl) event.getNodeInstance()).getLevel()); Integer value = nodeInstanceExecutionCounter.get(event.getNodeInstance().getNodeName()); if (value == null) { value = new Integer(0); } value++; nodeInstanceExecutionCounter.put(event.getNodeInstance().getNodeName(), value); } }); TestWorkItemHandler handler = new TestWorkItemHandler(); TestWorkItemHandler handler2 = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("testWI", handler); ksession.getWorkItemManager().registerWorkItemHandler("testWI2", handler2); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", -1); ProcessInstance processInstance = ksession.startProcess("Process_1", params); assertProcessInstanceActive(processInstance); List<WorkItem> workItems = handler.getWorkItems(); assertNotNull(workItems); assertEquals(2, workItems.size()); for (WorkItem wi : workItems) { assertProcessInstanceActive(processInstance); ksession.getWorkItemManager().completeWorkItem(wi.getId(), null); } assertProcessInstanceActive(processInstance); ksession.getWorkItemManager().completeWorkItem(handler2.getWorkItem().getId(), null); assertProcessInstanceActive(processInstance); ksession.getWorkItemManager().completeWorkItem(handler2.getWorkItem().getId(), null); assertProcessInstanceActive(processInstance); ksession.getWorkItemManager().completeWorkItem(handler.getWorkItem().getId(), null); assertProcessInstanceCompleted(processInstance); assertEquals(13, nodeInstanceExecutionCounter.size()); assertEquals(1, (int)nodeInstanceExecutionCounter.get("Start")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("Sub Process 1")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("sb-start")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("sb-end")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("OR diverging")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("tareaWorkflow3")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("tareaWorkflow2")); assertEquals(3, (int)nodeInstanceExecutionCounter.get("OR converging")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("tareaWorkflow6")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("Script")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("XOR diverging")); assertEquals(2, (int)nodeInstanceExecutionCounter.get("XOR converging")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("End")); } @Test public void testMultiInstanceLoopCharacteristicsProcessWithORGateway() throws Exception { KieBase kbase = createKnowledgeBaseWithoutDumper("BPMN2-MultiInstanceLoopCharacteristicsProcessWithORgateway.bpmn2"); ksession = createKnowledgeSession(kbase); TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler); Map<String, Object> params = new HashMap<String, Object>(); List<Integer> myList = new ArrayList<Integer>(); myList.add(12); myList.add(15); params.put("list", myList); ProcessInstance processInstance = ksession.startProcess( "MultiInstanceLoopCharacteristicsProcess", params); List<WorkItem> workItems = workItemHandler.getWorkItems(); assertEquals(4, workItems.size()); Collection<NodeInstance> nodeInstances = ((WorkflowProcessInstanceImpl) processInstance) .getNodeInstances(); assertEquals(1, nodeInstances.size()); NodeInstance nodeInstance = nodeInstances.iterator().next(); assertTrue(nodeInstance instanceof ForEachNodeInstance); Collection<NodeInstance> nodeInstancesChild = ((ForEachNodeInstance) nodeInstance) .getNodeInstances(); assertEquals(2, nodeInstancesChild.size()); for (NodeInstance child : nodeInstancesChild) { assertTrue(child instanceof CompositeContextNodeInstance); assertEquals(2, ((CompositeContextNodeInstance) child) .getNodeInstances().size()); } ksession.getWorkItemManager().completeWorkItem( workItems.get(0).getId(), null); ksession.getWorkItemManager().completeWorkItem( workItems.get(1).getId(), null); processInstance = ksession.getProcessInstance(processInstance.getId()); nodeInstances = ((WorkflowProcessInstanceImpl) processInstance) .getNodeInstances(); assertEquals(1, nodeInstances.size()); nodeInstance = nodeInstances.iterator().next(); assertTrue(nodeInstance instanceof ForEachNodeInstance); if (isPersistence()) { // when persistence is used there is slightly different behaviour of ContextNodeInstance // it's already tested by SimplePersistenceBPMNProcessTest.testMultiInstanceLoopCharacteristicsProcessWithORGateway nodeInstancesChild = ((ForEachNodeInstance) nodeInstance) .getNodeInstances(); assertEquals(1, nodeInstancesChild.size()); Iterator<NodeInstance> childIterator = nodeInstancesChild .iterator(); assertTrue(childIterator.next() instanceof CompositeContextNodeInstance); ksession.getWorkItemManager().completeWorkItem( workItems.get(2).getId(), null); ksession.getWorkItemManager().completeWorkItem( workItems.get(3).getId(), null); assertProcessInstanceFinished(processInstance, ksession); } else { nodeInstancesChild = ((ForEachNodeInstance) nodeInstance) .getNodeInstances(); assertEquals(2, nodeInstancesChild.size()); Iterator<NodeInstance> childIterator = nodeInstancesChild .iterator(); assertTrue(childIterator.next() instanceof CompositeContextNodeInstance); assertTrue(childIterator.next() instanceof ForEachJoinNodeInstance); ksession.getWorkItemManager().completeWorkItem( workItems.get(2).getId(), null); ksession.getWorkItemManager().completeWorkItem( workItems.get(3).getId(), null); assertProcessInstanceFinished(processInstance, ksession); } } @Test public void testInclusiveJoinWithLoopAndHumanTasks() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-InclusiveGatewayWithHumanTasksProcess.bpmn2"); ksession = createKnowledgeSession(kbase); final Map<String, Integer> nodeInstanceExecutionCounter = new HashMap<String, Integer>(); ksession.addEventListener(new DefaultProcessEventListener(){ @Override public void beforeNodeTriggered(ProcessNodeTriggeredEvent event) { logger.info("{} {}", event.getNodeInstance().getNodeName(), ((NodeInstanceImpl) event.getNodeInstance()).getLevel()); Integer value = nodeInstanceExecutionCounter.get(event.getNodeInstance().getNodeName()); if (value == null) { value = new Integer(0); } value++; nodeInstanceExecutionCounter.put(event.getNodeInstance().getNodeName(), value); } }); TestWorkItemHandler handler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", handler); Map<String, Object> params = new HashMap<String, Object>(); params.put("firstXor", true); params.put("secondXor", true); params.put("thirdXor", true); ProcessInstance processInstance = ksession.startProcess("InclusiveWithAdvancedLoop", params); // simulate completion of first task assertProcessInstanceActive(processInstance); ksession.getWorkItemManager().completeWorkItem(handler.getWorkItem().getId(), null); assertProcessInstanceActive(processInstance); List<WorkItem> workItems = handler.getWorkItems(); assertNotNull(workItems); assertEquals(2, workItems.size()); WorkItem remainingWork = null; for (WorkItem wi : workItems) { assertProcessInstanceActive(processInstance); // complete second task that will trigger converging OR gateway if(wi.getParameter("NodeName").equals("HT Form2")) { ksession.getWorkItemManager().completeWorkItem(wi.getId(), null); } else { remainingWork = wi; } } assertProcessInstanceActive(processInstance); ksession.getWorkItemManager().completeWorkItem(remainingWork.getId(), null); assertProcessInstanceActive(processInstance); ksession.getWorkItemManager().completeWorkItem(handler.getWorkItem().getId(), null); assertProcessInstanceCompleted(processInstance); assertEquals(13, nodeInstanceExecutionCounter.size()); assertEquals(1, (int)nodeInstanceExecutionCounter.get("Start")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("HT Form1")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("and1")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("HT Form2")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("xor1")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("xor2")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("HT Form3")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("Koniec")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("xor 3")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("HT Form4")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("xor4")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("Koniec2")); assertEquals(1, (int)nodeInstanceExecutionCounter.get("or1")); } @Test public void testMultiInstanceLoopCharacteristicsProcess() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-MultiInstanceLoopCharacteristicsProcess.bpmn2"); 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); assertProcessInstanceCompleted(processInstance); } @Test public void testMultiInstanceLoopNumberTest() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-MultiInstanceLoop-Numbering.bpmn2"); ksession = createKnowledgeSession(kbase); Map<String, Object> params = new HashMap<String, Object>(); final Map<String, String> nodeIdNodeNameMap = new HashMap<String, String>(); ksession.addEventListener(new DefaultProcessEventListener() { @Override public void beforeNodeTriggered(ProcessNodeTriggeredEvent event) { NodeInstance nodeInstance = event.getNodeInstance(); String uniqId = ((NodeInstanceImpl) nodeInstance).getUniqueId(); String nodeName = ((NodeInstanceImpl) nodeInstance).getNode().getName(); String prevNodeName = nodeIdNodeNameMap.put( uniqId, nodeName ); if( prevNodeName != null ) { assertEquals(uniqId + " is used for more than one node instance: ", prevNodeName, nodeName); } } }); TestWorkItemHandler handler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", handler); ProcessInstance processInstance = ksession.startProcess("Test.MultipleInstancesBug", params); List<WorkItem> workItems = handler.getWorkItems(); logger.debug( "COMPLETING TASKS."); ksession.getWorkItemManager().completeWorkItem(workItems.remove(0).getId(), null); ksession.getWorkItemManager().completeWorkItem(workItems.remove(0).getId(), null); assertProcessInstanceCompleted(processInstance); } @Test public void testMultiInstanceLoopCharacteristicsProcess2() throws Exception { KieBase kbase = createKnowledgeBaseWithoutDumper("BPMN2-MultiInstanceProcessWithOutputOnTask.bpmn2"); ksession = createKnowledgeSession(kbase); TestWorkItemHandler handler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", handler); Map<String, Object> params = new HashMap<String, Object>(); List<String> myList = new ArrayList<String>(); List<String> myOutList = null; myList.add("John"); myList.add("Mary"); params.put("miinput", myList); ProcessInstance processInstance = ksession.startProcess("miprocess", params); List<WorkItem> workItems = handler.getWorkItems(); assertNotNull(workItems); assertEquals(2, workItems.size()); myOutList = (List<String>) ksession.execute(new GetProcessVariableCommand(processInstance.getId(), "mioutput")); assertNull(myOutList); Map<String, Object> results = new HashMap<String, Object>(); results.put("reply", "Hello John"); ksession.getWorkItemManager().completeWorkItem(workItems.get(0).getId(), results); myOutList = (List<String>) ksession.execute(new GetProcessVariableCommand(processInstance.getId(), "mioutput")); assertNull(myOutList); results = new HashMap<String, Object>(); results.put("reply", "Hello Mary"); ksession.getWorkItemManager().completeWorkItem(workItems.get(1).getId(), results); myOutList = (List<String>) ksession.execute(new GetProcessVariableCommand(processInstance.getId(), "mioutput")); assertNotNull(myOutList); assertEquals(2, myOutList.size()); assertTrue(myOutList.contains("Hello John")); assertTrue(myOutList.contains("Hello Mary")); ksession.getWorkItemManager().completeWorkItem(handler.getWorkItem().getId(), null); assertProcessInstanceFinished(processInstance, ksession); } @Test public void testMultiInstanceLoopCharacteristicsProcessWithOutput() throws Exception { KieBase kbase = createKnowledgeBaseWithoutDumper("BPMN2-MultiInstanceLoopCharacteristicsProcessWithOutput.bpmn2"); ksession = createKnowledgeSession(kbase); Map<String, Object> params = new HashMap<String, Object>(); List<String> myList = new ArrayList<String>(); List<String> myListOut = new ArrayList<String>(); myList.add("First Item"); myList.add("Second Item"); params.put("list", myList); params.put("listOut", myListOut); assertEquals(0, myListOut.size()); ProcessInstance processInstance = ksession.startProcess( "MultiInstanceLoopCharacteristicsProcessWithOutput", params); assertProcessInstanceCompleted(processInstance); assertEquals(2, myListOut.size()); } @Test public void testMultiInstanceLoopCharacteristicsProcessWithOutputCompletionCondition() throws Exception { KieBase kbase = createKnowledgeBaseWithoutDumper("BPMN2-MultiInstanceLoopCharacteristicsProcessWithOutputCmpCond.bpmn2"); ksession = createKnowledgeSession(kbase); Map<String, Object> params = new HashMap<String, Object>(); List<String> myList = new ArrayList<String>(); List<String> myListOut = new ArrayList<String>(); myList.add("First Item"); myList.add("Second Item"); params.put("list", myList); params.put("listOut", myListOut); assertEquals(0, myListOut.size()); ProcessInstance processInstance = ksession.startProcess( "MultiInstanceLoopCharacteristicsProcessWithOutput", params); assertProcessInstanceCompleted(processInstance); assertEquals(1, myListOut.size()); } @Test public void testMultiInstanceLoopCharacteristicsProcessWithOutputAndScripts() throws Exception { KieBase kbase = createKnowledgeBaseWithoutDumper("BPMN2-MultiInstanceLoopCharacteristicsProcessWithOutputAndScripts.bpmn2"); ksession = createKnowledgeSession(kbase); Map<String, Object> params = new HashMap<String, Object>(); List<String> myList = new ArrayList<String>(); List<String> myListOut = new ArrayList<String>(); List<String> scriptList = new ArrayList<String>(); myList.add("First Item"); myList.add("Second Item"); params.put("list", myList); params.put("listOut", myListOut); params.put("scriptList", scriptList); assertEquals(0, myListOut.size()); ProcessInstance processInstance = ksession.startProcess("MultiInstanceLoopCharacteristicsProcessWithOutput", params); assertProcessInstanceCompleted(processInstance); assertEquals(2, myListOut.size()); assertEquals(2, scriptList.size()); } @Test public void testMultiInstanceLoopCharacteristicsTaskWithOutput() throws Exception { KieBase kbase = createKnowledgeBaseWithoutDumper("BPMN2-MultiInstanceLoopCharacteristicsTaskWithOutput.bpmn2"); ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", new SystemOutWorkItemHandler()); Map<String, Object> params = new HashMap<String, Object>(); List<String> myList = new ArrayList<String>(); List<String> myListOut = new ArrayList<String>(); myList.add("First Item"); myList.add("Second Item"); params.put("list", myList); params.put("listOut", myListOut); assertEquals(0, myListOut.size()); ProcessInstance processInstance = ksession.startProcess( "MultiInstanceLoopCharacteristicsTask", params); assertProcessInstanceCompleted(processInstance); assertEquals(2, myListOut.size()); } @Test public void testMultiInstanceLoopCharacteristicsTaskWithOutputCompletionCondition() throws Exception { KieBase kbase = createKnowledgeBaseWithoutDumper("BPMN2-MultiInstanceLoopCharacteristicsTaskWithOutputCmpCond.bpmn2"); ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", new SystemOutWorkItemHandler()); Map<String, Object> params = new HashMap<String, Object>(); List<String> myList = new ArrayList<String>(); List<String> myListOut = new ArrayList<String>(); myList.add("First Item"); myList.add("Second Item"); params.put("list", myList); params.put("listOut", myListOut); assertEquals(0, myListOut.size()); ProcessInstance processInstance = ksession.startProcess( "MultiInstanceLoopCharacteristicsTask", params); assertProcessInstanceCompleted(processInstance); assertEquals(1, myListOut.size()); } @Test public void testMultiInstanceLoopCharacteristicsTaskWithOutputCompletionCondition2() throws Exception { KieBase kbase = createKnowledgeBaseWithoutDumper("BPMN2-MultiInstanceLoopCharacteristicsTaskWithOutputCmpCond2.bpmn2"); ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", new SystemOutWorkItemHandler()); Map<String, Object> params = new HashMap<String, Object>(); List<String> myList = new ArrayList<String>(); List<String> myListOut = new ArrayList<String>(); myList.add("approved"); myList.add("rejected"); myList.add("approved"); myList.add("approved"); myList.add("rejected"); params.put("list", myList); params.put("listOut", myListOut); assertEquals(0, myListOut.size()); ProcessInstance processInstance = ksession.startProcess( "MultiInstanceLoopCharacteristicsTask", params); assertProcessInstanceCompleted(processInstance); // only two approved outcomes are required to complete multiinstance and since there was reject in between we should have // three elements in the list assertEquals(3, myListOut.size()); } @Test public void testMultiInstanceLoopCharacteristicsTask() throws Exception { KieBase kbase = createKnowledgeBaseWithoutDumper("BPMN2-MultiInstanceLoopCharacteristicsTask.bpmn2"); ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", new SystemOutWorkItemHandler()); 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( "MultiInstanceLoopCharacteristicsTask", params); assertProcessInstanceCompleted(processInstance); } @Test public void testMultipleInOutgoingSequenceFlows() throws Exception { CountDownProcessEventListener countDownListener = new CountDownProcessEventListener("timer", 1); System.setProperty("jbpm.enable.multi.con", "true"); KieBase kbase = createKnowledgeBase("BPMN2-MultipleInOutgoingSequenceFlows.bpmn2"); 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(1, list.size()); System.clearProperty("jbpm.enable.multi.con"); } @Test public void testMultipleIncomingFlowToEndNode() throws Exception { System.setProperty("jbpm.enable.multi.con", "true"); KieBase kbase = createKnowledgeBase("BPMN2-MultipleFlowEndNode.bpmn2"); ksession = createKnowledgeSession(kbase); ProcessInstance processInstance = ksession.startProcess("MultipleFlowEndNode"); assertProcessInstanceCompleted(processInstance); System.clearProperty("jbpm.enable.multi.con"); } @Test public void testMultipleEnabledOnSingleConditionalSequenceFlow() throws Exception { System.setProperty("jbpm.enable.multi.con", "true"); KieBase kbase = createKnowledgeBase("BPMN2-MultiConnEnabled.bpmn2"); ksession = createKnowledgeSession(kbase); final List<Long> list = new ArrayList<Long>(); ksession.addEventListener(new DefaultProcessEventListener() { public void afterNodeTriggered(org.kie.api.event.process.ProcessNodeTriggeredEvent event) { if ("Task2".equals(event.getNodeInstance().getNodeName())) { list.add(event.getNodeInstance().getNodeId()); } } }); assertEquals(0, list.size()); ProcessInstance processInstance = ksession.startProcess("BPMN2-MultiConnEnabled"); assertProcessInstanceActive(processInstance); ksession.signalEvent("signal", null, processInstance.getId()); assertProcessInstanceCompleted(processInstance); assertEquals(1, list.size()); System.clearProperty("jbpm.enable.multi.con"); } @Test public void testMultipleInOutgoingSequenceFlowsDisable() throws Exception { try { KieBase kbase = createKnowledgeBase("BPMN2-MultipleInOutgoingSequenceFlows.bpmn2"); fail("Should fail as multiple outgoing and incoming connections are disabled by default"); } catch (Exception e) { assertEquals( "This type of node [ScriptTask_1, Script Task] cannot have more than one outgoing connection!", e.getMessage()); } } @Test public void testConditionalFlow() throws Exception { System.setProperty("jbpm.enable.multi.con", "true"); String processId = "designer.conditional-flow"; KieBase kbase = createKnowledgeBase("BPMN2-ConditionalFlowWithoutGateway.bpmn2"); ksession = createKnowledgeSession(kbase); WorkflowProcessInstance wpi = (WorkflowProcessInstance) ksession .startProcess(processId); assertProcessInstanceFinished(wpi, ksession); assertNodeTriggered(wpi.getId(), "start", "script", "end1"); System.clearProperty("jbpm.enable.multi.con"); } @Test public void testLane() throws Exception { KieBase kbase = createKnowledgeBase("BPMN2-Lane.bpmn2"); 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); assertProcessInstanceFinished(processInstance, ksession); } @Test public void testExclusiveSplitDefaultNoCondition() throws Exception { KieBase kbase = createKnowledgeBaseWithoutDumper("BPMN2-ExclusiveSplitDefaultNoCondition.bpmn2"); KieSession ksession = createKnowledgeSession(kbase); ProcessInstance processInstance = ksession.startProcess("com.sample.test"); assertProcessInstanceFinished(processInstance, ksession); } @Test public void testMultipleGatewaysProcess() throws Exception { KieBase kbase = createKnowledgeBaseWithoutDumper("BPMN2-MultipleGatewaysProcess.bpmn2"); ksession = createKnowledgeSession(kbase); ksession.addEventListener(new DefaultProcessEventListener(){ ProcessInstance pi; @Override public void afterNodeTriggered(ProcessNodeTriggeredEvent event) { if(event.getNodeInstance().getNodeName().equals("CreateAgent")){ pi.signalEvent("Signal_1", null); } } @Override public void beforeNodeTriggered(ProcessNodeTriggeredEvent event) { logger.info("Before Node triggered event received for node: {}", event.getNodeInstance().getNodeName()); } @Override public void beforeProcessStarted(ProcessStartedEvent event) { pi=event.getProcessInstance(); } }); Map<String, Object> params = new HashMap<String, Object>(); params.put("action", "CreateAgent"); ProcessInstance processInstance = ksession.startProcess("multiplegateways", params); assertProcessInstanceCompleted(processInstance); } @Test public void testTimerAndGateway() throws Exception { CountDownProcessEventListener countDownListener = new CountDownProcessEventListener("timer", 1); KieBase kbase = createKnowledgeBase("timer/BPMN2-ParallelSplitWithTimerProcess.bpmn2"); ksession = createKnowledgeSession(kbase); ksession.addEventListener(countDownListener); TestWorkItemHandler handler1 = new TestWorkItemHandler(); TestWorkItemHandler handler2 = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("task1", handler1); ksession.getWorkItemManager().registerWorkItemHandler("task2", handler2); ProcessInstance instance = ksession.createProcessInstance("timer-process", new HashMap<String, Object>()); ksession.startProcessInstance(instance.getId()); WorkItem workItem1 = handler1.getWorkItem(); assertNotNull(workItem1); assertNull(handler1.getWorkItem()); //first safe state: task1 completed ksession.getWorkItemManager().completeWorkItem(workItem1.getId(), null); ksession = restoreSession(ksession, true); ksession.addEventListener(countDownListener); ksession.getWorkItemManager().registerWorkItemHandler("task1", handler1); ksession.getWorkItemManager().registerWorkItemHandler("task2", handler2); //second safe state: timer completed, waiting on task2 countDownListener.waitTillCompleted(); WorkItem workItem2 = handler2.getWorkItem(); //Both sides of the join are completed. But on the process instance, there are two //JoinInstance for the same Join, and since it is an AND join, it never reaches task2 //It fails after the next assertion assertNotNull(workItem2); assertNull(handler2.getWorkItem()); ksession.getWorkItemManager().completeWorkItem(workItem2.getId(), null); assertProcessInstanceCompleted(instance); } private static class GetProcessVariableCommand implements ExecutableCommand<Object> { private long processInstanceId; private String variableName; public GetProcessVariableCommand(long processInstanceId, String variableName) { this.processInstanceId = processInstanceId; this.variableName = variableName; } public Object execute(Context context) { KieSession ksession = ((RegistryContext) context).lookup( KieSession.class ); org.jbpm.process.instance.ProcessInstance processInstance = (org.jbpm.process.instance.ProcessInstance) ksession.getProcessInstance(processInstanceId); VariableScopeInstance variableScope = (VariableScopeInstance) processInstance.getContextInstance(VariableScope.VARIABLE_SCOPE); Object variable = variableScope.getVariable(variableName); return variable; } } }