Download Rules Rules! - Java User Group

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Rules Rules!
Solving problems with business rules and
declarative development
Christian Parker
[email protected]
President, Founder, Adigio, Inc.
www.adigio.com • [email protected]
Copyright © 2004
Presentation Agenda
In this presentation we will discuss:
 Thinking in Rules
 Solving a problem with a rules approach
 Declarative programming
 When we use rules
 When do you need rules?
 Explaining rules engines
 What are my options for rules engines?
 Rules in the Enterprise
Copyright © 2004 by Adigio, Inc
Solving a typical logic problem
What if you had to write a program to solve this problem:
A foursome of golfers is standing at a tee, in a line from left
to right. Each golfer wears different colored pants:
•
•
•
•
•
One
The
Joe
Bob
Tom
is wearing red pants
golfer to Fred’s immediate right is wearing blue pants
is second in line
is wearing plaid pants
isn’t in position one or four, and he isn’t wearing orange pants
Question: In what order will the four golfers tee off, and
what color are each golfer’s pants?
How would you traditionally do this?
Copyright © 2004 by Adigio, Inc
Solving a typical logic problem
Hacking the solution in Java code…
…
if (foo … && … || …) {
if (…) {
for (..) {
}
}
}
…
A very hard way to solve the problem. You have to think out
the entire execution path. Is there a simpler way…
Copyright © 2004 by Adigio, Inc
Solving a typical logic problem
Using a Rules Based Approach to the solution
It is easy to express the various rules for the problem
;; The golfer to Fred's right is wearing blue pants.
(position (of Fred) (is ?p1))
(pants-color (of Fred) (is ?c1))
(position (of ?n&~Fred) (is ?p&:(eq ?p (+ ?p1 1))))
(pants-color (of ?n&~Fred) (is blue&~?c1))
;; Joe is in position #2
(position (of Joe) (is ?p2&2&~?p1))
(pants-color (of Joe) (is ?c2&~?c1))
Note that we haven’t had to think through the possible
execution paths to make this all work…
Copyright © 2004 by Adigio, Inc
ill Structured Problems
When is this “rules based” way of thinking useful?
Rules based solutions are perfect for
Ill Structure problems
An ill structured problem can not easily be solved using an
algorithm, and are characterized by questions such as:
Where should I travel for a fortnights holiday?
What is the best price of gas?
Where should I drill for oil?
Copyright © 2004 by Adigio, Inc
Declarative vs. Procedural
What we are really talking about here, is declarative
programming…
Procedural languages provide a linear flow of execution, and are
good for deterministic problems
 a step follows inevitably from the last one
