16.7. DRL でのルール属性

ルール属性は、ルールの動作を修正するビジネスルールを指定する追加設定です。DRL ファイルでは、ルール属性は、以下の形式で、通常ルールの条件とアクションの上に定義します。複数の属性がある場合には、別々の行に指定します。

rule "rule_name"
    // Attribute
    // Attribute
    when
        // Conditions
    then
        // Actions
end

次の表では、ルールに割り当て可能な属性の名前と、対応する値を紹介します。

表16.1 ルールの属性

属性

salience

ルールの優先順位を定義する整数。顕著性の値が高いルールは、アクティベーションキューの順番で、優先度が高くなります。

例: salience 10

enabled

ブール値。このオプションを選択すると、ルールが有効になります。このオプションを選択しないと、ルールは無効になります。

例: enabled true

date-effective

日付定義および時間定義を含む文字列。現在の日時が date-effective 属性よりも後の場合は、このルールがアクティブになります。

例: date-effective "4-Sep-2018"

date-expires

日付定義および時間定義を含む文字列。現在日時が date-expires 属性よりも後になると、このルールをアクティブにすることはできません。

例: date-expires "4-Oct-2018"

no-loop

ブール値。このオプションが選択される場合は、ルールの結果が以前一致した条件を再度トリガーすると、ルールは再アクティブ化 (ループ) されません。条件を選択しないと、この状況でルールがループされます。

例: no-loop true

agenda-group

ルールを割り当てるアジェンダグループを指定する文字列。アジェンダグループを使用すると、アジェンダをパーティションで区切り、ルールのグループに対する実行をさらに制御できます。フォーカスを取得したアジェンダグループのルールだけがアクティブになります。

例: agenda-group "GroupName"

activation-group

ルールを割り当てるアクティベーション (または XOR) グループを指定する文字列。アクティベーショングループでは、1 つのルールのみをアクティブ化できます。最初のルールが実行すると、アクティベーショングループの中で、アクティベーションが保留中のルールはすべてキャンセルされます。

例: activation-group "GroupName"

duration

ルールの条件が一致している場合に、ルールがアクティブになってからの時間をミリ秒で定義する長整数値。

例: duration 10000

timer

ルールのスケジュールに対する int (間隔) または cron タイマー定義を指定する文字列。

例: timer ( cron:* 0/15 * * * ? ) (15 分ごと)

calendar

ルールのスケジュールを指定する Quartz カレンダーの定義。

例: calendars "* * 0-7,18-23 ?* *" (営業時間外を除く)

auto-focus

アジェンダグループ内のルールにのみ適用可能なブール値。このオプションが選択されている場合は、次にルールがアクティブになった場合に、そのルールが割り当てられたアジェンダグループにフォーカスが自動的に指定されます。

例: auto-focus true

lock-on-active

ルールフローグループまたはアジェンダグループ内のルールにのみ適用可能なブール値。このオプションを選択すると、次回、ルールのルールフローグループがアクティブになるか、ルールのアジェンダグループがフォーカスを受け取ると、(ルールフローグループがアクティブでなくなるか、アジェンダグループがフォーカスを失うまで) ルールをアクティブにすることができません。これは、no-loop 属性を強力にしたものです。なぜなら、一致するルールのアクティベーションが、(ルールそのものによるものだけでなく) 更新元にかかわらず破棄されるためです。この属性は、ファクトを修正するルールが多数あり、ルールの再一致と再発行を希望しない計算ルールに適しています。

例: lock-on-active true

ruleflow-group

ルールフローグループを指定する文字列。ルールフローグループで、関連するルールフローによってそのグループがアクティブになった場合に限りルールを発行できます。

例: ruleflow-group "GroupName"

dialect

ルールのコード表記に使用される言語を指定する文字列 (JAVA または MVEL)。デフォルトでは、ルールは、パッケージレベルに指定されている方言を使用します。ここで指定した方言は、ルールのパッケージ方言設定を上書きします。

例: dialect "JAVA"

注記

