Objectives
In this example we will integrate Drools, Spring and Camel.
- We will first execute a test to show that our Rules are firing using just Drools
- Next we will test our Spring / Drools integration is working by loading a Drools Stateful Session bean and firing the rules associated with it.
- We will then execute a program to bind our Stateful Session to JNDI and use Camel to access the session and fire the rules.
- Finally, we will use Spring to bind our Stateful Session to JNDI and use Camel to load the CamelContext bean and fire the rules associated with the session.
Create the Project
File -> New -> Maven Project
Create a Simple Project
Group Id: com.skills421.drools.examples
Artifact Id: DroolsCamelSpring
Finish
Edit pom.xml
Edit the pom.xml file 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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.skills421.examples.drools</groupId> <artifactId>DroolsCamelSpring</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <drools.version>5.6.0.Final</drools.version> <commons-version>1.1.3</commons-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 Spring --> <dependency> <groupId>org.drools</groupId> <artifactId>drools-spring</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> <!-- Logging --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>${commons-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 both src/main/resources and src/test/resources create the directory structure rules/skills421/examples.
In the examples folder create the file 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 ApplicationContext.xml
In src/main/resources create the file applicationContext.xml as follows:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <import resource="classpath:drools-context.xml"/> <!-- Show Spring where to search for the beans (in which packages) --> <!-- <context:component-scan base-package="com.skills421.examples.drools.model" /> --> </beans>
applicationContext.xml
Create drools-context.xml
In src/main/resources create the file drools-context.xml as follows:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:drools="http://drools.org/schema/drools-spring" xmlns:camel="http://camel.apache.org/schema/spring" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd http://drools.org/schema/drools-spring http://drools.org/schema/drools-spring.xsd"> <bean id="droolsPolicy" class="org.drools.camel.component.DroolsPolicy" /> <drools:grid-node id="node1" /> <drools:resource id="resource1" type="DRL" source="classpath:rules/skills421/examples/rules.drl" /> <drools:kbase id="kbase1" node="node1"> <drools:resources> <drools:resource ref="resource1" /> </drools:resources> </drools:kbase> <drools:ksession id="ksession1" type="stateful" kbase="kbase1" node="node1" /> <camel:camelContext id="camelContext"> <camel:route> <camel:from uri="direct:test-session2" /> <camel:policy ref="droolsPolicy"> <camel:unmarshal ref="xstream" /> <camel:to uri="drools:node1/ksession1" /> <camel:marshal ref="xstream" /> </camel:policy> </camel:route> </camel:camelContext> </beans>
drools-context.xml
Create the JUnit Tests as follows
In src/test/java create the class SimpleRuleRunnerTest as follows:
package com.skills421.drools.examples; import static org.junit.Assert.*; 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; import org.hibernate.mapping.Array; import org.junit.Test; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SimpleRuleRunnerTest { @Test public void testDrools() { 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(); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); ksession.fireAllRules(); } @Test public void testWithSpring() { AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); applicationContext.start(); StatefulKnowledgeSession ksession1 = (StatefulKnowledgeSession) applicationContext.getBean("ksession1"); ksession1.fireAllRules(); applicationContext.stop(); applicationContext.close(); } @Test public void testWithCamel() { try { 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(); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); 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); 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); @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); } catch (Exception e) { fail(e.getMessage()); } } @Test public void testWithSpringAndCamel() { AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext( "applicationContext.xml"); applicationContext.start(); CamelContext camelContext = (CamelContext) applicationContext .getBean("camelContext"); @SuppressWarnings("rawtypes") List<Command> commands = new ArrayList<Command>(); FireAllRulesCommand fireAllRulesCommand = (FireAllRulesCommand) CommandFactory .newFireAllRules("executed-rules"); commands.add(fireAllRulesCommand); BatchExecutionCommand batchExecutionCommand = CommandFactory .newBatchExecution(commands, "ksession1"); try { camelContext.start(); ProducerTemplate template = camelContext.createProducerTemplate(); ExecutionResults response = (ExecutionResults) template .requestBody("direct:test-session2", batchExecutionCommand); applicationContext.stop(); applicationContext.close(); } catch (Exception e) { fail(e.getMessage()); } } }
SimpleRuleRunnerTest.java
Run the Tests
Run the JUnit Tests and you should see the following output:
Woohoo - Rules are running! Woohoo - Rules are running! Woohoo - Rules are running! Woohoo - Rules are running!