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…
<?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:cxf="http://camel.apache.org/schema/cxf"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<cxf:rsServer id="rsServer"
address="/kservice/rest"
serviceClass="org.drools.jax.rs.CommandExecutorImpl">
<cxf:providers>
<bean class="org.drools.jax.rs.CommandMessageBodyReader"/>
</cxf:providers>
</cxf:rsServer>
<bean id="droolsPolicy" class="org.drools.camel.component.DroolsPolicy" />
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="cxfrs://bean://rsServer"/>
<policy ref="droolsPolicy">
<unmarshal ref="xstream" />
<to uri="drools:node1/ksession1" />
<marshal ref="xstream" />
</policy>
</route>
</camelContext>
</beans>
RESTful service endpoint creation: In the next xml snippet code we are creating a RESTful (JAX-RS) endpoint binded to /kservice/rest address and using org.drools.jax.rs.CommandExecutorImpl as the service implementor. This class is only used to instantiate the service endpoint because all the internal implementation is managed by Camel, and you can see in the source file that the exposed execute service must be never called.
Also a JAX-RS Provider is provided to determine if the message transported can be processed in this service endpoint.
<cxf:rsServer id="rsServer"
address="/kservice/rest"
serviceClass="org.drools.jax.rs.CommandExecutorImpl">
<cxf:providers>
<bean class="org.drools.jax.rs.CommandMessageBodyReader"/>
</cxf:providers>
</cxf:rsServer>
Ideally this configuration doesn’t need to be modified, at least the Service Class and the JAX-RS Provider, but you can add more endpoints associated to different addresses as you wish.
Camel Drools Policy: This class is used to add Drools support in Camel, basically what it does is to add interceptors into the camel route to create Camel Processors on the fly and modify the internal navigation route. If you want to have SOAP support, you need to create your custom Drools Policy.
Maybe in the future we can do this one more extensible and be able to add custom Processor Definitions modificators using Spring or at least make DroolsPolicy more object extensible, instead of recreate a new Policy and duplicate code.
But at this moment you don’t need to know more internal details, only instantiate this bean:
<bean id="droolsPolicy" class="org.drools.camel.component.DroolsPolicy" />
Camel Context creation: In the next XML definition we create the camel route that will have the responsibility to execute the commands sent through JAX-RS.
Basically we create a route definition associated with the JAX-RS definition as the data input, the camel policy to be used and inside the “execution route” or ProcessorDefinitions. As you can see, we set XStream as the marshaller/unmarshaller and the drools execution route definition
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="cxfrs://bean://rsServer"/>
<policy ref="droolsPolicy">
<unmarshal ref="xstream" />
<to uri="drools:node1/ksession1" />
<marshal ref="xstream" />
</policy>
</route>
</camelContext>
The drools endpoint creation has the next arguments
<to uri="drools:{0}/{1}" />
{0} : Execution Node identifier that is registered in the CamelContext
{1} : Knowledge Session identifier that was registered in the Execution Node with identifier {0}
Both parameters are configured in knowledge-service.xml file.
Knowledge Services configuration: the next step is create the Knowledge Sessions that you are going to use
<?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:drools="http://drools.org/schema/drools-spring"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://drools.org/schema/drools-spring http://drools.org/schema/drools-spring.xsd">
<drools:execution-node id="node1" />
<drools:kbase id="kbase1" node="node1">
<drools:resources>
<drools:resource type="DRL" source="classpath:test.drl"/>
</drools:resources>
</drools:kbase>
<drools:ksession id="ksession1" type="stateless" kbase="kbase1" node="node1"/>
</beans>
Basically you need to create an Drools Execution node that will be the responsible of managing the other resources.
<drools:execution-node id="node1" />
Then you need to create the Knowledge Base, identify it with a id and set the node attribute with the Execution Node that will generate this kbase.
Obviously, to made a functional kbase, you need to add the resources that are going to be incorporated into the kbase.
<drools:kbase id="kbase1" node="node1">
<drools:resources>
<drools:resource type="DRL" source="classpath:test.drl"/>
</drools:resources>
</drools:kbase>
With the last Spring modifications, you can add a XSD file with your model definition as a resource
<drools:resource type="XSD" source="classpath:model.xsd"/>
Finally, you need to create the Knowledge Session that is going to be used to execute the commands sent to the JAX-RS service. You need to specify the id, the knowledge session type (stateless or stateful), the knowledge base bean reference and the execution node bean reference to create this ksession.
<drools:ksession id="ksession1" type="stateless" kbase="kbase1" node="node1"/>
Remember that the ksession id attribute must be equal to the identifier used in the camel drools endpoint configured previously.
Initial Commands: if you need execute commands when the application is deployed you can add them using Spring.
<drools:ksession id="ksession1" type="stateful" name="ksession1" kbase="kbase1" node="node1">
<drools:script>
<drools:set-global identifier="list" >
<bean class="java.util.ArrayList" />
</drools:set-global>
</drools:script>
</drools:ksession>
Currently, the commands supported are:
- insert-object
- set-global
- fire-all-rules
- fire-until-halt
- start-process
- signal-event
As always, you can have more information in the Drools Spring documentation.
Hopefully i will update the documentation to show all the possibilities that you can do with this version, but you have to wait a few days.
Finally, this new version is going to be included in 5.1.0.RC1 version, which will be released right now.
Have fun!
Filed under: English, General, PlugTree Tagged: camel, community work, drools, execution, jboss, server, spring

English