JBoss Drools Tutorial

JBoss Drools tutorial

Introduction tutorial to JBoss Drools.

Today most enterprise Java applications can be split into three parts: the front-end interface to the user, the service layer which is connected to Enterprise information systems and the business layer.

In the last years we've seen a growing number of framework which handle both the front-end and the service layer (Struts, Spring, Hibernate, Enterprise Java Bean, JDO just to mention a few). Yet is missing a standard way to handle your business logic. This was until JBoss Drools.


What is a Rule Engine ?

The term Rule Engine can be referred to any system that uses rules, in any form, that can be applied to data to produce outcomes; it may refer to simple systems like form validation or more complex systems like dynamic expression engines. In a few words a Rule engine allow you to say "What to do" and not "How to do it".

Why using a Rule Engine ?

Rule systems are capable of solving very, very hard problems, providing an explanation of how the solution was arrived at and why each "decision" along the way was made.
Among the main benefit of a Rule engine can be mentioned:

  • Logic and Data Separation

Breaking your domain objects from business rules can lead to a mach easier to maintain application as it can shield from changes in the future, since the logic is all laid out in rules.

  • Speed and Scalability

Many times we apply "if" conditions that we didn't really need. The Rete algorithm, as implemented by Drools, replaces all of the if ... then statements with an optimized network.

  • Centralization of Knowledge

By using rules, you create a repository of knowledge (a knowledgebase) which can be considered as a single point of truth, for business policy (for instance) - ideally rules are so readable that they can also serve as documentation

  • Tool Integration

Writing rules means also to get accustomed with Rule language, validation and debugging. Eclipse provide an excellent tool to deliver and test your Rules.

  • Understandable Rules

JBoss Drools rules can make it easy to express solutions to difficult problems and consequently have those solutions verified (rules are much easier to read then code).Often, business users are more comfortable with expressing things that they know to be true, than to express things in an if...then format. Examples of things that you might hear from a business expert are:

"We need to buy that estate if the price is not over 1000000 $ and estate agency doesn't claim more then 5000 $"
"We buy shares when the price goes over 15 Euro before next week"

By focusing on what we know to be true, rather than the mechanics of how to express it in Java code, the above statements are much more clean than exposing it with traditional "if...then" clause


How is JBoss Drools is made up

Drools is split into two main parts: Authoring and Runtime.

The Authoring process involves the creation Rules files (.DRL) which contain the rules which are fed into a parser. The parser checks for correctly syntax of the rules and produces an intermediate structure that "describes" the rules. This is then passed to the Package Builder which produces Packagesand undertakes any code generation and compilation that is necessary for the creation of the Package.

On the other hand, the RuleBase is a runtime component made up of one or more Packages. A RuleBase can instantiate one or more WorkingMemories at any time.
The Working Memory consists of a number of sub components, including Working Memory Event Support, Truth Maintenance System, Agenda and Agenda Event Support.

The Working memory is a key point of the Drools engine: it's here that Facts are inserted.

Facts are plain Java classes which rely on the Java Bean pattern( your Java beans from your application). Facts are asserted into the Working Memory where they may then be modified or retracted. 

When facts are asserted into the working memory, it will result in one or more rules being concurrently true and scheduled for execution by the Agenda - we start with a fact, it propagates and we end in a conclusion. This method of execution for a Production Rule Systems is called Forward Chaining - it's depicted in this picture:


jboss drools

At this point I guess you're eager to see JBoss Drools in action, let's take a look how to install it.

The rule workbench (for Eclipse) requires that you have eclipse 3.2 or greater, as well as Eclipse GEF 3.2 or greater. You can install it either by downloading the plugin or, or using the update site

JBoss IDE has GEF already, as do many other "distributions" of Eclipse, anyway if you don't have GEF installed, you can install it : open the Help->Software updates->Find and install from the help menu. Then you choose the Calisto update site:

Now let's move to JBoss Drools installation:

In order to install JBoss Drools download it from JBoss site the Api

http://download.jboss.org/drools/release/4.0.7.19894.GA/drools-4.0.7-bin.zip

Done with this, download the Eclipse plugin

http://download.jboss.org/drools/release/4.0.7.19894.GA/drools-4.0.7-eclipse3.2.zip

