Version 26


    Rule Flow

    Rule flows can now built with the eclipse gui and saved as a file, those files can then be used to control the execute flow of rules:

    final PackageBuilder builder = new PackageBuilder();
    builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "ruleflow.drl" ) ) );
    final Package pkg = builder.getPackage();
    final ProcessBuilder processBuilder = new ProcessBuilder();
    processBuilder.addProcessFromFile( new InputStreamReader( getClass().getResourceAsStream( "ruleflow.rfm" ) ) );
    final RuleBase ruleBase = getRuleBase();
    ruleBase.addPackage( pkg );
    ruleBase.addProcess( processBuilder.getProcesses()[0] );


    Invoke a Rule Flow by executing the applicable process:

    workingMemory.startProcess( processId );


    use the rule-flow-group attribute to specify that a rule belongs to a particular rule flow group.


    The plugin generates 2 versions of your ruleflow:

    • a .rf (ruleflow file) containing the entire ruleflow, including all graphical information like coordinates of all the elements

    • a .rfm version (ruleflow model file) containing only the definition of the ruleflow, not the graphical information


    It is this second file (the .rfm) that needs to be used when adding a ruleflow to a ProcessBuilder.

    Trying to add the .rf file will indeed result in the exception "CannotResolveClassException", because the classes containing the graphical information are not part of the drools core and thus cannot be found.



    Once an agenda-groups or rule-flow-group starts to fire it's rules, it cannot accept any further new transactions for the rule that specifies this attribute as true, which helps deal with recursion.


    WorkingMemory now split into StatefulSession and StatelessSession

    WorkingMemory wm = ruleBase.newWorkingMemory()

    is now removed and instead you have:

    StatefulSession session = ruleBase.newStatefulSession();
    StatelessSession session = ruleBase.newStatelessSession();


    Async methods

    Both StatefulSession and StatelessSession support async methods for working memory actions and fireAllRules. It uses the DefaultExecutorService to handle the threading model, which just spins off a new thread. A custom ExecutorService can be sepcified using the RuleBaseConfiguration.


    Slimmed deps

    The additional dependencies for core and compiler has been reduced.


    stateful conways game of life

    Conway's Game of Life example has been updated and is now fully stateful, this is the best example to look at now in trying ot understand rule engines.


    DSLs re-introduced

    • New improved formula, fully i18n capable (can have LHS and RHS mixed up, even keywords customizable)


    New operators: "in", "not in", "memberOf", "not memberOf"

    • Examples:

    Cheese( type in ( 'stilton', 'brie' )) Cheese( type not in ( 'stilton', 'brie' )) Cheese( type memberOf $myCheeseTypeList ) Cheese( type not memberOf $myCheeseTypeList )


    New automatically avaible field: "this" can now be used as a field for constraining the fact

    • Now you can constrain facts that are "equals" like:

    rule "keeps consistency" when     $r : Relationship( $s: source, $t: target )     not( Source( this == $s ) ) then     retract( $r ); end

    Facts do not require default constructor anymore

    • Shadow facts do not require that facts implement a default no-arg constructor anymore. They also cache hashcode now for improved performance.


    Implicit bindings for predicates and return values

    • There is no need to bind fields to use exclusively inside predicates and return values anymore. Example:


    Cheese( oldPrice : oldPrice, newPrice == ( oldPrice  1.10 ) )


    is exactly the same as:


    Cheese( newPrice == ( oldPrice  1.10 ) )


    As the field "oldPrice" is implicitly declared for use inside the return value predicate.



    The BRMS (business rule management system) is now for the first time available

    as part of a milestone.

    This component has a LOT of features, which are only briefly summarised here (tutorials

    and manual is in progress).




    The BRMS application itself is a war file, this means deploying it can be as simple

    as dropping it into an deploy directory (if you are happy with defaults, thats

    all you need to do)



    Package configuration

    • Once deployed, go to "http://<your server>/drools-jbrms/"

    • This will show the initial info screen

    • If it is brand new, you will want to go to "Admin", and choose "Manage Categories"

      • Add a few categories of your choosing, categories are only for classification, not for execution or anything else.

    • Rules need a fact model (object model) to work off, so next you will want to go to the Package management feature. From here you can click on the icon to create a new package.

    • To upload a model, use a jar which has the fact model (API) that you will be using in your rules and your code. Then click on the icon for uploading a new model. When you are in the model editor screen, you can upload a jar file, choose the package name from the list that you created in the previous step.

    • Now edit your package configuration (you just created) to import the fact types you just uploaded, and save the changes.

    • At this point, the package is configured and ready to go.



    Rule authoring

    • Once you have at least one category and one package setup, you can author rules.

    • There are multiple rule "formats", but from the BRMS point of view, they are all "assets".

    • You create a rule by clicking the icon with the rules logo (the head), and from that you enter a name.

    • You will also have to choose one category. Cateogies provide a way of viewing rules that is seperate to packages (and you can make rules appear in multiple packages) - think of it like tagging.

    • Chose the "Business rule" formats

    • This will open a rule modeller, which is a guided editor. You can add and edit conditions and actions based on the model that is in use in the current package. Also, any DSL sentence templates setup for the package will be available.

    • The other notable rule formats are:

      • DSL Template rule, which is a textual format, which can use natural language as specified in a package's DSL configuration.

      • There is also plain old drl, for "technical" rules - these can be either single rules (just include the "when" and the "then" part is all you need) or a whole lot of rules like you may have seen in the past (you don't need any imports or other declarations, they are taken care of in the package). Note that if the rule name is not included in the drl, it will use the name of the "asset".

      • You can also upload XLS decision tables (create a new Spreadsheet based decision table, and then upload yours - by default it comes with a template you can download and work off).

    • When you are done with rule editing, you can check in the changes (save), or you can validate or "view source" (for the effective source).

    • You can also add/remove categories from here, and other attributes such as documentation (if you aren't sure what to do, write a document in natural language describing the rule, and check it in, that can also serve as a template later)


    Finding stuff

    In terms of navigating, you can either use the Rules feature, which shows things grouped by categories, or you can use the Package feature, and view by package (and rule type). If you know the name or part of the name of an asset, you can also use the "Finder", start typing a rule name and it will return a list of matches as you type (so if you have a sensible naming scheme, it will make it very quick to find stuff).

    • Categories can be used like tags, you can add and remove them, eg marking something as "draft" etc (its entirely up to you).

    • You will also notice that everything has a status, this is also only for reporting (you can choose to ignore it if you like).



    • After you have edited some rules in a package, you can go to the package feature, and build the whole package.

      • If that succeeds, then you will be able to download a binary package file which can be deployed into a runtime system.

    • You can also take a "snapshot" of a package for deployment. This freezes the package at that point in time, so any concurrent changes to not effect the package. It also makes the package available on a URL of the form: "http://<your server>/drools-jbrms/org.drools.brms.JBRMS/packages/<packageName>/<snapshotName>"



    Configuration (optional)

    • By default, the first time the repository is run, it will create a new database in the directory that the server runs in: this consists of a file "repository.xml" and a directory called "repository".

    • If you want to have the repository in a different location, you can unzip the war file, and locate the "components.xml configuration file. In that, you will see how you can tell the repository "home" to be on a different directory (or filesystem).

    • If you want to use a different RDBMS to store all repository content, that can also be be achieved with some configuration.

      • An easy way is to start up the repository, and let it generate a default "repository.xml" for you (either in the default location, or where you told it to be in the step above).

      • You then can edit the repository.xml file to use the database of your choice.

    The BRMS uses the Apache Jackrabbit JCR implementation as the content store, which has

    the concept of "PersistenceManagers" - these PMs support every database under the sun

    (and you can also use filesystems). For more information on configuring a persistence

    manager for your environment, refer to Apache Jackrabbit:

    (the repository.xml will have some examples in it already).

      • It is important to note that if you are using an external RDBMS, then the credentials used to access it should have permissions to create tables (at least the first time, when the repository sets itself up).




    • An app server/servlet container capable of working with Java 5 (doesn't have to be JEE5, just Java 5 runtime is fine)

      • This is actively tested on JBoss AS 4.0.5, JBossWeb 1.0.1, but should also work with Tomcat and others (perhaps with adding/removing dependencies in the war)

    • No external database required, but one can be configured if needed.