SeamFramework.orgCommunity Documentation
Seam では、Seam コンポーネントあるいは jBPM プロセス定義から JBoss Rules (Drools) の RuleBase を容易に呼び出せます。
最初のステップは、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
>
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();
}
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 に機能を追加したい場合は完全なディストリビューションをダウンロードしてから必要に応じて追加の依存性を追加してください。