JBoss.com Enterprise Documentation

- Prev
- Next

## Chapter 14. Seam and JBoss Rules

Seam makes it easy to call JBoss Rules (Drools) rulebases from Seam components or jBPM process definitions.

## 14.1. Installing rules

The first step is to make an instance of `org.drools.RuleBase` available in a Seam context variable. For testing purposes, Seam provides a built-in component that compiles a static set of rules from the classpath. You can install this component via `components.xml`:

    <drools:rule-base name="policyPricingRules">

        <drools:rule-files>

            <value>policyPricingRules.drl</value>

        </drools:rule-files>

    </drools:rule-base>

This component compiles rules from a set of `.drl` files and caches an instance of `org.drools.RuleBase` in the Seam `APPLICATION` context. Note that it is quite likely that you will need to install multiple rule bases in a rule-driven application.

If you want to use a Drools DSL, you alse need to specify the DSL definition:

    <drools:rule-base name="policyPricingRules" dsl-file="policyPricing.dsl">

        <drools:rule-files>

            <value>policyPricingRules.drl</value>

        </drools:rule-files>

    </drools:rule-base>

In most rules-driven applications, rules need to be dynamically deployable, so a production application will want to use a Drools RuleAgent to manage the RuleBase. The RuleAgent can connect to a Drools rule server (BRMS) or hot deploy rules packages from a local file repository. The RulesAgent-managed RuleBase is also configurable in `components.xml`:

    <drools:rule-agent name="insuranceRules"

                        configurationFile="/WEB-INF/deployedrules.properties" />

The properties file contains properties specific to the RulesAgent. Here is an example configuration file from the Drools example distribution.

    newInstance=true
    url=http://localhost:8080/drools-jbrms/org.drools.brms.JBRMS/package/org.acme.insurance/fmeyer
    localCacheDir=/Users/fernandomeyer/projects/jbossrules/drools-examples/drools-examples-brms/cache
    poll=30
    name=insuranceconfig

It is also possible to configure the options on the component directly, bypassing the configuration file.

    <drools:rule-agent name="insuranceRules"

       url="http://localhost:8080/drools-jbrms/org.drools.brms.JBRMS/package/org.acme.insurance/fmeyer"

       local-cache-dir="/Users/fernandomeyer/projects/jbossrules/drools-examples/drools-examples-brms/cache"

       poll="30"

       configuration-name="insuranceconfig" />

Next, we need to make an instance of `org.drools.WorkingMemory` available to each conversation. (Each `WorkingMemory` accumulates facts relating to the current conversation.)

    <drools:managed-working-memory name="policyPricingWorkingMemory" auto-create="true" rule-base="#{policyPricingRules}"/>

Notice that we gave the `policyPricingWorkingMemory` a reference back to our rule base via the `ruleBase` configuration property.

## 14.2. Using rules from a Seam component

We can now inject our `WorkingMemory` into any Seam component, assert facts, and fire rules:

    @In WorkingMemory policyPricingWorkingMemory;

    @In Policy policy;

    @In Customer customer;

    public void pricePolicy() throws FactException

    {

        policyPricingWorkingMemory.assertObject(policy);

        policyPricingWorkingMemory.assertObject(customer);

        policyPricingWorkingMemory.fireAllRules();

    }

## 14.3. Using rules from a jBPM process definition

You can even allow a rule base to act as a jBPM action handler, decision handler, or assignment handler—in either a pageflow or business process definition.

    <decision name="approval">

        <handler class="org.jboss.seam.drools.DroolsDecisionHandler">

            <workingMemoryName>orderApprovalRulesWorkingMemory</workingMemoryName>

            <assertObjects>

                <element>#{customer}</element>

                <element>#{order}</element>

                <element>#{order.lineItems}</element>

            </assertObjects>

        </handler>

        <transition name="approved" to="ship">

            <action class="org.jboss.seam.drools.DroolsActionHandler">

                <workingMemoryName>shippingRulesWorkingMemory</workingMemoryName>

                <assertObjects>

                    <element>#{customer}</element>

                    <element>#{order}</element>

                    <element>#{order.lineItems}</element>

                </assertObjects>

            </action>

        </transition>

        <transition name="rejected" to="cancelled"/>

    </decision>

The `<assertObjects>` element specifies EL expressions that return an object or collection of objects to be asserted as facts into the `WorkingMemory`.

There is also support for using Drools for jBPM task assignments:

    <task-node name="review">

        <task name="review" description="Review Order">

            <assignment handler="org.jboss.seam.drools.DroolsAssignmentHandler">

                <workingMemoryName>orderApprovalRulesWorkingMemory</workingMemoryName>

                <assertObjects>

                    <element>#{actor}</element>

                    <element>#{customer}</element>

                    <element>#{order}</element>

                    <element>#{order.lineItems}</element>

                </assertObjects>

            </assignment>

        </task>

        <transition name="rejected" to="cancelled"/>

        <transition name="approved" to="approved"/>

    </task-node>

Certain objects are available to the rules as Drools globals, namely the jBPM `Assignable`, as `assignable` and a Seam `Decision` object, as `decision`. Rules which handle decisions should call `decision.setOutcome("result")` to determine the result of the decision. Rules which perform assignments should set the actor id using the `Assignable`.

    package org.jboss.seam.examples.shop

    import org.jboss.seam.drools.Decision

    global Decision decision

    rule "Approve Order For Loyal Customer"
      when
        Customer( loyaltyStatus == "GOLD" )
        Order( totalAmount <= 10000 )
      then
        decision.setOutcome("approved");
    end

    package org.jboss.seam.examples.shop

    import org.jbpm.taskmgmt.exe.Assignable

    global Assignable assignable

    rule "Assign Review For Small Order"
      when
        Order( totalAmount <= 100 )
      then
        assignable.setPooledActors( new String[] {"reviewers"} );
    end

- PrevChapter 13. The Seam Application Framework
- Top of page
- Front page
- NextChapter 15. Security