Mastering jBPM6 - Sample Chapter
Mastering jBPM6 - Sample Chapter
Mastering jBPM6 - Sample Chapter
ee
$ 59.99 US
39.99 UK
P U B L I S H I N G
pl
C o m m u n i t y
Simone Fiorini
Arun V Gopalakrishnan
Mastering jBPM6
Mastering jBPM6
Sa
m
D i s t i l l e d
Mastering jBPM6
Design, build, and deploy business process-centric applications
using the cutting-edge jBPM technology stack
E x p e r i e n c e
Simone Fiorini
Arun V Gopalakrishnan
Preface
jBPM is a leading open source BPM and workflow platform whose development is
sponsored by Red Hat under Apache Software License (ASL) licensing. The jBPM
product has been around for almost 10 years; its strongest points rely on flexibility,
extensibility, and lightness, and it is a modular, cross-platform pure Java engine that
is BPMN2 compliant.
It features a robust management console and development tools that support
the user during the business process life cycle: development, deployment, and
versioning. It integrates with widely-adopted frameworks and technologies (SOAP,
REST, Spring, Java EE CDI, and OSGi) and provides off-the-shelf support to Git
and Maven.
It fits into different system architectures and can be deployed as a full-fledged
web application or as a service; it can be tightly embedded into a classical desktop
application or loosely integrated into a complex event-driven architecture. In its
default configuration, jBPM can be hosted by the enterprise class application
server Red Hat EAP 6.x or the bleeding-edge Red Hat WildFly 8 server.
Mastering JBPM6 takes you through a practical approach to using and extending
jBPM 6.2. This book provides a detailed jBPM 6.2 overview; it covers the BPM
notation supported by the engine and explains the advanced engine and API
topics focusing, as much as possible, on several working practical examples.
The book presents the user with solutions to common real-time issues like BAM
(which stands for business activity monitoring) and production scenarios.
Preface
BPMN Constructs
To classify the level of support that a BPMN software tool provides, the BPMN
standard defines the "conformance classes" as follows:
Process Modeling Conformance: This class includes the BPMN core elements,
process, collaboration, and conversation diagrams. It defines subclasses
that contain a limited set of visual elements (descriptive), an extended set of
modeling elements (analytical), and modeling elements that are required to
model executable processes (common executable).
jBPM introduced the implementation of the BPMN 2.0 specification with the jBPM 5
release, for both the graphical notation (element visual representation) and the XML
serialization, easing the task of exchanging process definitions between developers
and the business team (in terms of Eclipse-based BPMN editor and process Webbased designer interoperability).
[ 125 ]
BPMN Constructs
Parameters: These are the data input coming from the user through the
API. The user can pass parameters during process creation, at a human task
completion, or into a service task for a Web service call.
Globals: Static variables shared across different process instances for a single
Kie working session.
[ 126 ]
Chapter 5
Facts: Data that can be added to the Kie session and then updated or
removed (retracted). This information is inserted, technically speaking, into
the session through channels named entry points, and evaluated according
to the Drools business rules, for activation. Drools Agenda manages the rule
activation and firing mechanism.
Please refer to Drools reference documentation for additional
details on facts, rules, entry points, Agenda, and the Drools
rule engine in general: https://docs.jboss.org/drools/
release/6.2.0.Final/drools-docs/html. Drools and jBPM
are complementary projects that integrate together very nicely.
Variables and globals are accessed through context-type implicit references made
available to the jBPM constructs at runtime:
and facts
[ 127 ]
BPMN Constructs
Sequence flow
The sequence flow is the connector between two elements of the process. It
represents a flow of execution. A sequence flow may optionally have a condition
defined (conditional sequence flow). The engine always evaluates a task node's
outgoing sequence flows: If the condition evaluates to true then the engine selects
and follows that sequence flow; a sequence flow with no condition defined is
always followed by the engine. A diamond shaped connector (see Appendix B, jBPM
BPMN Constructs Reference, Gateways section for some pictorial examples) indicates
a conditional sequence flow. Multiple sequence flows represent branching and
merging without the usage of a gateway. Gateways, depending on their nature,
handle conditional sequence flows in specific ways as we are about to see.
jBPM allows you to enable multiple outgoing conditional sequence
flows from a task by setting the jbpm.enable.multi.con system
property to true (default is false).
The following example process (see the figure) shows how the jbpm.enable.multi.
con property affects the sequence flow behavior.
Example process:
sequenceflows.bpmn
[ 128 ]
Chapter 5
Description: The test creates the process instance with an Order variable with
different cost values. The process, thanks to the jbpm.enable.multi.con system
property set to TRUE, allows the execution of multiple (here, we have two)
conditional sequence flows that diverge from a single Script Activity. The first
sequence flow is taken if the Order costs more than 10, while the second one is taken
when the Order cost is 10.
Gateways
Gateways are elements that allow you to create branches in your process. These
branches can be, conceptually, diverging or converging. You can model the behavior
of the different types of business process sequence flows: conditional branching
(inclusive and exclusive), forking, merging, and joining.
Let us first review the key gateway concepts and the practical examples in the
upcoming sections:
Fork (split) indicates a flow dividing into two or more paths that should
execute in a logically parallel (concurrent) way: jBPM, for implementation
reasons, never executes parallel flows concurrently (at the thread level) but
always sequentially, one step at a time
Branch (or decision) is a point where the control flow can take one or more
alternative paths
Merge refers to a process point where two or more alternative sequence flow
paths are combined into a single sequence flow path
[ 129 ]
BPMN Constructs
Example process:
gateway_parallel.bpmn
Description: The plan route script task calculates the order delivery route, while the
Prepare Ingredients human task adds some mozzarella to the order bill of materials.
The closing Done Script task displays the result after all outgoing flows are complete.
Conditional branching
These gateways introduce the condition expression. The condition expressions linked
to each of the outgoing/incoming sequence flows are evaluated during process
execution using process data (data-based gateways). Optionally, one of the gateway
outgoing paths can be flagged as the default flow (its condition is ignored): this path
is taken only if none of the other path flows can be selected. The default (sequence)
flow is visually marked with a slash mark as shown in the following image:
[ 130 ]
Chapter 5
Drools
We briefly introduced Drools facts and rules in the first section. Conditional
branching based on Drools expressions works with facts but not with process
variables. If we want to leverage the Drools expression features in the gateway
constructs, we have to insert the process variable as a Drools fact, for example,
given the process variable order:
Order order = new Order();
order.setNote("urgent");
order.setCost(110);
From inside the process definition (by a Script task, a Task on exit Script, and so on),
we insert the following fact:
kcontext.getKnowledgeRuntime().insert(order);
[ 131 ]
BPMN Constructs
Example process:
gateway_exclusive.bpmn
Description: Different paths are taken for successful Pizza deliveries; the default path
is chosen when other conditions are not met.
Example process:
gateway_inclusive.bpmn
[ 132 ]
Chapter 5
Description: Multiple different paths are taken for evaluation of the order delivery
status; the testIssues test is set up so as to make the process take both the delivery
not on time (deliveryDate > dueDate) and the retries > 1 path. The default path is
chosen when other conditions are not met (see the testNoIssues test).
Event-based gateways
Event-based gateways are similar to exclusive gateways, but the gateway trigger is
based on event occurrence instead of condition evaluation. When our process arrives
at an event-based gateway, we will have to wait until something happens. A specific
event, usually the receipt of a message, determines the path that will be taken.
Basically, the decision is made by another actor on the basis of data that is not visible
to a process. This gateway is always a diverging gateway and must have at least one
event attached.
Example test class:
com.packt.masterjbpm6.gateway.GatewayEventAndTaskTest
[ 133 ]
BPMN Constructs
Example process:
gateway_event_and_task.bpmn
Description: The event gateway has a timer attached; when the timer expires, the
send alert script is executed, bringing the process to termination.
Instantiating gateway
The instantiating gateway is a specialized event-based gateway, which triggers the
process instantiation as soon as an attached event is received. The "instantiate" option
(as of jBPM 6.2 the option is available in the jBPM Eclipse plug-in only) configures
the gateway as a diverging gateway with no incoming connections: this gives you a
way to instantiate a process by using an event, such as timer expiration or a catching
signal event (see the following sections for timers and signals). jBPM does not
support a pure instantiating gateway with no incoming connection: you always have
to link it to a Start "None" event (see the following figure) or the process compilation
will fail (complaining with a "missing incoming connection" error)
Example test class:
com.packt.masterjbpm6.gateway.GatewayEventTest
Example process:
gateway_event.bpmn
[ 134 ]
Chapter 5
Description: Depending on events sent from an external (API call), different paths
are taken (the testCustomerPhoneCallEvent and testDeliveredEvent methods);
the timer triggers after 15 s if no event is caught (the testTimerExpired method).
Note that both catching events pass the signal data (a randomly generated orderid
string) to the process parameter orderid, which is later printed from the script tasks.
Complex gateway
This gateway can be used to model complex synchronization behavior.
The construct options are available at the designer level, but jBPM has no
implementation for this construct.
Events
Events are elements used to model something that happens during the process
lifetime. BPMN 2.0 defines two main event categories: catching and throwing events.
[ 135 ]
BPMN Constructs
Start events
The start event defines where (and how) the process is started; Start events are
catching-only events. When a specific start event trigger fires (timer, messages,
signal, and so on) the process is started. We will now see the None Start event;
the other start event types are discussed in their respective sections.
Supported start events are: None, Message, Timer, Escalation, Conditional, Error,
Compensation, Signal
[ 136 ]
Chapter 5
End events
The End events are meant to express the end of a process or subprocess, and they are
always throwing events. When the process execution arrives in the End event node,
the associated event type is thrown. A process definition can have one or more End
events defined. In this section, we will see the None and the Terminate End event;
the other End event types are discussed in their respective sections.
Supported end events are: None, Message, Escalation, Error, Cancel, Compensation,
Signal, Terminate
Boundary events
Boundary events are events (always catching) that are graphically attached to an
activity (subprocesses included) boundary (see the following figure). The event is
registered for a certain type of trigger (see the following supported boundary events)
and reacts only within the scope of the execution of the attached activity, with slight
variations depending on the event type. In case the event triggers, it can optionally
cancel the activity that it is attached to (by its cancelActivity property), and the
event's outgoing sequence flow is executed. The boundary events are activated when
the attached activity is started; in other words, they are bound to the activity instance
life cycle. When the engine process execution path leaves the activity, all its attached
boundary events are deactivated and their triggering is cancelled.
Supported boundary events are: Conditional, Error, Escalation, Message, Signal, Timer
See the Boundary Message event section for a working example.
[ 137 ]
BPMN Constructs
Signal events
A signal is a generic, simple form of communication, such as messages (see below). We
can use signals to synchronize and exchange information. A catching signal may not
have a corresponding throwing signal construct. It can also be sent programmatically
from an external source (API). In contrast to other events (error event), if a signal
is caught, it is not consumed. If there are two active intermediate catching events
firing on the same signal event name, both events are triggered, even if they are part
of different process instances and definitions. If the signal is sent and there are no
catching signals registered for this event, the event is lost.
Scope
Signals can have visibility between different parts of the same process or broadcast
processes (scope across all process instances), or targeted to a specific process
instance. You can throw a signal event in a process instance, and other process
instances with a different process definition can react to the event. Please keep in
mind that this behavior (broader or narrower signal scope) can be affected by the
runtime strategy chosen to create your Kie session (the subject is discussed in Chapter
6, Core Architecture).
Chapter 5
With a process generated from a jBPM Web console editor, the signal ID is equal to
the name attribute; customerPhoneCall must be used with the API.
This is a very flexible mechanism. By delivering data with your signals, you can
update process variables, convey extra information, or change the process flow
very easily.
[ 139 ]
BPMN Constructs
Example process:
start_signal.bpmn
Description: Different Start Signal events are sent so as to create different process
instances. The signal data is mapped to the process variable (see the previous section
for an explanation of event data mapping).
Message events
Message events reference a name and can optionally have a payload. Unlike a signal,
a message event is always targeted at a single catching message. The name of the catch
and throw messages must be exactly the same in order to make the message flow work
properly. Let us point out some differences between messages and signals:
[ 140 ]
Chapter 5
Inside the BPMN diagram, the message flow is drawn linking the sender to
the receiver, while signals are never directly connected on the diagram. The
throwing and the catching signal are implicitly connected only by their name.
Message Start events are supported only with top-level processes and not with
embedded subprocesses.
[ 141 ]
BPMN Constructs
Example process:
boundary.bpmn
Description: A process with a human task is created. The timer event's duty is to
cycle and expire every 15 s calling the script task "time out warning" (its timer
expression is 15s###15s, and it is not flagged as "cancel activity"; therefore, the task
will not be cancelled as the timer triggers). When the user continues with the test (the
test class asks the user to press a key to proceed), a message is sent (sendSignal),
the process message boundary event is triggered, and the activity is cancelled (since
the boundary message event has the "cancel activity" flag enabled). Note that the
message is sent by our test class with some data that serves as the task cancellation
reason ("cancelled by ADMIN"):
sendSignal("Message-messageCancelService", "cancelled by ADMIN");
[ 142 ]
Chapter 5
[ 143 ]
BPMN Constructs
Example processes:
start_message_catch.bpmn, start_message_throw.bpmn
Timer events
Timer events are events that are triggered when a timer construct expression is met;
the timer properties are as follows:
Timer Cycle: The time expression that shall be evaluated. It can be a string
(interval-based 20 s or 5 m###35 s, where the first value is the initial delay
and the second value is the delay between repeated fires), a string cron
expression, or a process variable. In the case of JBPM 6.x, it can also be
a ISO-8601 formatted date.
Timer Cycle Language: Can be a default interval (empty value and time
duration set) or cron.
[ 144 ]
Chapter 5
Error events
Error events are used to model business exceptions. They are triggered by an
exception that might be generated during the execution of an activity. Intermediary
throw/catch error events do not apply.
Example process:
errorboundary.bpmn
[ 145 ]
BPMN Constructs
Description: Two different boundary error events are attached to the same user
task registered on different errorCode properties (FileNotFoundException or
RuntimeException); the error handler logs the exception message. Depending on
the process parameter (triggerexceptionflag) value passed, the user task throws
a different exception upon completion (the onExit script), which triggers
the appropriate boundary error event.
The process is started with a variable whose value affects the type of exception to
be thrown:
Map<String, Object> params = new HashMap<String, Object>();
// "1" for a runtime exception; "2" for a FileNotFoundException
String trigger = "1";
params.put("triggerexceptionflag", trigger);
ProcessInstance processInstance =
ksession.startProcess("errorboundary", params);
The user task's onExit script evaluates the process variable and throws the
exception accordingly:
String trigger=(String)context.getVariable ("triggerexceptionflag");
if (trigger.equals ("1"))
{
throw new RuntimeException("a runtime exception");
}
else
{
throw new FileNotFoundException("a filenotfoundexception exception");
}
[ 146 ]
Chapter 5
The engine triggers the appropriate boundary error event depending on the
exception thrown; the event, in fact, must be configured with the errorCode
property set to the exception classname: java.lang.RuntimeException
(see the following screenshot).
Note that the boundary error can bind the exception to a process variable. In the
example, this variable (exceptionvar) is logged to the console by the script task:
Throwable exc=(Throwable )context.getVariable ("exceptionvar");
System.out.println("log error message:"+exc.getMessage());
[ 147 ]
BPMN Constructs
Example process:
errorsubprocess.bpmn
Description: The main process features a human task and an Error End event, which
triggers an embedded subprocess Script task by an Error Start event.
Compensation
Complex business processes may involve a number of heterogeneous parties and
systems such as modern transactional systems, legacy systems (not transactional),
and Web services. In order to preserve business consistency, when something fails
and no transactional protocols are available, these systems may require you to
perform programmatic corrective actions by invoking some dedicated API or by any
other means. The compensation is the action of post-processing trying to remedy
(not properly undoing or rolling-back) the effects produced by an action.
We want to stress the fact that jBPM compensations are not a transactional feature or
a try/catch error mechanism. The compensation is a BPM business feature, which
models an activity as the compensating counterpart for an already completed activity.
Here you have the common steps, which take place during a compensation event
(see the following process example figure for a visual reference of the sequence).
Chapter 5
The engine is ignorant of what the compensating activity will do since it is up to the
developer to define the compensating business logic.
Compensating activity
This activity (also called a compensation handler) is directly connected to the
triggering boundary compensation event and must have no outgoing sequence flows.
Example test class:
com.packt.masterjbpm6.event.CompensationTest (method
testCompensationEvent)
Example process:
compensateorder.bpmn
[ 149 ]
BPMN Constructs
You must use the compensation signal type and pass the signal data a string that
results from concatenating the CompensationScope class constant and the process
definition ID resulting in the following:
"implicit:compensateorder"
[ 150 ]
Chapter 5
Example processes:
compensateendsubprocess.bpmn
[ 151 ]
BPMN Constructs
Multi-instance compensation
Compensation catching events attached to a multi-instance subprocess are not
implemented. See the Subprocess section for details about multi-instance activities.
Escalation
Escalation, according to the common policies of an institution, organization, or
corporate, refers to the existing relationships between the working personnel and
their duties. The presence of an escalation event indicates that there is a condition
that requires the business process flow to be diverted to a different user group. For
instance, if an order above a certain price threshold is received, the approval task
must be performed by a user in a higher role (for example, a manager); otherwise,
it can also be approved by a clerk user.
In the case of jBPM 6.2.0, escalation events seem to be partially implemented and it
is not clear what part of the BPMN specification is supported at this stage. You can
partially overcome the lack of an escalation event with Deadlines and Notifications
(see the User Task section).
[ 152 ]
Chapter 5
Conditional events
Conditional events are a jBPM feature extension. They are triggered by an evaluation
of user-provided expressions of Drools rules and facts properties. Conditional Start
and Boundary events are supported.
Example test class:
com.packt.masterjbpm6.event.ConditionalTest (method
testSubprocessStartError)
Example process:
conditional.bpmn
Description: The main process is started when the Fact order note property matches
"urgent"; the following script task ordercost is cancelled if Order cost > 100.
Activities
An activity is a unit of work that is executed within a business process; it can be
atomic or non-atomic (Compound activity, Call activity, or Subprocess). Activities
can be of the Task, Call activity, or Subprocess type.
Task
A task is the smallest atomic activity unit that can be included within a process.
Usually, the performer of the task can be an end user (called human) using a UI-based
application, a participating external service, or a generic set of business statements.
Tasks have their local scope and can accept input parameters from their container and
return output parameters.
[ 153 ]
BPMN Constructs
User Task
A user task is used to model work that needs to be done by a human actor. When
the process execution arrives at the user task node, a new task instance is created in
the work list of the actor(s) or group(s) defined for this task (the Actors and Groups
properties). Human tasks can transition to several different states and involve
human stakeholders depending on the action taken on the task itself and the defined
human roles.
Human roles
Human roles define what a person or a group of actors can do with tasks. Let us
review the roles defined for the human task activities:
Task initiator: The person who creates the task instance. Depending on how
the task has been created, the task initiator may not be defined.
Actual owner: The person who owns the task and is performing it. A task
always has one actual owner.
Potential owners: Persons who are given a task so that they can claim and
complete it. A potential owner can become the actual owner of a task by
claiming it.
State transitions
The task remains in the Created state until it is activated. When the task has a single
potential owner, it transitions into the Reserved state (it is assigned to a single
actual actor); otherwise, it transitions into the Ready state; this state indicates that
the task can be claimed by one of its potential owners. After being claimed, the
task transitions into the Reserved state, elevating the potential owner to the actual
owner actor. At this point, the actor can start the task that is in either the Ready or
the Reserved state and make it transition to the InProgress state. The InProgress
state means that the task is being worked on. If the actor completes the work, the
task transitions into the Completed state. If the completion of the work goes wrong
(exception), the task is put into the Failed state. Alternatively, the user can release the
task, bringing it back to the Ready state. No transition is allowed from the Complete
state and the Failed state.
[ 154 ]
Chapter 5
State transitions
BPMN Constructs
Task reassignment
Task reassignment is a jBPM mechanism that lets you change a task ownership by
setting specific rules, which are based on the task state transition and a deadline time
expression, for example: "if Luigi (a named task actor) does not start the task in 60
seconds then reassign the task instance to Mario." The nominated user is replaced
by the new user as the potential owner for the task. The resulting reassignment rule
syntax is as follows:
[users:mario|groups:]@[60s]@not-started
Example process:
reassign.bpmn
Description: The main process is started, and the task is assigned to Luigi. The
reassign rule states that "if Luigi (named task actor) does not start his task in 60
seconds then the task should be assigned to Mario."
Notifications
A notification is the action of alerting someone (actor, group) when a task deadline
expires. The default jBPM notification is e-mail based, and the default e-mail
configuration is read from the userinfo.properties and email.properties files.
The userinfo.properties file lists the user/group information in the following form:
entityId=email:locale:displayname:[member,member]
Member data is optional and is used for listing members belonging to a group
organizational entity.
[ 156 ]
Chapter 5
Delegation
Delegation is the process of setting a task's potential owners. The actual owners,
potential owners, or business administrators can delegate a task to another user,
adding this user to the potential owners (if he/she isn't already) and making the
user the task owner. A task can be delegated when it is in an active state (Ready,
Reserved, or InProgress) and transitioned into the Reserved state, and its skippable
property can be flagged to true (the target actor/owner can skip the task). The task's
state and parameters will not change after delegation.
Forward
Task forwarding is the process performed by a potential owner on an active task
who replaces himself in the potential owner list, passing the task to another person.
The potential owner can only forward tasks when in the Ready state. If the task is in
the Reserved or InProgress state, the task is transitioned to the Ready state again.
Suspend/resume
A task can be suspended in any of its active states (Ready, Reserved, or InProgress),
transitioning it into the Suspended state. The Suspended state has sub-states to
indicate the original state of the task. When resumed, the task transitions back to the
original state from which it had been suspended.
Skip
A stakeholder working on a human task or a business administrator may decide that
a task is no longer needed and hence, skip this task. This makes the task transition
into the Obsolete state. The task can only be skipped if this capability is specified
during the task configuration (the skippable property).
[ 157 ]
BPMN Constructs
For delegate, forward and skip, and suspend/resume examples have a look at
a test class:
com.packt.masterjbpm6.task.TaskTest (methods
testDelegateReadyStateAndSkip, testForwardAndSkip,
testSuspendAndResume)
Example process:
delegate_forward.bpmn
Description: The main process is started, and a human task is reserved to Luigi.
The test methods check for task delegation, forwarding, and suspend/resume.
Release
A task may be released by the current owner as a human task, making it available
for other potential owners. From active states that have an actual owner (Reserved or
InProgress), a task can be released and transitioned into the Ready state. Task data
associated with the task is kept unchanged.
If a task is currently InProgress, it can be stopped by the actual owner, transitioning
it into the Reserved state. Business data associated with the task as well as its actual
owner is kept unchanged.
Script Task
A Script task is an automatic activity. When a process execution arrives at the Script
task, the corresponding script is executed. All process variables that are accessible
through the execution context (the kcontext variable) can be referenced within the
script. It has the following properties:
The script task transitions to the complete state after the script execution
For a complete MVEL reference, please visit http://mvel.
codehaus.org/.
[ 158 ]
Chapter 5
Example process:
script.bpmn
Description: The process script activity updates the process variable order
description property:
Order order=(Order)kcontext.getVariable ("order");
order.setNote ("order modified");
Service Task
The service task indicates the work that is to be automatically performed by a service
provider. Usually, all work that has to be executed outside the engine should be
designed as a service task. jBPM supports two types of service task implementations:
plain Java class and Web service. The service task is backed by a WorkItemHandler
implementation (org.jbpm.process.workitem.bpmn2.ServiceTaskHandler)
registered with the name Service Task.
The parameters are as follows:
In case of a service task of type Java, jBPM uses Java reflection to load the Java class
type (by using an Interface parameter), instantiate it, and invoke the specified
method (searched by Operation and ParameterType) with the value provided by
Parameter. Only method signatures with a single parameter are supported, and the
result of the invoked method is mapped in the activity Results output parameter.
The Mode parameter applies to a Web service only and describes the way a request
has to be performed:
The Web service runtime leverages the "dynamic clients" features of the Apache CXF
framework in order to generate Java classes at runtime.
[ 159 ]
BPMN Constructs
A Service task can be really useful for rapid prototyping, but when it comes to
complex external service integration, it falls short in meeting common development
needs: multiple parameter passing, additional Web service configuration, and so on.
The following example demonstrates how to override the standard jBPM service
task component by adding a custom workItem handler. Note, however, that the
input/output parameters of the custom service task handler cannot be changed from
the process designer because the task interface is defined in the configuration files of
the jBPM workItem handlers.
WorkItem handlers are thoroughly explained in Chapter 7, Customizing
and Extending jBPM.
Example process:
servicetask.bpmn
Rule Task
The (Business) Rule tasks let us execute rules and get output from the embedded rule
engine (Drools). Remember that process variables can be shared with the Rule tasks
by using global variables or Drools session facts.
Example class:
com.packt.masterjbpm6.task.RuleTaskTest
[ 160 ]
Chapter 5
Description: The main process is started, and the rule task triggers when the order
cost is >100, and as a result, it changes the order's note property to URGENT. Look at
the rule.drl file:
global StringBuffer newnote;
global com.packt.masterjbpm6.pizza.model.Order orderglobal;
rule "checkorder" ruleflow-group "masterRuleGroup"
when
$o: com.packt.masterjbpm6.pizza.model.Order (cost>100)
then
{
System.out.println ("checkorder triggered");
String desc="big order ! (cost="+$o.getCost()+")";
orderglobal.setNote("URGENT");
newnote.append (desc);
}
End
The order variable (with cost > 100) is inserted into the knowledge session to
activate the rule that triggers when Order (cost > 100); see the RuleTaskTest.
testRule() method:
ksession.insert(order);
While the shared orderglobal variable is used to get the result back:
ksession.setGlobal("orderglobal", order);
Send/Receive Task
Send/Receive tasks are general-purpose messaging tasks since they do not
provide a default implementation. They are handled as workItem and it is up
to the implementer to back them with a working implementation through the
WorkItemHandler interface, registering it with the jBPM WorkItemManager.
The workItem name of the receive task must be Receive Task. Receive Task refers to
the message ID through the messageRef attribute; the handler receives the message
ID value with the MessageId parameter.
[ 161 ]
BPMN Constructs
The workItem name of the send task must be Send Task. Send Task refers to the
message ID through the messageRef attribute; for additional reference, check the
Intermediate Message event.
Example class
com.packt.masterjbpm6.task.TaskTest (method testSendReceive)
Description: The subprocess send task passes data to the receive task of the parent
process. The test registers two custom workItem handlers, and the Send task and the
Receive task share a message by using a global process variable.
Manual Task
A manual task defines a task that is to be performed externally to the engine. It
is used to model work that is done by a stakeholder without interacting with the
system; the engine does not know anything about the task, and it does not need to.
There is no UI interface or system available for the manual task completion. For the
engine, a manual task is managed as a passthrough activity. It continues the process
from the moment process execution arrives into it.
[ 162 ]
Chapter 5
The handler is registered for all workItems of the given workItemName and is called
every time the process activates a node with that name. Further, workItemName
must match the taskname attribute of the task element. WorkItemHandler is
responsible for completing or aborting the task instance.
See the Conditional events section for a working example.
Async tasks
We are now going to take a closer look at some peculiar usage of the custom
task. In Chapter 4, Operation Management we introduced the new jBPM executor
service and the job scheduling features of the KIE console. The custom task can be
conveniently configured to instruct the executor to call service-oriented components
in an asynchronous fashion by scheduling an execution job in the background. The
jBPM handler responsible for the job submission is org.jbpm.executor.impl.wih.
AsyncWorkItemHandler (more on this in Chapter 7, Customizing and Extending jBPM).
The jBPM process designer gives you the ability to toggle a waitfor-completion flag on the workitem handler node. This flag does
not reflect the sync/async nature of the handler invocation. It does tell
the engine to evaluate (by an event listener) the handler results and
map them back to the process context variables, using the task output
mapping. If the flag is set to false, the custom task results will be ignored.
(Optional) adding a data input parameter called Retries, which tells the
executor how many times the execution should be retried (default = 3)
Chapter 4, Managing Jobs and Asynchronous Command Execution explains
in detail how to write Command classes.
BPMN Constructs
Example class:
com.packt.masterjbpm6.task.AsyncTaskTest
The following figure shows the main process on the left and the callactivitySub1
process "zoomed out" from the CallActivity node:
[ 164 ]
Chapter 5
The callee construct supports, like other activity nodes (tasks), data input and output
mappings from/to the caller process, as we are going to see in the
following example.
Example class:
com.packt.masterjbpm6.task.CallactivityTaskTest
(testIndependentSubprocess method)
Description: The main process is started and callActivity is executed; the main
process passes the process order variable to callActivity. The callActivity
subprocess modifies the order variable and returns it to the calling process definition.
As a side note, if we examine the PROCESSINSTANCELOG table, we can see the two
instances of the processes (the main and the called process) logged; their parentship
relation is saved through the PARENTPROCESSINSTACEID column; it shows
that callactivitySubprocess is a child process of the callactivityprocess. This is the
output when callActivity has the independent=true and waitforcompletion=true
properties set.
Let us look at another example and see how the independent property affects the
called subprocess.
Example class:
com.packt.masterjbpm6.task.CallactivityTaskTest (method
testAbortProcess)
[ 165 ]
BPMN Constructs
Subprocess
A subprocess, as the name suggests, is a process that is included within another
process. It can contain activities, events, gateways, and so on, which form a boxed
process that is part of the enclosing process. The subprocess can be completely
defined inside a parent process (an embedded subprocess) or can be linked through
a CallActivity element by its ID or Name property. You can link a subprocess (by
callActivity) across different multiple process definitions, reusing common groups
of process elements (activities, gateways, and so on). The embedded subprocess
construct can have multi-instance capabilities (see the MultiInstance section).
However, using a subprocess does impose the following constraints:
Ad hoc subprocess
Ad hoc subprocesses are commonly used when a number of tasks can be selected and
performed in any order (because unspecified or unknown), and there is no execution
dependency between them. Tasks might have unknown dependencies, most often
because they are dynamic and managed by a human user on a case-by-case basis. The
subprocess can complete even if some of the tasks are not executed at all. An ad hoc
subprocess is represented as a subprocess with a tilde () marker at the base.
[ 166 ]
Chapter 5
Because of their nature, ad hoc subprocesses are hard to design and of little use
in real structured business processes; nevertheless, here, we provide you with an
example that you can tweak and experiment with:
Example class:
com.packt.masterjbpm6.task.AdHocSubprocessTest
Description: The ad hoc subprocess has 2 script activities and 1 human task.
The script tasks are signaled, and the human task is completed.
[ 167 ]
BPMN Constructs
Multiple instances
This construct can be used to create multiple instances of a reusable subprocess
definition as well as an embedded subprocess. Passing an input parameter collection
works as the instantiation loop. jBPM will create one instance of the looping process
for each element in the collection. The following figure shows the process with the
embedded multi-instance subprocess (Log pizzas, the parallel symbol denotes that
it is a multi-instance process) and the subprocess attributes. The loop input is the
process variable list and the loop instance parameter (the collection item) is item of
type Pizza. The item variable is visible in the instantiated subprocess scope.
Example class:
com.packt.masterjbpm6.task.MultiInstanceTest
Subsequently, two subprocess instances are created, and each is passed the loop item
variable (a Pizza instance). The subprocess script activity simply prints the pizza
description, and the subprocess exits.
System.out.println("pizza desc " + item.getDesc());
[ 168 ]
Chapter 5
Lanes
A lane is a partitioning box-shaped element used to group activities within the
process definition. Lanes can be used to visually point out different group task
assignments. For example, you can think of a lane as a company department (IT,
business administration, and so on) where all employees have (more or less) the
same duties. jBPM will try to assign (making a task reserved for the user) all tasks
within the same lane to the same user. For example, if there are several tasks on a
lane, the user who claimed and completed the first task will be assigned to the other
tasks on the lane. Usually, it is convenient to assign the same group ID to all the tasks
in the same lane.
Example class:
com.packt.masterjbpm6.task.LaneTest
Description: The task1 and task2 (on lane) activities are assigned to the
pizzerianapoli group, while Mario's Task is assigned to the actor Mario.
taskNotInLane is also assigned to pizzerianapoli but it's not on lane.
After the process is started, the actor Luigi (belonging to the pizzerianapoli group;
see the LaneUserCallBack class) has 2 tasks on the list (task1 and taskNotInLane).
After he completes task1, he is automatically given the task2 activity
(status = Reserved), while the taskNotInLane status remains unchanged (Ready).
[ 169 ]
BPMN Constructs
Data objects
Data objects are BPMN constructs that represent how data is required or produced
by an activity. Data objects can have a direct association to one or more activity
providing the input or the target output for that activity.
Example class:
com.packt.masterjbpm6.task.DataObjectTest
Description: The task1 and task2 activities share the same data object (pizza class type);
the first task produces the pizza, which then serves as the input of the second task.
Summary
In this chapter, we examined the jBPM BPMN constructs, providing hands-on
working examples, tips, and, whenever possible, some details regarding the jBPM
internal mechanisms. The chapter is not meant to be a BPMN tutorial or a BPMN
best practices modeling guide for which we suggest picking more suitable books and
a lot of real-world practice. In the next chapter, we will cover the jBPM subsystems
API with several practical examples: the new Kie API, the runtime engine, the
human task service, and the persistence engine.
[ 170 ]
www.PacktPub.com
Stay Connected: