Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introducing Drools

Introducing Drools

In this talk I will present how a rule engine in general and Drools in particular work. After a quick introduction showing the main differences between imperative and declarative programming and describing the most common use cases when the second should be used or at least considered, I will delve in more details into how this concepts have been implemented in Drools and which are its characteristic features including: the Drools Rule Language, the possibility to combine forward and backward chaining, the Truth Management System and the temporal reasoning capabilities (Complex Events Processing). Finally I will illustrate the new features added to the version 7 of Drools including: the new multithreaded version of the rule engine; the new OOPath syntax to ease the navigation of graph of objects inside the working memory; the Rule Units that allow to partition a rules set into smaller units, binding different data sources to those units and orchestrate the execution of the individual unit; the executable model that provides a pure Java-based representation of a rule set, together with a convenient Java DSL to programmatically create such model.

Mario Fusco

May 08, 2022
Tweet

More Decks by Mario Fusco

Other Decks in Programming

Transcript

  1. What a rule engine is A business rules engine is

    a software system that executes one or more business rules in a runtime production environment. The rules might come from legal regulation ("An employee can be fired for any reason or no reason but not for an illegal reason"), company policy ("All customers that spend more than $100 at one time will receive a 10% discount"), or other sources. A business rule system enables these company policies and other operational decisions to be defined, tested, executed and maintained separately from application code.
  2. What a rule-based program is ➢ A rule-based program is

    made up of discrete rules, each of which applies to some subset of the problem ➢ It is simpler, because you can concentrate on the rules for one situation at a time ➢ It can be more flexible in the face of fragmentary or poorly conditioned inputs ➢ Used for problems involving control, diagnosis, prediction, classification, pattern recognition … in short, all problems without clear algorithmic solutions Declarative (What to do) Imperative (How to do it) Vs.
  3. Advantages of Declarative Programming ➢ Easier to understand → It

    is more likely for a technically skilled business analyst to verify, validate or even change a rule than a piece of Java code ➢ Improved maintainability → We don't care about how to implement a solution only what needs to be done to solve a problem ➢ Deals with evolving complexity → It's easier to modify a rule than a Java program and to determine the impact of this change on the rest of the application ➢ Modularity → Each rule models an isolated and small portion of your business logic and is not part of a monolithic program ➢ Requirements can be more naturally translated into rules ➢ Clear separation of business logic from the rest of the system
  4. When should you use a Rule Engine? ➢ The problem

    is beyond any obvious algorithmic solution or it isn't fully understood ➢ The logic changes often ➢ Domain experts (or business analysts) are readily available, but are nontechnical ➢ You want to isolate the key parts of your business logic, especially the really messy parts
  5. Rule's anatomy rule “<name>” <attribute> <value> when <LHS> then <RHS>

    end Quotes on Rule names are optional if the rule name has no spaces. salience <int> agenda-group <string> no-loop <boolean> auto-focus <boolean> duration <long> .... Pattern-matching against objects in the Working Memory Code executed when a match is found
  6. Imperative vs Declarative public void helloMark(Person person) { if (

    person.getName().equals( “mark” ) { System.out.println( “Hello Mark” ); } } rule “Hello Mark” when Person( name == “mark” ) then System.out.println( “Hello Mark” ); end A method must be called directly Specific passing of arguments Rules can never be called directly Specific instances cannot be passed but are automatically selected with pattern- matching
  7. What is a pattern Person( name == “mark” ) Pattern

    Object Type Field Constraint Field Name Restriction
  8. Rule's definition // Java public class Applicant { private String

    name; private int age; private boolean valid; // getter and setter here } rule "Is of valid age" when $a : Applicant( age >= 18 ) then modify( $a ) { valid = true }; end // DRL declare Applicant name : String age : int valid : boolean end
  9. More Pattern Examples Person( $age : age ) Person( age

    == ( $age + 1 ) ) Person(age > 30 && < 40 || hair in (“black”, “brown”) ) Person(pets contain $rover ) Person(pets[’rover’].type == “dog”)
  10. Conditional Elements not Bus( color = “red” ) exists Bus(

    color = “red” ) forall ( $bus : Bus( color == “red” ) ) $owner : Person( name == “mark” ) Pet( name == “rover” ) from $owner.pets $zipCode : ZipCode() Person( ) from $hbn.getNamedQuery(“Find People”) .setParameters( [ “zipCode” : $zipCode ] ) .list() Hibernate session 'from' can work on any expression
  11. Complex Event Processing Event A record of state change in

    the application domain at a particular point in time Complex Event An abstraction of other events called its members Complex Event Processing Processing multiple events with the goal of identifying the meaningful events within the event cloud
  12. Drools CEP ➢ Drools modules for Complex Event Processing ➢

    Understand and handle events as a first class platform citizen (actually special type of Fact) ➢ Select a set of interesting events in a cloud or stream of events ➢ Detect the relevant relationship (patterns) among these events ➢ Take appropriate actions based on the patterns detected
  13. Cloud vs. Stream Mode Cloud Mode (default) Stream Mode ➢

    No notion of time ➢ No requirement on event ordering ➢ Since they are based on the concept of “now” it is not possible to use sliding windows ➢ Not possible to determine when events can no longer match, so the application must explicitly retract events when they are no longer necessary ➢ Events in each stream must be time-ordered ➢ The engine will force synchronization between streams through the use of the session clock ➢ Sliding Window support ➢ Automatic Event Lifecycle Management ➢ Automatic Rule Delaying when using Negative Patterns
  14. Events as Facts in Time rule "Sound the alarm" when

    $f : FireDetected( ) not( SprinklerActivated( this after[0s,10s] $f ) ) then // sound the alarm end Temporal relationships between events
  15. Entry-point All facts are inserted here Type Nodes Discriminate on

    fact type Alpha Network Evaluate name == “Mark” Terminal Nodes Put activated rule into the agenda Beta Network Evaluate age > other.age From ReteOO
  16. • Facts are propagated into the network lazily, at firing

    time instead of insertion time • Facts are propagated in batches • Same nodes as ReteOO but grouped in segments • Segments, like nodes, can be shared across multiple rules • The sequence of one or more segments performing the evaluation of a rule is called a path • A segment can be selectively unlinked from the rete network if no facts satisfies the conditions of one of its node • A path is linked, and then the corresponding rule evaluated, only if all its segments are also linked … to Phreak
  17. From ReteOO to Phreak Advantages and attention points • Preserves

    all ReteOO features and optimizations combining them with pros of other well known algorithms like Leaps, Collection Oriented Match, L/R Unlinking … ◦ Order of execution of rules with the same priority may be different • Laziness: all propagations and corresponding constraints evaluations are performed at firing time and not at insertion time ◦ Set based propagation and WMA normalization: In ReteOO every working memory change would cause a rule to fire. In Phreak, a sequence of actions can be normalized to reduce overhead (only the “last” change is applied) • On average 20% faster then ReteOO (and up to 400% faster on specific use cases) • Reduced memory footprint • More forgiving in presence of badly written rules (rules that cannot fire are never evaluated) • Enables future optimizations including engine parallelization (Drools 7 already includes an experimental parallel engine)
  18. 26 Drools Deep Dive Representing a rule in pure Java

    rule “Older than Mark” when $p1: Person( name == “Mark” ) $p2: Person( name != “Mark”, age > $p1.age ) then System.out.println( $p1.getName() + " is older than " + $p2.getName() ); end
  19. 27 Drools Deep Dive Representing a rule in pure Java

    Variable<Person> markV = declarationOf( Person.class ); Variable<Person> olderV = declarationOf( Person.class ); Rule rule = rule( "Older than Mark" ) .build( pattern(markV) .expr("exprA", p -> p.getName().equals( "Mark" ), alphaIndexedBy( String.class, ConstraintType.EQUAL, 1, p -> p.getName(), "Mark" ), reactOn( "name", "age" )), pattern(olderV) .expr("exprB", p -> !p.getName().equals("Mark"), alphaIndexedBy( String.class, ConstraintType.NOT_EQUAL, 1, p -> p.getName(), "Mark" ), reactOn( "name" )) .expr("exprC", markV, (p1, p2) -> p1.getAge() > p2.getAge(), betaIndexedBy( int.class, ConstraintType.GREATER_THAN, 0, p -> p.getAge(), p -> p.getAge() ), reactOn( "age" )), on(olderV, markV).execute((p1, p2) -> System.out.println( p1.getName() + " is older than " + p2.getName() )) ); rule “Older than Mark” when $p1: Person( name == “Mark” ) $p2: Person( name != “Mark”, age > $p1.age ) then System.out.println( $p1.getName() + " is older than " + $p2.getName() ); end Executabl e model
  20. 28 Drools Deep Dive Representing a rule in pure Java

    Variable<Person> markV = declarationOf( Person.class ); Variable<Person> olderV = declarationOf( Person.class ); Rule rule = rule( "Older than Mark" ) .build( pattern(markV) .expr("exprA", p -> p.getName().equals( "Mark" ), alphaIndexedBy( String.class, ConstraintType.EQUAL, 1, p -> p.getName(), "Mark" ), reactOn( "name", "age" )), pattern(olderV) .expr("exprB", p -> !p.getName().equals("Mark"), alphaIndexedBy( String.class, ConstraintType.NOT_EQUAL, 1, p -> p.getName(), "Mark" ), reactOn( "name" )) .expr("exprC", markV, (p1, p2) -> p1.getAge() > p2.getAge(), betaIndexedBy( int.class, ConstraintType.GREATER_THAN, 0, p -> p.getAge(), p -> p.getAge() ), reactOn( "age" )), on(olderV, markV).execute((p1, p2) -> System.out.println( p1.getName() + " is older than " + p2.getName() )) ); rule “Older than Mark” when $p1: Person( name == “Mark” ) $p2: Person( name != “Mark”, age > $p1.age ) then System.out.println( $p1.getName() + " is older than " + $p2.getName() ); end Executabl e model
  21. 29 Drools Deep Dive Representing a rule in pure Java

    Variable<Person> markV = declarationOf( Person.class ); Variable<Person> olderV = declarationOf( Person.class ); Rule rule = rule( "Older than Mark" ) .build( pattern(markV) .expr("exprA", p -> p.getName().equals( "Mark" ), alphaIndexedBy( String.class, ConstraintType.EQUAL, 1, p -> p.getName(), "Mark" ), reactOn( "name", "age" )), pattern(olderV) .expr("exprB", p -> !p.getName().equals("Mark"), alphaIndexedBy( String.class, ConstraintType.NOT_EQUAL, 1, p -> p.getName(), "Mark" ), reactOn( "name" )) .expr("exprC", markV, (p1, p2) -> p1.getAge() > p2.getAge(), betaIndexedBy( int.class, ConstraintType.GREATER_THAN, 0, p -> p.getAge(), p -> p.getAge() ), reactOn( "age" )), on(olderV, markV).execute((p1, p2) -> System.out.println( p1.getName() + " is older than " + p2.getName() )) ); rule “Older than Mark” when $p1: Person( name == “Mark” ) $p2: Person( name != “Mark”, age > $p1.age ) then System.out.println( $p1.getName() + " is older than " + $p2.getName() ); end Indexes and reactivity explicitly defined Executabl e model
  22. Executable Model at a glance • A pure Java DSL

    for Drools rules authoring • A pure Java canonical representation of a rule base • Automatically generated by Maven plugin • Can be embedded in JAR ◦ Faster compilation ◦ Backward/Forward compatible • Allow for faster prototyping and experimentation of new features • Prerequisite to make Drools natively compilable on GraalVM RULES
  23. • A cloud-native development, deployment and execution platform for business

    automation: ◦ Rules and Decisions ◦ Processes and Cases • ... under the covers ◦ the backbone is code generation based on business assets ◦ executable model for the process/rule/decision definitions ◦ type safe data model that encapsulates variables ◦ REST api for each public business process/decision/rule Introducing
  24. Q&A