Tag Archives: jboss

Drools channels and Apache Camel integration.

The previous posts only showed how to build a route using the Drools endpoint as the target consumer of the message, but what happen if we need to start the route from a Drools endpoint (the source endpoint) and send a message from the rules consequence to the target endpoint? In this case we need to use Drools channels.

A Drools channel provides a mechanism to send objects from the working memory to some external process or functions.
Continue reading

JBoss Drools Developer‘s Cookbook released

Maybe you noticed, or not, that this blog hasn’t had too much activity lately (but hey, I wasn’t blooging much before, right?). Well, one of the reasons was the Drools Developer Cookbook, a book that I was writing and that after a few months of hard work is finally finished and released by Packt Publishing.

Drools Developer's Cookbook cover

Inside this book you will find lots of recipes to apply in your Drools projects, in order to take advantage of the latest features released in JBoss Drools 5.2 and 5.3. It covers all the main modules, Expert, Fusion, Guvnor, Planner and even jBPM5.

I would like to thank Packt Publishing & crew, Edson Tirelli, Geoffrey De Smet, Toni Rikkola and everyone else that in any way helped me.

The chapters 2 & 7 are available to read in the next links:

Expert: behind the rules (Full chapter)
Integration: How to connect Drools (Article)

As always, for further details you can take a look in the book website
http://www.packtpub.com/drools-developers-using-jboss-cookbook/book

Have fun

jBPM5/Drools Apache Camel integration

 

After a few months I’m back with another useful, or maybe not, post about the integration between Apache Camel and Drools/jBPM5. I decided to write this post because 1) people are continuously asking about the last changes in the integration and 2) I already had a POC using the last Drools/jBPM5/Camel integration in my github account.

So, in this example I’m going to explain how to use jBPM5 together with Apache Camel but the same concepts and configuration can be applied to a Drools integration with Camel.
Continue reading

Drools Metrics Persistence

I would like to introduce a small project that I developed at @plugtree in the last months. It’s a project to monitor and persist internal metrics of Drools Knowledge Session’s. This will allow you to gather internal metrics information of the knowledge base and sessions registered into the JVM (local or remote) using the Drools JMX API and persist this information into a database (right now it’s using Hibernate as the ORM but it’s pluggable enough to use another persistence framework, which should be the ideal because of the huge amount of data to be stored). As you can imagine it’s really useful to use to create your custom dashboard to monitor how healthy are your knowledge session´s, to made predictive analysis, etc.

It currently supports the following features, but there are more coming:

  • knowledge base auto discovery.
  • knowledge sessions auto discovery.
  • configurable knowledge scanners.
  • pluggable persistence framework.
  • spring framework configuration friendly.

Continue reading

Drools Camel Integration

The Apache Camel integration allows us to interact with a Drools Stateless or Stateful session through a pipeline. It basically works by transforming XML commands into executable commands and executing each of them. The advantage of this integration is that Apache Camel makes possible the implementation of more advanced enterprise integration patterns, which is an improvement of Drools Pipeline.

This integration with Drools allows us to add any of the current Camel components. Using the Apache Components you can, receive commands from several entry points and send the execution result to another entry point. Just to name a few of the components: JMS queue/Atom Feed/Mina connection/a Mail/etc. As you can see, this brings a more powerful interoperability mechanism to integrate your application with Drools. Actually Drools is using Camel 2.4.0 that allows a more strong internal integration between them.

Introduction to Drools Grid
This integration is coupled with another drools module called: drools-grid. This module allow us to interact with Drools sessions independent of the JVM location. At the moment we can use two implementations:

  • Local: Used when the drools sessions and clients are in the same JVM
  • Remote: Used when you have drools sessions on a remote JVM. Currently, the only implementation is based on Apache Mina. HornetQ support is actually done, but don’t available in trunk

Drools Grid is embedded inside the Drools Camel component, so don’t worry about further implementation information because this is hidden by Drools. With this information we can start to configure our Camel Context.
Continue reading

Drools Server configuration updated

In the past days Drools Execution Server was updated to use a new version of the Drools Camel integration and more features were added.
One of the biggest differences is that now everything is configured using Spring, and no java code is included inside the WAR file. And, opposite to the previous version, SOAP isn’t supported out-of-the-box (you could use SOAP in the previous version) but you can add your own support right now.

