SeamFramework.org Community Documentation

- 前のページ
- 次のページ

## 第14章 Seam と JBoss Rules

Seam では、Seam コンポーネントあるいは jBPM プロセス定義から JBoss Rules (Drools) の RuleBase を容易に呼び出せます。

## 14.1. ルールをインストールする

最初のステップは、Seam コンテキスト変数で `org.drools.RuleBase` のインスタンスを使用可能にすることです。 テスト目的で、Seam はクラスパスから静的なルール一式をコンパイルする組み込みコンポーネントを提供しています。 このコンポーネントは `components.xml` を使ってインストールすることができます。

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

        <drools:rule-files>

            <value

    >policyPricingRules.drl</value>

        </drools:rule-files>

    </drools:rule-base

    >

このコンポーネントは、DRL (`.drl`) ファイルやデシジョンテーブル (`.xls`) ファイルのセットからルールをコンパイルし、 Seam `アプリケーション` コンテキストの `org.drools.RuleBase` にインスタンスをキャッシュします。 1 つのルール駆動型アプリケーションに複数の RuleBase をインストールする必要が生じる可能性が非常に高いので注意してください。

Drools DSLを利用するのであれば DSL 定義も指定しなければなりません。

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

        <drools:rule-files>

            <value

    >policyPricingRules.drl</value>

        </drools:rule-files>

    </drools:rule-base

    >

Drools RuleFlowに対するサポートも利用可能で、下記のようにルールファイルに `.rf` もしくは `.rfm` ファイルを追加するだけです。

            <drools:rule-base name="policyPricingRules" rule-files="policyPricingRules.drl, policyPricingRulesFlow.rf"/>

Drools 4.x RuleFlow (`.rfm`) フォーマットを使うとき、サーバー起動時に -Ddrools.ruleflow.port=true というシステムプロパティを指定する必要があることに注意してください。しかしながらこれはまだ実験的な機能なので、私たちは可能であれば、Drools5 (`.rf`) フォーマットを利用することをお勧めします。

もし RuleBaseConfiguration 経由のカスタムの結果例外ハンドラを登録したい場合は、以下の例のようにハンドラを記述する必要があります。

    @Scope(ScopeType.APPLICATION)

    @Startup

    @Name("myConsequenceExceptionHandler")

    public class MyConsequenceExceptionHandler implements ConsequenceExceptionHandler, Externalizable {

       public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {

       }

       public void writeExternal(ObjectOutput out) throws IOException {

       }

       public void handleException(Activation activation,

                                   WorkingMemory workingMemory,

                                   Exception exception) {

           throw new ConsequenceException( exception,

                                           activation.getRule() );

       }

    }

そして、これを登録します。

    <drools:rule-base name="policyPricingRules" dsl-file="policyPricing.dsl" consequence-exception-handler="#{myConsequenceExceptionHandler}">

        <drools:rule-files>

            <value

    >policyPricingRules.drl</value>

        </drools:rule-files>

    </drools:rule-base

    >

ほとんどのルール型アプリケーションでは、 ルールが動的にデプロイ可能である必要があるので実稼働アプリケーションは RuleBase の管理に Drools RuleAgent の使用を好みます。 RuleAgent は Drools ルールサーバー (BRMS) またはローカルファイルレポジトリにあるホットデプロイルールのパッケージに接続することができます。 RulesAgent 管理の RuleBase も `components.xml` で設定が可能です。

    <drools:rule-agent name="insuranceRules"

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

プロパティファイルはその RulesAgent に固有のプロパティを含んでいます。 Drools サンプルディストリビューションからの設定ファイルの例を示します。

    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

また、 設定ファイルを避けコンポーネントで直接オプションを設定することも可能です。

    <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" />

次に、各対話に対して `org.drools.WorkingMemory` インスタンスを有効化する必要があります。 (各 `WorkingMemory` は、現在の対話に関連する fact を蓄積します。)

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

`policyPricingWorkingMemory` に、 `ruleBase` 設定プロパティにより、 RuleBase への参照を与えていることに留意してください。

私たちはまた、WorkingMemory にイベントリスナーを追加することによって、ルールを発火したり、オブジェクトをアサートしたりするなどのルールエンジンのイベントを通知する手立てを追加することもできます。

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

            <drools:event-listeners>

                <value

    >org.drools.event.DebugWorkingMemoryEventListener</value>

            <value

    >org.drools.event.DebugAgendaEventListener</value>

            </drools:event-listeners>

    </drools:managed-working-memory

    >

## 14.2. Seam コンポーネントからのルールを使用する

`WorkingMemory` を、 任意の Seam コンポーネントにインジェクトし、 fact をアサートし、そしてルールを実行することができます。

    @In WorkingMemory policyPricingWorkingMemory;

    @In Policy policy;

    @In Customer customer;

    public void pricePolicy() throws FactException

    {

            policyPricingWorkingMemory.insert(policy);

            policyPricingWorkingMemory.insert(customer);

            // if we have a ruleflow, start the process

            policyPricingWorkingMemory.startProcess(startProcessId)

        policyPricingWorkingMemory.fireAllRules();

    }

## 14.3. jBPM プロセス定義からのルールを使用する

RuleBase が jBPM アクションハンドラ、デシジョンハンドラ、あるいは割り当てハンドラなどとして動作するようにさせることも可能です — ページフローまたはビジネスプロセス定義のどちらでも可。

    <decision name="approval">

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

            <workingMemoryName

    >orderApprovalRulesWorkingMemory</workingMemoryName>

            <!-- if a ruleflow was added -->

            <startProcessId

    >approvalruleflowid</startProcessId>

            <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

    >

`<assertObjects>` 要素は `WorkingMemory` に fact としてアサートされるオブジェクトの集合または 1 オブジェクトを返す EL 式を指定します。

一方、`<retractObjects>` 要素は `WorkingMemory` にリトラクトされるオブジェクトの集合または 1 オブジェクトを返す EL 式を指定します。

jBPM タスク割り当てのために Drools の使用もサポートしています。

    <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

    >

ルールに対して特定のオブジェクトが Drools のグローバルとして使用可能です。 jBPM `Assignable` は `assignable` として、 Seam `Decision` オブジェクトは `decision` として使用可能です。 decision を処理するルールは `decision.setOutcome"result")` を呼び出して決定結果を確定します。 assignment を実行するルールは `Assignable` を使ってそのアクターIDを設定するはずです。

    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

## 注意

Drools については http://www.drools.org を参照してください。

## 注意

Seam はシンプルなルールを実装するのには十分な Drools の依存性を同梱しています。 Drools に機能を追加したい場合は完全なディストリビューションをダウンロードしてから必要に応じて追加の依存性を追加してください。

- 前のページ第13章 Seamアプリケーションフレームワーク
- 上に戻る
- ホーム
- 次のページ第15章 セキュリティ