Red Hat Training

A Red Hat training course is available for JBoss Enterprise SOA Platform

第4章 ルールサービス

4.1. ルールサービスとは?

この章を参照し、ルールサービスのコンセプトと、ルールサービスの使用方法について学びます。JBoss Business Rules Management System (BRMS) のバックグラウンドを理解していると、この章を読み進めていく際に役立ちます。

4.1.1. はじめに

JBoss Enterprise SOA Platformルールサービス があると、ESB 上で サービスとして貴社のビジネスアナリストが記述したビジネスルールをデプロイできます。これには大きく2つの利点があります。
  1. ルールをあるアプリケーション環境に統合するのに必要なクライアントコードの量が大幅に削減される
  2. アクションチェーンから、あるいはオーケストレーションされたビジネスプロセス内からルールにアクセスできる

注記

JBoss Business Rules Management System は対応オプションですが、ご希望であれば rule engine を利用できます。
ルールサービス機能は、BusinessRulesProcessorDroolsRuleService のアクションクラスで提供され、後者は RuleService インターフェースも実装します。
BusinessRulesProcessor クラスにより、クラスパスからルールをロードすることができます。これらのルールは .drl および .dsl ファイルや決定テーブル (.xls 形式) で定義されます。ただし、1つの BusinessRulesProcessor アクションを複数のルールファイルで指定する方法はないため注意してください。これらのファイルベースのルールは、主にプロトタイプのテストができるように存在します。より複雑なルールサービスは、JBoss Rules KnowledgeAgent を使う必要があります。
RuleService は、KnowledgeAgent を使い、Business Rules Management System からか、ローカルファイルシステムからルールパッケージにアクセスします。ルールパッケージには、様々なソースを持つ何千ものルールが含まれています。例えば以下が挙げられます。
  1. JBoss Business Rules Management System
  2. インポートされた DRL ファイル
  3. ドメイン固有言語 (DSL) ファイル
  4. 決定テーブル

重要

Red Hat は、実稼働システムでは KnowledgeAgent アプローチを使うよう推奨しています。
BusinessRulesProcessor アクションは、 ステートレスステートフルの JBoss Rules の実行モデルに対応します。
ルールサービスの多くがストートレスモデルに準拠します。このモデルでは、メッセージがルールサービスに送信されます。このメッセージのボディに含まれているものは、ルールエンジンにより処理されるファクトすべてです。このルールが実行され、メッセージやファクトを更新します。
反対に、ステートフル実行はより長い時間をかけて複数のメッセージをルールサービスに送信します。メッセージが送信されるたびに、ルールが再度実行され、メッセージやファクトが更新されます。プロセスの最後に、最終メッセージがルールサービスがステートフルセッションの作業メモリを消去するか通知し、その後ルールエンジンから完全に消去されます。

重要

RuleAgent は SOA Platform の ESB では利用されなくなっており、設定方法が違う KnowledgeAgent が代わりに利用されます。DRL 変更のポーリング設定は ruleAgentProperties ファイルの poll プロパティから設定されなくなっており、今はesb.deployer/jbossesb-properties.xml 内にある org.jboss.soa.esb.services.rules.resource.scanner.interval プロパティからグローバルに設定可能です (デフォルト値は 60)。つまり、KnowledgeAgents すべてでリソース変更があるかシステムが60秒おきにチェックします。
また、これらのプロパティを提供し、基本認証でセキュリティが確保された URL にアクセスする必要があります。
username=admin
password=admin
enableBasicAuthentication=true

注記

ステートフルモデルには制限があります。それは、メッセージフロー内にルールサービスを1つしか置くことができませんが、今後この制限はなくなる可能性があります。

4.2. JBoss Rules でのルールサービスの利用

4.2.1. はじめに

JBoss Rules は、SOA Platformルールサービス機能を提供するエンジン名です。詳細については本章を参照してください。
JBoss Rules は以下のコンポーネントを使い SOA Platform とやり取りを行います。
  • BusinessRulesProcessor アクションクラス
  • JBoss Rules、DRL、DSL、決定テーブル、Business Rule Editor のいずれかで記述されたルール
  • Enterprise Service Bus メッセージ (これは JBoss Rules Engine の作業メモリに挿入されます)
  • Enterprise Service Bus メッセージのコンテンツ (JBoss Rules エンジンに送信されるメッセージにある "fact" オブジェクトで構成されている)
メッセージを BusinessRulesProcessor に送信すると、ルールセット がそのメッセージに含まれているファクトオブジェクトを処理します。それぞれ、このルールセットはファクトオブジェクトの1つを更新するか、メッセージ自体を更新します。

4.2.2. ルールセットの作成

JBoss Developer Studio を使いルールセットを作成します。メッセージがグローバルとして作業メモリに送信されるため、jbossesb-rosetta.jar ファイルを JBoss Rules プロジェクトに追加する必要があります。

注記

ルール作成と JBoss Rules 言語自体の詳しい説明は、同梱の JBoss Rules リファレンスガイドを参照してください。
JBoss Enterprise SOA Platform でサービスとしてデプロイメントのルールを記述する場合、これらの要件に必ず準拠します。
名前とアクションクラスの両方が必要です (名前はユーザー定義)。
<action class="org.jboss.soa.esb.actions.BusinessRulesProcessor"
  name="OrderDiscountRuleService">
以下のうち1つが必要となります:
  • DRL ファイル
    <property name="ruleSet" value="drl/OrderDiscount.drl" />
    
  • DSL あるいは DSLR (ドメイン固有言語) ファイル
    <property name="ruleSet" value="dsl/approval.dslr" />
    <property name="ruleLanguage" value="dsl/acme.dsl" />
    
  • クラスパスの decisionTable
    <property name="decisionTable" value="PolicyPricing.xls" />
    
  • クラスパス上のプロパティファイル (rule agent にルールパッケージの検索方法を伝えることを目的ととする)。その方法ですが、URL あるいはローカルファイルへのパスのいずれかを指定します。
    <property name="ruleAgentProperties"
               value="brmsdeployedrules.properties" />
    
以下に設定例を示します。
  1. ここでは、ルールが DRL ファイルに置かれており、ステートレスモデルに従い実行されます。
    <action class="org.jboss.soa.esb.actions.BusinessRulesProcessor"
      name="OrderDiscountRuleService">
        <property name="ruleSet" value="drl/OrderDiscount.drl" />
        <property name="ruleReload" value="true" />
        <property name="object-paths">
            <object-path esb="body.Order" />
        </property>
    </action>
    
  2. ここでは、ルールが DRL ファイルに置かれており、ステートフルモデルに従い実行されます。
    このシナリオでは、一定期間にクライアントが複数のメッセージをルールサービスに送信することができます。例えば、最初のメッセージには顧客オブジェクトが含まれており、続きのメッセージはその顧客に対する注文がそれぞれ含まれています。メッセージが受信されるたびにルールが実行されます (クライアントは、作業メモリのコンテンツを消去するようルールサービスに伝える最終メッセージにプロパティを追加することができます)。

    注記

    1. 同期セッションインスタンス1つをステートフルセッションデプロイメントの同期実行すべてにて共有します。これにより、ステートフルモデルのユースケースの数が大幅に制限されます。複数のクライアント指向セッションサービスデプロイメントが必要な場合、代わりに jBPM あるいは BPEL ソリューションの利用を検討してください。
    2. ステートフルセッションは 永続的ではありません。
    3. ステートフルセッションは クラスター化されていません
    <action class="org.jboss.soa.esb.actions.BusinessRulesProcessor"
      name="OrderDiscountMultipleRuleServiceStateful">
        <property name="ruleSet"
                  value="drl/OrderDiscountOnMultipleOrders.drl" />
        <property name="ruleReload" value="false" />
        <property name="stateful" value="true" >
        <property name="object-paths">
            <object-path esb="body.Customer" />
            <object-path esb="body.Order" />
        </property>
    </action>
    
  3. この例では、ルールは DRL ファイルに置かれており、ステートフルモデルを使い、監査ロギングが有効になっています。JBoss Rules clockTypeeventProcessingTypeチャネル を設定し複合イベント処理 (CEP: complex event processing) を容易にします。
    ruleMultithreadEvaluationfalse に設定されているため、ナレッジベースパーティショニング は有効ではありません(また、ruleMaxThreads1 に設定されている点も注意してください)。

    注記

    複合イベント処理のシナリオでは、ステートフルモデルを使っているため、前述した例と同じように、これらのシナリオはステートフルセッションデプロイメントの同期実行すべてにおいて共有されます。
    <action class="org.jboss.soa.esb.actions.BusinessRulesProcessor"
      name="OrderEventsRuleServiceStateful">
        <property name="ruleSet" value="drl/OrderEvents.drl" />
        <property name="ruleReload" value="false" />
        <property name="stateful" value="true" >
        <property name="ruleFireMethod" value="FIRE_UNTIL_HALT" />
        <property name="ruleAuditType" value="THREADED_FILE" />
        <property name="ruleAuditFile" value="myaudit" />
        <property name="ruleAuditInterval" value="1000" />
        <property name="ruleClockType" value="REALTIME" />
        <property name="ruleEventProcessingType" value="STREAM" />
        <property name="ruleMultithreadEvaluation" value="false" />
        <property name="ruleMaxThreads" value="1" />
        <property name="object-paths">
            <object-path esb="body.OrderStatus"
                entry-point="OrderStatusStream" />
            <object-path esb="body.OrderInfo"
                entry-point="OrderInfoStream" />
        </property>
        <property name="channels">
            <!-- chan1 and chan2 are equivalent
                (but timeout only applies if async is false) -->
            <send-to channel-name="chan1"
                service-category="cat1" service-name="svc1" />
            <send-to channel-name="chan2"
                service-category="cat1" service-name="svc1"
                channel-class="org.jboss.soa.esb.services.rules.ServiceChannel"
                async="true" timeout="30000"
                set-payload-location="org.jboss.soa.esb.message.defaultEntry" />
            <!-- chan3 is a custom channel -->
            <send-to channel-name="chan3"
                channel-class="com.example.MyChannel" />
        </property>
    </action>
    
  4. この例では、ルールはドメイン固有言語形式で、ステートレス実行モデルが採用されています。
    <action class="org.jboss.soa.esb.actions.BusinessRulesProcessor"
      name="PolicyApprovalRuleService">
        <property name="ruleSet" value="dsl/approval.dslr" />
        <property name="ruleLanguage" value="dsl/acme.dsl" />
        <property name="ruleReload" value="true" />
        <property name="object-paths">
            <object-path esb="body.Driver" />
            <object-path esb="body.Policy" />
        </property>
    </action>
    
  5. この例ではルールは決定テーブルにあり、ステートレス実行モデルが採用されています。
    <action class="org.jboss.soa.esb.actions.BusinessRulesProcessor"
      name="PolicyPricingRuleService">
        <property name="decisionTable"
                  value="decisionTable/PolicyPricing.xls" />
        <property name="ruleReload" value="true" />
        <property name="object-paths">
            <object-path esb="body.Driver" />
            <object-path esb="body.Policy" />
        </property>
    </action>
    
  6. この例では、ルールは BRMS 形式で、ステートレス実行モデルが採用されています。
    <action class="org.jboss.soa.esb.actions.BusinessRulesProcessor"
      name="RuleAgentPolicyService">
        <property name="ruleAgentProperties"
                  value="ruleAgent/brmsdeployedrules.properties" />
        <property name="object-paths">
            <object-path esb="body.Driver" />
            <object-path esb="body.Policy" />
        </property>
    </action>
    