Configuration
As in the previous version, the configuration files are included in the WEB-INF/ folder inside the WAR file. Now we have three configuration files: beans.xml, camel-server.xml and knowledge-services.xml

  • beans.xml: It is the main xml file, but only is used to import the next two files. So, you don’t need to modify this one.
  • camel-server: This file includes the configuration of REST interface and Camel routes.

Let’s go to do a deep configuration review…
Continue reading

Drools Server Configuration Using Spring

Now we can forget the profiles.xml configuration file, that I introduce on my previous post, and configure the service using Spring. If you have used the drools-spring module you know what I’m talking about. Or you can check this here

Don’t get crazy, but now we have 4 xml configuration files. Let’s talk a little about them.

configuration.xml: It is the main xml file, but only is used to import the next three files. So, you don’t need to modify this file.

core.xml
: As the previous file, you don’t need to modify this one either. This file only contains the REST/SOAP services configuration.

sessions.xml: In this file you can configure the knowledge base and knowledge sessions that are going to be used on the service definition. The configuration is the same as previously used on the drools-spring module, but now the drools:kbase can have a XSD model definition file using the tag <drools:model/>

<?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"
    xmlns:drools="http://drools.org/schema/drools-spring"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
		http://drools.org/schema/drools-spring http://drools.org/schema/drools-spring.xsd"
    default-autowire="byName">

    <drools:connection id="connection1" type="local" />

    <drools:execution-node id="node1" connection="connection1" />

    <drools:kbase id="kbase1" node="node1">
	<drools:resource source="classpath:changesets/change-set-1.xml" type="CHANGE_SET" />
        <drools:model source="classpath:model/person.xsd" />
    </drools:kbase>

    <drools:kbase id="kbase2" node="node1">
        <drools:resource source="classpath:changesets/change-set-2.xml" type="CHANGE_SET" />
    </drools:kbase>

    <drools:ksession id="ksession1" type="stateful"  kbase="kbase1" node="node1"/>

    <drools:ksession id="ksession2" type="stateless" kbase="kbase2" node="node1"/>

</beans>

services.xml: In this file you can configure the drools server service, and contains the new definitions added to the drools-spring service.

The first thing that you should know is that there’s a new xml namespace for this, named drools-service. The configuration files shipped with the drools-service.war already have this definition, so you shouldn’t take care about this.

Here’s a full configuration example.


<?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"
    xmlns:camel="http://camel.apache.org/schema/spring"
    xmlns:drools-service="http://drools.org/schema/drools-service-spring"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
		http://drools.org/schema/drools-service-spring http://drools.org/schema/drools-service-spring.xsd
		http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"
    default-autowire="byName">

	<!-- Only needed to deploy on JBoss AS 5.X -->
    <bean id="jbossResolver" class="org.apache.camel.jboss.JBossPackageScanClassResolver"/>

    <!-- This camel context bean is required -->
	<camelContext id="executionContext" xmlns="http://camel.apache.org/schema/spring" />

	<drools-service:configuration id="service-conf-2" marshaller="XSTREAM" session="ksession2" />

	<drools-service:definition id="service" smId="sm1" camelContext="executionContext">
		<drools-service:configuration marshaller="JAXB" session="ksession1">
			<drools-service:class>org.drools.model.Person</drools-service:class>
			<drools-service:startup-command>
				<![CDATA[
				<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
				<batch-execution lookup="ksession1" xmlns:ns2="http://drools.org/model">
				    <insert out-identifier="santa">
				        <object xsi:type="ns2:person" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
				            <ns2:name>santa</ns2:name>
				            <ns2:age>99</ns2:age>
				        </object>
				    </insert>
				</batch-execution>
	  	   		]]>
			</drools-service:startup-command>
		</drools-service:configuration>
		<drools-service:configuration-ref id="service-conf-2" />
	</drools-service:definition>

</beans>

There are a lot of new definitions, so let’s go step by step.

The next bean definition is only needed when the war file is deployed on a JBoss AS 5, to solve Apache Camel issues with the new AS classloader.

<bean id="jbossResolver" class="org.apache.camel.jboss.JBossPackageScanClassResolver"/>

Here we configure the Apache Camel Context bean instance.

<camelContext id="executionContext" xmlns="http://camel.apache.org/schema/spring" />

We can define an external drools service configuration, in this example we define a configuration that will use the Stateless Knowledge Session with id ksession2 and with XStream as the command marshaller.

<drools-service:configuration id="service-conf-2" marshaller="XSTREAM" session="ksession2" />