実行可能モデルなしで Red Hat Process Automation Manager を使用する場合には、dialect "JAVA" ルールの結果は、Java 5 構文のみをサポートします。実行可能モデルに関する詳細は、Red Hat Process Automation Manager プロジェクトのパッケージ化およびデプロイ を参照してください。

16.7.1. DRL でのタイマーおよびカレンダールール属性

タイマーおよびカレンダーは、DRL ルール属性であり、これを使用してスケジュールと時間の制約を DRL ルールに適用できます。これらの属性を使用するには、ユースケースによって追加の設定が必要になります。

DRL ルールの timer 属性は、ルールのスケジュール設定を行うための int (間隔) または cron タイマー定義を指定する文字列で、以下の形式をサポートします。

タイマー属性の形式

timer ( int: <initial delay> <repeat interval> )

timer ( cron: <cron expression> )

間隔タイマー属性の例

// Run after a 30-second delay
timer ( int: 30s )

// Run every 5 minutes after a 30-second delay each time
timer ( int: 30s 5m )

cron タイマー属性の例

// Run every 15 minutes
timer ( cron:* 0/15 * * * ? )

間隔タイマーは、最初に遅延があり、オプションで間隔が繰り返されるという java.util.Timer オブジェクトのセマンティクスに従います。Cron タイマーは標準の Unix cron 式に準拠します。

以下の DRL ルール例では、cron タイマーを使用して 15 分ごとに SMS テキストメッセージを送信します。

cron タイマーを使用した DRL ルールの例

