Rule Engines save the day

The problem

* Have you developed/seen business logic code with so many nested if statements that actually looked like a nest?
* Have you spent sleepless nights debugging when you modified one of those ‘if’ statements and found that it screwed up the next if statement?
* Ever wondered how do others implement such things?

Then read on; this article is exactly for you.

If our logic requires triggering different business actions based on many conditions (rules), then implementing such logic in the code becomes a pain. Understanding the code becomes even more painful and it will be a nightmare for people maintaining such code.

In addition, if the business rules are changing frequently, then incorporating these quick changes within the stiff deadlines becomes nearly impossible. We would ideally like to keep these changing rules out of our code. Another reason for this separation is that business people know the rules properly and it would be better if they were allowed to write the rules rather than the developers. Rule engines achieve separation of the rules from the code and make it easier to maintain the code.

What are rule engines and how do they solve my problem?

Rule engines are specialized applications that read a set of rules from external sources (known as rule database or knowledge base); identify the correct rule(s) based on input conditions and execute the corresponding action(s). Rule engines are a great way to collect complex decision-making logic and work with data too large for humans to effectively use.

Rule engines separate the source code from the rule database. Hence, the code does not have to change if there are any changes in the rules. The code looks much neater, simpler to understand and easier to maintain. Business people own the rules while developers own the code.

Case Study

OK; enough of theory. Let us look at some practical usage of rule engines and how they solve our problems.

Let us take one of scenarios in the telecom domain where we want to implement a component that determines whether a customer is eligible to register with the telecom operator. The decision would be based on several factors and is expected to alter frequently.

Just to give you an idea, the decision would be based on the following input conditions,

1. The front-end channel the customer is using, i.e. web-based or through Customer Service Representatives
2. Customer’s scheme, i.e. Monthly Rental (MR) or Pre-paid (PP)
3. Customer status, i.e. New or Existing
4. Response from External Credit History checking authorities about the customer (NCHC and ECHC)
5. Response from systems checking customer details against fraud profiles (PC)
6. Response from Address Verification systems against blacklisted addresses etc (AV)

To complicate the matters, some conditions could be ignored if some of the pre-conditions are met. E.g. If the response from External Credit history check entities is to “DECLINE”, then customer must be declined irrespective of responses from other systems.

Let us see if we implement the above logic in the code itself, how it looks

..................................................................................................................................................
// request is object containing input data

if (request.getChannel().equals(“WEB”)) {
  if (request.getCustScheme().equals(“MR”) {
    if (request.custStatus().equals(“NEW”) {
      if (request.getCreditCheckResp(“ACC”) &&
         request.getProfileCheckResp(“ACC”) &&
         request.getAddressCheckResp(“ACC”)) {
              response.setDecision(“ACCEPT”);
      }

      else if (request.getCreditCheckResp(“DEC”)) {
        response.setDecision(“DECLINE”);
      }
      else if (……) {
      }
    }  

   
else if (……) {
    }
  }
  else if (……) {
  }
}
else if (……)

The developers will go crazy seeing this code. Clearly the above code is unrealistic, but it shows the complexity.

The next thing we might think is, we will store all the possible values in a database table like the following,

Channel

CustScheme

CustStatus

NCHC

PC

EC

AC

FinalDecision

WEB

MR

NEW

ACC

ACC

 

ACC

ACCEPT

WEB

MR

NEW

ACC

DEC

 

ACC

REFER

WEB

MR

NEW

DEC

 

 

 

DECLINE

The above might look like a perfect solution as we can get the final decision in one wonderful SQL query. But there is a problem.

Consider that the input data contains the following responses,

* “DEC” from NCHC system
* “ACC” from PC system
* “ACC” from AC system

The SQL query will not fetch any results with the above data in the tables. For the query to work, we will have to add all the combinations of rules even if we know that “DEC” from NCHC system is sufficient to arrive at a final decision (As told previously, if response from Credit History Check system is ‘DEC’, the customer should be declined irrespective of responses from other systems). Though the solution is better, adding all the worthless data into the above rule table seems pointless. Is there some way we can avoid this?

The answer is yes; rule engines come to our help.

There are many open source Java rule engines. We have chosen ‘Drools’ as our rule engine because it supports rule specification in an excel sheet apart from many other advantages.

The following is the rule specification spreadsheet,

Type of Decision Request

Channel

Customer Scheme

Customer Type

NCHC

EC

PC

AC

ECHC

Final Decision

           New MR Customer Check From Web channel

WEB

MR

NEW

ACC

 

ACC

ACC

 

ACCEPT

         New MR Customer Check From Web channel

WEB

MR

NEW

DEC

 

 

 

 

DECLINE

         New MR Customer Check From Web channel

WEB

MR

NEW

ACC

 

 

REF

 

REFER

         New MR Customer Check From Web channel

WEB

MR

EXISTING

 

ACC

ACC

ACC

ACC

ACCEPT

           New PP Customer Check From Web channel

WEB

PP

NEW

 

 

ACC

DEC

 

REFER

As can be seen, Business people could easily add the rules to this spreadsheet document. This excel sheet will contain additional information that is relevant to developer and is hidden to the business user.



The code using the rule engine APIs is as follows,

private RuleBase _ruleBase;
            

private void loadRuleBase() 
throws SAXException, IOException, 
IntegrationException {
  InputStream stream = 
      this.getClass().

getResourceAsStream("Rule-Decision-Table.xls");
                    

_ruleBase = DecisionTableLoader.loadFromInputStream(stream);

}

private void executeRules(DecisionRequest req, DecisionResponse resp) 
              throws SAXException, IOException, 
              IntegrationException, FactException {                   

WorkingMemory engine = _ruleBase.newWorkingMemory();
                    

       engine.assertObject(req);
       engine.assertObject(resp);
       engine.fireAllRules();

}  

public static void main(String[] args) throws Exception {   
      
loadRuleBase();
       DecisionResponse resp = new DecisionResponse();
     
// Populate DecisionRequest req object containing input data 
// i.e. front-end, customer scheme and type and responses from 
// individual verification systems
       executeRules(req, resp);
 

       // Print the decision stored in the request object by Rule engine
       System.out.println(“Final decision: “ + resp.getDecision());
}

Given the above excel sheet, Drools reads the rules and executes them according to input conditions (data). All the developers have to do is populate the Request object with the input parameters, invoke Drools API to execute the rules and retrieve the output parameters from the Response object.

The above solution is much neater, simple to understand and implement. It clearly separates the roles of Business analyst and developer, hence reduces considerable amount of time in development and testing of the applications.

Advantages of Drools 

  • Drools is completely open-source and freely downloadable from the Internet. It uses very liberal ASL/BSD/MIT-esque license.
  • Drools conforms to JSR-94 (Rule Engine API) specification
  • Drools rule APIs are easier to use
  • Drools provides very good documentation
  • Drools rule specification language is fairly easy and flexible compared to other rule engines
  • Drools supports rule specification in Excel Spreadsheets
  • Drools’s performance is excellent
  • Commercial support available
  • Supports multiple semantic modules Java, Python, Groovy and C#

    References:

    * Why Use Rules
    http://drools.codehaus.org/Why+Use+Rules
    * Some Guidelines For Deciding Whether To Use A Rules Engine
    http://www.jessrules.com/jess/guidelines.shtml
    * Drools site (v3.0)
    http://labs.jboss.com/portal/jbossrules



Added on August 30, 2007 Comment

Comments

Post a comment

Your name:

Comment: