0

私は Drools アプリケーション、特に Drools フュージョンの初心者です。私のオフィスでは、スタンドアロンの複合イベント処理アプリケーションに取り組んでいます。主な要件の 1 つは、各イベントの開始時間、頻度、終了時間、期間を計算できることです。Drools Fusion でこれを行うようにテストしていますが、動作しないこの例を作成しました。この例では、期間を計算しようとしています。補足として、イベントのタイムスタンプを計算できませんでした。今のところ、System.currentTimeMillis() を使用して解決しました。

Drools は適切なフレームワークではなく、選択を変更する必要があるのではないでしょうか?

サンプル.drl

import it.ipiu.other.SElDroolsTest.Message;
declare Message
 @role(event)
 @timestamp(time)
 @duration(howMuch)
end

rule "Message"
    when
        Message() from entry-point "entry"
    then
        System.out.println("a message!!!");
end

およびサンプルクラス

package it.ipiu.other;

import java.util.Date;
import java.util.concurrent.TimeUnit;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseConfiguration;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.common.EventFactHandle;
import org.drools.conf.EventProcessingOption;
import org.drools.io.ResourceFactory;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.KnowledgeSessionConfiguration;
import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.conf.ClockTypeOption;
import org.drools.runtime.rule.FactHandle;
import org.drools.runtime.rule.WorkingMemoryEntryPoint;
import org.drools.time.SessionClock;
import org.drools.time.impl.PseudoClockScheduler;

/**
 * This is a sample class to launch a rule.
 */
public class SElDroolsTest {

    public static final void main(String[] args) {
        try {
            // load up the knowledge base
            KnowledgeBase kbase = readKnowledgeBase();
            KnowledgeSessionConfiguration sessionConfiguration = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
            sessionConfiguration.setOption(ClockTypeOption.get("pseudo"));

            StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(sessionConfiguration, null);
            KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");

            PseudoClockScheduler sessionClock = ksession.getSessionClock(); // !!!
            // go !
            Message message = new Message();
            message.setMessage("Hello World");
            message.setStatus(Message.HELLO);
            message.setTime(System.currentTimeMillis());

            WorkingMemoryEntryPoint entryPoint = ksession.getWorkingMemoryEntryPoint("entry");

            sessionClock.advanceTime(1, TimeUnit.HOURS);

            EventFactHandle factHandle = (EventFactHandle) entryPoint.insert(message);

            sessionClock.advanceTime(1, TimeUnit.HOURS);

            int fireAllRules = ksession.fireAllRules();
            System.out.println("FACT : startTimeStamp " +  factHandle.getStartTimestamp());
            System.out.println("FACT : duration " +  factHandle.getDuration());
            System.out.println("FIRED : " + fireAllRules);
            System.out.println("TIME STAMP " + message.getTime()); 
            System.out.println("TIME DURATION " + message.getHowMuch()); 
            logger.close();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    private static KnowledgeBase readKnowledgeBase() throws Exception {
        KnowledgeBaseConfiguration configuration = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
        configuration.setOption(EventProcessingOption.STREAM);
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        kbuilder.add(ResourceFactory.newClassPathResource("Sample.drl"), ResourceType.DRL);
        KnowledgeBuilderErrors errors = kbuilder.getErrors();
        if (errors.size() > 0) {
            for (KnowledgeBuilderError error : errors) {
                System.err.println(error);
            }
            throw new IllegalArgumentException("Could not parse knowledge.");
        }

        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(/*configuration*/);
        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
        return kbase;
    }

    public static class Message {

        public static final int HELLO = 0;
        public static final int GOODBYE = 1;
        private Long time = new Long(0);
        private Long howMuch = new Long(0);


        public Long getHowMuch() {
            return howMuch;
        }

        public void setHowMuch(Long howMuch) {
            this.howMuch = howMuch;
        }

        public Long getTime() {
            return time;
        }

        public void setTime(Long time) {
            this.time = time;
        }

        private String message;

        private int status;

        public String getMessage() {
            return this.message;
        }

        public void setMessage(String message) {
            this.message = message;
        }

        public int getStatus() {
            return this.status;
        }

        public void setStatus(int status) {
            this.status = status;
        }

    }

}
4

1 に答える 1

3

Drools Fusion の使用にはいくつかの誤解があると思います。それらのいくつかを明確にしようとします:

  • 「各イベントの開始時間、頻度、終了時間、期間を計算する」という意味がわかりません。一般に、CEP 製品を使用すると、アプリケーションはイベントをリッスンし、それらのイベントを照合してそれらと他のデータを関連付けることでパターンを検出し、それらのパターンが検出されたときに反応することができます。したがって、イベントを検出してその頻度を計算することはできますが、開始時間、期間 (および終了時間) はイベント自体の一部であり、エンジンが思いつくものではありません。もちろん、エンジンはアトミック イベントを複雑なイベントに関連付けることができます。この場合、継続時間などを複雑なイベントに割り当てますが、それは依然としてアプリケーション ロジックであり、魔法を行うエンジンではありません。

  • Drools は、バッチ (イベントのクラウドのように CLOUD モードと呼ばれる) とリアルタイム モード (イベントのストリームのように STREAM モードと呼ばれる) の 2 つのモードで動作します。時間の流れは、STREAM (リアルタイム) モードでのみ意味があります。STREAM モードの構成をコメントアウトしたため、アプリケーションでクロックを使用して行っていることはすべて無視されます。

    KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(/構成/);

  • あなたのコードは疑似クロックを使用するようにエンジンを構成していますが、マシンクロックを使用してタイムスタンプをイベントに割り当てていますSystem.currentTimeMillis(). アプリケーションは一貫している必要があります。リアルタイム クロックを使用するか、疑似クロックを使用します。

  • 軽微な修正:SessionPseudoClock内部実装クラスの代わりにパブリック インターフェイスを使用する必要がありますPseudoClockSchedulerEventFactHandleアプリケーションがそれを使用する必要はないため、テストのためだけに使用していると思われる内部クラスと同じことです。

  • 最後に、この例で何を達成しようとしているのかわかりません。メッセージクラスのタイムスタンプと期間は、例がエンジンに次のように指示するため、クラス属性から読み取られます。

    宣言メッセージ @role(event) @timestamp(time) @duration(howMuch) end

Drools は、意図的に属性 ( などhowMuch) を変更することはありません。

Drools Fusion のドキュメントをもう一度見て、Drools メーリング リストに参加することをお勧めします。人々はとても親切で、フォローアップの質問があれば助けてくれます。

于 2012-02-15T18:53:32.233 に答える