rule "Send SMS message every 15 minutes"
  timer ( cron:* 0/15 * * * ? )
  when
    $a : Alarm( on == true )
  then
    channels[ "sms" ].insert( new Sms( $a.mobileNumber, "The alarm is still on." );
end

一般的に、タイマーが制御するルールは、ルールがトリガーされた時点でアクティブになり、タイマーの設定に合わせてルールの結果が繰り返し実行されます。実行は、ルールの条件が受信ファクトに一致しなくなる時点で停止します。ただし、デシジョンエンジンがタイマー付きのルールを処理する方法は、デシジョンエンジンが アクティブモード か、パッシブモード かによって異なります。

デフォルトでは、ユーザーまたはアプリケーションが明示的に fireAllRules() を呼び出した場合に、デシジョンエンジンは パッシブモード で実行され、定義されたタイマー設定によりルールが評価されます。一方、ユーザーまたはアプリケーションが fireUntilHalt() を呼び出す場合、デシジョンエンジンは アクティブモード でで実行され、ユーザーまたはアプリケーションが halt() を明示的に呼び出すまでルールを継続的に評価します。

デシジョンエンジンがアクティブモードの場合は、fireUntilHalt() への呼び出しからコントロールが戻った後でもルールの結果が実行され、デシジョンエンジンは、ワーキングメモリーに加えられた変更に対して リアクティブ のままになります。たとえば、タイマールールの実行のトリガーに関連したファクトを削除すると、反復実行が停止になり、ファクトが挿入されるので、ルールが一致するとそのルールが実行します。ただし、デシジョンエンジンは継続して アクティブ な訳ではなく、ルールの実行後にだけアクティブになります。そのため、タイマーで制御されるルールが次回に実行されるまで、デシジョンエンジンは非同期のファクト挿入には反応しません。KIE セッションを破棄するとタイマーアクティビティーはすべて中断されます。

デシジョンエンジンがパッシブモードの場合は、タイマー付きのルールの結果は、fireAllRules() が再度呼び出される場合にのみ評価されます。ただし、以下の例にあるように、パッシブモードでは TimedRuleExecutionOption オプションで KIE セッションを設定することで、デフォルトのタイマー実行動作を変更できます。

パッシブモードでタイマー付きルールを自動的に実行するための KIE セッションの設定

KieSessionConfiguration ksconf = KieServices.Factory.get().newKieSessionConfiguration();
ksconf.setOption( TimedRuleExecutionOption.YES );
KSession ksession = kbase.newKieSession(ksconf, null);

以下の例のように、TimedRuleExecutionOption オプションに追加で FILTERED 仕様を設定することで、対象のルールをフィルターするコールバックを定義できるようになります。

どのタイマー付きのルールを自動的に実行するかをフィルターするための KIE セッション

KieSessionConfiguration ksconf = KieServices.Factory.get().newKieSessionConfiguration();
conf.setOption( new TimedRuleExecutionOption.FILTERED(new TimedRuleExecutionFilter() {
    public boolean accept(Rule[] rules) {
        return rules[0].getName().equals("MyRule");
    }
}) );

間隔タイマーの場合は、int ではなく、expr を指定した式タイマーを使用して、固定値の代わりに、式として遅延と間隔の両方を定義できます。

以下の DRL ファイルの例では、遅延と期間でファクトタイプを宣言し、後続のルールの式タイマーでこの遅延と期間を使用します。

式タイマーが含まれるルールの例

declare Bean
  delay   : String = "30s"
  period  : long = 60000
end

rule "Expression timer"
  timer ( expr: $d, $p )
  when
    Bean( $d : delay, $p : period )
  then
    // Actions
end

この例の $d$p などの式は、ルールのパターンが一致する部分に定義した変数を使用できます。この変数には String の値を使用でき、これは期間や、期間の long 値 (ミリ秒単位) に内部で変換される数値に解析できます。

間隔と式のタイマーはいずれも、以下のオプションのパラメーターを使用できます。

  • start および end: Date、または Date または long 値を表す String。この値には、Number も指定でき、数字は new Date( ((Number) n).longValue() ) 形式の Java の Date に変換されます。
  • repeat-limit: タイマーが許可する最大反復回数を定義する整数。end および repeat-limit の両パラメーターが設定されている場合は、2 つのどちらかに先に到達した時点でタイマーが停止します。

任意の startend、および repeat-limit パラメーターが使用されるタイマー属性の例

timer (int: 30s 1h; start=3-JAN-2020, end=4-JAN-2020, repeat-limit=50)

この例では、ルールは 1 時間ごとに 30 秒の遅延の後に実行されるようにスケジュールされ、2020 年 1 月 3 日に開始し、2020 年 1 月 4 日またはサイクルが 50 回繰り返された後に終了するようにスケジュールされています。

システムが一時停止すると (セッションがシリアライズされた後にデシリアライズされる場合など)、ルールは、一時停止中に実施されなかったアクティベーションの数にかかわらず、実施されなかったアクティベーションからの回復を 1 回のみ実施するようにスケジュールされており、ルールはその後にタイマー設定と同期して再度スケジュールされます。

DRL ルールの calendar 属性は、ルールのスケジュールのための Quartz カレンダー定義であり、以下の形式をサポートします。

カレンダー属性の形式

calendars "<definition or registered name>"

カレンダー属性の例

// Exclude non-business hours
calendars "* * 0-7,18-23 ? * *"

// Weekdays only, as registered in the KIE session
calendars "weekday"

以下の例ように、Quartz カレンダー API に基づいて Quartz カレンダーを適用し、そのカレンダーを KIE セッションに登録することができます。

Quartz カレンダーの適用

Calendar weekDayCal = QuartzHelper.quartzCalendarAdapter(org.quartz.Calendar quartzCal)

KIE セッションでのカレンダーの登録

ksession.getCalendars().set( "weekday", weekDayCal );

カレンダーは、標準のルールや、タイマーを使用するルールと共に使用できます。カレンダー属性には、String リテラルとして記述された 1 つ以上のコンマ区切りのカレンダー名を含めることができます。

以下のルールの例では、カレンダーとタイマーの両方を使用してルールをスケジュールします。

カレンダーとタイマーを使用したルールの例

rule "Weekdays are high priority"
  calendars "weekday"
  timer ( int:0 1h )
  when
    Alarm()
  then
    send( "priority high - we have an alarm" );
end

rule "Weekends are low priority"
  calendars "weekend"
  timer ( int:0 4h )
  when
    Alarm()
  then
    send( "priority low - we have an alarm" );
end