Objective

In this post we are going to create a Drools Stateful Knowledge Session and bind it to a JNDI address.
We will then use Camel to fire all the rules in that session.
This is useful where we wish to have multiple Knowledge Sessions on multiple servers.

This example uses the Drools Grid – the main idea behind Drools Grid is to provide a simple API to be able to interact and create remote and distributed services in multiple machines.

Create the Project

File -> New -> Maven Project

Create a Simple Project

Group Id: com.skills421.drools.examples

Artifact Id: DroolsCamel

Finish

Edit pom.xml

Edit the pom.xml as follows:

<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.skills421.drools.examples</groupId>
	<artifactId>DroolsCamel</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<properties>
		<drools.version>5.6.0.Final</drools.version>
		<commons-version>1.1.3</commons-version>
		<camel.version>2.4.0</camel.version>
		<junit.version>4.11</junit.version>
	</properties>

	<dependencies>
		<!-- drools dependencies -->
		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>knowledge-api</artifactId>
			<version>${drools.version}</version>
		</dependency>
		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-core</artifactId>
			<version>${drools.version}</version>
		</dependency>
		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-compiler</artifactId>
			<version>${drools.version}</version>
		</dependency>

		<!-- Drools Grid -->
		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-grid-impl</artifactId>
			<version>5.6.0.Final</version>
		</dependency>

		<!-- Drools Camel -->
		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-camel</artifactId>
			<version>${drools.version}</version>
		</dependency>

		<!-- test dependencies -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
		</dependency>

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.0</version>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

pom.xml

Create a Simple Rule

In src/main/resources create the folder structure rules/skills421/examples.
In the examples folder create the rules.drl as follows:

package rules.skills421.examples

rule "always true"
dialect "mvel"
when
then
	System.out.println("Woohoo - Rules are running!");
end

rules.drl

Create the RuleRunner

Ideally, I should be creating a JUnit Test, but I want to get something running very quickly here, all in one file, so in src/main/java create the RuleRunner class as follows:

package com.skills421.drools.examples;

import java.util.ArrayList;
import java.util.List;

import javax.naming.Context;

import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.util.jndi.JndiContext;
import org.drools.KnowledgeBase;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.command.BatchExecutionCommand;
import org.drools.command.Command;
import org.drools.command.CommandFactory;
import org.drools.command.runtime.rule.FireAllRulesCommand;
import org.drools.grid.GridNode;
import org.drools.grid.impl.GridImpl;
import org.drools.grid.service.directory.WhitePages;
import org.drools.grid.service.directory.impl.WhitePagesImpl;
import org.drools.io.impl.ClassPathResource;
import org.drools.runtime.ExecutionResults;
import org.drools.runtime.StatefulKnowledgeSession;

public class RuleRunner
{
	private StatefulKnowledgeSession createKnowledgeSession()
	{
		KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
		kbuilder.add(new ClassPathResource("rules/skills421/examples/rules.drl", getClass()),
				ResourceType.DRL);

		if (kbuilder.hasErrors())
		{
			if (kbuilder.getErrors().size() > 0)
			{
				for (KnowledgeBuilderError kerror : kbuilder.getErrors())
				{
					System.err.println(kerror);
				}
			}
		}

		KnowledgeBase kbase = kbuilder.newKnowledgeBase();
		return kbase.newStatefulKnowledgeSession();
	}

	private Context createContext(StatefulKnowledgeSession ksession) throws Exception
	{
		GridImpl grid = new GridImpl();
		grid.addService(WhitePages.class, new WhitePagesImpl());
		GridNode node = grid.createGridNode("node");
		Context context = new JndiContext();
		context.bind("node", node);
		node.set("ksession1", ksession);
		return context;
	}

	private CamelContext createCamelContext(Context context) throws Exception
	{
		CamelContext camelContext = new DefaultCamelContext(context);
		RouteBuilder rb = new RouteBuilder()
		{
			public void configure() throws Exception
			{
				from("direct:test-session1").to("drools://node/ksession1");
			}
		};
		camelContext.addRoutes(rb);
		
		return camelContext;
	}

	public static void main(String[] args) throws Exception
	{
		RuleRunner runner = new RuleRunner();
		
		StatefulKnowledgeSession ksession = runner.createKnowledgeSession();
		Context context = runner.createContext(ksession);
		CamelContext camelContext = runner.createCamelContext(context);
		
		@SuppressWarnings("rawtypes")
		List<Command> commands = new ArrayList<Command>();
		
		FireAllRulesCommand fireAllRulesCommand = (FireAllRulesCommand) CommandFactory.newFireAllRules("executed-rules");
		
		commands.add(fireAllRulesCommand);
		
		BatchExecutionCommand batchExecutionCommand = CommandFactory.newBatchExecution(commands, "ksession1");
		
		camelContext.start();
		
		ProducerTemplate template = camelContext.createProducerTemplate();
		ExecutionResults response = (ExecutionResults) template.requestBody("direct:test-session1", batchExecutionCommand);
	}
}

RuleRunner.java

Run the RuleRunner

If you run RuleRunner you should see the following output:

Woohoo - Rules are running!
Advertisements

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