站内搜索: 请输入搜索关键词
当前页面: 在线文档首页 > JBoss JBPM 3.0.4 userguide 英文版文档

Chapter 4. Graph Oriented Programming - JBoss JBPM 3.0.4 userguide 英文版文档

Chapter 4. Graph Oriented Programming

The current landscape of workflow and business process management (BPM) solutions is extremely fragmented. Little concensus can be found in tools, specs and the academic community. The traditional approach has lead to monolithic, heavy-weight systems that have combined a lot of functionalities in a single system.

A missing feature in the Java programming language has led to a whole series of solutions in this space. This article will identify the missing feature and propose a simple solution for it called graph oriented programming. Graph oriented programming is to be seen as a common building block for workflow, BPM and orchestration solutions.

4.1. Missing link

Let's start with a high level look at the current landscape of solutions in the fields of workflow, BPM and orchestration.

Overview of the workflow, BPM and orchestration landscape

Figure 4.1. Overview of the workflow, BPM and orchestration landscape

While there are no clear and general accepted definitions of workflow, BPM and orchestration, we can make some general observations.

Workflow is mostly related to the management of tasks for people. The core focus of a workflow process specifies tasks performed by humans are related to achieve a certain process goal.

Business process management, combines workflow with enterprise application integration (EAI). A business process specifies a combination of human tasks with pieces of software and how they are related to accomplish the business process goal.

Orchestration is mainly different by it's environment. Orchestration languages (like BPEL) are targetted towards a web service environment. An orchestration language is a programming language for (web) services. This means that you can write a new webservice by orchestrating other web services. Orchestration languages have control flow constructs as in regular programming languages. But the primitive operations are calls to other web services.

Now, we want to highlight a common aspect in these three fields. It is the ability to have wait states as part of the processes. Executions of these processes needs to suspend execution during the wait states.

Suspending an execution in java is not possible. Actually, it is possible to suspend and resume a thread in java (with e.g. Object.wait() and Object.notify()). But this does not match the needs for the process wait states because of persistence. Workflow, BPM and orchestration solutions need to persist their execution during wait states. In fact, state changes in a process should correspond to transactions on a server. Inbetween those transactions the suspended execution should be persistable in e.g. a database or on the file system.

Suspending the path of execution is a missing feature in Java.

Figure 4.2. Suspending the path of execution is a missing feature in Java.

Actually, it is not so surprising that java does not have a built-in mechansim for suspending and persisting executions. That is because java is built on top of the Von Neumann architecture. This essentially comes down to an environment for executing a sequence of instructions. This article presents a technique for extending the Von Neumann architecture for supporting the suspension and persistence of executions.

Products in the three fields have all solved this problem in their own way, from their own perspective. As a consequence, each solution combined a technique for suspending an execution with a whole lot of other functionalities. This is the fundamental reason why these topics are perceived as confusing and unclear by the development community.

4.2. Graphical representation and the development process

One aspect is quite important and needs to be mentioned before we propose a solution for suspending an execution : Graphical representation of a process.

The technical ability to suspend an execution creates a very interesting opportunity : a direct link between the business process and the technical implementation. The business process is a central part of the requirements specified by the business analyst. Without a mechansim for suspending executions, the implementation of the business process requires a complex translation into a software design. In that case, the developer will have to store the executional state in some form in the database during wait states. This complexity is added and combined with the functional requirements of the business process.

The conclusion is that it would be great if we could find a solution for suspending an execution that is related to the graphical representation of a business process. Many (probably all) of the graphical representations of business processes are based upon a directed graph. Some of the process languages are limited to a tree which is a subset of a directed graph. Those languages are called block structured languages.

An important consideration is that the proposed solution should embrace iterative development. With UML class diagrams, this is an established practice. The analyst can draw an analysis model in an UML class diagram. Then the developer takes this model as a starting point and transforms it into a design model. Adding more technical details will result in an implementation. Too many proposed solutions ended up in being visual programming environments.

4.3. Traditional approach

The traditional approach is to specify a process language as a set of constructs. Each construct has a graphical representation and a runtime behaviour.

There are substantial drawbacks to this generally used approach:

  • Monolithic systems: traditionally workflow, BPM and orchestration solutions are packaged as monolithic systems which require a separate environment. In most cases this means that they are hard to use in your applications and difficult to manage because they are outside the scope of your own applications.
  • Incomplete process language: Academic research (workflowpatterns.com) has pointed out that all current standards and solutions have serious limitations even when the scope of this research is limited to control flow constructs.
  • No modelling freedom: By having a fixed link between the graphical representation and the runtime behaviour of process constructs, the analyst looses the freedom of modelling. The drawing of a construct immediatly includes all implementation details with which the business analyst should not be not concerned.
  • Visual programming: As a consequence of the fixed link between graphical representation of process constructs and their runtime behaviour, this always ends up in some form of visual programming. From experience, we know that this is a very time-consuming way of writing software.

4.4. What is Graph Oriented Programming

Graph oriented programming is a technique for solving problem of suspending and persisting an execution. Because of its limited scope, this technique, is easy to understand and serves as the building block for other functionalities targeted by workflow, BPM and orchestration solutions.

The central idea of Graph Oriented Programming is that a we complement plain imperative programming with a runtime model for executing graphs. So a graph is specified as part of the software and at runtime, executions of the graph are coupled to the execution of the imperative programmed software.

A process graph is made up of Nodes and Transitions. Transitions have a direction and connect two nodes in the graph.

A process is a directed graph

Figure 4.3. A process is a directed graph

The graph can be seen as a state machine. Although, the executional model that we will explain here is concrete and has better support for concurrent paths of execution.

The following UML class diagram sketches how the process elements can be modelled in an UML class diagram. This also shows that a process graph can be represented as data. The process graph data can be expressed in different formats : XML, java objects, records in a database,...

A process graph can be modelled with nodes and transitions

Figure 4.4. A process graph can be modelled with nodes and transitions

The next part is the most difficult part to understand for programmers and technical people. That is because we are specifying an executional model that differs from the well known Von Neumann architecture.

We define a Token as a path of execution. It's a path of execution within one system.

A token is a path of execution in one system

Figure 4.5. A token is a path of execution in one system

Note that an execution of a process can involve multiple concurrent paths of execution. We now define an execution of a process as a tree of tokens. A token has a pointer to a node in the process graph.

The execution of a process can be represented as a tree of tokens

Figure 4.6. The execution of a process can be represented as a tree of tokens

The following UML class diagram shows the tree of tokens modelled as a UML class diagram. This is included to show that an execution of a process can be represented as data. This is actually the crucial part of making an execution persistable.

The data model for the execution of a process

Figure 4.7. The data model for the execution of a process

Now, we'll explain how the execution of java can be coupled to the execution of the graph. The next image shows the methods in Node and Transition that are involved in graph execution. To calculate the next state of an execution, we propose a modified version of the chain of responsibility pattern as described by the GOF 'Design Patterns' book.

Graph execution is a variant of the chain of responsibility pattern

Figure 4.8. Graph execution is a variant of the chain of responsibility pattern

The Nodes in the graph can represent wait states. During a wait state, a Token points to that Node. Each Token that is in a Node can receive a signal. A Signal can be send to a Token to resume execution after a wait state is finished. This will cause the graph execution to start.

A Signal is the trigger that resumes graph execution

Figure 4.9. A Signal is the trigger that resumes graph execution

The effect of this signal is that the Token will leave the node. In case the node has more then one leaving transition, the leaving transition has to be specified as part of the signal. Transitions just take a Token to the destination Node. When a token arrives in a Node, the Node is executed. Each node in the graph is of a specific type that determines its runtime behaviour. Each node type corresponds to a subclass of Node and the behaviour is implemented in the execute-method.

The node's execute-method has 2 responsibilities. First, it can perform some business logic, related to the type of the node. E.g. sending a message, updating a database, creating a task for a user,... And the second responsibility of the node's execute-method is the propagation of the graph execution. If the node does not propagate the execution, it behaves as a wait state. It can propagate the token that arrived in the node down one of the leaving transitions. Or it can create new Tokens and propagate those down the leaving transitions.

Graph execution ends when all tokens have entered a wait state. At that time, the signal has been completely processed and the complete process execution (that is made up of a tree of tokens) enters a new overall wait state. At this time, the tree of tokens can be persisted. Each token is now waiting to receive another signal.

One crucial refinement of this model is necessary : Actions. Actions are pieces of java code that are executed upon events in the process. Examples of events are 'leaving a node', 'entering a node' and 'taking a transition'. These are all instantanious events that cannot span wait states.

The refinement of the graph execution model with actions is necessary because this allows the technical developer to add implementation details to the business process, without having to change the graph that was originally created by the business analyst.

Now we can summarize how this model solves the traditional problems of workflow, BPM and orchestration solutions.

  • Simple API + chain of responsibility: replaces monolithic systems.
  • Inheriting from Node: gives ultimate process language power.
  • Adding ‘invisible’ Actions: gives modelling freedom to the business analysts.
  • Process development cycle: replaces visual programming.

4.5. Building blocks

The model that we have presented adds support for wait states to plain programming. With graph oriented programming we can now define paths of execution that span wait states. This model can be used as the basis for implementing workflow, BPM and orchestration functionalities.

Graph Oriented Programming as a building block

Figure 4.10. Graph Oriented Programming as a building block

Structured programming, Object Oriented Programming (OOP) and Aspect Oriented Programming (AOP) can all be seen as mechanisms to structure software. Graph Oriented Programming can also be seen as another mechansim to structure software. Adding structure to software is crucial for managing the complexity. Since the cost of software projects increases exponentially with their size, the cost savings of an extra mechanism to reduce the complexity can therefore be huge.