Home > Business Rules > Rules hot deploy using Drools / Guvnor – part 2

Rules hot deploy using Drools / Guvnor – part 2

In the first part of this tutorial, I introduced the basics and the Drools Guvnor, as well as demonstrated the creation of a simple rule in Guvnor. The objective of this part is to show how to consume the rule set, as well as present as expose it as web service.

Preparing rules for consumption

To prepare the rules for consumption, it is necessary to generate a snapshot of the rules. This is done by his own administration interface Guvnor by selecting the package, performing the same build and selecting the option to create snapshot, as shown:

As a rule created to consume

The rules can be consumed by the Drools API itself, as shown in the code below:

package com.alesaudate.drools.sample.client;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.drools.RuleBase;
import org.drools.StatelessSession;
import org.drools.agent.RuleAgent;
import org.drools.definition.type.FactType;

public class Client {
private Properties config;
private String factName;
private Map factValues;
private Map expectedResultsMap;
private static Map agents = new HashMap();

public void consume () throws InstantiationException, IllegalAccessException {
RuleAgent agent = getAgent(getConfig().getProperty("url"));
RuleBase ruleBase = agent.getRuleBase();
FactType factType = ruleBase.getFactType(getFactName());
Object fact = factType.newInstance();
Map values = getFactValues();
for (String key : values.keySet()) {
factType.set(fact, key, values.get(key));
}
StatelessSession statelessSession = ruleBase.newStatelessSession();
statelessSession.execute(fact);
Map expectedResults = getExpectedResultsMap();
for (String key : expectedResults.keySet()) {
Object resultValue = factType.get(fact, key);
expectedResults.put(key, resultValue);
}
}
private RuleAgent getAgent(String url) {
if (!agents.containsKey(url)) {
RuleAgent agent = RuleAgent.newRuleAgent(getConfig());
agents.put(url, agent);
}
return agents.get(url);
}
// getters and setters…

}

Where the field config is the configuration of the API (to be explained), the field factName represents the fully qualified name of the POJO that will be used as fact (in our example, is seguradora.Segurado) factValues is a map that will be used to populate fields and the fact expectedResultsMap is a map that will be used to retrieve the desired values of the implementation of the rule (in our case, the status field is interesting).

The field config can be configured using the following data:

  • newInstance: Used to determine whether a new instance of the rule will be created (for the case of rules that keep state)
  • file: to determine which file (local) will be read
  • dir: to establish a directory for reading
  • url: URL to determine a reading (which will be used, in our case)
  • poll: interval in seconds, rereading the selected source (to determine whether the rule needs to be updated on the local machine)
  • name: name of the configuration
  • localCacheDir: directory will be cached remotely read the rule.

For the last class as an example, you can perform the reading of the rule using the following code:

 
public static void main(String[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Client client = new Client();
		Properties config = new Properties();
		config.put("url", "http://localhost:8080/drools-guvnor/org.drools.guvnor.Guvnor/package/seguradora/LATEST");
		client.setConfig(config);
		client.setFactName("seguradora.Segurado");
		
		Map factValues = new HashMap();
		factValues.put("idade", 18);
		client.setFactValues(factValues);
		
		Map expectedResults = new HashMap();
		expectedResults.put("status", null);
		client.setExpectedResultsMap(expectedResults);
		
		
		client.consume();
		
		System.out.println(client.getExpectedResultsMap());
		
	}

Still using the example code, you can expose the rules as services for two distinct ways:

  • Creating a custom web service (the sample code is available on the downloads page, next to the sample code consumer rules)
  • Using Drools Server, placing a file. properties (similar to the properties file passed as parameter to the client) in the “WEB-INF/classes” Application of Drools Server. In this way, however, the web service will be exposed as REST.

The downloads page , is available for download the client’s consumption and exposure rule as SOAP web service.

The next part will present how to perform deploy a rule dynamically.

Advertisements
  1. Xinhua
    10/11/2010 at 3:40 AM

    Hi Alexandre

    When I debug the client code to “client.consume();”, “http 401 error” happens. Seems it needs access privilege of the folder, isn’t it?

    BR
    Xinhua

    • 10/17/2010 at 12:04 PM

      Hi!

      Firstly, I would like to apologize for taking so long to reply.. that was due to the fact that I was travelling and, well, I don´t check the internet while doing so =)

      Second.. well, depending on the Guvnor version you are using, it might require some type of authentication to perform some operations. Try adding a BASIC authentication with username/password “admin”, and check out what happens. If you become able to do anything, you could 1) remove the authentication; 2) modify the code to add automatically this header.

      Please tell me what option you want 😉

      Cheers,
      Alexandre

      • Xinhua
        10/20/2010 at 10:31 AM

        Hi Alexandre

        Thanks for your reply.

        I am using Guvnor 5.1. I prefer the second way (modify the code to add authentication) of course. But I don’t know how to insert user/passwd into the code.

        BR
        Xinhua

      • 10/23/2010 at 7:17 PM

        Hi, Xinhua!

        To add it automatically, you got to setup your client to include the following properties:

        enableBasicAuthentication=true
        username=admin
        password=admin

        (username / password are the ones that you use to access Guvnor, and also are JMX´s JBoss console password).

        So, mentioning the code in the blog, it would be like:

        config.put(“enableBasicAuthentication”, “true”);
        config.put(“username”, “admin”);
        config.put(“password”, “admin”);

        Hope it helps!

        Alexandre

  2. Xinhua
    10/26/2010 at 12:21 PM

    Dear Alexandre

    It works! Thanks very much for your help!

    BR
    Xinhua

  3. kumar
    11/26/2010 at 11:11 AM

    hi, i added user/password for guvnor 5.1.1 call, i still get “java.io.IOException: Server returned HTTP response code: 401 for URL……”
    any idea what is going on here.
    help would be highly appreciated.

    thanks
    kumar

    • 11/26/2010 at 11:55 AM

      Hi, Kumar!

      How are you passing username / password ? Also, can you log in to Guvnor using the data you are trying to pass as parameters? (Just to know if login and password are correct..)

  1. No trackbacks yet.

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

%d bloggers like this: