2014年2月13日木曜日

Red Hat JBoss BPM Suite - ルールからプロセス変数にアクセスする

原文: Red Hat JBoss BPM Suite - accessing process context variables from a rule by Eric D. Schabell


今回の JBoss BPM Suite のヒント/トリック集では、BPMプロジェクトで使われるルールから、どうやってプロセス変数の値を更新するかご紹介します。

GitHubで公開しているデモコレクションでご確認いただけますが、シンプルなデモプロジェクトを使います。JBoss BPM Suite でお試しいただけます。

JBoss BPM Suite のインストール作業は別途実施していただく必要があります。JBoss BPM Suite インストールプロジェクトをご利用いただくことで、遭遇する可能性のあるトラブルを回避できます。

ゴール

この記事とデモプロジェクトのゴールは、ルールを使ったプロセスのデザイン方法をご紹介することです。ルールがファイヤーされると、プロセス変数の値を更新します。私はこのような、ビジネスプロセスとルール間の連携についてよく質問されます。

セットアップ

デモプロジェクトのリポジトリーを解凍し、JBpss BPM Suite インストールプロジェクトディレクトリにコピーしてください。

# Start by cloning project at 
#   https://github.com/eschabell/demo-collections.
#
$ git clone git@github.com:eschabell/demo-collections.git

$ cd demo-collections

$ unzip niogit-rule-procvar.zip

# Follow instructions and install JBoss BPM Suite 
# via https://github.com/eschabell/bpms-install-demo.
#
# Then copy the demo repository into the JBoss BPM Suite server.
#
$ cp -rv .niogit bpms-install-demo/target/jboss-eap-6.1/bin

# Start the JBoss BPM Suite server.
#
$ ./bpms-install-demo/target/jboss-eap-6.1/bin/standalone.sh

# Login with user 'erics' and password 'bpmsuite' to get started.

さて、これでビジネスプロセスを確認できます。プロセスはどのように設定されデプロイされていますか? ルールの内容は? プロセス変数の値を変更する為にどういった修正が必要ですか? 出力結果はどうなりますか?

初期の出力結果

ビジネスプロセスは、最初のノードでまずログを出力します。次に、ルールを実行します。(ここで、プロセス変数の値を修正する予定です) 次に、ルールがファイヤーされたかどうかで分岐するゲートウェイがあります。最後に、それぞれのパスでログを出力します。

プロセス変数の値を変えるルールを保有するビジネスプロセス
私たちがテストしたい内容は、左側にあるルールが変数を TRUE にすることで、右側にあるノードが「ルールがファイヤーされた」とログに出力することです。

初期の段階では、ビジネスプロセスに最初の 2ノードだけ持たせ、エンドノードに進むよう実装しました。もし 3プロセスインスタンスを実行したら、以下のようなログが出力されると予想しました。

17:29:46,315 INFO  [stdout] (http-localhost/127.0.0.1:8080-5) Execute Java Step
17:29:46,330 INFO  [stdout] (http-localhost/127.0.0.1:8080-5) Tested Rule
17:29:46,315 INFO  [stdout] (http-localhost/127.0.0.1:8080-5) Execute Java Step
17:29:46,330 INFO  [stdout] (http-localhost/127.0.0.1:8080-5) Tested Rule
17:29:46,315 INFO  [stdout] (http-localhost/127.0.0.1:8080-5) Execute Java Step
17:29:46,330 INFO  [stdout] (http-localhost/127.0.0.1:8080-5) Tested Rule

実際には、以下のログが出力されました。

17:29:46,315 INFO  [stdout] (http-localhost/127.0.0.1:8080-5) Execute Java Step
17:29:46,330 INFO  [stdout] (http-localhost/127.0.0.1:8080-5) Tested Rule
17:29:46,315 INFO  [stdout] (http-localhost/127.0.0.1:8080-5) Execute Java Step
17:29:46,315 INFO  [stdout] (http-localhost/127.0.0.1:8080-5) Execute Java Step

この時点で、私達はビジネスプロセスを上記でご覧いただいた画像イメージへ修正しました。ルールがファイヤーされたかどうか確認する為です。3プロセスインスタンスが実行されたら、以下のようなログが出力されると予想しました。

20:51:22,491 INFO  [stdout] (http-localhost/127.0.0.1:8080-2) Execute Java Step
20:51:22,494 INFO  [stdout] (http-localhost/127.0.0.1:8080-2) Tested Rule
20:51:22,497 INFO  [stdout] (http-localhost/127.0.0.1:8080-2) Rule fired!
20:51:35,615 INFO  [stdout] (http-localhost/127.0.0.1:8080-2) Execute Java Step
20:51:35,618 INFO  [stdout] (http-localhost/127.0.0.1:8080-2) Tested Rule
20:51:35,621 INFO  [stdout] (http-localhost/127.0.0.1:8080-2) Rule fired!
20:51:43,312 INFO  [stdout] (http-localhost/127.0.0.1:8080-2) Execute Java Step
20:51:43,316 INFO  [stdout] (http-localhost/127.0.0.1:8080-2) Tested Rule
20:51:43,320 INFO  [stdout] (http-localhost/127.0.0.1:8080-2) Rule fired!

実際には、以下のログが出力されました。

20:51:22,491 INFO  [stdout] (http-localhost/127.0.0.1:8080-2) Execute Java Step
20:51:22,494 INFO  [stdout] (http-localhost/127.0.0.1:8080-2) Tested Rule
20:51:22,497 INFO  [stdout] (http-localhost/127.0.0.1:8080-2) Rule fired!
20:51:35,615 INFO  [stdout] (http-localhost/127.0.0.1:8080-2) Execute Java Step
20:51:35,618 INFO  [stdout] (http-localhost/127.0.0.1:8080-2) Rule did not fire...
20:51:43,312 INFO  [stdout] (http-localhost/127.0.0.1:8080-2) Execute Java Step
20:51:43,316 INFO  [stdout] (http-localhost/127.0.0.1:8080-2) Rule did not fire...

2回目と 3回目にルールをファイヤーする時、何が起こったのでしょう?それだけではなく、2回目と 3回目にはルールがファイヤーされていないようです。なぜでしょうか?

この問題を解決する為には、デフォルト値として用意されているセッション・ストラテジーを確認する必要があります。

デプロイ

このビジネスプロセスがどのようにデプロイされたかよく確認してみましょう。デフォルト値である、SINGLETONが適応されていました。これは、すべてのプロセスインスタンスが1つの ksession で動作することを意味します。

デフォルト値である SINGLETONストラテジー でデプロイされている

プロセスはファクトをワーキングメモリーに投入し、プロセスを実行します。ルールタスクではルールを評価するでしょう。これが 1回目のプロセスインスタンスが行う処理内容です。

2回目以降は、ワーキングメモリーが更新されていない為、ルールは評価されません。ルールタスクでは何事も起きずに次の処理へ進みます。

この問題を修正する為、私達はプロセスをきれいにする必要がありました。ルールがファイヤーされた時に更新されるプロセス変数を用意し、ゲートウェイはプロセス変数を確認するように変更しました。ルールがファイヤーされていれば、ログにも記録します。覚えておいていただきたい点は、ルールがファイヤーされる時、プロセス変数の値を更新することです。

どのように修正されたか見てみましょう。

ルール

初期段階ではアクションをファイヤーさせる為、常に条件をマッチさせるべく以下の内容で実装しました。

rule "update-procvar"
ruleflow-group "fire-always"

when 
  eval(true)
then
  System.out.println("Tested Rule");
end

SINGLETON ksession では、初回はファイヤーされますが、2回目以降はファイヤーされません。修正する為には、プロセスインスタンスが実行される際、フォームオブジェクトもしくはファクトをワーキングメモリーに投入するよう修正する必要があります。

幸運にも、ルールタスクにはこのような機能が用意されています。データアサインメントを作成し、投入するデータセットをマッピングすることができます。ルールタスクを選択し、プロパティ画面を広げてください。fired という変数を用意し、nullを設定してあります。これをデータインプットセットとしてワーキングメモリーへ投入します。

fired 変数をワーキングメモリーへ毎回投入する為にマップ

import org.kie.api.runtime.process.WorkflowProcessInstance;

rule "update-procvar"
ruleflow-group "fire-always"

when 
  $pi: WorkflowProcessInstance()
  String()
then
  $pi.setVariable("fired", "true");
end

ルールの変更箇所について説明します。 import を追記することで、実行中のプロセスインスタンスにアクセスすることができます。ローカル変数 $pi を宣言することで、プロセス変数にアクセスすることができるようになります。新しい String オブジェクトが ワーキングメモリーにあるか確認する条件を追記しました。これは常に真となります。ルールタスクノードへ入る時、毎回 fired変数に設定したオブジェクトを投入していることを覚えていますか?

この修正によりルールは評価され、プロセスインスタンスが持つ fired変数の値は更新されます。この変更は、後続のゲートウェイノードで確認されます。

それでは実際に何回か実行し、結果を確認してみましょう。

出力結果


今、私達は問題を整理し、SINGLETON ksession を利用する意味を理解しました。それは、ワーキングメモリー内に変更があった場合のみ、新規プロセスインスタンス上でもファイヤーされるというものです。いよいよ、修正されたコードをテストしてみます。

3プロセスインスタンスを実行すると、以下の内容が出力されるはずです。

21:06:32,767 INFO  [stdout] (http-localhost/127.0.0.1:8080-5) Execute Java Step
21:06:32,774 INFO  [stdout] (http-localhost/127.0.0.1:8080-5) Tested Rule
21:06:32,777 INFO  [stdout] (http-localhost/127.0.0.1:8080-5) Rule fired!
21:06:41,646 INFO  [stdout] (http-localhost/127.0.0.1:8080-5) Execute Java Step
21:06:41,654 INFO  [stdout] (http-localhost/127.0.0.1:8080-5) Tested Rule
21:06:41,656 INFO  [stdout] (http-localhost/127.0.0.1:8080-5) Rule fired!
21:06:47,559 INFO  [stdout] (http-localhost/127.0.0.1:8080-5) Execute Java Step
21:06:47,565 INFO  [stdout] (http-localhost/127.0.0.1:8080-5) Tested Rule
21:06:47,567 INFO  [stdout] (http-localhost/127.0.0.1:8080-5) Rule fired!

今回の記事を通して、ルールを含んだプロセスがどのようにデプロイされたか理解いただけたと思います。また、ルールからプロセス変数へどのようにアクセスするかもご理解いただけたはずです。ぜひ、このテクニックをあなたのプロジェクトにご活用ください。

原文: Red Hat JBoss BPM Suite - accessing process context variables from a rule by Eric D. Schabell

0 件のコメント:

コメントを投稿