これはアクションタグの属性です。これらの属性を使い実行すべきアクションと、このアクションを渡す名前を指定します。
BusinessRulesProcessor アクション設定属性
属性説明
クラスアクションクラス
名前カスタムアクションの名前
アクションプロパティが表2に示されています。これらのプロパティは、このアクションで使うルールセット (ruleSet) を指定します。
BusinessRulesProcessor アクション設定プロパティ
プロパティ説明
ruleSetこれはコンテンツの評価に利用するルールセットである ruleSet を含むファイルへの参照(任意)です。各 rule service インスタンスに対して ruleSet 1つのみを渡すことができます。
ruleLanguageこれは、ルールセットの評価に利用するドメイン固有言語の定義を含むファイルへの参照(任意)です。この定義はルールセットの評価に利用できます。利用されている場合、ruleSet のファイルは dslr であるようにします。
ruleReloadrule setsホットデプロイメントを有効にするには、このプロパティ (任意) を true に設定します (ただし、この機能を有効にするとルール処理のオーバーヘッドが増加します)。ルールが存在する .esb アーカイブが再デプロイされた場合、ルールもリロードされる点に注意してください。
decisionTableこれは、ルール仕様のスプレッドシートの定義を含むファイルへの参照 (任意) です。
statefulこの任意のプロパティを true に設定し rule service が一定期間中に複数のメッセージを受信するよう指定します (新しいファクトが rule engineworking memory に追加されルールが毎回再実行されます)。
object-pathsメッセージオブジェクトを JBoss Rules の Working Memory に渡す任意のプロパティ
ruleFireMethodステートフルルール実行メソッドを定義する任意のプロパティ。有効な値は FIRE_ALL_RULES (デフォルト) と FIRE_UNTIL_HALT (自身のスレッドをキックオフ。複合イベント処理 (CEP) に便利)
ruleAuditTypeDrools に監査ロギングを実行させる任意のプロパティ。ログを Drools Eclipse プラグインに読み込ませ確認することができます。有効な値は CONSOLE、FILE、THREADED_FILE で、デフォルトでは監査ロギングが実行されます。
ruleAuditFile監査ロギングのファイルパスを定義する任意のプロパティ。FILE あるいは THREADED_FILE ruleAuditType のみに適用されます。デフォルトは "event" です。JBoss Drools は ".log" を自動で追加します。このファイルのデフォルトの場所は "." (現在の作業ディレクトリ、つまり JBoss では bin/ ディレクトリ) となっています。
ruleAuditInterval監査イベントを監査ログにフラッシュする頻度を定義する任意のプロパティ。これは THREADED_FILE ruleAuditType のみに適用されます。デフォルトは 1000 (ミリ秒) です。
ruleClockTypeJBoss Drools が利用するクロックを定義する任意のプロパティ。有効な値は REALTIME および PSEUDO です。デフォルトは REALTIME です。
ruleEventProcessingTypeDrools で使うイベント処理オプションを定義する任意のプロパティ。有効な値は CLOUD あるいは STREAM (CEP に便利) で、デフォルトは CLOUD です。
ruleMultithreadEvaluationナレッジベースパーティショニングを有効にするかを定義する任意のプロパティ。デフォルトは null で、これは false となっている Drools のデフォルトに委譲します。
ruleMaxThreadsナレッジベースパーティショニングを利用するスレッドの数を定義する任意のプロパティ。これは、ruleMultithreadEvaluation が true の場合のみ考慮されます。デフォルトは null で、これは JBoss Rules のデフォルトに委譲します。
channelsルールがオブジェクトを送信できるチャネルを定義する任意のプロパティ。チャネルのコンセプトは従来 ExitPoint として知られるものです。「チャネル」の章を参照してください。

4.2.3. オブジェクトパス

