JBoss jBPM Concepts
JBoss jBPM is built around the concept of waiting. That may sound strange given that software is usually about getting things done, but in this case there is a very good reason for waiting. Real-life business processes cut across an organization, involve numerous humans and multiple systems, and happen over a period of time. In regular software, the code that makes up the system is normally built to "do all these tasks as soon as possible". This wouldn't work for a business process, as the people who need to take part in the process won't always want or be able to "do their task now".
The software needs some way of waiting, until the process actor is ready to do their activity. Then once they have done their activity, the software needs to know what is the next activity in the chain and then wait for the next process actor to get round to doing their bit.
The orchestration of this sequence of "wait, work, wait, work" is handled by the JBoss jBPM engine. The jBPM engine looks up our process definition and works out which way it should direct us through the process. We know the "process definition" better as our graphical process map.
jBPM Process Definition Language—jPDL
We will introduce the key terms and concepts here to get the ball rolling. We won't linger too long over the definitions, as the best way to fix the terminology in the brain is to see it used in context. At this point, we will introduce some core terminologies for a better understanding.
The visual process map in the Designer is an example of what the JBoss jBPM project calls "Graph Oriented Programming". Instead of programming our software in code, we are programming our software using a visual process map: referred to as a "directed graph". This directed graph is also defined in the XML representation of the process we saw in the Source view. The graph plus the XML is a notation set, which is properly called jPDL, the "jBPM Process Definition Language".
A process definition specified in jPDL is composed of "nodes", "transitions", and "actions", which together describe how an "instance" of the process should traverse the directed graph. During execution of the process, as the instance moves through the directed graph, it carries through a "token", which is a pointer to the node of the graph at which the instance is currently waiting. A "signal" tells the token which "transition" it should take from the node: signals specify which path to take through the process.
Let's break this down a little bit with some more detail.
A node in jPDL is modeled visually as a box, and hence looks very similar to the activity box we are used to from our workflow and activity flow diagrams. The concept of "nodes" does subtly differ from that of activities, however.
In designing jPDL, the jBPM team have logically separated the idea of waiting for the result of an action from that of doing an action. They believe that the term "activity" blurs the line between these two ideas, which causes problems when trying to implement the logic behind a business process management system. For example, both "Seek approval" and "Record approval" would be modeled as activities on an activity flow diagram, but the former would be described as a "state" and the latter as an "action" in jPDL: the state element represents the concept of waiting for the action to happen, moving the graph to the next state.
"Node" is therefore synonymous with "state" in jPDL. "Actions" are bits of code that can be added by a developer to tell the business process management system to perform an action that needs to be done by the system: for example, recording the approval of a holiday request in a database. Actions aren't mapped visually, but are recorded in the XML view of the process definition. We'll cover actions a bit later.
There are different types of node, and they are used to accomplish different things. Let's quickly go through them so we know how they are used.
A task node represents a task that is to be performed by humans. If we model a task node on our graph, it will result in a task being added to the task list of the person assigned to that task, when the process is executed. The process instance will wait for the person to complete that task and hand back the outcome of the task to the node.
A state node simply tells the process instance to wait, and in contrast to a task node, it doesn't create a task in anybody's task list. A state node would normally be used to model the behavior of waiting for an external system to provide a response. This would typically be done in combination with an Action, which we'll talk about soon. The process instance will resume execution when a signal comes back from the external system.
Forks and Joins
We can model concurrent paths of execution in jPDL using forks and joins. For example, the changes we made to our model to design our To Be process can be modeled using forks and joins to represent the parallel running of activities. We use a Fork to split the path of execution up, and then join it back together using a Join: the process instance will wait at the Join until the parallel tasks on both sides are completed. The instance can't move on until both chains of activities are finished. jBPM creates multiple child tokens related to the parent token for each path of execution.
In modeling our process in jBPM, there are two distinct types of decision with which we need to concern ourselves. Firstly, there is the case where the process definition itself needs to make a decision, based on data at its disposal, and secondly, where a decision made by a human or an external system is an input to the process definition. Where the process definition itself will make the decision, we can use a decision node in the model.
Where the outcome of the decision is simply input into the process definition at run time, we should use a state node with multiple exiting transitions representing the possible outcomes of the decision.
A node of type "node" is a special type. It allows a developer to write a custom-defined node. Typically, this would be used when a developer needs to write some code to make the system perform an action, but the logic in that code is particularly relevant to the work of the Business Analyst, and they therefore want to see it represented on the graph. If it isn't relevant, then the preferred route would be for the developer to write the code as an Action, thus hiding the details from the visual graph.
Transitions specify the route between nodes. Transitions can be named on the graph, if we need to make them distinct and choose between them during process execution, for example, if we are modeling two potential outcomes to a decision. If the transitions aren't differentiated like this, then the process instance will just take the first available transition.
Actions are aimed at developers. They allow a developer to add Java code to the model that will be executed, as events are triggered in the process execution, for example, entering or leaving a node. This means that we can include programming logic in our model without having to represent it visually. The action is modeled in the source of the process definition, but it doesn't show up on the graph. Typically, actions are going to be used when we need to do something in an automated way that doesn't strictly fall within the scope of the process definition, for example writing some data to a database.
Swimlanes represent process roles, and they are used to assign tasks to specific people. This can either be one actor or a pooled group of actors, where one person from within the pool will pick up the task. Unlike our activity flow diagram, they aren't mapped visually in the process definition, but are added as technical details behind the visual map.
jBPM uses its own component to manage users, although in a real live environment, this can be replaced by a plug into the company's own directory of users, for example the Windows domain. Swimlanes can be modeled as users or groups, depending on which makes the most sense in the context of the process. Sometimes, tasks will always be assigned to an individual user, sometimes, they will be assigned to a group and anyone in that group can pick up the task.
Process variables are the contextual data that a process instance builds up during its execution. Again, process variables are considered technical details and therefore aren't modeled in the visual version of the process definition. In our business process example scenario, we might have a variable called "bandName", which we would need to maintain as context for the process whenever we run it. If we can't provide our process actors with the band name when we ask them to do something, then chances are that they won't be able to do it.
Process state is used when we need to model sub-processes that sit within a higher-level process. This allows us to abstract our models and break down complex models into more manageable chunks. We may well do this at some point with our example business process as we have quite a large end-to-end workflow. This will help us keep our model clean.
Super states are a way of modeling a group of nodes. Typically, we would use this to group a set of nodes into a "phase" of the process. For example, we might specify a group of nodes within our process model as the "manufacturing" phase of the process. This will be a helpful categorization later, when we try to report on the operation of our process.
In this article, we looked at the fundamental concepts that underpin JBoss jBPM. It is only through the use of these fundamental concepts that we would be able to build any kind of process definition. jBPM Process Definition Language (jPDL) is also introduced in this article.