Drools Fusion длительность и метка времени, почему это не работает? - PullRequest
0 голосов
/ 15 февраля 2012

Я новичок в приложениях Drools и, прежде всего, в Drools Fusion.В моем офисе мы работаем над отдельным приложением обработки сложных событий.Одним из основных требований является возможность рассчитать время начала, частоту, время окончания, продолжительность каждого события.Для этого мы тестируем Drools Fusion и создали этот пример, который не работает.В этом примере мы пытаемся вычислить продолжительность.Как примечание, мы не смогли рассчитать метку времени события, и на данный момент мы решили использовать System.currentTimeMillis ().

Может быть, Drools не является хорошей структурой, и мы должны изменить наш выбор?

Sample.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;
        }

    }

}

1 Ответ

3 голосов
/ 15 февраля 2012

Я думаю, что в использовании Drools Fusion есть несколько заблуждений. Я постараюсь уточнить некоторые из них:

  • Я не уверен, что вы подразумеваете под «рассчитать время начала, частоту, время окончания, продолжительность каждого события». Продукты CEP в целом позволяют приложению прослушивать события, обнаруживать шаблоны, сопоставляя эти события и сопоставляя их и другие данные, и реагировать при обнаружении этих шаблонов. Таким образом, вы можете обнаружить события и рассчитать их частоту, но время начала, продолжительность (и время окончания) являются частью самих событий, а не чем-то, что придумывает двигатель. Конечно, движок может коррелировать атомарные события в сложные события, и в этом случае он назначит сложные события, например, длительность, но это все-таки логика приложения, а не движок, создающий магию.

  • Drools работает в двух режимах: пакетный (режим CLOUD, как в облаке событий) и режим реального времени (режим STREAM, как в потоках событий). Поток времени имеет смысл только в режиме STREAM (в реальном времени). Вы прокомментировали конфигурацию режима STREAM, и поэтому все, что вы делаете с часами в вашем приложении, игнорируется:

    KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase (/ конфигурация /);

  • Ваш код настраивает движок на использование псевдо-часов, но вы используете машинные часы для назначения временных меток вашим событиям с помощью System.currentTimeMillis(). Ваше приложение должно быть согласованным: либо вы используете часы реального времени, либо псевдо-часы.

  • Незначительное исправление: вы должны использовать открытый интерфейс SessionPseudoClock вместо внутреннего класса реализации PseudoClockScheduler. То же самое и с внутренним классом EventFactHandle, который, как я полагаю, вы используете только для теста, поскольку ваше приложение никогда не должно его использовать.

  • Наконец, я не уверен, чего вы пытаетесь достичь с помощью этого примера. Отметка времени и продолжительность вашего сообщения будут считаны из атрибутов класса, поскольку ваш пример говорит движку:

    объявить сообщение @role (событие) @timestamp (время) @duration (howMuch) конец

Drools не будет преднамеренно изменять атрибуты (например, howMuch), если вы ожидаете этого.

Я предлагаю вам еще раз взглянуть на документацию Drools Fusion и присоединиться к списку рассылки Drools. Там люди очень полезны и могут помочь вам с любыми вопросами, которые у вас могут возникнуть.

...