Adding Rules to Drools Guvnor Programmatically with WebDAV


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

http://localhost:8080/drools-guvnor/org.drools.guvnor.Guvnor/Guvnor.html

and the screen would look like this

Now, interestingly, you can access the same information using WebDAV by using the URL as
http://localhost:8080/drools-guvnor/org.drools.guvnor.Guvnor/webdav

This would show you the following information

Contents of this Folder:
packages
snapshots

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,

http://localhost:8080/drools-guvnor/org.drools.guvnor.Guvnor/webdav/packages/Analytics
and I get the following output

Contents of this Folder:
AnalyticsModel.jar
drools.package
NewRule.brl
NewDRLRule.drl
AnotherDRLRule.drl
YADRLRule.drl

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 {
		listAllResources();
		addARule();
	}

	private static void listAllResources() throws SardineException {
		Sardine sardine = SardineFactory.begin("admin", "admin");
		List<DavResource> resources = sardine
				.getResources("http://localhost:8080/drools-guvnor/org.drools.guvnor.Guvnor/webdav/packages");
		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 {

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

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

	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

xmlns='http://drools.org/drools-5.0/change-set'
    xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'
    xs:schemaLocation='http://drools.org/drools-5.0/change-set http://anonsvn.jboss.org/repos/labs/labs/jbossrules/trunk/drools-api/src/main/resources/change-set-1.0.0.xsd' >
    <add>
         <resource source='http://localhost:8080/drools-guvnor/org.drools.guvnor.Guvnor/package/Analytics/LATEST.drl' type='DRL' basicAuthentication="enabled" username="admin" password="admin"/>
    </add>
</change-set>

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 https://issues.jboss.org/browse/GUVNOR-1080 here and if you have a working example of how you managed to use it, please link it 🙂
Related discussion on this topic http://drools-java-rules-engine.46999.n3.nabble.com/Drools-Guvnor-API-information-td2471798.html

About Vikas Hazrati

Vikas is the Founding Partner @ Knoldus which is a group of software industry veterans who have joined hands to add value to the art of software development. Knoldus does niche Reactive and Big Data product development on Scala, Spark and Functional Java. Knoldus has a strong focus on software craftsmanship which ensures high-quality software development. It partners with the best in the industry like Lightbend (Scala Ecosystem), Databricks (Spark Ecosystem), Confluent (Kafka) and Datastax (Cassandra). To know more, send a mail to hello@knoldus.com or visit www.knoldus.com
This entry was posted in Architecture, Java and tagged , , , . Bookmark the permalink.

4 Responses to Adding Rules to Drools Guvnor Programmatically with WebDAV

  1. Pingback: Tweets that mention Adding Rules to Drools Guvnor Programmatically with WebDAV « Inphina Thoughts -- Topsy.com

  2. Pingback: jBPM 5.1 « Tobias Wittur's Blog

  3. Diduch Cordova says:

    great job, Do you have some example to create a package in guvnor from my java application

  4. Most people seem to get a ‘javax.jcr.AccessDeniedException’ in the tomcat log when trying this. How were you able to get around that? What were your authentication configurations?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s