Search code examples
droolsjbpm

JBPM work items in guided decision table only executed once?


I am designing a guided decision table to execute some work items which are simply printing out some texts in executeWorkItem function.

In the workbench settings, I have added the work item handlers into a stateful session. Also I have defined them in a wid file.

The rules in the guided decision table is quite straightforward. It is as following in source view

//from row number: 1
rule "Row 1 dt1"
    dialect "mvel"
    when
    then
        org.drools.core.process.instance.WorkItemManager wim = (org.drools.core.process.instance.WorkItemManager) drools.getWorkingMemory().getWorkItemManager();
        org.drools.core.process.instance.impl.WorkItemImpl wiQianhaiAddrWorkItemHandler = new org.drools.core.process.instance.impl.WorkItemImpl();
        wiQianhaiAddrWorkItemHandler.setName( "QianhaiAddrWorkItemHandler" );
        wim.internalExecuteWorkItem( wiQianhaiAddrWorkItemHandler );
end

No conditional checking just because I want to fire it every time there is a request sent to the KIE server.

This is the request fired to KIE server

URL:http://localhost:8080/kie-server/services/rest/server/containers/instances/poc2_1.0.1
body:
{"commands": [
  {
    "fire-all-rules": {}
  }
]}

I can see the work item was executed when first time the request fired to KIE server. However, it doesn't run anymore since the second time because I couldn't see any printing in console.

The response from KIE server is always correct as following

{
  "type" : "SUCCESS",
  "msg" : "Container poc2_1.0.1 successfully called.",
  "result" : {
    "execution-results" : {
      "results" : [ ],
      "facts" : [ ]
    }
  }
}

May I know how to execute the work item per my "fire-all-rules" command sent? Or is it a default behavior in JBPM ?


Solution

  • Let's start by saying that even if you are using a WorkItemManager your problem is entirely related to Drools.

    In Drools, a rule without conditions is only going to be executed once per session the first time you or somebody calls fireAllRules(). In your case, because your requests are reusing the same stateful session, your rule will be executed once.

    The first approach would be to use a stateless session if possible. If that's not possible, you may need to explicitly tell Drools when a new request is processed by sending a fact along with the request and to adding it to the condition of your rule. You can later on remove these facts if you don't need them in your session:

    rule "Row 1 dt1"
    dialect "mvel"
    when
        Request()
    then
        org.drools.core.process.instance.WorkItemManager wim = (org.drools.core.process.instance.WorkItemManager) drools.getWorkingMemory().getWorkItemManager();
        org.drools.core.process.instance.impl.WorkItemImpl wiQianhaiAddrWorkItemHandler = new org.drools.core.process.instance.impl.WorkItemImpl();
        wiQianhaiAddrWorkItemHandler.setName( "QianhaiAddrWorkItemHandler" );
        wim.internalExecuteWorkItem( wiQianhaiAddrWorkItemHandler );
    end
    
    
    rule "Cleanup Request"
    salience -10
    when
        $r: Request()
    then
        delete($r);
    end
    

    Hope it helps,