Oracle® Fusion Middleware Oracle Business Rulesランゲージ・リファレンス・ガイド 11gリリース1 (11.1.1.9) B56239-06 |
|
![]() 前 |
![]() 次 |
この章では、RuleSessionオブジェクトの使用方法を説明します。
この章の内容は次のとおりです。
この項では、ルール対応アプリケーションを作成する手順を示し、RuleSession
オブジェクトの使用方法について説明します。RuleSession
オブジェクトはパッケージoracle.rules.rlに含まれています。
RuleSession
コンストラクタは、引数がない場合、デフォルトのロケールおよびロギング・オプションにデフォルトの構成パラメータが設定されたRuleSession
を戻します。
表4-1に、マップに設定可能でRuleSessionコンストラクタに渡される構成パラメータを示します。
表4-1 RuleSessionコンストラクタの構成パラメータ
パラメータ・キー | 値 |
---|---|
CFG_LOGGING |
ブール。trueの場合、ロギングが有効です。falseの場合、ロギングは無効です。デフォルトはtrueです。 |
CFG_LOCALE |
任意のロケールに対するロケール・オブジェクト。デフォルトはJVMデフォルト・ロケールです。 |
CFG_WATCH |
RAWアクティビティ監視のトレース機能に関する必要な設定。この設定は、セッションのリセット時にリストアされます。 WATCH_RULES: 起動される監視ルール。 WATCH_ACTIVATIONS: 監視ルールのアクティブ化および非アクティブ化。 WATCH_FACTS: 監視のファクト操作(アサート、変更、撤回)。 WATCH_FOCUS: 監視ルールセット・スタックの変更。 WATCH_COMPILATION: 監視ルール定義。 WATCH_ALL: 前述のすべての監視。 デフォルトでは、トレース設定は1つも有効化されません。 |
CFG_DECISION_TRACE_LEVEL |
トレース対象のルール・エンジン・アクティビティを制御するデシジョン・トレース・レベルを設定します。このレベルは、セッションのリセット時にリストアされます。 DECISION_TRACE_OFF: すべてのデシジョン・トレースを無効化します。 DECISION_TRACE_PRODUCTION: 起動されるルールをトレースします。 DECISION_TRACE_DEVELOPMENT: 詳細なデシジョン・トレース。WATCH_ALLおよびリセットのトレースに相当します。 デフォルトはDECISION_TRACE_OFFです。 |
CFG_DECISION_TRACE_LIMIT |
トレースが取得されるまで内部的に格納されるトレース・エントリ数に制限を課す整数。 デフォルトのデシジョン・トレース制限は10000です。 |
outputWriter
プロパティは、println
、watch
およびshow
の出力先を決定します。
rulesetNameプロパティは、明示的にルールセット名を指定せずに、RL文の実行時にルールセットを設定します。デフォルトのrulesetNameはmain
です。
executeRulesetメソッドは、指定のルールセット・テキスト(Stringまたはjava.io.Readerとして指定)を解析して実行します。
callFunctionメソッドは、名前付きRL関数(組込みRL関数または以前にexecuteRulesetメソッドの1つを使用してパラメータなしで定義した関数)を起動し、その結果を戻します。単一の引数を取る関数は、callFunctionWithArgumentメソッドを使用して起動できます。任意の数の引数を取る関数は、callFunctionWithArgumentList
またはcallFunctionWithArgumentArray
メソッドを使用してコールできます。引数のリストまたは配列には、各RL関数パラメータのJavaオブジェクトが記載されている必要があります。
表4-2に、引数をRL関数に渡すためにJavaオブジェクト型をRL型に変換する方法、およびRL関数の戻り値をJavaに渡すためにRL型をJava型に変換する方法を示します。
表4-2 RLからJavaオブジェクトへの変換
Javaクラス | RL型 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RuleSessionメソッドの起動でParseException
またはTypeCheckException
がスローされても、RuleSessionの状態には影響を与えません。Javaアプリケーション(たとえば、対話型のコマンドライン)では、これらの例外を検出し、RuleSessionの使用を続行できます。
RuleSessionメソッドの起動でRLRuntimeException
がスローされた場合は、RuleSessionの状態に影響を与える可能性があり、アプリケーションでRuleSessionを処理できない状態になる場合があります。堅牢なアプリケーションの場合は、RLでRLRuntimeException
を検出し、例外がスローされた近辺でリカバリするように試みます。
その他の例外は、多くの場合、アプリケーションで処理できない重大な問題を示します。
RLクラスは、Javaクラスと同様にRLプログラムで使用できます。new
、instanceof
およびcast
の演算子は、両方のクラスで使用できます。ただし、Javaプログラムに渡されたRLクラスのインスタンスは、実際にはoracle.rules.rl.RLObject
のインスタンスです。Javaプログラムでは、RLObject
を調べるためにRLClass
、RLProperty
およびRLArray
クラスを使用できます。使用方法は、java.lang.Class
、java.lang.reflect.Field
およびjava.lang.Array
クラスを使用してjava.lang.Object
を反映する場合と同じです。RLCLass
、RLProperty
およびRLArray
は、パッケージoracle.rules.rl
に含まれます。
XLinkオブジェクトは、assertTree関数によって作成され、ファクトとしてアサートされます。RLルールでは、XLinkを使用して、assertTreeによってアサートされた要素の階層を推論できます。
Oracle Business Rulesを使用してルール対応プログラムを作成したときの一般的な疑問は、「評価の結果を取得する方法は?」です。
この項では、ルール・エンジンからルール評価の結果を抽出または表示する方法について説明します。
内容は次のとおりです。
関連項目: 『Oracle Business Rulesユーザーズ・ガイド』のRules SDKデシジョン・ポイントAPIの使用に関する項 |
この項で使用する例は、高速道路の事故通知システムを示しています。それぞれの例は、ルール・エンジンの評価結果にアクセスするための異なる方法を示しています。これらの例では、2つのJavaクラスtraffic.TrafficIncident
およびtraffic.IncidentSubscription
を使用します。
注意: サンプルのtraffic.* クラスは、Oracle Business Rulesに同梱されていません。 |
TrafficIncident
クラスは、交通状況に影響を与える事故の情報を表し、次のプロパティが含まれています。
どの高速道路か
上りか下りか
事故の種類
事故発生時刻
渋滞の見積時間(分単位)
IncidentSubscription
クラスは、特定の高速道路における事故の通知へのサブスクリプションを記述し、次のプロパティが含まれています。
サブスクライバ - サブスクライバの名前
該当する高速道路
上りか下りか
この例では、高速道路で交通状況に影響を与える事故が発生したとき、これらのクラスを使用してTrafficIncident
オブジェクトをアサートし、ルール評価によって通知の受信者を判断します。
例に示すsess
オブジェクトはRuleSession
で、事故通知の多数のサブスクリプションがアサートされます。単純化するために、TrafficIncident
オブジェクトは永続的でないことを前提にしています。実際には、このオブジェクトはアサート対象イベントを表し、その時点で登録されているサブスクライバにのみ通知が送信されます。
この例で使用するクラスはすべてJavaクラスです。ただし、RLクラスの反映を使用して、JavaでRLクラスのインスタンスを操作することもできます。
関連項目: ドキュメントについては、oracle.rules.rl パッケージにあるRLClass、RLObject、RLPropertyおよびRLArrayクラスに関するJavadocを参照してください。RLオブジェクト、つまりRLクラスのインスタンスを使用すると、Javaオブジェクトと同様に、ルール・エンジンの結果を保持できます。 |
この方法は、結果用のコンテナをアサートする方法と同じです。ただし、コンテナではなくオブジェクトを使用して、ルール・エンジンの外部にあるリソースに作用します。たとえば、予定の作業をキューに挿入したりスケジュールする場合、データベースを更新する場合、メッセージを送信する場合が該当します。結果を導出するには、アクションでアクセス可能な任意のJavaメソッドを起動できます。コンテナを使用する場合と同様に、外部リソースにアクセスするためにこの例で使用されているオブジェクトは、その内容が推論の対象でないため、再度アサートされることはありません。
例4-1に示すIncidentDispatcher
オブジェクトは、アサートされて通知の配信に使用されます。
例4-1 外部リソースを使用した結果の取得
rule incidentAlert { if (fact TrafficIncident ti && fact IncidentSubscription s && s.highway == ti.highway && s.direction == ti.direction && fact IncidentDispatcher dispatcher) { dispatcher.dispatch(s.subscriber, ti); } }
例4-2に示すJavaコードはIncidentDispatcher
およびTrafficIncident
をアサートし、ルール・エンジンを起動します。これは、推論の対象となるオブジェクトを使用しても実行できます。ただし、この場合は、ルール起動の無限ループを回避するために、ルール条件のテストが必要になります。
例4-2 外部リソースを使用した結果の例
sess.callFunctionWithArgument("assert", new IncidentDispatcher()); // An accident has happened TrafficIncident ti = new TrafficIncident(); ti.setHighway("I5"); ti.setDirection("south"); ti.setIncident("accident"); ti.setWhen(new GregorianCalendar(2005, 1, 25, 5, 4)); ti.setDelay(45); sess.callFunctionWithArgument("assert", ti); sess.callFunction("run");
ランタイムでは、RLスタック・トレースに詳細なデバッグ情報が提供されます。エラーが発生した場合は、可能なかぎり、問題箇所の識別に役立つ特別なコンテキストが提供されます。この特別なコンテキストは、ルールSDKとルール・デザイナを併用している場合に有効です。
スタック・トレースには、ルール条件、ルール・アクション、関数、変数およびRLクラス定義に関する情報を示す特別なコンテキストが含まれています。XPath形式のフォーマットは、RL構成とそれに続くカッコで囲まれた名前(名前が指定されている場合)で構成されます。構成の後に大カッコで囲まれた番号n
が表示される場合は、前の構成に続いてn
番目の項目を示します。ルールSDKと併用している場合、ルール・デザイナでは、RL生成によってエラーの場所を非常に特定しやすくなります。
たとえば、例4-3に示されたルールセットについて考えてみます。このルールセットを実行すると、次のレポートが提供されます。
RLNullPointerException: object cannot be null at line 12 column 13 in stackTraceContext /Rule(porsche)/Pattern(car)/Test[1] at line 17 column 5 in stackTraceContext
例4-3 テスト・ルールセット
ruleset stackTraceContext { class Car { String make; String model; } rule porsche { if (fact Car car && car.make.startsWith("Porsche")) { println(car.make + " " + car.model); } } assert(new Car()); }
ruleset stackTraceContext
{
class Car
{
String make;
String model;
}
rule porsche
{
if (fact Car car &&
car.make.startsWith("Porsche"))
{
println(car.make + " " + car.model);
}
}
assert(new Car());
ルールを使用する典型的なアプリケーションでは、個々のリクエストに対応する異なるファクトを使用して、同じルールを何回も評価します。RuleSessionの初期化に要する時間は、含まれているルールの数によって異なりますが、通常は数秒です。これに対し、ルールの実行に必要なのは、初期化よりはるかに短い時間です。したがって、RuleSessionを1回初期化し、新規の各リクエストに対して再利用することで、パフォーマンスを向上させることができます。RuleSessionプールを使用すると、RuleSessionインスタンスのプールを作成できるため、ルールを使用するアプリケーションのパフォーマンスとスケーラビリティが向上します。
負荷の増加に対応したパフォーマンスを実現するには、複数のRuleSessionが必要です。RuleSessionインスタンスのプールにより、ルールを使用するアプリケーションのパフォーマンスとスケーラビリティが向上します。プールは、RLコードのリストを使用してインスタンス化されます。RLコードは、プールで作成された各RuleSessionを初期化するために使用されます。RLコードは、リストに記載されている順に実行されます。最初に作成するRuleSessionインスタンスの数を指定できます。一般的には小さい値を指定しますが、通常は、このデフォルト値で十分です。
RLコードは通常、ルールSDKで作成されたRuleDictionaryから生成されます。例4-4は、RuleDictionaryから生成されたRLコードでRuleSessionPoolを作成および使用する方法を示しています。
例4-4 RuleSessionプールの作成方法
RuleDictionary rd; // Code to load rule dictionary not shown List rlList = new ArrayList(); rlList.add(rd.dataModelRL()); List rulesetAliases = rd.getRuleSetAliases(true); for (String alias : rulesetAliases) { rlList.add(rd.ruleSetRL(alias)); } RuleSessionPool pool = new RuleSessionPool(rlList);
アプリケーションで使用中のルールが更新された場合は、後続のルール実行で新しいルールが使用されるように、アプリケーションは新しいルールをロードする必要があります。これをプールでサポートするには、refreshPoolメソッドを起動して新しいRLのリストを渡します。プールが更新されると、getPoolableRuleSessionで戻されるRuleSessionは、新しいRLコードで初期化されています。更新前に取得されたRuleSessionがreturnPoolableRuleSessionを使用して戻された場合、そのRuleSessionはプールに戻されません。更新後のプールに保存されるのは、新しいRLコードで初期化されたRuleSessionのみです。
RuleSessionを使用してルールを実行する場合は、プールからRuleSessionを取得し、実行後にプールに戻します。プール可能なRuleSessionを取得するには、getPoolableRuleSessionメソッドを起動します。プールでは、必要に応じて新しいRuleSessionが作成されます。getPoolableRuleSessionの起動は、空きRuleSessionの待機を妨げることはありません。
ルール実行の完了後、プール可能なRuleSessionをプールに戻すには、returnPoolableRuleSessionメソッドを起動します。プールに戻されたRuleSessionをプールでリセットするには、組込みRL関数のreset()を起動します。これによって、作業メモリーからすべてのファクトが削除され、そのRuleSessionは次の実行のために準備されます。プールから取得したすべてのRuleSessionは、プールに戻す必要があります。ルールの実行中に発生したエラーが原因で今後の使用に適さなくなったRuleSessionは、プールで検出されて廃棄されます。
reset()関数は、作業メモリーの消去に加えて、非ファイナル・グローバル変数のイニシャライザを再実行します。非ファイナル・グローバル変数のイニシャライザを使用すると、必要な場合は、リセット時に他の初期化を実行できます。
例4-5は、プールからRuleSessionを使用する方法を示しています。
例4-5 RuleSessionプールの使用方法
PoolableObject po = pool.getPoolableRuleSession(); RuleSession engine = po.getPooledObject(); // use the RuleSession to execute rules as required here pool.returnPoolableRuleSession(po);
プールのサイズに対するソフト上限を指定できます。この指定によって、一時的な需要の増加に対応するためにプールを拡大する一方、需要の減少時には、プールをソフト上限まで縮小できます。
getPoolableRuleSessionが起動されてプールが空の場合には、RuleSessionプールの実装を使用してRuleSessionインスタンスを作成します。負荷が非常に大きい場合は、ソフト制限を超えるインスタンス件数になります。
負荷の減少に従って、プール内のRuleSesionインスタンスの数は、ソフト制限まで自動的に減少します。
RuleSessionを使用したRLランタイムは、次のオプションをサポートしています。
RuleSession.CFG_LOGGING
RuleSession.CFG_DECISION_TRACE_LEVEL
RuleSession.CFG_DECISION_TRACE_LIMIT
RL Languageランタイムでは、システム・プロパティとしてのCFG_LOGGING
と、RuleSessionコンストラクタに渡される構成マップのBooleanが検索されます。システム・プロパティの値は、マップの値でオーバーライドされます。
RuleSession.CFG_DECISION_TRACE_LEVEL
初期化パラメータをインクルードして、RuleSessionまたはRuleSessionPoolコンストラクタに渡される構成マップのレベルを指定することで、RuleSessionまたはRuleSessionPoolのトレース・レベルを構成できます。これはRuleSessionの作成時のデシジョン・トレース・レベルを設定します。reset()
を起動すると、reset()
の後、ルール実行中にレベルが変更されていた場合にレベルを構成値に戻すことができます。詳細は、第1.7.2項「ルール・エンジン・レベルのデシジョン・トレースの使用方法」を参照してください。
トレースのサイズは、デシジョン・トレースのエントリ数を制限することで制限します。JVM内で使用可能なすべてのヒープを消費するトレースを作成することから、ルール内の不具合の可能性があるため、ルール起動の無限ループを回避するために制限が必要となります。トレースの制限は、setDecisionTraceLimit関数を使用して設定します。この制限は、RuleSession (またはRuleSessionPool)で構成することも可能です。構成するには、RuleSessionまたはRuleSessionPoolコンストラクタに渡される構成マップに目的の制限を指定したRuleSession.CFG_DECISION_TRACE_LIMIT
初期化パラメータをインクルードします。詳細は、第1.7.2項「ルール・エンジン・レベルのデシジョン・トレースの使用方法」を参照してください。