And next is the drools service definition, named by default as service (note: if you want to change the drools service definition id you must also change the bean reference on core.xml file). Also this definition must reference to the serviceManager used in the Knowledge Sessions creation and the Camel Context bean defined previously.

Inside the definition we can add multiple configurations, defined internally or externally. In this example we are adding to configurations: one externally referenced as “service-conf-2” and another internally.
The internal definition is using the JAXB marshaller and associated to the Stateful Knowledge Session with id ksession1. Also it is making a reference to the class called org.drools.model.Person, which was defined on the XSD file used in the creation of the KnowledgeBase with id kbase1, to be included on the JAXB Context that is going to be used on the marshalling/unmarshalling of the commands with JAXB format.

And finally, there is a tag named to specify commands that are going to be executed when the .war file is deployed. You don’t need to include this startup commands, it’s just only in case that you need something to initialize your Knowledge Session. Remember that you must use the tags, that allows us to include xml snippets without the need of escaping all the xml tags, when you add one xml command.

<drools-service:definition id="service" smId="sm1" camelContext="executionContext">
		<drools-service:configuration marshaller="JAXB" session="ksession1">
			<drools-service:class>org.drools.model.Person</drools-service:class>
			<drools-service:startup-command>
				<![CDATA[
				<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
				<batch-execution lookup="ksession1" xmlns:ns2="http://drools.org/model">
				    <insert out-identifier="santa">
				        <object xsi:type="ns2:person" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
				            <ns2:name>santa</ns2:name>
				            <ns2:age>99</ns2:age>
				        </object>
				    </insert>
				</batch-execution>
	  	   		]]>
			</drools-service:startup-command>
		</drools-service:configuration>
		<drools-service:configuration-ref id="service-conf-2" />
	</drools-service:definition>

How to use drools-server

On this new version we are using the Drools Commands API in XML form. Take a look at the following example:

BatchExecutionCommand executionCommand = new BatchExecutionCommand();

InsertObjectCommand insertCommand = new InsertObjectCommand();
insertCommand.setObject(new Person("lucaz"));
insertCommand.setOutIdentifier("person1");

executionCommand.setLookup("ksession1");
executionCommand.getCommands().add(insertCommand);

String xml = BatchExecutionHelper.newXStreamMarshaller().toXML(executionCommand);

With this lines you will get the xml command representation, using xstream marshaller, that you can use to interact with the drools execution server:

<batch-execution lookup="ksession1">
  <insert out-identifier="person1" return-object="true">
    <org.drools.pipeline.camel.Person>
      <name>lucaz</name>
    </org.drools.pipeline.camel.Person>
  </insert>
</batch-execution>

RestWS integration

Let’s test the RestWS service by following this steps:

1) Create an Apache HttpClient instance and configure it with the drools-server ip address and port:

HttpClient httpClient = new HttpClient();
httpClient.getHostConfiguration().setHost("127.0.0.1", 8080);

2) Create a PosthMethod and send the xml command to the URI /drools-server/services/rest/execute

PostMethod postMethod = new PostMethod("/drools-server/services/rest/execute");
postMethod.addParameter("command", xmlCommand);

3) Execute the method. If the execution was succesfull you will got a HTTP Response Code OK (200) otherwise a BAD_REQUEST (400) response code will be thrown to the client.

httpClient.executeMethod(postMethod);
assertEquals(200, postMethod.getStatusCode());

4) And finally, get the execution response

String response = postMethod.getResponseBodyAsString();

SOAP integration

Here’s one way to use the SOAP interface with Apache CXF:

1) Create a JaxWsProxyFactoryBean, set the KnowledgeServiceSoap (that could be generated with the WSDL exposed at http://127.0.0.1:8080/drools-server/services/soap?wsdl ) as the Service Class and the URL

JaxWsProxyFactoryBean clientFactory = new JaxWsProxyFactoryBean();
clientFactory.setServiceClass(KnowledgeServiceSoap.class);
clientFactory.setAddress("http://127.0.0.1:8080/drools-server/services/soap");

2) Create the KnowledgeServiceSoap client and execute the xml command

<span style="font-size: x-small;">KnowledgeServiceSoap client = (KnowledgeServiceSoap) clientFactory.create();
String response = client.execute(xmlCommand);</span>

That’s all, not too much more magic. Now, with these features, we have a more unified service definition using the drools-spring module. If you want to see this running, you can download a client project and the compiled drools-server.war from this link

Feedback is always appreciated.