Showing posts with label jbpm_tutorial. Show all posts
Showing posts with label jbpm_tutorial. Show all posts

2014/02/10

Reuse your business assets with jBPM 6

As described in the article about deployment model in jBPM 6, business assets are included in so called knowledge archives - kjars. Kjar is nothing more than regular jar file with knowledge descriptor - kmodule.xml that is under control of Apache Maven. But there is more in this...

Since kjars are managed by maven one kjar can declare other kjar as its dependency. Which means that assets included in the dependent one will be available for execution as well. That is all available when working with jbpm console (aka kie workbench). So to provide more information on this let's look at an example.

Use case definition

There is a need to prepare a simple registration process that will ask user who starts the process for basic personal information like name, age. Then there will be some business rules that will evaluate if that person is adult or a teenager. Once completed it will be presented to reviewer to see the details of the evaluation. Last but not least is to proceed with actual registration in the system. So we can see that there is part of this logic that might be a very well considered a reusable - part that is responsible for gathering information about a person.

So let's design it this way:

  • first project - reusable project - will actually deal only with gathering personal information and presenting that to verifying personnel after business rules were evaluated.
           As you can see, besides business assets data model is included in reusable-project so it can
           be used by projects that declare it as dependency, same as with any other Maven based project.
  • second project - top project - will provide additional process logic on top of the common collect info procedure and do registration stuff.
So, this is the structure of the projects we are going to use to support the case described.

What must be actually done to make this work? First of all the reusable project needs to be created as it will be a dependency of the top project so it must exists. In the reusable project we need to define knowledge base and knowledge session to disable auto deploy, as we don't want to have it on runtime as a standalone project but included in top project.  With that said we create:
  • one knowledge base (kbase) - ensure it's not marked as default
  • one stateful knowledge session (ksession) - ensure it's not marked as default
  • include all packages - use * wildcard for it
Note: we do this to illustrate what configuration options we have here and to ensure that auto deployment to runtime environment will not be possible - no default knowledge base and knowledge session.

Let's create this collect info process that could look like this:
a simple process, two user tasks and business rule task. So what will it do:
  • Enter person details will collect personal information from a user - name and age
  • Evaluate will execute business rules that are responsible for marking given person as adult if (s)he is older than 21
  • Verify simply presents the results of the process
Both rule and user tasks operate on data model, to be more specific org.jbpm.test.Person class. It was created using Data Modeler and places inside the kjar.
Next process and tasks forms are generated and altered to ask for the right information only. Person class includes three properties:
  • name - string
  • age - integrer
  • adult - boolean
Since we have business rules for evaluating if user is adult or teenager we don't want to ask for it via forms. So these are removed from the "Enter person details" task.
With all that we are ready to build the project so it can be used as dependency. So, just hit the build and deploy button in Project Editor and observe Problems Panel. If everything went ok, it will display single error saying that deployment failed because it cannot find defaultKBase. That is expected as we defined knowledge base and knowledge session that is not marked as default and thus auto deploy fails. But the kjar is available in maven repository so it can be used as dependency.

Next we create top project and add single dependency to it of reusable-project. This is done in Project Editor in Dependencies list section. You can add it from repository as it's already built. Next we need to define knowledge base and knowledge session:
  • one knowledge base (kbase-top) - ensure it's marked as default
  • one stateful knowledge session (ksession-top) - ensure it's marked as default
  • include all packages - use * wildcard for it
  • include kbase defined in reusable project - kbase
Note: make sure that names do no collide between kjars as that will result in failing compilation of knowledge base.

Now we are ready to create our top level process that could look like this:

Again simple process, that will:

  • log incoming request for registration using script task - Log registration
  • invoke common part to collect info - Collect Info - by invoking the reusable project process, rules, forms etc
  • and lastly will show the outcome of the collection process for approval
The most important part here is that Collect Info activity will use process (and other assets) from another kjar thanks to usage of maven dependencies and kbase inclusion.

