I am trying to set KieSession
date to same date with the date variable in my object before running the rules. I use this configuration to create my KieSession
KieSessionConfiguration configuration = KieServices.Factory.get().newKieSessionConfiguration();
configuration.setOption(ClockTypeOption.get("pseudo"));
Before running the rules I use advanceTime()
to set the date of the session to desired date.
final SessionPseudoClock clock = kSession.getSessionClock();
clock.advanceTime(object.getDate().getTime() - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
final List<Command<?>> commands = new ArrayList<>();
commands.add(CommandFactory.newInsertElements(objects)
commands.add(CommandFactory.newInsert(object, "object"));
final ExecutionResults results = kSession.execute(CommandFactory.newBatchExecution(commands));
This resulted misfires in the rules that uses sliding windows. Lets say checking the objects that passed in 1 hour and I don't have any in the last hour. I only have 3 objects day before. Here is an example dataset of objects.
objects: [
{
clientId: "id",
date: 2021-02-09T12:00:38.249Z,
...
}
{
clientId: "id",
date: 2021-02-09T13:00:38.249Z,
...
}
{
clientId: "id",
date: 2021-02-09T14:00:38.249Z,
...
}
]
I have a rule which checks if there are more than 2 objects with the same clientId
over 1 hour.
$object : Object($clientId : clientId)
List( size > 2 ) from collect ( Object( this before $object, clientId == $clientId ) over window:time(1h))
When I pass an object with these values. The rule above returns true but we clearly don't have any objects that has a date within last hour.
{ clientId: "id", date: 2021-02-10T14:00:38.249Z, ... }
I believe this is broken because of the new configuration as it was working previously (when I did not try to change session clock) but I want session date to be equal to object date. Anyone has ideas what is the problem here and how to fix it?
As Roddy of the Frozen Peas made the remark, you need to manipulate SessionPseudoClock
in between every insert of your events. I'd implement a new Command
, extend InsertElementsCommand
and @Override
it's execute
method:
@Override
public Collection<FactHandle> execute(Context context) {
KieSession kSession = ((RegistryContext) context).lookup(KieSession.class);
List<FactHandle> handles = new ArrayList<>();
Object workingMemory = StringUtils.isEmpty(super.getEntryPoint()) ?
kSession :
kSession.getEntryPoint(super.getEntryPoint());
SessionPseudoClock clock = kSession.getSessionClock();
super.objects.forEach(event -> {
clock.advanceTime(((YourObject) event).getDate().getTime() - clock.getCurrentTime(), TimeUnit.MILLISECONDS);
handles.add(((EntryPoint) workingMemory).insert(event));
});
...
return handles;
}
and instead of:
commands.add(CommandFactory.newInsertElements(objects));
I'd:
commands.add(new YourInsertElementsCommand(objects));