As with other Eclipse plugin, copy the plugin .jar file in the "plugin" directory of your Eclipse. Last thing to do, copy the directory org.drools.eclipse.feature_4.0.7 (containing the feature.xml file) in the features directory.

Now restart Eclipse, you should see a new wizard in the "New..." Menu

 jboss drools

Create a new Project, then add a new Rule Resource to the project.

You'll switch your editor to the Rule Editor which looks like this:

Now let's examine a simple example :

package drools

import drools.Message;

rule "Hello World"
dialect "mvel"
when
m : Message( status == Message.HELLO, message : message )
then

modify ( m ) { message = "Goodbye cruel world",
status = Message.GOODBYE };
System.out.println( message );
end

rule "Good Bye"
dialect "java"
when
Message( status == Message.GOODBYE, message : message )
then
System.out.println( message );

end

This example is provided with 2 Rules: the first Rule ("HelloWorld") checks the value of the field status in the class Message, if the value equals to the constant Message.HELLO then a new value for status is setted and a goodbye message is printed.

On the other hand the "Good bye" Rule will check as well the value of field status. If it's equal to Message.GOODBYE then we've reached the bottom of our Rules and we exit printing a message.

Everything clear ? maybe not. Let's see closer a few pieces of this Rule:

m : Message( status == Message.HELLO, message : message )

What does this mean ?

This is the Pattern element: the most important Conditional Element. It consists of zero or more constraints and has an optional pattern binding. A constraint can be either a Field Constraint, Inline Eval (called a predicate in 3.0) or a Constraint Group. Constraints can be separated by the following symbols ',', '&&' or '||'.

So this simply says that the Rule will be activated for each Message object inserted into the working memory whose status is Message.HELLO. Besides that, two variable binds are created: "message" variable is bound to the message attribute and "m" variable is bound to the object matched pattern itself.

And the dialect "mvel" keyword ?

When writing Rules you have the option to use Java Language and MVEL sytnax to modify objects passed to the Working memory. MVEL's syntax allows you to apply a block of setters in one statement, with the engine being automatically notified of the changes at the end of the block.

modify ( m ) {

message = "Goodbye cruel world",
status = Message.GOODBYE

};

Ok, so we've our Rule. In order to execute them we'll create a Java Class, in this example we'll use a simple Servlet as front end for our Rules.

Inside our Servlet class the first step is building the rule package and add it to the rulebase. (This step is a low level Api which will be almost identical in any application)

private static RuleBase readRule() throws Exception {   //read in the source  

  Reader source = new InputStreamReader( Servlet.class.getResourceAsStream( "/Rule.drl" ) );

  //Use package builder to build up a rule package.

  PackageBuilder builder = new PackageBuilder();

  //this wil parse and compile in one step   
  builder.addPackageFromDrl( source );

  //get the compiled package (which is serializable)   
  Package pkg =   builder.getPackage();

  //add the package to a rulebase (deploy the rule package).  

  RuleBase ruleBase = RuleBaseFactory.newRuleBase();  

  ruleBase.addPackage( pkg );  

  return ruleBase;

}

This method will be used in the invokeRule method, which actually fires our rules:

private void invokeRule() {

  RuleBase ruleBase = readRule();   WorkingMemory workingMemory = ruleBase.newStatefulSession();

  Message message = new Message();   message.setMessage( "Hello World" );   message.setStatus( Message.HELLO );

  workingMemory.insert(message);   workingMemory.fireAllRules();

}

As you can see, with the instruction

workingMemory.insert(message);

your object is asserted into the Working Memory where they may then be modified or retracted. This means all of the work is done during insertion; however, no rules are executed until you call "fireAllRules()". You don't call "fireAllRules()" until after you have finished inserting your facts.

When executed the output will be:

14:22:43,453 INFO [STDOUT] Hello World
14:22:43,468 INFO [STDOUT] Goodbye cruel world


This is a very trivial example just to get accustomed with JBoss Drools environment: in the following articles we'll see how a rules engine can significantly reduce the complexity of components that implement the business-rules logic in your Java applications. By expressing your rules using JBoss Drools declarative approach your application has higher chance of being more maintainable and extensible than one that doesn't.


Advertisement
 

Search our tutorials