JBPM 6 Filip
Jump to navigation
Jump to search
Exercises
Inclusive Gateway
- default path may not work (Eclipse bug)
public class ProcessTest extends JbpmJUnitBaseTestCase {
@Test
public void testProcess() throws Exception {
/**
* A salesman will get a 100 bonus if his sales is over 1000
* if his sales is over 5000 he will get a car as well
* if his sales is over 10000 he will be made a Managing Director
*
* 1. Create appropriate gateway and process variables
* 2. Create a test which checks appropriate End events (NodeTriggered)
*/
createRuntimeManager("inclusive.bpmn");
RuntimeEngine engine = getRuntimeEngine(null);
KieSession ksession = engine.getKieSession();
Map<String, Object> params = new HashMap<String, Object>();
params.put("sales", 15000);
ProcessInstance processInstance = ksession.startProcess("com.sample.bpmn", params);
//Ends 1 to 3 will be reached
assertNodeTriggered(processInstance.getId(),"End1");
assertNodeTriggered(processInstance.getId(),"End2");
assertNodeTriggered(processInstance.getId(),"End3");
assertProcessInstanceCompleted(processInstance.getId(), ksession);
}
}
Parallel Gateway
- no variables, no params (remove params attribute from startProcess method)
- just 2 script tasks
- change second parallel gateway type to Converging
public class ProcessTest extends JbpmJUnitBaseTestCase {
@Test
public void testProcess() throws Exception {
createRuntimeManager("BPMN2-Parallel.bpmn");
RuntimeEngine engine = getRuntimeEngine(null);
KieSession ksession = engine.getKieSession();
/**
* Trip booking requires booking hotel and the flight
* These things can be done concurrently (use parallel gateway)
*
* Advanced:
* If booking of a hotel or flight fails, create a mechanism for cancelling the reservation (use exclusive gateway)
*/
ProcessInstance processInstance = ksession.startProcess("com.sample.bpmn");
assertNodeTriggered(processInstance.getId(),"Book Hotel");
assertNodeTriggered(processInstance.getId(),"Book Flight");
assertProcessInstanceCompleted(processInstance.getId(), ksession);
}
}
Parallel Gateway - Compensation
- we want to check the result of booking
- 2 process variables: hotelBooked:boolean, flightBooked:boolean
- conditions:
- return (hotelBooked && flightBooked);
- return (! hotelBooked && ! flightBooked);
- return (hotelBooked && ! flightBooked);
- return (! hotelBooked && flightBooked);
public class ProcessTestAdvanced extends JbpmJUnitBaseTestCase {
@Test
public void testProcess() throws Exception {
createRuntimeManager("ParallelAdvanced.bpmn");
RuntimeEngine engine = getRuntimeEngine(null);
KieSession ksession = engine.getKieSession();
Map<String, Object> params = new HashMap<String, Object>();
params.put("hotelBooked", false);
params.put("flightBooked", false);
ProcessInstance processInstance = ksession.startProcess("com.sample.bpmn.advanced",params);
assertNodeTriggered(processInstance.getId(),"Book Hotel");
assertNodeTriggered(processInstance.getId(),"Book Flight");
assertProcessInstanceCompleted(processInstance.getId(), ksession);
assertNodeTriggered(processInstance.getId(),"both failed");
}
@Test
public void testProcessBothOK() throws Exception {
createRuntimeManager("ParallelAdvanced.bpmn");
RuntimeEngine engine = getRuntimeEngine(null);
KieSession ksession = engine.getKieSession();
Map<String, Object> params = new HashMap<String, Object>();
params.put("hotelBooked", true);
params.put("flightBooked", true);
ProcessInstance processInstance = ksession.startProcess("com.sample.bpmn.advanced",params);
// System.out.println(params.get("hotelBooked"));
// System.out.println(params.get("hotelBooked"));
assertNodeTriggered(processInstance.getId(),"Book Hotel");
assertNodeTriggered(processInstance.getId(),"Book Flight");
assertProcessInstanceCompleted(processInstance.getId(), ksession);
assertNodeTriggered(processInstance.getId(),"both OK");
}
}
Timer - delay
- Timer event has two expressions sections:
- first - specific time
- second - specific cycle
- If you can't connect script task to intermediate timer event use context menu:
Scenario: A boyfriend sends an SMS message for his girlfriend. She waits 5s and sends reply SMS message.
- timer - time duration 5s
public class ProcessTest extends JbpmJUnitBaseTestCase {
@Test
public void testProcess() throws InterruptedException {
RuntimeManager manager = createRuntimeManager("sample.bpmn");
RuntimeEngine engine = getRuntimeEngine(null);
KieSession ksession = engine.getKieSession();
ProcessInstance processInstance = ksession.startProcess("com.sample.bpmn.hello");
assertNodeTriggered(processInstance.getId(), "Receive SMS");
assertProcessInstanceActive(processInstance.getId(), ksession);
// now wait for 2 seconds for timer to trigger
Thread.sleep(2000);
assertProcessInstanceActive(processInstance.getId(), ksession);
Thread.sleep(4000);
//Here process instance is no longer active
//assertProcessInstanceActive(processInstance.getId(), ksession);
// check whether the process instance has completed successfully
assertProcessInstanceCompleted(processInstance.getId(), ksession);
manager.disposeRuntimeEngine(engine);
manager.close();
}
}
05.2_timer_boundary_interrupting_time
- To add boundary event drag and drop event from boundary section - not from Intermediate catching section.
05.3_timer_boundary_non_interrupting_cycle
timer cycle 500ms###1s is 500ms initial delay + 1s delay -after 0.5s every 1s
Loop
- Init task
kcontext.setVariable("i", 0);
- loop task
System.out.println("i = " + i);
kcontext.setVariable("i", i+1);
- done task
System.out.println("Loop completed");
- conditions
return i < count;
return true; (change to default flow)
public class LoopingExample extends JbpmJUnitBaseTestCase {
@Test
public void testProcess() throws MalformedURLException {
createRuntimeManager("Looping.bpmn");
RuntimeEngine engine = getRuntimeEngine(null);
KieSession ksession = engine.getKieSession();
Map<String, Object> params = new HashMap<String, Object>();
params.put("count", 5);
ksession.startProcess("com.sample.looping", params);
}
}
Multi instance
- Say Hi task
System.out.println(kcontext.getVariable("mi_person_name") );
public class MultipleInstanceExample extends JbpmJUnitBaseTestCase {
@Test
public void testProcess(){
createRuntimeManager("multipleinstance.bpmn");
RuntimeEngine engine = getRuntimeEngine(null);
KieSession ksession = engine.getKieSession();
Map<String, Object> params = new HashMap<String, Object>();
List<String> list = new ArrayList<String>();
list.add("Bernard");
list.add("Greg");
list.add("Phil");
params.put("list", list);
ksession.startProcess("com.sample.multipleinstance", params);
}
}
- to set MI attributes change editor to BPMN2 Process Editor
- 07.1_exercise
- copy BPMN file from 07_looping_multiinstance and add gateway:
- Sent e-mail task:
System.out.println("E-mail sent to: " + kcontext.getVariable("mi_person_name") );
- conditions
return kcontext.getVariable("mi_person_name") != "Greg";
Boundary events
- Message event in jBPM is implemented as signal event
//If you send a message, it will be Message-ID
ksession.signalEvent("Message-BookingCancelation",null,processInstance.getId());
https://www.packtpub.com/networking-and-servers/jbpm-6-developer-guide
Message boundary exercise
- Create new jBPM Project (not MAVEN, not KJAR)
- Add process variable (string)
- Define Message Event
- Assign target to process variable
- Write JUnit test
- add add throws Exception to test method (to use Thread.sleep):
@Test
public void testProcess() throws Exception {
- final code
package com.sample;
import org.jbpm.test.JbpmJUnitBaseTestCase;
import org.junit.Test;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.manager.RuntimeEngine;
import org.kie.api.runtime.manager.RuntimeManager;
import org.kie.api.runtime.process.ProcessInstance;
/**
* This is a sample file to test a process.
*/
public class ProcessTest extends JbpmJUnitBaseTestCase {
@Test
public void testProcess() throws Exception {
RuntimeManager manager = createRuntimeManager("sample.bpmn");
RuntimeEngine engine = getRuntimeEngine(null);
KieSession ksession = engine.getKieSession();
ProcessInstance processInstance = ksession.startProcess("com.sample.bpmn.hello");
// check whether the process instance has completed successfully
Thread.sleep(1000);
ksession.signalEvent("Message-CancelMessage",null,processInstance.getId());
assertProcessInstanceCompleted(processInstance.getId(), ksession);
//assertNodeTriggered(processInstance.getId(), "Hello");
manager.disposeRuntimeEngine(engine);
manager.close();
}
}
- Change boundary event type to non interrupting and change test:
@Test
public void testProcess() throws Exception {
RuntimeManager manager = createRuntimeManager("sample.bpmn");
RuntimeEngine engine = getRuntimeEngine(null);
KieSession ksession = engine.getKieSession();
ProcessInstance processInstance = ksession.startProcess("com.sample.bpmn.hello");
Thread.sleep(1000);
ksession.signalEvent("Message-CancelMessage",null,processInstance.getId());
Thread.sleep(1000);
ksession.signalEvent("Message-CancelMessage",null,processInstance.getId());
Thread.sleep(10000);
manager.disposeRuntimeEngine(engine);
manager.close();
- Console window:
inside message received message received after
Error boundary exercise
- Create process with error events
- process variables:
- ok:Boolean (for a gateway)
- errorVar:Integer
- Add Error Event details
- Error End Event
- Error Boundary Intermediate Event
- JUnit code
package com.sample;
import java.util.HashMap;
import java.util.Map;
import org.jbpm.test.JbpmJUnitBaseTestCase;
import org.junit.Test;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.manager.RuntimeEngine;
import org.kie.api.runtime.manager.RuntimeManager;
import org.kie.api.runtime.process.ProcessInstance;
/**
* This is a sample file to test a process.
*/
public class ProcessTest extends JbpmJUnitBaseTestCase {
@Test
public void testProcessNoErrors() {
RuntimeManager manager = createRuntimeManager("ErrorBoundary.bpmn");
RuntimeEngine engine = getRuntimeEngine(null);
KieSession ksession = engine.getKieSession();
Map<String, Object> params = new HashMap<String, Object>();
params.put("ok", true);
ProcessInstance processInstance = ksession.startProcess("com.sample.bpmn.hello", params);
// check whether the process instance has completed successfully
assertProcessInstanceCompleted(processInstance.getId(), ksession);
manager.disposeRuntimeEngine(engine);
manager.close();
}
@Test
public void testProcessError() {
RuntimeManager manager = createRuntimeManager("ErrorBoundary.bpmn");
RuntimeEngine engine = getRuntimeEngine(null);
KieSession ksession = engine.getKieSession();
Map<String, Object> params = new HashMap<String, Object>();
params.put("ok", false); //trigger error
ProcessInstance processInstance = ksession.startProcess("com.sample.bpmn.hello", params);
// check whether the process instance has completed successfully
assertProcessInstanceCompleted(processInstance.getId(), ksession);
manager.disposeRuntimeEngine(engine);
manager.close();
}
}
Event-Based Gateway
- Create diagram
- JUnit test
package com.nobleprog;
import org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler;
import org.jbpm.test.JbpmJUnitBaseTestCase;
import org.junit.Test;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.manager.RuntimeEngine;
import org.kie.api.runtime.process.ProcessInstance;
public class ProcessTest extends JbpmJUnitBaseTestCase {
@Test
public void testProcessMessage1() throws Exception {
createRuntimeManager("EventBasedGateway-Loan.bpmn2");
RuntimeEngine engine = getRuntimeEngine(null);
KieSession ksession = engine.getKieSession();
ProcessInstance processInstance = ksession.startProcess("com.sample.test");
ksession.signalEvent("Message-Message_1", null, processInstance.getId());
assertProcessInstanceCompleted(processInstance.getId(), ksession);
}
@Test
public void testProcessTimer() throws Exception {
createRuntimeManager("EventBasedGateway-Loan.bpmn2");
RuntimeEngine engine = getRuntimeEngine(null);
KieSession ksession = engine.getKieSession();
ProcessInstance processInstance = ksession.startProcess("com.sample.test");
Thread.sleep(6000);
assertProcessInstanceCompleted(processInstance.getId(), ksession);
}
}
Compensation
- Create diagram
- to add compensation boundary event drag and drop empty boundary event and change event definition
- then drag and drop script task and connect boundary event with the task using association
- JUnit code
package com.sample;
import java.util.HashMap;
import java.util.Map;
import org.jbpm.test.JbpmJUnitBaseTestCase;
import org.junit.Test;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.manager.RuntimeEngine;
import org.kie.api.runtime.manager.RuntimeManager;
import org.kie.api.runtime.process.ProcessInstance;
/**
* This is a sample file to test a process.
*/
public class ProcessTest extends JbpmJUnitBaseTestCase {
@Test
public void testProcess() {
RuntimeManager manager = createRuntimeManager("BPMN2-Compensation-IntermediateThrowEvent.bpmn2");
RuntimeEngine engine = getRuntimeEngine(null);
KieSession ksession = engine.getKieSession();
Map<String, Object> params = new HashMap<String, Object>();
params.put("x", 10);
System.out.println("Initialized value: " + params.get("x"));
ProcessInstance processInstance = ksession.startProcess("CompensateIntermediateThrowEvent", params);
// check whether the process instance has completed successfully
assertProcessInstanceCompleted(processInstance.getId(), ksession);
manager.disposeRuntimeEngine(engine);
manager.close();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://www.jboss.org/drools" xmlns="http://www.jboss.org/drools" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd http://www.jboss.org/drools drools.xsd http://www.bpsim.org/schemas/1.0 bpsim.xsd" id="Definition" expressionLanguage="http://www.mvel.org/2.0" targetNamespace="http://www.example.org/MinimalExample" typeLanguage="http://www.java.com/javaTypes">
<bpmn2:itemDefinition id="_xItem" structureRef="String"/>
<bpmn2:itemDefinition id="_Integer" structureRef="Integer"/>
<bpmn2:process id="CompensateIntermediateThrowEvent" tns:version="1" tns:packageName="defaultPackage" tns:adHoc="false" name="Compensate Intermediate Throw Event Process" isExecutable="true" processType="Private">
<bpmn2:property id="x" itemSubjectRef="_Integer"/>
<bpmn2:startEvent id="_1" name="StartProcess">
<bpmn2:outgoing>_1-_2</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:sequenceFlow id="_1-_2" tns:priority="1" name="" sourceRef="_1" targetRef="_2"/>
<bpmn2:scriptTask id="_2" name="Task">
<bpmn2:incoming>_1-_2</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_1</bpmn2:outgoing>
<bpmn2:script>System.out.println("Inside (before compensation): " + x=99);</bpmn2:script>
</bpmn2:scriptTask>
<bpmn2:boundaryEvent id="_10" name="CompensateEvent" attachedToRef="_2" cancelActivity="false">
<bpmn2:compensateEventDefinition id="CompensateEventDefinition_2" activityRef="_2"/>
</bpmn2:boundaryEvent>
<bpmn2:scriptTask id="_11" name="Compensate" isForCompensation="true">
<bpmn2:script>System.out.println("After compensation: " + x);</bpmn2:script>
</bpmn2:scriptTask>
<bpmn2:sequenceFlow id="SequenceFlow_1" tns:priority="1" name="" sourceRef="_2" targetRef="_4"/>
<bpmn2:intermediateThrowEvent id="_4" name="CompensateEvent">
<bpmn2:incoming>SequenceFlow_1</bpmn2:incoming>
<bpmn2:outgoing>_4-_5</bpmn2:outgoing>
<bpmn2:compensateEventDefinition id="CompensateEventDefinition_1" activityRef="_2"/>
</bpmn2:intermediateThrowEvent>
<bpmn2:sequenceFlow id="_4-_5" tns:priority="1" name="" sourceRef="_4" targetRef="_5"/>
<bpmn2:endEvent id="_5" name="EndEvent">
<bpmn2:incoming>_4-_5</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:association id="_10-_11" sourceRef="_10" targetRef="_11"/>
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_Process_1" bpmnElement="CompensateIntermediateThrowEvent">
<bpmndi:BPMNShape id="BPMNShape_StartEvent_1" bpmnElement="_1">
<dc:Bounds height="36.0" width="36.0" x="50.0" y="57.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_IntermediateThrowEvent_1" bpmnElement="_4">
<dc:Bounds height="36.0" width="36.0" x="340.0" y="57.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_EndEvent_1" bpmnElement="_5">
<dc:Bounds height="36.0" width="36.0" x="490.0" y="57.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_ScriptTask_1" bpmnElement="_2">
<dc:Bounds height="50.0" width="110.0" x="136.0" y="50.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_BoundaryEvent_1" bpmnElement="_10">
<dc:Bounds height="36.0" width="36.0" x="173.0" y="82.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_ScriptTask_2" bpmnElement="_11">
<dc:Bounds height="50.0" width="110.0" x="136.0" y="150.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_1" bpmnElement="_1-_2" sourceElement="BPMNShape_StartEvent_1" targetElement="BPMNShape_ScriptTask_1">
<di:waypoint xsi:type="dc:Point" x="86.0" y="75.0"/>
<di:waypoint xsi:type="dc:Point" x="108.0" y="75.0"/>
<di:waypoint xsi:type="dc:Point" x="108.0" y="75.0"/>
<di:waypoint xsi:type="dc:Point" x="136.0" y="75.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_4" bpmnElement="_4-_5" sourceElement="BPMNShape_IntermediateThrowEvent_1" targetElement="BPMNShape_EndEvent_1">
<di:waypoint xsi:type="dc:Point" x="376.0" y="75.0"/>
<di:waypoint xsi:type="dc:Point" x="427.0" y="75.0"/>
<di:waypoint xsi:type="dc:Point" x="427.0" y="75.0"/>
<di:waypoint xsi:type="dc:Point" x="490.0" y="75.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="BPMNEdge_Association_1" bpmnElement="_10-_11" sourceElement="BPMNShape_BoundaryEvent_1" targetElement="BPMNShape_ScriptTask_2">
<di:waypoint xsi:type="dc:Point" x="191.0" y="118.0"/>
<di:waypoint xsi:type="dc:Point" x="191.0" y="132.0"/>
<di:waypoint xsi:type="dc:Point" x="191.0" y="132.0"/>
<di:waypoint xsi:type="dc:Point" x="191.0" y="150.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_5" bpmnElement="SequenceFlow_1" sourceElement="BPMNShape_ScriptTask_1" targetElement="BPMNShape_IntermediateThrowEvent_1">
<di:waypoint xsi:type="dc:Point" x="246.0" y="75.0"/>
<di:waypoint xsi:type="dc:Point" x="288.0" y="75.0"/>
<di:waypoint xsi:type="dc:Point" x="288.0" y="75.0"/>
<di:waypoint xsi:type="dc:Point" x="340.0" y="75.0"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
UserTask - not working
- Create new jBPM project
- Create BPMN diagram
- set gateway type to diverging
- add approved:boolean local process variable
- add conditions after the gateway
- add script task script
Work Item
Scenario: We need to get Order data to issue an invoice using external system.
Project Explorer
Work Item Definition (GetOrder.wid)
import org.drools.core.process.core.datatype.impl.type.StringDataType;
[
[
"name" : "GetOrder",
"parameters" : [
"orderId" : new StringDataType(),
"orderTotal" : new StringDataType(),
],
"displayName" : "GetOrder",
"icon" : "icons/getoutlinetitle.gif"
]
]
drools.rulebase.conf
drools.workDefinitions = GetOrder.wid
Work Item Handler
package com.nobleprog;
import java.util.HashMap;
import java.util.Map;
import org.kie.api.runtime.process.WorkItem;
import org.kie.api.runtime.process.WorkItemHandler;
import org.kie.api.runtime.process.WorkItemManager;
public class GetOrderWorkItemHandler implements WorkItemHandler {
public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {
// extract parameters
String orderId = (String) workItem.getParameter("orderId");
Map<String, Object> result = new HashMap<String,Object>();
result.put("orderTotal","12000");
System.out.println("Retriving order information (mock service) for orderId:" + orderId);
manager.completeWorkItem(workItem.getId(), result);
}
public void abortWorkItem(WorkItem workItem, WorkItemManager manager) {
// Do nothing, notifications cannot be aborted
}
}
ProcessTest.java
package com.nobleprog;
import java.util.HashMap;
import java.util.Map;
import com.nobleprog.GetOrderWorkItemHandler;
import org.jbpm.test.JbpmJUnitBaseTestCase;
import org.junit.Test;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.manager.RuntimeEngine;
import org.kie.api.runtime.process.ProcessInstance;
public class ProcessTest extends JbpmJUnitBaseTestCase {
@Test
public void testProcess() throws Exception {
String[] processes = new String[]{"IssueInvoice.bpmn2"};
createRuntimeManager(processes);
RuntimeEngine engine = getRuntimeEngine(null);
KieSession ksession = engine.getKieSession();
ksession.getWorkItemManager().registerWorkItemHandler("GetOrder", new GetOrderWorkItemHandler());
Map<String, Object> params = new HashMap<String, Object>();
params.put("orderId", "15");
ProcessInstance processInstance = ksession.startProcess("com.sample.test", params);
assertProcessInstanceCompleted(processInstance.getId(), ksession);
}
}
Using Eclipse with Workbench
- Eclipse -> KIE Workbench
- KIE Workbench -> Eclipse
- [KIE] Authoring/Administration
- [Eclipse] Right click/Team/Pull