オブジェクトパスについてはこのセクションを参照してください。
JBoss Rules エンジンはオブジェクトをシャローとみなします。このソフトウェアはパフォーマンスを最適化するためこのように設計されました。
object tree 階層の下の方にあるオブジェクトを評価したい場合は、任意の object tree を使います。ESB Message Object Path を使い、このプロパティを取り出し、このプロパティを設定します。
JBoss Rules エンジンは MVFLEX Expression Language (MVEL) を使いオブジェクトを抽出します。お使いのパスは、この構文に従う必要があります。
location.objectname.[beanname].[beanname]...
この場合:
  • location は {body, header, properties, attachment} のいずれかでなければなりません。
  • objectname はオブジェクトの名前です (attachment は名前をつけるか、数字をつけることができます。そのため、attachment が複数ある場合、数字にすることも可能です)。
  • beannames は任意です。このタグを使い、bean graph を探索します。
他の MVEL 式言語例についても以下に示しています。
MVEL 式言語の例
結果
properties.Orderこれを使い、 Orderという名前のプロパティオブジェクトを取得します。
attachment.1最初の attachment オブジェクトを取得
attachment.AttachmentOneAttachmentOne という名前の attachment を取得
attachment.1.Order添付オブジェクト上で getOrder()リターンオブジェクトを取得
body.Order1.lineitemメッセージのオブジェクトから Order1 という名前のオブジェクトを取得。次に、このオブジェクトで getLineitem() が呼び出されます。bean グラフをトラバースするために、他の要素をクエリに追加することもできます。

重要

ルールセットにインポートしたオブジェクトに、java import ステートメントを追加するのを忘れないでください。

注記

オブジェクトマッパー はコレクション全体を「フラット化」します。 フラット化の必要がある場合、まずメッセージで変換プロセスを行うことでコレクションを展開します。

4.2.4. チャネル

オブジェクトを JBoss Rules エンジンチャネルに送信するには、この DRL 構文を使います (ルール定義の右側に行きます)。
channels["mychannel"].send(myobject);
このコードスニペットを機能させるには、mychannel を自身のチャネルに追加します。方法は、jboss-esb.xml 設定ファイルに channels プロパティセクションを追加します。
同じあるいは違うチャネル名を使うことで、チャネルはいくつでも定義できます (各チャネル名ですが、チャネルは設定ファイルに表示されている順番で実行されます)。
以下のタイプのチャネルに対応しています。
  • デフォルトで提供されている ServiceChannel。機能させるには send-to 要素の属性として、channel-nameservice-categoryservice-name を指定する必要があります。
    他にasynctimeoutset-payload-location という任意の属性があります (チャネルに送信されるオブジェクトは新しい ESB メッセージに置かれます)。
    このコードは属性の設定方法を表しています。
    <property name="channels">
        <send-to channel-name="mychannel"
            service-category="cat1" service-name="svc1" />
    </property>
    

    重要

    ターゲットサービスにて invmScope="GLOBAL" が定義されているよう確認します。
  • 独自の org.drools.runtime.Channel 実装クラスを使い指定可能なカスタムのチャネル。このsend-to 属性はchannel-classです。お使いの実装には public な引数なしのコンストラクターが必要です。
    実装を設定可能にするには、org.jboss.soa.esb.Configurable インターフェースを実装しsetConfiguration(ConfigTree() メソッドが呼び出されるようにします。こうすることで、属性とサブプロパティ要素をカスタムチャネルに渡すことができます。
    このコードサンプルは、カスタムのチャネル設定の方法を示しています。
    <property name="channels">
        <send-to channel-name="mychannel"
            channel-class="com.example.MyChannel" />
    </property>
    

4.2.5. ルールのパッケージングとデプロイ

Red Hat は、ルールコードを機能単位にパッケージするよう推奨しています。これは.esb パッケージに入れることで行います (rule setsを使う rule services の横にルーティングルールをパッケージ化するのが目的です)。
jbrules.esb アーカイブを作成すると、deployment.xml ファイルを使いデプロイ、参照します。このコードは以下を行う方法を示しています。
<jbossesb-deployment>
 <depends>jboss.esb:deployment=jbrules.esb</depends>
</jbossesb-deployment>