Development, Design, Architecture

How to develop systems with rule engines involved?


My rules don't work as expected. What can I do?

Welcome to real life. Don't ever believe that rules can and will be written by business-people only.

I suggest the following tactics:

  1. Try to modularize the problem. Start with a smaller ruleset or fewer facts.

  2. Add output to the consequence-parts of the rules - a few System.out won't hurt during development time.

  3. Does working-memory contain the correct facts?

    • Simple version: Create a new rule to output important facts (catch them on the LHS, print them on RHS). An Example:

       
       rule "debug: watch for my facts"
          when f: MyCrucialFact()
          then System.out.println( f.toString() );
       end
      

      Be careful with too specific LHS: If any fact you state in LHS is not present, the rule won't fire.

    • Before calling fireAllRules(), retrieve ALL existing facts from working-memory.

       for ( Iterator it = session.iterateObjects(); it.hasNext(); ) {
          System.out.println( it.next() );
      }
      session.fireAllRules();
      
    • You can query the working memory with a query-rule of the following format:

       query "MyCrucialFacts" 
          f : MyCrucialFact( )
       end
      

      You can get the results with the following lines of java code:

      QueryResults results = workingMemory.getQueryResults( "MyCrucialFacts" );
      System.out.println( "found " + results.size() + " MyCrucialFacts" );
        for ( Iterator it = results.iterator; it.hasNext(); ) {
            QueryResult result = ( QueryResult ) it.next();
            MyCrucialFact mf = (MyCrucialFacts) result.get( "f"); 
            System.out.println( mf.toString() );
        }
      
  4. Write a JUnit-test for every rule. Create the facts specifically to the rules' LHS (conditions), assert on the consequences.

  5. Try adding a DebugEventListener to your working memory (that's JBoss-Rules specific). Output is hard to read!

  6. Add some breakpoints to the consequence-part of suspicious rules and debug your application. You need to add a new Debug-configuration in Eclipse - consult the JBoss-Rules documentation for details. A sample screenshot from JBoss-Drools-IDE:

    Figure: JBR-debugging with Eclipse


How do I incorporate rule engines into my architecture?

A long version here - you'll need to adapt it.

The short version:

  • Hide away all the rule-engine specific stuff behind a wrapper (I prefer to call this one RuleInvoker or RuleEngineWrapper).
  • Have one component add business objects to this RuleEngineWrapper, call the rule engine and propagate its results back to your application.
  • Construct a proper testing facility. It is difficult to test rules with pure unit tests, so you gotta invest some brain here. Start with simple unit tests.
  • Care for operations: Integrate logging facilities into your RuleEngineWrapper- many rule engines support you with clever strategies.
  • Take special care for an effective rule governance: Somebody within your organization has to care for rule management:
    • When to introduce new rules?
    • When to delete rules from the rule base?
    • How to modularize your rule base?