BonitaSoft Custom Application Development
BonitaSoft Custom Application Development
Contents
1. Introduction
Creating applications with Bonita Open Solution is easy with the help of Bonita Web
Application Builder which dramatically reduces the need for coding. But sometimes
developers may want to break away from Bonita end-user technology either to create highly
customized interfaces - using for example a different framework than GWT (Google Web
Toolkit) used in Bonita User Experience - or embed Bonita Execution Engine in even more
complex applications, which is possible through the use of Bonita Execution Engine APIs.
Bonita Execution Engine - also referred as “Runtime” in this paper - was designed to provide
a lot of flexibility through service injection. It is a completely configurable engine using an
XML file called “environment”. This configuration describes all services used. You can change
all of them or replace them with your own implementation.
In addition, Bonita Execution Engine is non-intrusive, meaning that it requires only Java. You
can install it in any JVM of your choice, in any web/JEE container or use it as a simple Java
library. Another remarkable feature of Bonita Execution Engine is that it supports for
command injection, allowing you to create your own operations in the Runtime.
The white paper aims at helping you understand how you can use Bonita Execution Engine
for your custom developments.
Bonita Execution Engine APIs use 2 different object models: ‘Definition‘ and ‘Runtime‘.
uuid
name
label
description
version
state
deployedBy
deployedDate
undeployedBy
undeployedDate
ProcessDefinition also contains a set of other entities: e.g. datafields, participants, activities,
attachments, metadata. The most used entities are: activities, datafields and participants.
All major elements in the ‘Definition‘ object model have the following fields in common:
uuid to identify uniquely an object
name
label
description
All objects which are children of ProcessDefinition also have direct access to the parent
process uuid.
instanceUUID
processUUID
state
startedBy
startedDate
endedBy
endedDate
activities
variables
attachments
involvedUsers
variableUpdates (history of all variables assignments during the process instance life)
stateUpdates (history of all states assignments during the process instance life)
started: the process instance is started and currently executing (some activities still have
to be done)
finished: the process instance has reached the end and is finished
canceled: an admin user has manually canceled this instance and it can no longer be
executed
aborted: an internal error has aborted this instance and it can no longer be executed
3. Using APIs
Bonita Execution Engine provides a very useful feature related to environment management.
This feature ensures that your application is not dependent on the target deployment
architecture. You can develop your application inside a simple web container and then
deploy it on a JEE server without modifying your Java code. This is automatically done
through AccessorUtil capabilities.
Bonita Execution Engine provides different APIs organized by the following concepts:
ManagementAPI
QueryDefinitionAPI
query operations related to the ‘Definition’ object model. These operations do not
modify the persisted objects.
e.g. getProcesses(), getProcess(processUUID), getProcessActivities(processUUID,
activityName)
RuntimeAPI
QueryRuntimeAPI
Query operations related to the ‘Runtime’ object model. These operations do not modify the
persisted objects.
CommandAPI
IdentityAPI
BAMAPI
Bonita Execution Engine can be exported from Bonita Open Solution Studio in ‘Process‘
menu and then ‘Export Application…’ menu entry. You only have to tick ‘Export Runtime’
option and click the ‘Finish‘ button.
You have now access to Bonita Execution Engine distribution. As you can see, it is mainly
composed by 3 different folders: ‘conf‘, ‘ear‘ and ‘lib‘.
Let’s start with one of the most important one: ‘lib‘. It is composed by 2 folders ‘client‘ and
‘server‘ - it is a very important distinction that you have to keep in mind when integrating
Bonita Execution Engine in your applications. Bonita Server module has a dependency on
Bonita Client module not vice versa. You also have to know that Bonita Server contains
Bonita Client.
Let me just define what is ‘Bonita Client side’ and ‘Bonita Server side’. In a very simple
architecture – i.e. all web applications + runtime installed within the same web server –
there is no real ‘client side’. In a more complex architecture you can install Bonita Execution
Engine in a JEE server and web applications in another web container. In this case, web
applications are on the client side.
There are many configuration points available both in client and server side.
This file is embedded in bonita-server.jar and is also provided in Bonita Execution Engine
distribution. This xml file defines all services used by the Execution Engine and you can
configure all of them either by modifying the embedded bonita-default-environment.xml file
or by defining bonita environment Java System property on the server side and linking your
own bonita-environment.xml (e.g. the one provided in the distribution).
Bonita Execution Engine only needs to know who is the current logged user to store this
information in its history. To get the userID, Bonita Execution Engine is calling a service
described in the environment xml file called ‘security‘.
By default, ‘org.ow2.bonita.facade.AutoDetectSecurityContext‘. This class uses an algorithm
to detect the current architecture: if no Bonita EJB3 can be reached, then try to lookup a
Bonita EJB2 and if none is found, the local architecture is used. In all these cases, the userId
is propagated from client side to server side using JAAS. This is not mandatory but this is the
default implementation. If you are integrating the runtime with a tiers application which for
example stores the userId in a session, you can write your own implementation of the
security service which is going to read the userId in this session.
If you want to use the default mechanism, you have to use JAAS to propagate the userId to
the server. Bonita Execution Engine distribution comes with a set of default JAAS
configuration files for widely used architectures either in local, with JBoss or with JOnAS
applications servers. On the client side, you have to login against the default login Module
(called Bonita) or one of your choice. Don’t forget to set Java System property to this JAAS
file (java.security.auth.login.config: see above).
5. Using EJBs
Bonita Execution Engine distribution contains an ‘ear‘ folder. In this folder, all necessary
artifacts are provided to build an ear containing Bonita Execution Engine ejbjar and all its
dependencies. The generated ear is build using the ‘conf‘ folder, i.e. if you modify
hibernate.properties files or environment, changes will be used in the ear. ‘ear‘ folder also
contains deployment descriptors for JBoss, JOnAS, Weblogic and Glassfish (EJB3 only).
If you want to include other deployment descriptors, you can add your own in this folder.
You can build ear files for both EJB3 and EJB2 by calling ear.ejb3 or ear.ejb2 from the root
folder of the distribution. Once the ear file is generated, you have to install it in your
preferred JEE application server and then start the server with the Java System properties:
6. Using commands
Bonita Execution Engine is providing its very useful mechanism called ‘Commands’ which
allows developers to write their own commands inside the Bonita Execution Engine Server. A
command is a Java class implementing org.ow2.bonita.util.Command interface. There is only
one operation to implement:
To execute a command, you have to make it available in both client and server side
classpath. You can do that either by
having the jar file containing the command available in the classpath (Env property or
common lib folder in a web container for example)
including the command compiled class in the deployed bar file
deploying the jar file containing the command inside Bonita class loader using
ManagementAPI
A command has many benefits and can be used for different purposes. A command is
executed on the server side and you have access to the entire runtime inside (I mean not
only APIs but all internal objects, services…). Let me give you the reasons why you could use
Commands:
1. Transaction: you want that a sequence of APIs calls to be executed in the same
transaction. e.g. you want to create a new ProcessInstance and then set some
variables. If setVariable call fails and you are doing that outside of a command, then
your ProcessInstance remains “created”. If the behavior you want is “Do no create
the ProcessInstance if something fails” then you have to write your own command
with these 2 calls inside.
2. Bug fixing: you’ve identified a bug in an API operation and you want to fix it without
waiting for the next maintenance release. You can use all internal Object model and
services to implement the needed feature without bug
3. Missing operation: APIs are offering a wide scope of operations but maybe you miss
one important thing for your application? In that case, you can use the commands
mechanism to implement your own feature just as explained in point 2.
You can find an example of commands in the community source explorer here.
In this chapter, I am going to help you to get started with your first Bonita project using
Maven. In this example I am going to setup a very simple architecture without any container
(neither Web neither EJB). Bonita Execution Engine is going to be used as a simple library.
This example will illustrate basic operations of the APIs such as
deploy process
instantiate process
get task list
execute task
…
This example will use a very simple process inside Bonita Open Solution Studio. This process
contains only 2 human tasks, both assigned to the process instance initiator:
Let’s start with our 5 minutes setup using my favorite IDE: Eclipse.
First of all, you can create a new simple maven project with the following parameters:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd"
<modelVersion>4.0.0</modelVersion>
<groupId>org.bonitasoft.example</groupId>
<artifactId>runtime</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<name>runtime</name>
<url>http://www.bonitasoft.org</url>
<parent>
<groupId>org.ow2</groupId>
<artifactId>ow2</artifactId>
<version>1.1</version>
</parent>
<dependencies>
<dependency>
<groupId>org.ow2.bonita</groupId>
<artifactId>bonita-server</artifactId>
<version>5.0.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
</dependency>
</dependencies>
</project>
Our maven project is now configured, we can start coding! In this application, we are going
to do the following operations:
1. login
2. deploy the bar file
3. create a new process instance
4. get task list and execute ‘task1′
5. assign ‘task2′ to another user and then back to the logged user
6. execute ‘task2′
7. check created process instance is finished
8. clean the database (delete all processes)
9. logout
/**
* Copyright (C) 2009 BonitaSoft S.A.
* BonitaSoft, 31 rue Gustave Eiffel – 38000 Grenoble
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2.0 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.bonitasoft.example.runtime;
import java.io.File;
import java.util.Collection;
import javax.security.auth.login.LoginContext;
import org.ow2.bonita.facade.ManagementAPI;
import org.ow2.bonita.facade.QueryRuntimeAPI;
import org.ow2.bonita.facade.RuntimeAPI;
import org.ow2.bonita.facade.def.element.BusinessArchive;
import org.ow2.bonita.facade.def.majorElement.ProcessDefinition;
import org.ow2.bonita.facade.runtime.ActivityState;
import org.ow2.bonita.facade.runtime.InstanceState;
import org.ow2.bonita.facade.runtime.TaskInstance;
import org.ow2.bonita.facade.uuid.ProcessDefinitionUUID;
import org.ow2.bonita.facade.uuid.ProcessInstanceUUID;
import org.ow2.bonita.util.AccessorUtil;
import org.ow2.bonita.util.BonitaConstants;
import org.ow2.bonita.util.BusinessArchiveFactory;
import org.ow2.bonita.util.SimpleCallbackHandler;
You can now launch this application like a Java Main: right click on the background and ‘Run
As -> Java Application’. If you want to use this example as a basis for your applications, you
can download it here: Compressed example
Example 2: Write your own Web applications with Bonita Execution Engine
Bonita Open Solution Studio is generating web applications for your processes using GWT
(Google Web Toolkit) technology. In some cases, this may not fit your needs as you want to
use another technology to develop your BPM applications. In that case, you can still leverage
Bonita Execution Engine – or runtime – functionalities by using APIs. In this example I’m
going to explain in details on how to use major APIs operations to create your own Web
application based on Bonita Execution Engine.
Application functionalities
To build this example application, I decided to use a different web technology than GWT to
demonstrate Bonita Execution Engine that can be leveraged in all Java compliant Web
technologies: Java Server Pages. The project contains different folders, so let me explain
what is the content of each of them.
In this section I’m going to explain all API calls performed in this application.
login.jsp
Bonita Execution Engine does not require JAAS authentication but this is the default
configuration. It comes with 2 different login modules:
BonitaAuth in charge of authenticating the user with the given login and password
BonitaStore in charge of propagating the user credentials to the server (in our case,
the runtime is embedded in the application, so credentials are stored in a
ThreadLocal)
You can see that both login modules are used. You will see in other jsp files that only
BonitaStore is called before using APIs. Once the user is authenticated, we store the user
name in the web session and we only need to propagate the user name to the server before
calling APIs. This jsp file also determines and stores in the web session if the user has admin
rights or not.
logout.jsp
In this action, we only remove information stored in the web session to force a new login.
apiCall.jsp
This jsp file is in charge of executing all “usual” Bonita Execution Engine API calls. This file has
2 required parameters:
back: the name of the jsp file to which the user must be redirected after the api call
action: the id of the action to execute
This file may have been split in one file per API action but to prevent code duplication, I
wrote everything in the same file.
home.jsp
tasks to perform
o queryRuntimeAPI.getLightTaskList(ActivityState.READY)
o returned objects are “light” objects as we do not need all information of the
retrieved activities
done tasks
o queryRuntimeAPI.getLightTaskList(ActivityState.FINISHED)
o returned objects are “light” objects as we do not need all information of the
retrieved activities
startable processes
o queryDefinitionAPI.getLightProcesses(ProcessDefinition.ProcessState.ENABLE
D)
o returned objects are “light” objects as we do not need all information of the
retrieved processes
taskDetails.jsp
task properties
o queryRuntimeAPI.getTask(ActivityInstanceUUID)
o using all task getters
local variables
o task.getLastKnownVariableValues()
o also retrieve activity datafields to get type information
activityDefinition =
queryDefinitionAPI.getProcessActivity(ProcessDefinitionUUID,
activityName)
activityDefinition.getDataFields()
global variables
o queryRuntimeAPI.getProcessInstanceVariables(ProcessInstanceUUID)
o also retrieve process datafields to get type information
queryDefinitionAPI.getProcessDataFields(ProcessDefinitionUUID)
processes.jsp
This page displays a form to deploy a new bar file and 2 tables:
processes of the journal (runtime database). This table is paginated: only the 20 first
processes (by name) are retrieved
o journalQueryDefinitionAPI =
AccessorUtil.getQueryDefinitionAPI(AccessorUtil.QUERYLIST_JOURNAL_KEY)
o journalQueryDefinitionAPI.getLightProcesses(0, 20)
o returned objects are “light” objects as we do not need all information of the
retrieved processes
processes of the history (history database). This table is paginated: only the 20 first
processes (by name) are retrieved
o historyQueryDefinitionAPI =
AccessorUtil.getQueryDefinitionAPI(AccessorUtil.QUERYLIST_HISTORY_KEY)
o historyQueryDefinitionAPI.getLightProcesses(0, 20)
o returned objects are “light” objects as we do not need all information of the
retrieved processes
instances.jsp
instances of the journal (runtime database). This table is paginated: only the 20 first
instances (by last update date) are retrieved
o journalQueryRuntimeAPI =
AccessorUtil.getQueryRuntimeAPI(AccessorUtil.QUERYLIST_JOURNAL_KEY)
o journalQueryRuntimeAPI.getLightProcessInstances(0, 20)
As you can see in jsp files, “light” objects are used as much as possible. In fact this improves
performance as light objects do not execute “join tables” in the database. I advise you to do
such a thing as much as possible.
You can download the bonita-application source code and the pre packaged version of this
example.
9. Conclusion
As described in this paper, Bonita Execution Engine provides great flexibility for your custom
application developments through the use of its APIs.
Whether you just want to integrate BPM capabilities in a Portal based on a specific
framework or you want to build complex applications making the most of the power and
effectiveness of Bonita Execution Engine, the way to achievement is not paved with such a
great complexity.
Last but not least, Bonita Execution Engine is released under LGPL license, offering you
multiple opportunities for developing simple to complex customized process-based
applications.
About BonitaSoft
BonitaSoft is the leading provider of open source business process management (BPM) software.
Created in 2009 by the founders of Bonita project, BonitaSoft democratizes the use of BPM in companies
of all sizes with an intuitive and powerful solution with an optimum cost. The Bonita solution has been
downloaded more than 370.000 times to date by companies and organizations worldwide.
Sales inquiries : [email protected] | Partner inquiries : [email protected]
www.bonitasoft.com bonitasoft.com/blog twitter.com/bonitasoft youtube.com/bonitasoft