Using Drools rules with jBPM 6

User Rating: 4 / 5

Star ActiveStar ActiveStar ActiveStar ActiveStar Inactive
 

jbpm drools business process rule process management jbpm5This tutorial has been updated to show how to invoke business rules from within jBPM 6 processes, and how to handle the interactions between process and rules.

Business processes and rules are two core concepts which should be stressed out:

Business processes: Represent what the business does.
Business rules: Represent decisions that the business does.


So, although processes and rules are two different thing, there is a clear advantage if your end users are allowed to combine processes and rules. This means for example that:

  • rules can define which processes to invoke,
  • rules can specify decisions in that process
  • rules can augment (or even override) the behaviour specified in the process (for example to handle exceptional cases)
  • assignment rules can be used to assign actors to (human) tasks
  • rules can be used to dynamically alter the behaviour of your process

So, by delegating important decision to be taken into your rules system, your business processes become much more resilient to change.

Create a new Drools Project

We will use JBoss Developer Studio to demonstrate how to create a project with Drools. Since the project will be Maven based, you can easily construct it with any IDE. Start by creating a new Drools Project

drools tutorial with jbpm

Next, choose to build the Project with Maven, which means you don't need to download the Drools Runtime by yourself. Choose the Maven settings for your project:

drools tutorial jboss jbpm 6

In this very simple rule, we will check a model class (Account) against some validation properties. The first rule is trivial: we just check that the name property of the Account class is not null:

import com.sample.Account;

rule "nameRequired"
ruleflow-group "helloworldgroup"
when
$account : Account( name == null )
then
  System.out.println( "Account name cannot be null!");

end

Now add the Account class to your project:

package com.sample;

public class Account {
    private long money;
    private String name;

    // getters and setters omitted for brevity

    @Override
    public String toString() {
        return "Account [money=" + money + ", name=" + name + "]";
    }


    public Account() {
    
    }

}

Good. Now add a new Drools jBPM Process Diagram to your Project:

jbpm diagram drools tutorial

Choose a name to your Process.  For example we will be adding the following simple test.bpmn2 process:

process drools jbpm 6 tutorial

As you can see, this process contains just a Business Rule Task, which will be in charge to fire our Rule. How do we connect to our Rule ? we can do this through the ruleflow-group attribute by setting it to "helloworldgroup":

drools jbpm 6 tutorial example

Now we need a Main class to test our project. An example class follows here:

package com.sample;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;

public class ProcessMain {

	public static void main(String[] args) throws Exception {

		KieServices ks = KieServices.Factory.get();
		KieContainer kContainer = ks.getKieClasspathContainer();
		KieSession kSession = kContainer.newKieSession();
		Account account = new Account();

		kSession.insert(account);
		kSession.startProcess("demo.test");
		int fired = kSession.fireAllRules();
		System.out.println("Number of Rules executed = " + fired);
	}

}

In order to compile and run your example with Maven you will need to include dependencies both for Drools and jBPM in your pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">

	<modelVersion>4.0.0</modelVersion>

	<groupId>com.sample</groupId>
	<artifactId>DemoDrools</artifactId>
	<version>1.0.0-SNAPSHOT</version>

	<name>Drools :: Sample Maven Project</name>
	<description>A sample Drools Maven project</description>

	<properties>
		<runtime.version>6.4.0.Final</runtime.version>
	</properties>

	<repositories>
		<repository>
			<id>jboss-public-repository-group</id>
			<name>JBoss Public Repository Group</name>
			<url>http://repository.jboss.org/nexus/content/groups/public/</url>
			<releases>
				<enabled>true</enabled>
				<updatePolicy>never</updatePolicy>
			</releases>
			<snapshots>
				<enabled>true</enabled>
				<updatePolicy>daily</updatePolicy>
			</snapshots>
		</repository>
	</repositories>


	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.drools</groupId>
				<artifactId>drools-bom</artifactId>
				<type>pom</type>
				<version>${runtime.version}</version>
				<scope>import</scope>
			</dependency>
			<dependency>
				<groupId>org.jbpm</groupId>
				<artifactId>jbpm-bom</artifactId>
				<type>pom</type>
				<version>${runtime.version}</version>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.jbpm</groupId>
			<artifactId>jbpm-flow</artifactId>
		</dependency>
		<dependency>
			<groupId>org.jbpm</groupId>
			<artifactId>jbpm-flow-builder</artifactId>
		</dependency>
		<dependency>
			<groupId>org.jbpm</groupId>
			<artifactId>jbpm-bpmn2</artifactId>
		</dependency>
		<dependency>
			<groupId>org.jbpm</groupId>
			<artifactId>jbpm-persistence-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.jbpm</groupId>
			<artifactId>jbpm-human-task-core</artifactId>
		</dependency>
		<dependency>
			<groupId>org.jbpm</groupId>
			<artifactId>jbpm-runtime-manager</artifactId>
		</dependency>
	</dependencies>
</project>

Please note that some dependencies such as jbpm-persistence-jpa and jbpm-human-task-core are not needed in this basic example, however as expand your project you will probably need to use Human Tasks

When launched the Console should report the message fired from the rule
Account name cannot be null!
Of course verify that setting the name attribute, the message will not be displayed.