Drools でルールの有効期間を指定する - date-effective, date-expires
Drools の DRL ではルール毎の有効期間を以下のルール属性を使って指定できるようになっています。
- date-effective 開始日時
- date-expires 終了日時
どちらも日付の指定に文字列が使えますが、デフォルトの日付フォーマットが "dd-MMM-yyyy" となっており、これ以外のフォーマットで日付を指定するとエラーが発生します。
ただし、以下のようにシステムプロパティ drools.dateformat の値を変更する事で任意の日付フォーマットが使えます。
Drools 日付フォーマットの変更例 ("2012-02-02 01:00:00" のような日付を指定できるようにするための設定)
System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
以下の例のようにルールを定義すると 2012-02-02 00:30:00 から 2012-02-03 00:30:00 の期間内に実行した場合にのみこのルールが有効になります。(drools.dateformat を上記のように変更している事が前提)
DRL 例(date-effective と date-expires の使用)
rule "・・・" ・・・ date-effective "2012-02-02 00:30:00" date-expires "2012-02-03 00:30:00" ・・・ when ・・・ then ・・・
ちなみに、date-effective と date-expires はどちらか片方だけを指定することもできます。
ルールの有効期間を指定したサンプル
以下では date-effective と date-expires を使った簡単なサンプルを Groovy で実装してみました。
- Drools 5.4.0 beta2
- Groovy 1.8.5 (java 1.7.0_02 64bit)
サンプルソースは http://github.com/fits/try_samples/tree/master/blog/20120202/
effective_expires_sample.groovy
@Grab("org.drools:drools-core:5.4.0.Beta2") @Grab("org.drools:drools-compiler:5.4.0.Beta2") @Grab("com.sun.xml.bind:jaxb-xjc:2.2.5-b09") import org.drools.KnowledgeBaseFactory import org.drools.builder.KnowledgeBuilderFactory import org.drools.builder.ResourceType import org.drools.io.ResourceFactory def drl = ''' dialect "mvel" rule "ルール1" no-loop salience 20 date-effective "2012-02-02 00:30:00" date-expires "2012-02-03 00:30:00" when $d : Data(done == false) then System.out.println("*** ルール1") $d.setDone(true) update($d) end rule "ルール2" no-loop salience 10 when $d : Data(done == false) then System.out.println("*** ルール2") $d.setDone(true) update($d) end ''' class Data { def done = false } def createSession = {drlString -> def builder = KnowledgeBuilderFactory.newKnowledgeBuilder() builder.add(ResourceFactory.newReaderResource(new StringReader(drlString)), ResourceType.DRL) if (builder.hasErrors()) { println builder.errors throw new RuntimeException("invalid DRL") } def base = KnowledgeBaseFactory.newKnowledgeBase() base.addKnowledgePackages(builder.getKnowledgePackages()) base.newStatefulKnowledgeSession() } //Drools デフォルトの日付フォーマットを変更 System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss") def session = createSession(drl) session.insert(new Data()) session.fireAllRules() session.dispose()
このスクリプトを実行した日時が有効期間内 *1 であれば "ルール1" が適用され、期間外であれば "ルール2" が適用される事を確認できます。
実行結果例1(有効期間内に実行した場合)
> groovy effective_expires_sample.groovy *** ルール1
実行結果例2(有効期間外に実行した場合)
> groovy effective_expires_sample.groovy *** ルール2
*1:date-effective で指定した日時から date-expires で指定した日時までの期間