To examine this example in details you can clone the repository in your jbpm console (kie workbench) and build both projects - first reusable project and then top project. 

This illustrates only the top of the mountain that is provided by maven dependencies and knowledge inclusion in jBPM 6. I would like to encourage you to explore this possibilities and look at options to reuse your knowledge in structured and controlled way - remember this is all standardized by maven so things like versioning are supported as well.

This is a feature that will be available in 6.1.0 so feel free to jump into the wild right away by making use of it in nightly builds. Comments and feedback are welcome.


2014/01/20

jBPM 6 with spring

As some of you might noticed jBPM got quite few improvements for version 6.0, to just name few:

  • RuntimeManager
  • enhanced timer service
  • new deployment model - based on kjar and maven
  • brand new tooling 
  • see release notes for more
there is (as always) still room for improvements. After 6.0 went out, we started to look at how we could ease the usage of jBPM in Spring based applications on top of the new API. Lots of the API is now based on the concept of fluent API which is not really Spring friendly.
Before we dive into details of the API and how it can be used in Spring let's look at possible usage scenarios that users might be interested in:

  • Self managed process engine
This is the standard (and the simplest) way to get up and running with jBPM in your application. You only configure it once and run as part of the application. With the RuntimeManager usage, both process engine and task service will be managed in complete synchronization, meaning there is no need from end user to deal with "plumbing" code to make these two work together. 
  • Shared task service
There could be a need in certain situations, that a single instance of a TaskService is used. This approach give more flexibility in configuring the task service instance as it's not behind RuntimeManager. Once configured it's then used by the RuntimeManager when requested. RuntimeManager in such situation will not create new instances of task service as it's done with self managed process engine approach.

To provide spring based way of setting up jBPM, few factory beans where added:

org.kie.spring.factorybeans.RuntimeEnvironmentFactoryBean


Factory responsible for producing instances of RuntimeEnvironment that are consumed by RuntimeManager upon creation. It allows to create following types of RuntimeEnvironment (that mainly means what is configured by default):
  • DEFAULT - default (most common) configuration for RuntimeManager
  • EMPTY - completely empty environment to be manually populated
  • DEFAULT_IN_MEMORY - same as DEFAULT but without persistence of the runtime engine
  • DEFAULT_KJAR - same as DEFAULT but knowledge asset are taken from KJAR identified by releaseid or GAV
  • DEFAULT_KJAR_CL - build directly from classpath that consists kmodule.xml descriptor
Mandatory properties depends on the selected type but knowledge information must be given for all types. That means that one of the following must be provided:
  • knowledgeBase
  • assets
  • releaseId
  • groupId, artifactId, version
Next for DEFAULT, DEFAULT_KJAR, DEFAULT_KJAR_CL persistence needs to be configured:
  • entity manager factory
  • transaction manager
Transaction Manager must be Spring transaction manager as based on its presence entire persistence and transaction support is configured.  Optionally EntityManager can be provided to be used instead of always creating new one from EntityManagerFactory - e.g. when using shared entity manager from Spring. All other properties are optional and are meant to override the default given by type of the environment selected.

org.kie.spring.factorybeans.RuntimeManagerFactoryBean

FactoryBean responsible for creation of RuntimeManager instances of given type based on provided runtimeEnvironment. Supported types:
  • SINGLETON
  • PER_REQUEST
  • PER_PROCESS_INSTANCE
where default is SINGLETON when no type is specified.  Every runtime manager must be uniquely identified thus identifier is a mandatory property. All instances created by this factory are cached to be able to properly dispose them using destroy method (close()).

org.kie.spring.factorybeans.TaskServiceFactoryBean

Creates instance of TaskService based on given properties. Following are mandatory properties that must be provided:
  • entity manager factory
  • transaction manager
