Adding Rules to Drools Guvnor Programmatically with WebDAV

Table of contents
Reading Time: 4 minutes

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

[sourcecode language=”java”]
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&quot;);
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&quot;, data);
System.out.println("Rule added …");
}
}
[/sourcecode]

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

[sourcecode language=”java”]
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();
}
}
[/sourcecode]

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

[sourcecode language=”xml”]
xmlns=’http://drools.org/drools-5.0/change-set&#8217;
xmlns:xs=’http://www.w3.org/2001/XMLSchema-instance&#8217;
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&#8217; >
<add>
<resource source=’http://localhost:8080/drools-guvnor/org.drools.guvnor.Guvnor/package/Analytics/LATEST.drl&#8217; type=’DRL’ basicAuthentication="enabled" username="admin" password="admin"/>
</add>
</change-set>
[/sourcecode]

The output is the following

[sourcecode language=”text”]
[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
[/sourcecode]

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

Written by 

Vikas is the CEO and Co-Founder of Knoldus Inc. 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). Vikas has been working in the cutting edge tech industry for 20+ years. He was an ardent fan of Java with multiple high load enterprise systems to boast of till he met Scala. His current passions include utilizing the power of Scala, Akka and Play to make Reactive and Big Data systems for niche startups and enterprises who would like to change the way software is developed. To know more, send a mail to hello@knoldus.com or visit www.knoldus.com

4 thoughts on “Adding Rules to Drools Guvnor Programmatically with WebDAV5 min read

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

  2. 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?

Comments are closed.

Discover more from Knoldus Blogs

Subscribe now to keep reading and get access to the full archive.

Continue reading