0
votes

I can see that for a stateful session there is e.g.

StatefulKnowledgeSessionImpl.getFactHandles() 

How can I access fact handles of a stateless session?

More background: This is a follow-up question to this: In drools can I access the working memory (or arbitrary facts) from within an AgendaFilter? I am trying to find a way to access arbitrary facts from within an AgendaFilter. The accepted answer (https://stackoverflow.com/a/34067851/932201) suggested to add the kieSession to the filter, but I failed to mention that I am working with stateless sessions.

Thanks!

1

1 Answers

0
votes

I think your question has an incoherence because I don't think is possible to pass an AgendaFilter to the execution method of the Stateless session; there is no API method available for the .execute() where you could pass the AgendaFilter as a parameter. EDIT: as pointed out in the comments, the AgendaFilter could be actually passed inside a FireAllRulesCommand.

Additionally the question preamble is a bit confusing, Stateless session are created and disposed as you pass the fact(s) and contextually launch the rules evaluation, there is no possibility to access the fact handles from the API because the session is already disposed as you called .execute(Object...), so no more fact handles.

Anyway-

By looking at the previous question's answer you linked, and IFF you want to follow-up on the proposed

A slightly more sophisticated approach would be

as user @laune suggested, it could be something like the below by binding an AgendaEventListener:

kieBase.newStatelessKieSession().addEventListener(new AgendaEventListener() {
    @Override
    public void afterMatchFired(AfterMatchFiredEvent event) {
        final String uid = (String) event.getMatch().getRule().getMetaData().get("uid"); // @uid("1234")
        @SuppressWarnings("unchecked") // is unchecked yes, but anyway okay because of ObjecFilter.
        Collection<? extends RuleConfig> facts = (Collection<? extends RuleConfig>) event.getKieRuntime().getObjects(object -> {
                if (object instanceof RuleConfig) {
                    return ((RuleConfig) object).getUid().equals(uid);
                }
                return false;
            });
        facts.forEach(o -> { o.decrementCounter();});

        // trickiest part, because need to signal updated Facts via the facthandles;
        for ( RuleConfig rc : facts ) {
            FactHandle factHandle = event.getKieRuntime().getFactHandle(rc);
            event.getKieRuntime().update(factHandle, rc);
        }
    }

, while you still need a condition in each rule LHS as per @laune example provided in the last part of that answer:

rule "abc"
@uid("1234")
when
  $ruleConfig : RuleConfig(uid="1234", counter > 0)
  // ...