Friday, August 22, 2008

Drools execution server - for the early adopters

This is a very early announcement of the first drop of the drools-server module. This is a NEW module which allows execution of stateless rules via a REST-style web service interface (XML and JSON). (Watch this space for stateful). This means you can deploy rules and excute them from any sort of client (no libraries needed - not even a JVM).

This builds on the rule agent itself to managing what packages are used, and can work with guvnor or against any rule source (including drl files, which I used for testing).

drools-server is a war file, which can be deployed in a servlet container. RuleBase configurations are then accessed via URL: http://server/drools-server/knowledgebase/{ruleagentConfigName}.

The data you post is either XML or JSON, and maps to the fact model that the rules use - there are globals, input facts, and output facts (in the case of globals and output facts, the data is returned in the response message - which is how you get results back !).

When drools-server.war is deployed, going to /drools-server should show a page like:

Which has some example request/response and details.

Benefits of a simple rest approach:
No libraries ! Just use HTTP and XML or JSON on the "client" (many languages have that built in).

In fact, to test this out I did a simple rails app and client using nothing but its plain old http library, and the "json" library (JSON == Javascript Object Notation - a fast textual object graph serialization format - it is literal Javascript syntax for Arrays and Maps). (I would like to do a PHP and .Net one next - time permitting - after my holidays !).

You can see from the above the JSON strucutre created in ruby literals, and then converted to JSON format at the last minute (which looks pretty similar). To parse the response:
answer = JSON.parse(data)
#digging out the results:
puts answer["knowledgebase-response"]["globals"]["named-fact"]["fact"]["teamName"]
#if there is more then one fact, they are a list
puts answer["knowledgebase-response"]["inOutFacts"]["named-fact"][0]["fact"]["specialty"]

You can see there is some hierarchy to the results and the request - which is easy to see with JSON. This example "client" code is in drools-server/sample-clients/ruby_json.rb.

Enjoy !


  1. that cool. There's another way to make an agent. Integrate a simple message client with the engine and have different content handlers. I did that for Jess back in 2002. A single engine instance could have multiple JMS clients. what I did was write a jess function for creating message clients. Users call the function to subscribe to one or more topics or queues.

  2. JMS puts a larger burden of configuration and complexity of use on the user, where as REST just works, which is why we chose to do REST first.

  3. the function I wrote for jess took 6 parameters:

    after that, it's ready to go. The rest is up to the jms client to assert/modify/retract and send the response through JMS. Plus, it scales much better than HTTP. I don't consider 6 parameters a huge configuration overhead. If the client doesn't need to authenticate, then it's just 4 parameters.

    FIPA provides a variety of transport protocols for agent communication. In jamocha, there's a function for getting data from a remote URL. In terms of overhead, HTTP has a greater burden if HTTP sessions are used. A REST service could use sessions, so depending on how it's used, the configuration overhead of REST could be higher.

    It comes down to the REST service and how it was built.