Transaction Manager must be Spring transaction manager as based on its presence entire persistence and transaction support is configured. Optionally EntityManager can be provided to be used instead of always creating new one from EntityManagerFactory - e.g. when using shared entity manager from Spring. In addition to above there are optional properties that can be set on task service instance:
  • userGroupCallback - implementation of UserGroupCallback to be used, defaults to MVELUserGroupCallbackImpl
  • userInfo - implementation of UserInfo to be used, defaults to DefaultUserInfo
  • listener - list of TaskLifeCycleEventListener that will be notified upon various operations on tasks
This factory creates single instance of task service only as it's intended to be shared across all other beans in the system.


Now we know what components we are going to use, so it's time to look at how we could actually configure our spring application to take advantage on jBPM version 6. We start with the simple self managed approach where we configure single runtime manager with inline resources (processes) added.

1. First we setup entity manager factory and transaction manager:

  <bean id="jbpmEMF" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="org.jbpm.persistence.spring.jta"/>
  </bean>

  <bean id="btmConfig" factory-method="getConfiguration" class="bitronix.tm.TransactionManagerServices">
  </bean>

  <bean id="BitronixTransactionManager" factory-method="getTransactionManager"
        class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig" destroy-method="shutdown" />
  
  <bean id="jbpmTxManager" class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="transactionManager" ref="BitronixTransactionManager" />
    <property name="userTransaction" ref="BitronixTransactionManager" />
  </bean>
with this we have ready persistence configuration that gives us:
  • JTA transaction manager (backed by bitronix - for unit tests or servlet containers)
  • entity manager factory for persistence unit named org.jbpm.persistence.spring.jta
2. Next we configure resource that we are going to use - business process

<bean id="process" factory-method="newClassPathResource" class="org.kie.internal.io.ResourceFactory">
  <constructor-arg>
    <value>jbpm/processes/sample.bpmn</value>
  </constructor-arg>
</bean>
this configures single process that will be available for execution - sample.bpmn that will be taken from class path. This is the simplest way to get your processes included when trying out jbpm.

3. Then we configure RuntimeEnvironment with our infrastructure (entity manager, transaction manager, resources)


<bean id="runtimeEnvironment" class="org.kie.spring.factorybeans.RuntimeEnvironmentFactoryBean">
  <property name="type" value="DEFAULT"/>
  <property name="entityManagerFactory" ref="jbpmEMF"/>
  <property name="transactionManager" ref="jbpmTxManager"/>
  <property name="assets">
    <map>
      <entry key-ref="process"><util:constant static-field="org.kie.api.io.ResourceType.BPMN2"/></entry>
    </map>
  </property>
</bean>
that gives us default runtime environment ready to be used to create instance of a RuntimeManager.

4. And finally we create RuntimeManager with the environment we just setup

<bean id="runtimeManager" class="org.kie.spring.factorybeans.RuntimeManagerFactoryBean" destroy-method="close">
  <property name="identifier" value="spring-rm"/>
  <property name="runtimeEnvironment" ref="runtimeEnvironment"/>
</bean>

with just four steps you are ready to execute your processes with Spring and jBPM 6, utilizing EntityManagerFactory and JTA transaction manager.

As an optional step, especially useful when testing you can create AuditLogService to get history information of your process executions.


<bean id="logService" class="org.jbpm.process.audit.JPAAuditLogService">
  <constructor-arg>
    <ref bean="jbpmEMF"/>
  </constructor-arg>
</bean>

Complete spring configuration file can be found here.

This is just one configuration setup that jBPM 6 supports - JTA transaction manager and EntityManagerFactory, others are:
  • JTA and SharedEntityManager
  • Local Persistence Unit and EntityManagerFactory
  • Local Persistence Unit and SharedEntityManager
What is important to note here is that there is no need to setup TaskService at all, some part of it like user group callback, can be configured via RuntimeEnvironment but the whole setup is done automatically by RuntimeManager. No need to worry about that.

