Test Event expiration in Drools Fusion CEP

风流意气都作罢 提交于 2019-12-11 01:06:39

问题


Ciao, I have tested in several ways, but I'm still unable to test and verify the Event expiration mechanism in Drools Fusion, so I'm looking for some little guidance, please?

I've read the manual and I'm interested in this feature:

In other words, one an event is inserted into the working memory, it is possible for the engine to find out when an event can no longer match other facts and automatically retract it, releasing its associated resources.

I'm using the Drools IDE in Eclipse, 5.4.0.Final and I modified the template code created by the "New Drools Project" wizard to test and verify for Event expiration.

The code below. The way I understood to make the "lifecycle" to work correctly is that:

  • You must setup the KBase in STREAM mode - check
  • You must Insert the Events in temporal order - check
  • You must define temporal constraints between Events - check in my case is last Message()

However, when I inspect the EventFactHandle at the end, none of the Event() has expired. Thanks for your help.

Java:

public class DroolsTest {

    public static final void main(String[] args) {
        try {
            KnowledgeBase kbase = readKnowledgeBase();
            // I do want the pseudo clock
            KnowledgeSessionConfiguration conf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
            conf.setOption(ClockTypeOption.get("pseudo"));
            StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(conf, null);
            SessionPseudoClock clock = ksession.getSessionClock();
            KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
            // Insert of 2 Event:
            Message message = new Message();
            message.setMessage("Message 1");
            message.setStatus(Message.HELLO);
            ksession.insert(message);
            ksession.fireAllRules();
            clock.advanceTime(1, TimeUnit.DAYS);
            Message message2 = new Message();
            message2.setMessage("Message 2");
            message2.setStatus(Message.HELLO);
            ksession.insert(message2);
            ksession.fireAllRules();
            clock.advanceTime(1, TimeUnit.DAYS);
            ksession.fireAllRules();
            // Now I do check what I have in the working memory and if EventFactHandle if it's expired or not:
            for (FactHandle f : ksession.getFactHandles()) {
                if (f instanceof EventFactHandle) {
                    System.out.println(((EventFactHandle)f)+" "+((EventFactHandle)f).isExpired());
                } else {
                    System.out.println("not an Event: "+f);
                }
            }
            logger.close();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    private static KnowledgeBase readKnowledgeBase() throws Exception {
        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();
        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
        // following 2 lines is the template code modified for STREAM configuration
        KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
        config.setOption( EventProcessingOption.STREAM );
        return kbase;
    }

    /*
     * This is OK from template, as from the doc:
     * By default, the timestamp for a given event is read from the Session Clock and assigned to the event at the time the event is inserted into the working memory.
     */
    public static class Message {

        public static final int HELLO = 0;
        public static final int GOODBYE = 1;

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

    }

}

Drools:

package com.sample

import com.sample.DroolsTest.Message;

declare Message
@role(event)
end

declare window LastMessageWindow
    Message() over window:length(1)
end

rule "Hello World"
    when
       accumulate( $m : Message(status==Message.HELLO) from window LastMessageWindow,
                $messages : collectList( $m ) )
    then
        System.out.println( ((Message)$messages.get(0)).getMessage() );
end

Please note: even if I add expiration of 1second to the Message event, by

@expires(1s)

I still don't get the expected result that the very first Message event inserted, I would have expected is now expired? Thanks for your help.


回答1:


Found solution! Obviously it was me being stupid and not realizing I was using Drools 5.4.0.Final while still referring to old documentation of 5.2.0.Final. In the updated documentation for Drools Fusion 5.4.0.Final, this box is added for 2.6.2. Sliding Length Windows:

Please note that length based windows do not define temporal constraints for event expiration from the session, and the engine will not consider them. If events have no other rules defining temporal constraints and no explicit expiration policy, the engine will keep them in the session indefinitely.

Therefore the 3rd requirement I originally enlisted of "You must define temporal constraints between Events" is obviously NOT met because I now understand Sliding Length Window in Drools 5.4.0.Final:

Message() over window:length(1)

are indeed NOT a definition of a temporal constraints for event expiration from the session.

Updating this answer hopefully somebody will find it helpful. Also, just so for your know, me being stupid actually for relying on googling in order to reach the doc, and sometimes you don't get redirected to the current release documentation, so it seems...



来源:https://stackoverflow.com/questions/12338385/test-event-expiration-in-drools-fusion-cep

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!