Adding Rules to Drools Guvnor Programmatically with WebDAV

Posted on Monday, February 14, 2011


First, a very basic introduction before we get into code. Drools is a Business Logic integration platform which offers an integrated platform for Rules, workflow, event processing etc. Drools started off as a Rete based rule engine but over the years has evolved to have multiple sub-projects. Main ones of course are Drools Expert (Rule Engine), Drools Flow (process/workflow) and Drools Guvnor ( Business Rules Manager). The main focus of this post is the Guvnor subproject which is centralized repository of rules. It provides a web-based application to access and create rules. It has an intuitive (or I feel so) UI to help non technical folks work with the repository.

All right, now the problem context. For our product, though we are interested in creating rules and adding them to the repository, however, instead of using the standard web UI provided by Guvnor, we would like to use our own jazzy web 3.0ish rich flex based UI, which is more appealing and user-friendly. So how do we do that?

There are possibly a few options available, two of which are

  1. Using the REST api exposed by the Guvnor
  2. Adding a rule using WebDAV

Ideally, I would have preferred the use of REST api and would still do however, there are a few complications to the use of REST api. The biggest one that I encountered was non-availability of any decent documentation. A couple of days of looking around and talking to some helpful people like @Rikkola on the Drools IRC channel, I got the idea that to do what I need to do, though REST is a viable option but there is another option with WebDAV. It is a set of methods based on the Hypertext Transfer Protocol (HTTP) that facilitates collaboration between users in editing and managing documents and files stored on World Wide Web servers.

When you run the Guvnor application in an application server, you would most likely access it with something like this


and the screen would look like this

Now, interestingly, you can access the same information using WebDAV by using the URL as

This would show you the following information

Contents of this Folder:

So, we are accessing the file system using Http. Now if I need to list down the contents of the package that I am interested in, I would do the following,

and I get the following output

Contents of this Folder:

So, how do I add a new rule to the above package from my Java program? For that you need a WebDAV api. I used Sardine to test out the simple case that I was interested in.

The code for connecting to the WebDAV and adding a rule looks like this

	public static void main(String[] args) throws SardineException {

	private static void listAllResources() throws SardineException {
		Sardine sardine = SardineFactory.begin("admin", "admin");
		List<DavResource> resources = sardine
		for (DavResource res : resources) {
			System.out.println(res); // calls the .toString() method.

	private static void addARule() throws SardineException {
		Sardine sardine = SardineFactory.begin("username", "password");
		String ruleDescription = "when Entity(entityName==\"Car1s\") then System.out.println( \"*************rule executed\")";
		byte[] data = ruleDescription.getBytes();
		sardine.put("http://localhost:8080/drools-guvnor/org.drools.guvnor.Guvnor/webdav/packages/Analytics/SimpleDRLRule.drl", data);
		System.out.println("Rule added ...");

As you would notice, listAllResources() lists down the resources which are found at a particular webdav location and addARule(), adds a new rule to the Guvnor package. In our case, the rule is being added to the Analytics package by the name of SimpleDRLRule.drl

Once you execute the code, you should be able to see the rule added through your Guvnor web ui too.

Now, let us see, how we can execute this rule. The code that I used was

public class GuvnorTest {

	public void testDroolsWithGuvnor() throws Exception {
		KnowledgeBase knowledgeBase = createKnowledgeBase();
		StatefulKnowledgeSession session = knowledgeBase.newStatefulKnowledgeSession();
		try {
			Entity entity = new Entity();
			Assert.assertTrue(session.getFactCount() == 1);
			System.out.println("And the count is  " + session.getFactCount());

			System.out.println("And the count is  " + session.getFactCount());
			Assert.assertEquals(1, session.getFactCount());
		finally {

	private static KnowledgeBase createKnowledgeBase() {
		 KnowledgeAgentConfiguration kaconf = KnowledgeAgentFactory.newKnowledgeAgentConfiguration();
		 kaconf.setProperty( "drools.agent.scanDirectories", "false" );
		 KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent( "test agent", kaconf );
		 kagent.applyChangeSet( ResourceFactory.newClassPathResource("opal-guvnor.xml"));
		 return kagent.getKnowledgeBase();

The opal-guvnor.xml is a changeset file and has the following

    xs:schemaLocation='' >
         <resource source='http://localhost:8080/drools-guvnor/org.drools.guvnor.Guvnor/package/Analytics/LATEST.drl' type='DRL' basicAuthentication="enabled" username="admin" password="admin"/>

The output is the following

[2011:02:45 23:02:558:debug] KnowledgeAgent adding KnowledgeDefinitionsPackage Analytics
[2011:02:45 23:02:583:info] KnowledgeAgent new KnowledgeBase now built and in use
[2011:02:45 23:02:583:debug] KnowledgeAgent finished rebuilding KnowledgeBase using ChangeSet
And the count is  1
*************rule executed
And the count is  1

As you can see, we did not have the rebuild the package for the rule to get activated or something. Once the rule was added to the package, after that I could execute the rule.

So, is this the recommended approach instead the REST api. I would say maybe not. Does it work? Depending on the scenario that you are looking to solve, Yes.

Ideally, I would like to use the REST api for my product but this gives me some respite and I can go ahead. You can follow the REST api status here and if you have a working example of how you managed to use it, please link it 🙂
Related discussion on this topic

Posted in: Architecture, Java