2015/4/3
第6回 デモアプリケーションを使って JBoss BRMS を理解する ~ルールフロー~
前回の「第5回 デモアプリケーションを使って JBoss BRMS を理解する」では、Coolstore デモの一つのルールについて見てきました。Coolstore デモはルールをグループ化し、順番に評価する仕組み(ルールフロー)が使われています。今回は、ルールフローについてご紹介していきます。
JBoss BRMS ではビジネスルールをフローに従って評価することができます。ルールフローをBPMN2.0の記法を用いて定義し、ビジネスルールタスクでルールフローグループ(複数のルールをグループ化した単位)を指定して呼び出すことで、この機能を実現します。 ここで注意したいポイントは、if-then-else のように前後の処理に依存する手続き型のフローではないという点です。 それぞれのルールは独立しており、同一のルールフローグループに属する他のルールや、前後のフローで実行されるルールには依存しません。
図 1 ルールフロー
ルールフローの処理を見て行く前に、ルールエンジンの内部構造を簡単にご紹介します。
図 2 ルールエンジンの内部構造
ファクト | ルールで評価する対象となるインスタンス。 Coolstoreデモではショッピングカートや購入アイテムに該当 |
---|---|
アジェンダ | ルールとファクトをマッチングした結果を保持する領域 |
アクティベーション | ルールとファクトのマッチング結果(評価は未実施)。アクティベーションの評価はファクトのinsert() / update() / retract() が呼ばれたタイミングで実行される |
insert() / update() / retract()は、ワーキングメモリ上のファクトを操作するためのメソッドで引数にファクトのインスタンスを指定します。これらのメソッドを呼ぶことにより、ワーキングメモリ、アジェンダの状態が変化します。
insert() | insert()により、ファクトがワーキングメモリに投入されると、ルールエンジンはファクトとルールのマッチングを行う |
---|---|
update() | update()により、引数で指定したファクトに関連づけられたアジェンダが実行(ルールが評価)され、ファクトの状態が更新される |
retract() | retract()により、ファクトがワーキングメモリから削除されるとともに、削除されたファクトに関連づけられたアクティベーションも削除される |
ルールを順次評価するためのフローをBPMN2.0形式で定義します。ビジネスルールタスクが呼ばれる毎にルールが実行されませんので、ビジネスルールタスク毎にルールを実行させる場合は、明示的に update() 関数を呼び出してルールを実行させる必要があります。
図 3 ルールの評価と実行
ルールフローグループは、複数のルールに同じラベルをつけてグループ単位でルールの評価と実行をする場合に利用します。ルールフローの各ビジネスルールタスクからルールフローグループを指定してルールの評価と実行を行います。
rule "Apply Cart Item Promotions" no-loop true ruleflow-group "promo-cart-rules" dialect "mvel" when $sci : ShoppingCartItem( $itemId : itemId) PromoEvent( itemId == $itemId && $pctOff : percentOff) from entry-point "Promo Stream" then $sci.setPromoSavings( $sci.price * $pctOff ); update( $sci ); $sci.setPrice( $sci.price * (1 - $pctOff) ); update( $sci ); end
KieSession session; // 中 略 session.getAgenda().getAgendaGroup("promo-cart-rule").setFocus(); session.fireAllRules();
例えば、次のような2つのルールを実行するルールフローを考えてみましょう。
ビジネルスールタスクから評価されるルールが明示的にupdate()をしていない場合は、ビジネスルールタスクを実行する毎にアジェンダにルールとファクトの組み合わせが登録されますが、ルールは実行されません。
ルールフローの最後にアジェンダに登録されたファクトとルールの組み合わせに従ってルールが実行されます。
図 4 ルールフローの動作(updateしない場合)
ビジネスルールタスクで評価されるルールが明示的に update() をしている場合は、ビジネスルールタスクを実行する毎にアジェンダにルールとファクトの組み合わせが登録されます。update()の実行によりアジェンダに登録されたルールとファクトの組み合わせに従ってルールが実行され、ワーキングメモリ上のファクトが更新されます。
図 5 ルールフローの動作(updateする場合)
Coolstoreデモのルールフローは、次のような処理の流れになっています。 それぞれの商品の値引や送料が決まらなければ合計金額を算出できませんので、ルールフローの特徴が活かされています。
Coolstoreデモでは、PriceProcess.bpmn2 でルールフローが定義されており、 brms-coolstore-demo/projects/brms-coolstore-demo/src/main/java/com/redhat/coolstore/service/ShoppingCartServiceImplBRMS.java でアプリケーションからルールフローが呼ばれていますので、これらのプログラムを参考にしてみてください。
今回はルールフローについてみていきました。ルールのグループ化は、ルールフローからの利用以外でも有効な方法です。BRMS を利用する場合には、ルールのグループ化やルールフローなども考慮して設計すると良いでしょう。
レッドハット株式会社
JBossサービス事業部
ソリューションアーキテクト 大溝 桂 様
サン・マイクロシステムズにてC言語/Java言語を利用した基幹業務システムの開発などを経験後、2012年にレッドハット株式会社に入社。パートナを担当するプリセールスエンジニアとして、JBoss Middlewareの拡販とパートナ企業の技術者育成に従事。