1

I wanted to check Anomalous events in a window of say 3 days. I have a following drools code which outputs all events and not restricting to just 3 days. Same problem happens even if I put 1 day instead of 3. I do fireAllRules after each insert.

If use window:length(3) it works perfectly but not by time. Is there anything wrong I am doing?

Also, I have another question @expires annotation, does it work on my custom timestamp or from the time an event/fact inserted into working memory?

Have put simplified unit test at https://github.com/mtekp/droolsExperiments/tree/main/testdrools

I am using drools:7.43.1.Final.

My kmodule.xml

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://www.drools.org/xsd/kmodule">

  <kbase name="TestEventsC" packages="test.events.continuous" eventProcessingMode="stream">
        <ksession name="TestDroolEventsContinous" clockType="realtime"/>
    </kbase>
    
</kmodule>

The drool rule

package test.events.continuous


declare AnomalyCount
 @role(event)
 @timestamp(anomalyDate)
 @expires(3d)
end

rule "insert anomaly count"
  dialect "java"

  when
     $aei: AnomalyEventInsert()
     not AnomalyCount(anomalyDate == $aei.ts)

  then
     insert(new AnomalyCount($aei.getTs(), 1));
     delete($aei);
end

rule "increment count"
  dialect "java"

  when
     $aei: AnomalyEventInsert()
     $ac: AnomalyCount(anomalyDate == $aei.ts)

  then
     modify($ac) { setAnomalyCount($ac.getAnomalyCount() + 1)};
     delete($aei);
end

rule "Check continuous 3 days"
   dialect "java"

   when
      $anomalies : List() from accumulate(AnomalyCount($dt : anomalyDate) over window:time(3d);collectList( $dt ))

   then
     System.out.println("anomalies: "+ $anomalies);
 end

AnomalyCount.java

import org.kie.api.definition.type.Role;

import java.util.Date;

@org.kie.api.definition.type.Role(Role.Type.EVENT)
@org.kie.api.definition.type.Timestamp("anomalyDate")
//@org.kie.api.definition.type.Expires("1d")
public class AnomalyCount {

    public AnomalyCount(Date anomalyDate, int anomalyCount) {
        this.anomalyDate = anomalyDate;
        this.anomalyCount = anomalyCount;
    }

    public Date getAnomalyDate() {
        return anomalyDate;
    }

    public void setAnomalyDate(Date anomalyDate) {
        this.anomalyDate = anomalyDate;
    }


    public int getAnomalyCount() {
        return anomalyCount;
    }

    public void setAnomalyCount(int anomalyCount) {
        this.anomalyCount = anomalyCount;
    }

    @Override
    public String toString() {
        return "AnomalyCount{" +
                "anomalyDate=" + anomalyDate +
                ", anomalyCount=" + anomalyCount +
                '}';
    }

    private Date anomalyDate;

    private int anomalyCount = 0;
}

AnomalyEventInsert.java


import java.time.LocalDate;
import java.time.ZoneOffset;
import java.util.Date;

public class AnomalyEventInsert extends AnomalyEvent {
    public AnomalyEventInsert(LocalDate ts, long sequenceCount, long value) {
        this.ts = Date.from(ts.atStartOfDay().toInstant( ZoneOffset.UTC));
        this.value = value;
        this.sequenceCount = sequenceCount;
    }

    public AnomalyEvent toAnomalyEvent() {
        return new AnomalyEvent(ts, sequenceCount, value);
    }

    @Override
    public String toString() {
        return "AnomalyEventInsert{" +
                "ts=" + ts +
                ", sequenceCount=" + sequenceCount +
                ", value=" + value +
                '}';
    }
}

When I insert data for 6th,7th,8th,9th I get all four instead of last 3 when the window moves.

found output

anomalies: [Tue Oct 06 05:30:00 IST 2020, Wed Oct 07 05:30:00 IST 2020, Thu Oct 08 05:30:00 IST 2020, Fri Oct 09 05:30:00 IST 2020]

instead of

anomalies: [Wed Oct 07 05:30:00 IST 2020, Thu Oct 08 05:30:00 IST 2020, Fri Oct 09 05:30:00 IST 2020]
manu
  • 223
  • 1
  • 2
  • 12
  • Can you show the unit test that you're using to test this? Or how are you verifying your functionality? – Roddy of the Frozen Peas Oct 06 '20 at 20:00
  • @RoddyoftheFrozenPeas I have put the sample here. https://github.com/mtekp/droolsExperiments/tree/main/testdrools – manu Oct 07 '20 at 05:35
  • @RoddyoftheFrozenPeas `TestDroolEventsContinousTest.java` is test class. I have simplified the code there in github – manu Oct 07 '20 at 06:31
  • 1
    I do not see where in your test code you're incrementing the rules engine's internal clock between inserts? Or even after inserts. The expires property will discard events greater than 3 days old, but 3 "days" does not pass according to that test case – Roddy of the Frozen Peas Oct 07 '20 at 11:49
  • The interesting thing is that he is using a real-time clock, and he is inserting events "from the future" but the accumulate rule still fires... The rule itself is working as if the `over window:time(3d)` was not there at all. – Esteban Aliverti Oct 07 '20 at 14:37
  • 1
    @RoddyoftheFrozenPeas got it. I changed clock to `pseudo` and did what you said by advancing time to my required event time and it worked. https://github.com/mtekp/droolsExperiments/tree/fix/testdrools @EstebanAliverti this is an interesting find and don't know why it happened though – manu Oct 08 '20 at 06:20

0 Answers0