Declarative programs describe what the computer should do rather
than the instruction on how to do it
Declarative programming concerns itself with what is
instead of how to.
Copyright © 2004 by Adigio, Inc
Comparing Declarative to
Procedural
Using a Rules Based Approach to the solution
It is easy to express the various rules for the problem
DECLARATIVE
If you want to eat out,
If your favorite restaurant is open,
Then you should go to your favorite restaurant.
If you are hungry,
Then you need to eat.
If your stomach is making noises,
And if you've not eaten in several hours,
Then you are hungry.
If you need to eat,
Then you want to eat out.
PROCEDURAL
if(person.stomachInKnot() &&
person.getHoursSinceEaten() > 5) {
// hungry.
if(time.between("12AM", "2AM") {
if(person.inCity("Minneapolis") {
call("burrito");
}
} else if(time.before("9PM") {
// ...
}
// ...
}
If you need to eat,
And if it's later than 9PM
Then you want to eat in.
If you need to eat,
And if it's between 12AM and 2AM,
And if you live in Minneapolis
Then call Burrito Loco for home delivery.
If you buy a burrito,
Then you get chips for free.
Copyright © 2004 by Adigio, Inc
Who uses rules?
Who uses rules based approaches on a regular basis?
Maybe more than you immediately think?
Email Rules for Filters
Spam Filters
DNS routing
cronjobs for scheduling
Copyright © 2004 by Adigio, Inc
Roadmap
Where are we?
 Thinking in Rules
 When do you need rules?
 Incremental way of using rules from home grown to full fledged
 Explaining rules engines
 What are my options for rules engines?
 Rules in the Enterprise
Copyright © 2004 by Adigio, Inc
Contention: Missing a tool
It is our contention that…
The Java community doesn’t make use of rules based
solutions effectively
There is confusion over when to use rules engines
When you get used to declarative approach, it changes the
way you develop applications
Copyright © 2004 by Adigio, Inc
When To Use?
Helps to understand how the organization deals with change
Examples of dealing with change:
 If the business rules change, we'll release a new version
 Load the values from config files (SQL statements, etc.)
 Write change-susceptible sections in Javascript, Groovy, etc.
 Use plugins (the command pattern)
 We'll write our own rule engine
No black and white criteria
It's not all or nothing
When you're bored and want to play with a new technology 
Copyright © 2004 by Adigio, Inc
Rules are everywhere
Business rules are everywhere!
Can you spot the business rule(s)?
CategoryInterest determineAgeInterest(Traveller trav) {
CategoryInterest ageMatch = null;
if (trav.isAdult()) {
// traveller is an adult
ageMatch = CategoryInterest.getCategoryInterestByValue(CategoryInterestValue.AGE_APPROPRIATE_ADULT);
} else {
if (trav.getAge().intValue() == -1) {
// if the child's traveler's birthday is not specified, let's just pick one in the middle, 5-8
ageMatch = CategoryInterest.getCategoryInterestByValue(CategoryInterestValue.AGE_APPROPRIATE_5_8YRS);
} else if (trav.getAge().intValue() >= 0 && trav.getAge().intValue() <= 4) {
ageMatch = CategoryInterest.getCategoryInterestByValue(CategoryInterestValue.AGE_APPROPRIATE_0_4YRS);
} else if (trav.getAge().intValue() >= 5 && trav.getAge().intValue() <= 8) {
ageMatch = CategoryInterest.getCategoryInterestByValue(CategoryInterestValue.AGE_APPROPRIATE_5_8YRS);
} else if (trav.getAge().intValue() >= 9 && trav.getAge().intValue() <= 13) {
ageMatch = CategoryInterest.getCategoryInterestByValue(CategoryInterestValue.AGE_APPROPRIATE_9_13YRS);
} else if (trav.getAge().intValue() >= 14) {
ageMatch = CategoryInterest.getCategoryInterestByValue(CategoryInterestValue.AGE_APPROPRIATE_14_OLDER);
}
}
return ageMatch;
}
 It took me about 3 minutes to find this code from a previous project
Copyright © 2004 by Adigio, Inc
Example of when to use, pt1
Simple example : let's say we're building a system to analyze stock data.
 The customer wants a report of all stocks with a P/E ratio above 10.
 This should be trivial!
private static final float peRatio = 10.0;
...
if (stock.getPeRatio > peRatio) {
// do something smart
}
 The peRatio could be in a config file, or a DB table
 Later when customer says, “I've changed my mind, let's look at
stocks with P/E > 8.0”, you say sure!
Copyright © 2004 by Adigio, Inc
Example of when to use, pt2
Things get more complex...
 Next, the client says, “Let's look for stocks with P/E ratio > 8.0, and price < $30”
 Now we have a new criteria
 Maybe a simple configurable SQL statement will suffice? Works if the data is in a
relational DB.
 If DB isn't the answer we could roll our own mini rules engine
 We would like to 'declare' a list of criteria for the stock object. Maybe we have a simple
config file like :
peRatio, >, 8.0
price, <, 45
 This gets a little involved. We'd have to parse this file, use reflection, etc.
 Hibernate has a criteria mechanism that let's you build and manage queries like this
 When we're done, we can handle new criteria requests from the customer. Not
Bad!
Copyright © 2004 by Adigio, Inc
Example of when to use, pt3
This gets even more complex...
The customer hits us with, let's use the above criteria, and add :
 If the stock is traded on Nasdaq, and today is Tuesday
 If the stock belongs to companies in the set
 (Sun, Microsoft, BEA, IBM, Adigio one day?)
 If the PE > 8.0 and price < 45, but not if the price is < 10 and it's 'the holliday
season', etc, etc.
Uh oh, we've out grown our mini rules engine
Now the ability to 'declare' just about any type of rule would come in
handy
Even if data is in a DB, tough to write a query
Copyright © 2004 by Adigio, Inc
Another approach
Another home rolled mini-rules engine is the command pattern:
 Let's say we have to find a list of products appropriate to display to an end user.
 We could have a configurable list of plugins (or interceptors) something like :
<plugins>
<class=”com.adigio.rules.BuildInitialProductPool”/>
<class=”com.adigio.rules.RemoveUnderstockedProducts”/>
<class=”com.adigio.rules.MatchPrice”/>
<class=”com.adigio.rules.MatchType”/>
<class=”com.adigio.rules.ApplyDiscounts”/>
<class=”com.adigio.rules.ApplySortCriteria”/>
</plugins>
 Here we have compartmentalized sections of rules
 When something has to change, it's usually easy to find where
 Writing and deploying new plugins could be done at runtime
 Could write the plugins in groovy and change them on the fly!
 This works well for many steps, but simple logic
 This doesn't solve complex if/then/else logic
Copyright © 2004 by Adigio, Inc
Advantages of better rule
management
Business policy is defined in one place
 Compare to how it is now all over our code!
Potentially allows policy makers to define rules themselves
 The holy grail
 This doesn’t mean we are out of a job 
 It just means that we may not get bugged as much
Potentially allows you to go back and understand what the rules were
in the past
 e.g., let's analyze this person's taxes using 1995 rules
 How did we handle discounts when we launched our online shopping site?
Copyright © 2004 by Adigio, Inc
In summary
The choices of how to better manage rules aren't limited to the full
blown business rules management system
Many viable 'in between' solutions
Understand how you need to manage change
Weigh the cost of maintaining your home-grown solution
If you find a lot of 40 line if then else statements it is probably time to
consider better rule management
Copyright © 2004 by Adigio, Inc
Roadmap
Where are we?
 Thinking in Rules
 When do you need rules?
 Explaining rules engines
 Rules
 Rule Engines
 Inference Engines
 Working memory
 Chaining Rules
 Rete Alorithm
 What are my options for rules engines?
 Rules in the Enterprise
Copyright © 2004 by Adigio, Inc
What is a Rule
A rule has various conditions, and actions are performed if the
conditions are met…
Simplest form:
IF
conditions
THEN
actions
Sometimes people call:
 conditions: predicate or premises
 actions: conclusions
Copyright © 2004 by Adigio, Inc
Rule Example
A simple rule example is…
RULE #1:
IF
Dion knows Java
AND
Dion knows J2EE
THEN
Dion knows EJB
RULE #2:
IF
Dion knows EJB
THEN
Dion knows overkill
technology
Copyright © 2004 by Adigio, Inc
Rule Example
Rules have linkage…
RULE #1:
IF
Dion knows Java
AND
Dion knows J2EE
THEN
Dion knows EJB
RULE #2:
IF
Dion knows EJB
THEN
Dion knows overkill
technology
It is important that rule actions can cause other rules to fire!
Copyright © 2004 by Adigio, Inc
What is a Rule Engine?
A glorified State Machine?
High level view:
Starts with facts
Apply rules
Derive more facts
… apply more rules
Copyright © 2004 by Adigio, Inc
Forward vs. Backward
Chaining
Application areas
Backward Chaining
Forward Chaining
 1. Working memory contains facts (like
Dion knows J2EE)
 2. Find a rule where the ‘if’ part is satisfied
by facts in working memory
 3. Fire rule, and add any facts generated
by the ‘then’ part
 4. repeat until no rules have satisfied if
parts
Few rules, then chain forward
Few facts, then chain backward
Copyright © 2004 by Adigio, Inc
 1. Start with a hypothesis (like Dion knows
Overkill technology.)
 2. find which rules satisfy the goal, create
necessary sub-goals as needed.
 3. query facts to see if rules can be
satisfied
How does a rule engine do its
work? Rete Algorithm
There are various algorithms to power a rules engine. The
most common is called the Rete algorithm
The Rete algorithm creates a network graph:
The matching is a repeating
process
Fact list changes each cycle
Rules are stable, facts change
Rete remembers past test
results
Copyright © 2004 by Adigio, Inc
Roadmap
Where are we?
 Thinking in Rules
 When do you need rules?
 Explaining rules engines
 What are my options for rules engines?
 Drools
 Jess
 Mandarax
 JRules
 JSR 94
 Rules in the Enterprise
Copyright © 2004 by Adigio, Inc
Rules Engines in Java
We are lucky in that there is a wealth of choice in the Java space
Open Source:
 Drools (http://drools.codehaus.org): Codehaus based OO Java implementation of
Rete (ASL based license)
 Jess (http://herzberg.ca.sandia.gov/jess): CLIPS-esque based Java
implementation (dual academic/commercial licenses)
 Mandarax (http://mandarax.sourceforge.net): OO Java implementation of a
backwards chaining engine (LGPL based license)
Commercial:
 ILOG JRules
 Fair Isaac Blaze Advisor
 Oracle Rules (based on Jess)
And many, many more (40+ listed on www.javarules.org)
Copyright © 2004 by Adigio, Inc
Using Drools Overview
Basic steps in Drools
In Java, load rules file
Create a org.drools.RuleBase from the rules file
Create a org.drools.WorkingMemory from the RuleBase
Assert facts on WorkingMemory, which builds a rule agenda
Fire rules, i.e. execute the agenda, which manipulates facts, changes
state
Copyright © 2004 by Adigio, Inc
Drools Example: Java
Simple java example that loads and executes drools rules
// (1) load the rules file
URL url = this.getClass().getClassLoader().getResource(rulesFileName);
if (url == null) {
throw new RuntimeException("URL not found for filename " + this.rulesFileName);
}
// (2) create an org.drools.RuleBase from the file
RuleBase ruleBase = RuleBaseLoader.loadFromUrl(url);
// (3) build an org.drools.WorkingMemory from the rule base
WorkingMemory wm = ruleBase.newWorkingMemory();
// (4) assert objects willy nilly
wm.assertObject(foo);
wm.assertObject(bar);
// (5) get a handle on a result context
RulesResultContext ctx = new RulesResultContext();
// (6) fire away
wm.fireAllRules();
Copyright © 2004 by Adigio, Inc
Drools Example: Rules File
The structure of a single rule is one or more parameters, one or more conditions,
and a single consequence
<rule-set name="cheese rules"
xmlns="http://drools.org/rules"
xmlns:java="http://drools.org/semantics/java">
(1) <rule name="Bob Likes Cheese">
(2)
<parameter identifier="bob">
<java:class>org.drools.examples.simple.Bob</java:class>
</parameter>
(3)
<java:condition>bob.likesCheese() == true</java:condition>
(4)
<java:consequence>
System.out.println( "Bob likes cheese." );
</java:consequence>
</rule>
</rule-set>
This simple example has one rule named “Bob Likes Cheese”
The rule looks in working memory instances of Bob objects (facts)
For each Bob in the working memory that likes cheese, the consequence will
execute
Copyright © 2004 by Adigio, Inc
Drools Semantic Modules
Drools has interchangeable semantic modules
The example uses the Java semantic module
This means the condition and consequence sections contain java code
Drools includes semantic modules for Java, Groovy, and Python
You could implement your own semantic module to create a domain-specific
language
<rule-set name="cheese rules"
xmlns="http://drools.org/rules"
xmlns:java="http://drools.org/semantics/java">
<rule name="Bob Likes Cheese">
<parameter identifier="bob">
<java:class>org.drools.examples.simple.Bob</java:class>
</parameter>
<java:condition>bob.likesCheese() == true</java:condition>
<java:consequence>
System.out.println( "Bob likes cheese." );
</java:consequence>
</rule>
</rule-set>
Copyright © 2004 by Adigio, Inc
Drools: Comparing Java /
Groovy
<rule name="Explode Cart" salience="20">
<parameter identifier="cart">
<class>org.drools.examples.petstore.ShoppingCart</class>
</parameter>
<java:condition>cart.getState( "Exploded" ) == false</java:condition>
<java:consequence>
import java.util.Iterator;
System.out.println( "Examining each item in the shopping cart." );
Iterator itemIter = cart.getItems().iterator();
while ( itemIter.hasNext() ) {
drools.assertObject( itemIter.next() );
}
cart.setState( "Exploded", true);
drools.modifyObject( cart );
</java:consequence>
<!-- assert each item in the shopping cart into the Working Memory -->
</rule>
<rule name="Explode Cart" salience="20">
<parameter identifier="cart">
<class>org.drools.examples.petstore.ShoppingCart</class>
</parameter>
<groovy:condition>cart.getState( "Exploded" ) == false</groovy:condition>
<groovy:consequence>
println "Examining each item in the shopping cart." ;
cart.getItems().each { item | drools.assertObject( item ) } ;
cart.setState( "Exploded", true);
drools.modifyObject( cart );
</groovy:consequence>
</rule>
Copyright © 2004 by Adigio, Inc
Drools Points of Interest
Gotcha:
Facts can be manipulated by consequences
Watch out for infinite recursion when doing this :
<rule name="example rule">
<parameter identifier="s">
<java:class>State</java:class>
</parameter>
<java:condition>s.getState() == true</java:condition>
<java:consequence>
s.setState(true);
drools.modifyObject(s);
</java:consequence>
</rule>
Copyright © 2004 by Adigio, Inc
Drools Summary
Fairly simple, easy to bring into an existing Java project
Rules can be written in Java
 no need to learn a new language
Drools is a engine only
 It has no concept of managing rules, versioning, loading, etc
Documentation is good, and seems to be improving
 No book yet (anyone interested? )
It's free :)
Copyright © 2004 by Adigio, Inc
Using Jess Overview
Let’s dive into Jess a little…
Jess == Java Expert System Shell
Written in Java
easy to embed and use in Java applications
Clone of CLIPS lisp-like expert system
The Jess language is very lisp-like
(deftemplate combination
(slot letter (type ATOM))
(slot number (type INTEGER)))
Copyright © 2004 by Adigio, Inc
Sample Jess Language
Sample Jess Language
;; Define a shadow fact
(defclass chart ShoppingChart)
;; Create a new chart
(bind ?chart (new ShoppingChart))
;; Bind instance to fact
(definstance ?c chart)
;; Set the value of the chart
(call ?c setValue 1000)
;; Writing a rule
(def rule discount-rule
;; if chart value > 1000 then apply the discount
(chart (value ?v&:(> ?v 1000)))
=>
(call ?c setDiscount 15))
Copyright © 2004 by Adigio, Inc
Calling Jess from Java
This is how you can call out to Jess from Java code:
// Setup local variables
Customer customer;
ShoppingChart chart;
Item item;
// Setup the rules engine
Rete engine = new Rete();
engine.store(“customer”, customer);
engine.store(“chart”, chart);
engine.store(“item”, item);
String ruleSet = read(“chart-rules.clp”);
engine.executeCommand(ruleSet);
engine.run();
Copyright © 2004 by Adigio, Inc
Jess Summary
Oldest, most mature, open source rules engine
Based on CLIPS (very old and proven expert system)
Jess language is very different
 ((Get (ready to learn) some LISP) baybee )
Documentation is very solid
 Website docs
 Jess In Action
Author is a professor who gets this stuff 
Licensing is a little strange (dual licensing)
 Trial editions run out of time
Copyright © 2004 by Adigio, Inc
Using Mandarax Overview
Mandarax is an LGPL solution
Based on backwards reasoning (not RETE)
Includes a library of pre-defined predicates and functions
Supports RuleML
Includes Oryx
Rule management tool
Repository for managing
the vocabulary
Natural language based
rule editor
Copyright © 2004 by Adigio, Inc
Using ILog JRules Overview
JRules is a commercial suite (more than a rules engine)
Written in Java
Two styles of language
Basic rule language
when {
?c:ShoppingChart(value > 1000);
} then {
?c.setDiscount(15);
}
Business action language (english )
IF
the shopping chart value is greater than 1000
THEN
apply a 15% discount
Copyright © 2004 by Adigio, Inc
JSR 94: Standardization
JSR 94 is The Java Rule Engine API
 javax.rules.*
GOAL:
To provide a common interface for integration
of Rules engines in Java programs
Only deals with getting handles to rule engines, NO
standard for the rule language etc…
This isn’t an API for cross platform rules
Copyright © 2004 by Adigio, Inc
JSR 94: Using it in code
Here is how you get access via JSR 94:
// Imports
import javax.rules.*;
import javax.rules.admin.*;
// Import the driver that you want to use, e.g. Drools
import org.drools.jsr94.rules.RuleServiceProviderImpl;
// Register the driver
RuleServiceProviderManager.registerRuleServiceProvider(
RULE_SERVICE_PROVIDER,
RuleServiceProviderImpl.class);
RuleServiceProvider ruleServiceProvider = RuleServiceProviderManager.getRuleServiceProvider(
RULE_SERVICE_PROVIDER );
// Load the rule admin
ruleAdministrator = ruleServiceProvider.getRuleAdministrator( );
// Load the rules and register them
LocalRuleExecutionSetProvider ruleSetProvider = ruleAdministrator.getLocalRuleExecutionSetProvider(
null );
InputStream rules = this.getClass( ).getResourceAsStream( ruleUri );
RuleExecutionSet ruleExecutionSet = ruleSetProvider.createRuleExecutionSet( rules, null );
ruleAdministrator.registerRuleExecutionSet( ruleUri, ruleExecutionSet, null );
Copyright © 2004 by Adigio, Inc
JSR 94: Integrating with Spring
Spring has nice clean JSR 94 integration so you don’t have
to mess with a lot of code to access your rules engine
There are a set of configuration steps to allow Spring to
administer and use rules engines
 Declare a RuleServiceProvider
 Declare a RuleAdministor
 Declare a RuleRuntime
 Define a ruleset
<bean id="ruleServiceProvider"
class="org.springmodules.jsr94.factory.DefaultRuleServ
iceProviderFactoryBean">
<property name="provider">
<value>org.jcp.jsr94.jess</value>
</property>
<property name="providerClass">
<value>org.jcp.jsr94.jess.RuleServiceProviderImpl</val
ue>
</property>
</bean>
This is all boilerplate <bean> XML in Springs config file!
Copyright © 2004 by Adigio, Inc
Roadmap
Where are we?
 Thinking in Rules
 When do you need rules?
 Explaining rules engines
 What are my options for rules engines?
 Rules in the Enterprise
 Business Rule Management System
 Workflow
 BPM
 BPEL
Copyright © 2004 by Adigio, Inc
Rules for the Enterprise
Large enterprise projects need more than just the rules
engine itself
This is where a Business Rule Management System
comes into play
A set of tools and processes that facilitate the communication,
deployment, and execution of business policy within an IT
infrastructure
Copyright © 2004 by Adigio, Inc
Business Rule Management
A BRMS contains:
Rich client editor for business rules
Potentially used by business types
Web interface
Central rule repository (version controlled)
Hot deployment of rules
Rule debugger
Rule engine
Business Reporting
Runtime monitoring
Copyright © 2004 by Adigio, Inc
Business Rule Management
An advanced BRMS contains:
Dynamic runtime reporting
Rule refactoring and analysis
Business simulation and testing framework
Collaboration features:
Security, policy, permissions, locking
Branching and merging rules
Dynamic healing and rule changing
Defining domain specific languages for rules and processes
Copyright © 2004 by Adigio, Inc
Other similar technologies…
There are other technologies which are similar…
Workflow
 Workflow helps you automate a range of business tasks, and electronically route the
right information to the right people at the right time. Users are notified of pending work,
and help managers route approvals through the system quickly.
BPM
 “an integrated management approach that includes Web-based analytical applications
(to gather and analyze data), business plans to achieve desired metrics and the
necessary reporting and forecasting to ensure performance goals.”
BPEL / BPEL4J / BPELWS
 All about defining process
 Does not directly support abstractions for people, roles, work items or inboxes/queues,
hence BPEL is not equivalent to workflow
 Does not specify a data model for process reporting, analysis or
monitoring/administration, hence BPEL is not equivalent to BPM
Copyright © 2004 by Adigio, Inc
Module Summary
In this module we discussed:
 “Thinking in Rules”
 What declarative programming is
good for
 The ideas behind rules engines and
rules
 How engines work
 How to work with rules
 Jess
 Drools
 Mandarax
 Spring support
 Rules in the enterprise
Copyright © 2004 by Adigio, Inc
Resources
Find information at the following web sites
 Java Rules
 http://www.javarules.org/
 Jess
 http://herzberg.ca.sandia.gov/jess/
 Drools
 http://drools.org/
 Mandarax
 http://www.mandarax.org/
 JSR 94
 http://www.jcp.org/en/jsr/detail?id=94
Copyright © 2004 by Adigio, Inc