/*
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;
}
}
}