Embedding and Testing Drools Flow in your Java Project


Drools Flow provides workflow capabilities and can easily integrate rules with processes. You can easily define the series of steps that would be followed in a workflow using the flowchart based approach to get a rule file. All this works like a charm with the drools plugin in eclipse and if you are interested then there is good information here to work with the plugin. This post however talks about a few struggles that I had to face to embed the drools flow in my Java based project.

We use maven for building our projects for a couple of reasons. First, we like it as a build tool and second, a fellow Inphiner is authoring a book on Maven. So we are bound to be biased.

Anyway, one of the problems that I see with the maven way of doing things is that many big projects would host a maven repository on their own rather that put it on maven central. Though, I am not a proponent of this approach as it makes findings libraries difficult for me as a developer, however, as per Spring, there are reasons why they do it that way. JBoss also does it this way.

The repository for Jboss through which you would get the drools file is

 <repository>
	<id>jboss-public-repository-group</id>
	<name>JBoss Public Repository Group</name>
	<url>http://repository.jboss.org/nexus/content/groups/public-jboss/</url>
   </repository>

Then you would need a few dependencies to make Drools work within your project, these are

<properties>
    <drools.process.version>5.1.1</drools.process.version>
    <xstream.version>1.2.2</xstream.version>
  </properties>

<dependency>
	<groupId>org.drools</groupId>
	<artifactId>drools-process-task</artifactId>
	<version>${drools.process.version}</version>
      </dependency>
      <dependency>
	<groupId>org.drools</groupId>
	<artifactId>drools-core</artifactId>
	<version>${drools.process.version}</version>
      </dependency>
      <dependency>
	<groupId>org.drools</groupId>
	<artifactId>drools-compiler</artifactId>
	<version>${drools.process.version}</version>
      </dependency>
      <dependency>
	<groupId>xstream</groupId>
	<artifactId>xstream</artifactId>
	<version>${xstream.version}</version>
      </dependency>

notice that I used, 5.1.1, there is 5.2.0.Snapshot as well but when I checked, that does not exist for drools-process-task. The main libraries required are drools-compiler, drools-core and drools-process-task. There is also an xstream requirement.

Once this was done, as a sample, I was able to execute the following code in my project

public static final void main(String[] args) {
		try {
			// load up the knowledge base
			KnowledgeBase kbase = readKnowledgeBase();
			StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
			KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
			
			
			SampleEntity entity = new SampleEntity();
			entity.setEntityName("Cars");
			
			Set<SampleAttribute> attributes = new HashSet<SampleAttribute>();
			SampleAttribute attribute1 = new SampleAttribute();
			attribute1.setAttributeName("color");
			attribute1.setAttributeType("red");
			SampleAttribute attribute2 = new SampleAttribute();
			attribute2.setAttributeName("shape");
			
			entity.setAttributes(attributes );
			
			ksession.insert(entity);
			ksession.insert(attribute1);
			
			
			// start a new process instance
			ksession.startProcess("com.sample.ruleflow");
			logger.close();
		} catch (Throwable t) {
			t.printStackTrace();
		}
	}

	private static KnowledgeBase readKnowledgeBase() throws Exception {
		KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
		kbuilder.add(ResourceFactory.newClassPathResource("ruleflow.rf"), ResourceType.DRF);
		KnowledgeBuilderErrors errors = kbuilder.getErrors();
		if (errors.size() > 0) {
			for (KnowledgeBuilderError error: errors) {
				System.err.println(error);
			}
			throw new IllegalArgumentException("Could not parse knowledge.");
		}
		KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
		kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
		return kbase;
	}

For acceptance testing, we use fitnesse. I included all the drools jars in my fitnesse library path as

classpath: /home/vikas/.m2/repository/org/drools/drools-api/5.1.1/drools-api-5.1.1.jar
classpath: /home/vikas/.m2/repository/org/drools/drools-compiler/5.1.1/drools-compiler-5.1.1.jar
classpath: /home/vikas/.m2/repository/org/drools/drools-core/5.1.1/drools-core-5.1.1.jar
classpath: /home/vikas/.m2/repository/org/drools/drools-process-task/5.1.1/drools-process-task-5.1.1.jar
classpath: /home/vikas/.m2/repository/org/drools/drools-workitems/5.1.1/drools-workitems-5.1.1.jar

However, the test would not run for the want to eclipse jdt. Hence I included the following

classpath: /home/vikas/.m2/repository/org/eclipse/jdt/core/compiler/ecj/3.5.1/ecj-3.5.1.jar
classpath: /home/vikas/.m2/repository/org/antlr/antlr-runtime/3.1.3/antlr-runtime-3.1.3.jar

Now, the functionality of drools flow that I am using right now works like a charm both inside my Java project as well as Fitnesse.

About Vikas Hazrati

Vikas is the Founding Partner @ Knoldus which is a group of software industry veterans who have joined hands to add value to the art of software development. Knoldus does niche Reactive and Big Data product development on Scala, Spark and Functional Java. Knoldus has a strong focus on software craftsmanship which ensures high-quality software development. It partners with the best in the industry like Lightbend (Scala Ecosystem), Databricks (Spark Ecosystem), Confluent (Kafka) and Datastax (Cassandra). To know more, send a mail to hello@knoldus.com or visit www.knoldus.com
This entry was posted in Java and tagged , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s