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!

19 thoughts on “Drools Server configuration updated

    1. lucaz Post author

      Thank you! I’m writing another post more focused in Drools Camel custom integration and the differents executions enviroments that you can create, maybe you’ll be interesed in it!

      Reply
  1. Pingback: Tweets that mention Drools Server configuration updated « lucaz -- Topsy.com

  2. clandestino_bgd

    Nice work,
    I am wondering how difficult it would be to configure drools server in Spring Integration (SI).
    Do you maybe have such plans?
    Anyway, I guess your next post about Drools Camel integration will be very useful.

    Milan

    Reply
    1. lucaz Post author

      Actually all the configuration is through Spring! And you have to use the drools spring tags to configure the knowledge sessions that you want to use. Nothing too dificult the learning curve is easy

      Reply
  3. mike

    Hi – Any chance you could post some tips on configuring a second knowledge base to run? I’m trying to hook up several different knowledge bases (each linking to a different .drl) that I want to access via my rest service. I was able to fairly easily reconfigure knowledge-services.xml and camel-server.xml from the default config to hook up to the new .drl file I’ve built, but I’d like to drop 3 different .drl files in there and call them all separately…. It seems trivially easy but every rearrangement I’ve made of the xml in these files causes drools-server to not even start in tomcat. Could you show what those two files would look like if they were linking to two separate .drl files? (I would pick which one to activate when I fire the xml at it, like this ”

    Thanks so much for the posts.

    Reply
    1. lucaz Post author

      Sorry, I wasn’t moderating the posts. Do you are still needing help? let me know and I’ll create a post about services declarations.

      Reply
  4. Fulton

    Lucaz,

    I’ve deployed Drools-Server 5.1.1 (not easy!) and the sample test rule/service is working, but I need to implement JSON instead of XML for RESTful requests/responses. After much searching, I could not find any current JSON request examples on the Internet (just the OLD one for knowledgebase-request), and I have been unsuccessful in converting your msg to JSON. Would you please provide the JSON version of the sample request or point me to the documentation that specifies the proper format/structure. By the way, I am behind a corporate proxy, so I cannot access certain web sites, such as plugtree.com.

    Muchas gracias! Fulton

    Reply
    1. lucaz Post author

      Hi Fulton,
      you can use the BatchExecutionHelper class to obtain a JSON marshaller as you can see in the next lines:

      List<GenericCommand> commands = new ArrayList<GenericCommand>();
      BatchExecutionCommand batchExecutionCommand = CommandFactory.newBatchExecution(commands, “ksession1”);
      String jsonXml = BatchExecutionHelper.newJSonMarshaller().toXML(batchExecutionCommand);

      Btw, I’m not associated with Plugtree LLC anymore, I’m a freelancer at the moment, so you can ask me here if you need further assistance.

      Hope it helps!

      Regards,

      Lucas

      Lucas

      Reply
      1. Fulton

        Lucas,

        Thanks for the quick reply! Actually, what I’m looking for is the JSON representation of the current XML request. That is, could you please show the actual JSON request that is equivalent to:

        Hello World

        The initial REST integration is with a PHP application, so I need to know how to build a JSON (not XML) request from there, so what I’m looking for is just the syntax for specifying the above in JSON, e.g.:

        { “batch-execution”:{“lookup”:”ksession1″,…}

        Thanks again! Fulton

      2. lucaz Post author

        Fulton, your XML isn’t displayed properly. Maybe you have to paste it using the tags, or using pastebin.com . Anyway, you can see below an example with two objects inserction and a fire rules declaration. There isn't available documentation about the JSON "schema", so you will have to dig into the source code or converting them using Java to see how to write it using PHP.

        {"batch-execution":
        {"lookup":"ksession1",
        "commands":[
        {"insert":{
        "out-identifier":"lucaz-person",
        "return-object":true,
        "entry-point":"DEFAULT",
        "object":{
        "org.drools.model.Person":{
        "name":"lucaz"
        }
        }
        }
        },
        {"insert":{
        "out-identifier":"emiliano-person",
        "return-object":true,
        "entry-point":"DEFAULT",
        "object":{
        "org.drools.model.Person":{
        "name":"emiliano"
        }
        }
        }
        },
        {"fire-all-rules":{
        "out-identifier":"executed-rules"
        }
        }
        ]
        }
        }


        Regards,

  5. Rupesh

    Lucaz,
    I am using 5.4.0 final drools stacks. I am fetching the resource from guvnor as follows.

    Is there any configuration I can do so that ksession/kbase always reload the resource from guvnor?

    Rupesh

    Reply
    1. lucaz Post author

      Hi Rupesh,
      I’m afraid that what you want to achieve isn’t possible. Maybe you can try configuring a knowledge agent, but I still thinking that isn’t going to work. Just give it a try!

      Sorry for the late response.

      Reply
      1. Rupesh

        Lucaz,
        I tried with all possible parameter. I problem with drools is its documentation: seems like they just copy the old docs and stamp with new version. I saw somewhere kAgent being used with parameter new-instance=”true” but with newest drools-camel-server, I didn’t see how I could use the Agent. way I am doing is:

        so, I didn’t see how I can use kAgent.

        I thank you for your help.
        Rupesh

      2. Rupesh

        Lucaz,
        I tried with all possible parameter. I problem with drools is its documentation: seems like they just copy the old docs and stamp with new version. I saw somewhere kAgent being used with parameter new-instance=”true” but with newest drools-camel-server, I didn’t see how I could use the Agent. way I am doing is:


        so, I didn't see how I can use kAgent.

        I thank you for your help.
        Rupesh

  6. Giuseppe

    Hello,

    Thanks to your post I might resolve a problem..
    Could you tell me please, what is that model.xsd , how did you create it and where it is?
    I’m using Guvnor and Drools server

    Thanks

    Reply

Leave a comment