Although if you need more control over TaskService instance you can set it up yourself and let RuntimeManager use it instead of creating its own instances.

To do so, you start the same as for self managed process engine case, follow step 1 and 2. Next we configure task service

<bean id="taskService" class="org.kie.spring.factorybeans.TaskServiceFactoryBean" destroy-method="close">
    <property name="entityManagerFactory" ref="jbpmEMF"/>
    <property name="transactionManager" ref="jbpmTxManager"/>
    <property name="listeners">
      <list>
        <bean class="org.jbpm.services.task.audit.JPATaskLifeCycleEventListener" />
      </list>
    </property>
  </bean>
with that we add an extra task life cycle listener to save all task operations as log entires.

Then, step 3 needs to be slightly enhanced to set task service instance in the runtime environment so RuntimeManager can make use of it


<bean id="runtimeEnvironment" class="org.kie.spring.factorybeans.RuntimeEnvironmentFactoryBean">
  <property name="type" value="DEFAULT"/>
  <property name="entityManagerFactory" ref="jbpmEMF"/>
  <property name="transactionManager" ref="jbpmTxManager"/>
  <property name="assets">
    <map>
      <entry key-ref="process"><util:constant static-field="org.kie.api.io.ResourceType.BPMN2"/></entry>
    </map>
   </property>
   <property name="taskService" ref="taskService"/>
 </bean>
that will disable task service creation by RuntimeManager and always use this single shared instance.
Step 4 (creating RuntimeManager) is exactly the same.

Look at the example configuration files and test cases for more details on how they are utilized.

Please also note that factory beans for spring integration are currently scheduled to be released with 6.1.0 version of jBPM but I would like to encourage you to give it a try before so in case something is not working or missing we will have time to fix it and let it out with 6.1.0.Final. So all hands on board and let's spring it :)

2013/11/22

jBPM 6 first steps

This post is about to give a very quick introduction to how users can take their first steps in jBPM 6. Using completely web tooling to build up:

  • processes
  • rules
  • process and task forms
  • data model
With just three simple examples you will learn how easy and quickly you can start with BPM. So let's start.

The simples process

First process is illustrating how you move around in KIE workbench web application. Where to:
  • create repository
  • create project
  • configure Knowledge Base, KnowledgeSession
  • create process
  • build and deploy
  • execute process and work with user task



Custom data and forms

Next let's explore more and start with bit advanced features like:

  • building custom data model that will be used as process variable
  • make use of process variables in user task
  • define custom forms for process and tasks
  • edit and adjust your process and task forms


Make use of business rules and decisions in your process

At the end let's make the process be more efficient by applying business rules in the process and then use gateways as deception points. This example introduces:

  • use of business rule task
  • define business rules with Drools
  • use XOR gateway to split between different paths in the process


Important to note that business rule task can automatically insert and retract process variables using data input and output of business rule task. When defining them make sure that both data input and output are named exactly the same to allow engine to properly retract the facts on business rule task completion.

That would be all for the first steps with jBPM 6. Stay tuned for more examples and videos!

As usual comments more than welcome.


2013/10/07

jBPM 6 workshops

I would like to inform that there will be some workshops regarding upcoming jBPM version 6 where you can gather some insight into what's in it for you.

There are currently two workshops scheduled:

  • 12 of October in Warsaw, Poland
  • 23-24 of October in London, UK

Workshop in Poland will be carried as part of Warsjava 2013 conference where besides "Introduction to jBPM 6" a lot more can be found. Unfortunately the conference is by default in Polish but I guess when there will be any non polish speaking attendees there won't be any issues to take it in English. I'll be giving the presentation and workshop for jBPM 6 at this year's Warsjava.

Workshops in London will be taken obviously in English and there will be lot of possibilities to learn a lot about the development in the projects. Presented by Mauricio "Salaboy" Salatino and Michael Anstis so an event you can't miss.

Please take a look at the content and register as places are limited.