JBoss Drools

Jboss Drools Facthandle Example

Hello Readers, in this article we will take a look on what is the FactHandle and how this works inside a drools engine implementing a example of this to ilustrate this feautre. Before starting, check the requirements related to technologies and frameworks used to this example below:

  1. Maven 3.3.9
  2. Jboss Studio 10.3
  3. Drools Engine 7.0
  4.  JDK 1.8.0_71

 
 
 

1. Introduction

Before continuing with the FactHandle Example implementation, we need to understand how this works and which is the use of this feature inside a drools rule program. General speaking the fact handle inside the drools engine is an identification or ID that represents the inserted object (fact) within WorkingMemory. Below we’ll see how this feature works on the different drools operations:

  • Insertion
  • Retraction
  • Update

2. Setting Up The Environment

To have the deveploment environment setting up, please refer to my previous drools post (backward chaining) on the section 2 “Configure Necessary Tools” and uses the name drools-facthandle for the new maven drools project used on this example.

3. FactHandle Example Implementation

Well, now in this section, we’ll start to implement our first agendaEventListener on a drools rule project. Below we see the steps that we’ll follow to achieve this.

  • Model creation class to wrap the data that will be evaluated by the rule.
  • Rule file with some example rule, in order to add a new agendaEventListener.
  • Add rule configuration to the kmodule.xml file, in order to get our rule on a drools session.
  • Test class creation, to put all together and see how the FactHandle works.

3.1 Model Class Creation

The model class is a representation of the data that will be evaluated by the rule. On this example we will use a class called Person. To create it please follow the next steps. Go to the drools-agenda-facthandle (created on the step 2) maven project on the jboss developer studio and create a new package named com.sample.model. Inside this package create a new class named Person with the below structure:

Person.java

package com.sample.model;

/**
 * POJO class to wrap the example data 
 * that will be evaluated by the rule
 *
 */
public class Person {
	
	private int id;
	private String name;
	
	public Person(int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}
	
	public int getId() {
		return id;
	}
	
	public void setId(int id) {
		this.id = id;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
}

3.2 Rule File Creation

The rule file will have our test rule that allows validate the data model when this is invoked and will allow to trigger our event listener. On the drools-facthandle maven project, inside the src/main/resources create a new folder named facthandle. Below this folder create a new Rule file named FactHandle with the below structure:

FactHandle.drl

package com.sample

import com.sample.model.Person


/**
When this rule matched, will be fired and a FactHandle object will be returned    
*/
rule "facthandletest"

    when
        Person( id == 12467, name == "carlos" )
    then
         System.out.println( "Fact handle Example" );

end

3.3 Add Rule Configuration

In order to get our rule program working and see how the fact handle works, it’s necessary to configure the drools session on the file kmodule.xml file inside src/main/resources/META-INF folder. See below the configuration for this example:

kmodule.xml

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
    <kbase name="facthandle" packages="facthandle">
        <ksession name="ksession-facthandle"/>
    </kbase>
</kmodule>

3.4 Test Class Creation

Now, we are ready to add our new FactHandle Test class in order to see how fact handle works on drools operations: insertion, retraction and  update.  On the drools-facthandle maven project, under the package com.sample create a new class named FactHandleTest with the below structure:

FactHandleTest.java

package com.sample;

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

public class FactHandleTest {

	public static void main(String[] args) {
		try {
			KieServices ks = KieServices.Factory.get();
			KieContainer kContainer = ks.getKieClasspathContainer();
			
			//drools session base on the xml configuration kmodule.xml
			KieSession kSession = kContainer.newKieSession("ksession-facthandle");
			
			
		} catch (Throwable t) {
			t.printStackTrace();
		}

	}
}

3.5 Fact Insertion

The fact in the drools project concept context, is each object that is inserted on a drools engine using a drools session, this is when you do kSession.insert(myObject);, when you insert a object (fact), it is examined for matches against the rules. In that moment the engine decides about firing or not a rule during fact insertion. but you have other option to made this, calling kSession.fireAllRules(); method on the drools engine session in order to execute all the rules.

A common misunderstood on fact insertion is thinks that the evaluation of the facts inside the engine occurs when the fireAllRules method is executed, actually this happens when is inserted into the engine, on drools context the evaluation is called Assertion too, lets take a look on how to get a FactHandle on insertion operation also called Assertion and how the evaluation occurs.

FactHandleTest.java

package com.sample;

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

public class FactHandleTest {

