Hi Tim,

   There are some concepts that one has to have in mind when playing with temporal reasoning and events. It is clear by your e-mail that we need to do better in documenting all that, as it is complex. I am also trying to improve the engine feedback to help users catch these problems more easily.

* Sliding windows only work and make sense on STREAM mode, although I think Drools 5.0.1 does not generate proper errors for trying to use them in CLOUD mode. I fixed that in 5.1 and now it raises a compile time error.

* Whatever temporal reasoning you are doing in STREAM mode, the session clock is integral part of it and needs to be taken into account. That is because a sliding window always use the current time as the reference date (or anchor if you will). I am not seeing any clock management in your code snippet, so I am assuming you are using the real time clock.

* Having said all that just to layout the ground, your case is clearly a case of using CLOUD mode. In cloud mode, you have all your events in advance and you reason over them. In STREAM mode, you are constantly receiving new events, so the engine has to be prepared to react to them or wait for them when necessary. That is why it also does not make sense to use STREAM mode with stateless sessions.

   So, we understand now that you have all your events in advance (so we will use CLOUD mode), and it does not make sense to use sliding windows. All you want to check is if given a time range you have more than 5 failed responses, so you need an interval fact that contains such date range. The rule would look like this:

declare Payment
       @role( event )
       @timestamp( created )
end

rule "Block IP with more than 5 failed payments in the last 24 hours"
when
   $fact : BlockRuleResponse()
   $int : Interval()
   $count : Number( intValue > 4 ) from accumulate(
                    Payment(responseCode == 0, this after $int.initDate, this before $int.endDate),
                                  count(1) ) )
then
   System.out.println("More than 5 failures in 24 hours");
   System.out.println( $count );
   $fact.setBlocked( true );
end

    Hope it helps,
          Edson


2009/12/4 Tim S <tim_siney@salvationarmy.org>

When I run a test case against drools from within eclipse, it will return the
expected results the first time, but fails every time after that. I'd like
to know what's going on and if my rules are written correctly.

The object of the rule is to check to see a particular IP address has
submitted more than 5 failed payments in the last 24 hours (indicated by
responseCode == 0). The input to this is a List containing all payments from
the IP address and a helper object to indicate whether further action needs
to be taken by way of a boolean flag.

declare Payment
       @role( event )
       @timestamp( created )
end

rule "Block IP with more than 5 failed payments in the last 24 hours"
when
   $fact : BlockRuleResponse()
   $count : Number( intValue > 4 ) from accumulate(
                    Payment(responseCode == 0, $id : id) over window:time(
24h ),
                               count( $id ) )
then
   System.out.println("More than 5 failures in 24 hours");
   System.out.println( $count );
   $fact.setBlocked( true );
end

The code in my test case which runs this is:

       BlockRuleResponse result = new BlockRuleResponse();
       result.setBlocked(false);

       // Add all commands to this rule session
       List<Command> cmds = new ArrayList<Command>();
       cmds.add(CommandFactory.newInsert(result));
       cmds.add(CommandFactory.newInsertElements(payments));

       StatelessKnowledgeSession ksession =
getBase().newStatelessKnowledgeSession();
       ksession.execute(CommandFactory.newBatchExecution(cmds));
       log.debug(result.isBlocked());

       return result.isBlocked();

The getBase() method just returns a KnowlegdeBase containing the rule above.
I then create two Lists of payment objects, one with creation dates set to
new Date(), the other with creation dates set more than 24 hours ago. I run
these through the rules engine and the result returned is always true.

I've tried using cloud + stream mode and also using a stateful session and
inserting the donations then firing all rules but none of this seems to
work. Stream mode always returns false, likewise stateful sessions always
return false whereas stateless cloud mode always returns true after the
first run.

Anyone have any idea what I'm missing?


--
View this message in context: http://n3.nabble.com/Rules-returning-unexpected-results-tp68205p68205.html
Sent from the Drools - User mailing list archive at Nabble.com.
_______________________________________________
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users



--
 Edson Tirelli
 JBoss Drools Core Development
 JBoss by Red Hat @ www.jboss.com