access drools session clock from accumulation function or rule code

2k Views Asked by At

i'm trying to write an accumulation function that needs to be aware of the current time. i could obviously use System.currentTimeMillis(), but for testing im running a drools session with a pseudo-clock and would like to be able to test this function.

im looking for a way of getting at the session clock (or better yet, the KnowledgeRuntime) either from within the getResult() method or, if thats not possible, from the drools code itself (in te when section) so i could pass the clock to the function

2

There are 2 best solutions below

6
On BEST ANSWER

Be careful when working with clocks as you can have quite a few surprises. Please note that the constraints are evaluated when the facts/events are inserted into the session or modified with an update/modify call. This means that the clock time when the constraint is evaluated will probably be different from the clock time when the rule is fired. That is the reason why drools does not exposes the current time directly to the LHS patterns.

Having said that, the way to do it is insert the session clock as a fact into the session and bind it as any other fact:

rule X
when
    $clock : SessionClock()
    ... your patterns / accumulate / etc  ...
then
    ...
end
0
On

During unit testing, I found that adding $clock : SessionClock() to when would cause unit tests not to trigger, FWR (probably because I had mocked it as a SessionPseudoClock and thus were no SessionClock facts in working memory).

I was able to however obtain the session clock (Pseudo or real) without needing a conditional bind, by using the drools KnowledgeHelper instance:

e.g.

then
  System.out.println(String.format(
      "It is now %s", 
         new java.util.Date(drools.getWorkingMemory()
                                  .getSessionClock()
                                  .getCurrentTime())
         .toString()));