	public static void main(String[] args) {
		try {
			KieServices ks = KieServices.Factory.get();
			KieContainer kContainer = ks.getKieClasspathContainer();
			
			//drools session base on the xml configuration kmodule.xml
			KieSession kSession = kContainer.newKieSession("ksession-facthandle");
			
			//fact creation (model pojo class)
			Person person = new Person(12467, "carlos");
			
			//we obtain the fact handle and at this moment the evaluation against the rule happens 
			FactHandle factHandle = kSession.insert(person);
			
			//here we print the fact representation of this object inside the rules engine
			System.out.println(factHandle.toExternalForm());
			//here the rule is fired
			kSession.fireAllRules();
		} catch (Throwable t) {
			t.printStackTrace();
		}
	}
}

The output of this program is:

0:1:1760401098:1760401098:1:DEFAULT:NON_TRAIT:com.sample.model.Person //The string representation of the ID or FactHandle inside the engine 
Fact handle Example //This is printing when the rule match

The FactHandle is also used for interactions with the current working memory data inside the rules engine in cases that is necessary retract or update a object(fact), in the previous output, you see the ID or FactHandle of the inserted object inside the rules engine and the example text that is printed when the rule’s condition match with the object.

3.6 Fact Retraction

The next operation that use the fact handle is retraction, the retraction is the way that drools engine allows to remove a object(fact) on the working memory , this means that this fact will not longer track and match, so any rules that are active and depends of the removed fact (object) will be cancelled. Retraction is done using the FactHandle object obtained from the insertion operation. See the code example below.

FactHandleTest.java

package com.sample;

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

public class FactHandleTest {

	public static void main(String[] args) {
		try {
			KieServices ks = KieServices.Factory.get();
			KieContainer kContainer = ks.getKieClasspathContainer();

			//drools session base on the xml configuration kmodule.xml
			KieSession kSession = kContainer.newKieSession("ksession-facthandle");

			//fact creation (model pojo class)
			Person person = new Person(12467, "carlos");

			//we obtain the fact handle and at this moment the evaluation against the rule happens 
			FactHandle personFactHandle = kSession.insert(person);
            
			//here we remove the fact from the current working memory 
			kSession.retract(personFactHandle);
			
			//the representation still there but the rules associated to this fact will be cancelled 
			System.out.println(personFactHandle.toExternalForm());
			
                        /*here the rule for this example "facthandletest" never execute the print statement, 
			because the fact was already removed from current working memory so is cancelled*/  
			kSession.fireAllRules();
		} catch (Throwable t) {
			t.printStackTrace();
		}
	}
}

The output of this program is:

0:1:1760401098:1760401098:1:DEFAULT:NON_TRAIT:com.sample.model.Person //The string representation of the ID or FactHandle inside the engine

The previous output shows just the ID or fact handle of the removed fact but never prints the rule message because the rule is cancelled after the retraction operation.

3.7 Fact Update

The next operation that use the fact handle is update, the update is the way that drools engine allows to be notified when a object(fact) is modified on the working memory, so that fact can be reprocessed by the engine again, internally the engine remove the fact from the current working memory and inserts again with the new values. The drools engine update method receive, the FactHandle of the object that will be updated and the instance of the object that will be modified. See the code example below.

FactHandleTest.java

package com.sample;

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

public class FactHandleTest {

	public static void main(String[] args) {
		try {
			KieServices ks = KieServices.Factory.get();
			KieContainer kContainer = ks.getKieClasspathContainer();

			//drools session base on the xml configuration kmodule.xml
			KieSession kSession = kContainer.newKieSession("ksession-facthandle");

			//fact creation (model pojo class), that will not match with the current rule
			Person person = new Person(1, "carlos");

			//we obtain the fact handle and at this moment the evaluation against the rule happens 
			FactHandle personFactHandle = kSession.insert(person);
            
			//here the rule is fired
			kSession.fireAllRules();
			System.out.println("Nothing is printing by the rule");
			
			//modification fact in order to match this fact with the rule
			person.setId(12467);that
			
			//here we use the FactHandle obtained by the insertion operation and the modified fact in order to notifies to the engine and get the rule reprocessed  
			kSession.update(personFactHandle, person);
			//here the rule is fired again
			kSession.fireAllRules();
		} catch (Throwable t) {
			t.printStackTrace();
		}
	}
}

The output of this program is:

Nothing by the rule printing //This is when the fact not match with the rules
Fact handle Example //This is printing by the rule after the fact modification was done in order to match with the rule and the update operation is invoked

4. Conclusions

In this article we learned about what is a FactHandle inside the drools engine, how this works and in which scenarios are used on a rules project. We also saw some examples that show how to get a FactHandle and how to use it on a different scenarios.

To summarize this article, we can say that the FactHandle is a ID that is assigned to a object or fact inside the drools engine when this is inserted, this ID allows to identified a object or fact inside the engine in order to perform the different operations supported by the engine, like insertion, retraction and update, you can make a analogy between the FactHandle and data base record ID that allows identified a record inside a table on a data base engine and perform some operations on that record.

5. Download the Eclipse Project

This was a Drools FactHandle example with Jboss developer studio

Download
You can download the full source code of this example here: FactHandleExample

Carlos Andres

Carlos Andres has graduated from Computer Engineering in the University cooperativa de colombia. He also have a certified in Cloud Architecture from ICESI university and Development Enterprise applications with java technologies from San buenaventura University. During his career he has been involved with a large number of projects ranging from insurance to virtualization products like a programmer, software designer and architect. he works as a technical lead in the software sector where he is mainly involved with projects based on Java, SOA, microservices, cloud and front end technologies.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Ashok
Ashok
4 years ago

Drools rule are blocked thread dump in case of concurrent request how to hand such kind of scenarios

Back to top button