1

I want to create a time-based rule that is being triggered every 5 minutes, and Drools documentation states that:

Conversely when the Drools engine runs in passive mode (i.e.: using fireAllRules instead of fireUntilHalt) by default it doesn’t fire consequences of timed rules unless fireAllRules isn’t invoked again. However it is possible to change this default behavior by configuring the KieSession with a TimedRuleExecutionOption as shown in the following example

KieSessionConfiguration ksconf = KieServices.Factory.get().newKieSessionConfiguration();
ksconf.setOption( TimedRuleExecutionOption.YES );
KSession ksession = kbase.newKieSession(ksconf, null);

However, I am not accessing the KieSession object directly because I am using the Java REST API to send requests to a Drools project deployed on KieExecution Server like so (example taken directly from the Drools documentation):

public class MyConfigurationObject {

  private static final String URL = "http://localhost:8080/kie-server/services/rest/server";
  private static final String USER = "baAdmin";
  private static final String PASSWORD = "password@1";

  private static final MarshallingFormat FORMAT = MarshallingFormat.JSON;

  private static KieServicesConfiguration conf;
  private static KieServicesClient kieServicesClient;

  public static void initializeKieServerClient() {
        conf = KieServicesFactory.newRestConfiguration(URL, USER, PASSWORD);
        conf.setMarshallingFormat(FORMAT);
        kieServicesClient = KieServicesFactory.newKieServicesClient(conf);
    }

  public void executeCommands() {

    String containerId = "hello";
    System.out.println("== Sending commands to the server ==");
    RuleServicesClient rulesClient = kieServicesClient.getServicesClient(RuleServicesClient.class);
    KieCommands commandsFactory = KieServices.Factory.get().getCommands();

    Command<?> insert = commandsFactory.newInsert("Some String OBJ");
    Command<?> fireAllRules = commandsFactory.newFireAllRules();
    Command<?> batchCommand = commandsFactory.newBatchExecution(Arrays.asList(insert, fireAllRules));

    ServiceResponse<ExecutionResults> executeResponse = rulesClient.executeCommandsWithResults(containerId, batchCommand);

    if(executeResponse.getType() == ResponseType.SUCCESS) {
      System.out.println("Commands executed with success! Response: ");
      System.out.println(executeResponse.getResult());
    } else {
      System.out.println("Error executing rules. Message: ");
      System.out.println(executeResponse.getMsg());
    }
  }
}

so I'm a bit confused as to how i can pass this TimedRuleExecutionOption to the session?

I've already found a workaround by sending a FireAllRules command periodically but I'd like to know if I can configure this session option so that I don't have to add periodical triggering for every timed event I want to create.

Also, I've tried using FireUntilHalt instead of FireAllRules, but to my understanding that command blocks the execution thread on the server and I have to send a HaltCommand at some point, all of which I would like to avoid since I have a multi-threaded client that sends events to the server.

D. Joe
  • 55
  • 1
  • 5

2 Answers2

0

You can use drools cron function. It acts as a timer and invoke rule based on the cron expresion. Example to execute a rule every 5 minutes :

rule "Send SMS every 5 minutes"
    timer (cron:* 0/5 * * * ?)
when
    $a : Event( )
then

end

you can find explanation here

Prog_G
  • 1,539
  • 1
  • 8
  • 22
  • I don't think you understood my issue properly. I already tried both time and cron functions, as well as duration, but as stated in the question, the timed rules won't be triggered unless FireAllRules is executed or the TimedRuleExecutionOption.YES is set to the KieSession object which I don't have because I'm using the client API. – D. Joe Feb 01 '19 at 13:08
  • @D.Joe Try passing "-Ddrools.timedRuleExecution=YES" while starting server instance where kie-server.war is deployed. – Abhijit Humbe Feb 01 '19 at 16:42
  • @Abhijit That seems to be the correct solution. I just passed the value of "true" instead of "YES" and it appears to be working. Please post it as an answer so I can mark the question as solved :) – D. Joe Feb 04 '19 at 09:43
0

pass "-Ddrools.timedRuleExecution=true" while starting server instance where kie-server.war is deployed.

Abhijit Humbe
  • 1,563
  • 1
  • 12
  • 13