JBPM work items in guided decision table only executed once? - drools

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 ?

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,

Related

Why does Drools re-evaluate and re-trigger rule actions after a persistent session is reloaded?

I have a simple rule like the one below:
package rules
dialect "mvel"
declare MyEvent
#role( event )
#expires( 2d )
id String
value: Double
end
rule "My Rule"
when
MyEvent($value : value)
then
System.out.println("My event with value: " + $value);
end
I create a persistent session and call fireAllRules() on it. Then, I insert a MyEvent fact, and as expected the rule is evaluated, matched and the action is executed. If I call fireAllRules() again the rule is not matched, as expected because it has already matched for the same fact. At this point everything is fine.
Then I kill the JVM and run the app again. At startup the app loads the session like this:
kieSession = kieServices.getStoreServices().loadKieSession(KIE_SESSION_ID, kieBase, kieSessionConfiguration, kieEnvironment);
The session gets loaded successfully, and then fireAllRules() is called again. Since the rule has already matched for the inserted event, I am expecting that it does not match again. However I can see the message in the rule action is printed again. Why does Drools match the rule for the same eventagaian? To me it looks like the session state is not properly saved to database. I mean, the event is saved, but Drools can not recogonize that it has already matched the rule. When I load a persistent session I expect to recover exactly the same state that the session had in the previous running instance. Is my assumption wrong? or Am I doing something wrong for the expected behaviour?
Running:
JavaSE 11
SpringBoot 2.3
Drools 7.53.0

how to add value to duration attribute in drools

Whenever i write duration(0s), it works but as soon as i change it to duration(1s) or duration(5s), the rule doesn't fire...
This is the rule which i want to fire.
rule "ContainsChecking"
agenda-group "town4"
duration(0s)
when
Town(owner matches "[N || n][a-z]+")
then
System.out.println("Rule Fired ContainsChecking");
end
do we need to import something for duration attribute to work, because i m not getting it anywhere. Thanks in advance.
You need to run the session using
kieSession.fireUntilHalt();
If you just use fireAllRules, the agenda is empty and the call terminates.
This is a CEP feature and need not and should not be used in a simple production rule environment.

Business rule execute only once on jbpm process

I execute a business rule from a process on Jbpm, the rule is simple:
package com.test.flow;
rule "sample"
ruleflow-group "test"
when
then
System.out.println("Hello World");
end
But, I don't no why, this rule execute only once, for instance, I run a new instance of the process and in the jbpm console print "Hello World", but, when I run a second instance of the process doesn print anymore "Hello World", some one can you help me? or tellme why does this happen?
Screen Jbpm console
For this kind of "hello-world" rule, using ruleflow-group is most likely just causing confusion. Do you control when this group is activated? How? - Omitting this rule attribute is indicated.
A rule with an empty left-hand-side will execute only once in a session (as Esteban pointed out).
If you want a rule that fires once for each inserted fact, use
rule "new fact"
when
Object()
then
System.out.println( "new fact inserted" );
end

How to control jobs of different families in eclipse

How to control jobs from different families
For example, when I perform the following actions in eclipse:
From the "Project" menu , select "Clean". Then the dialog appears I click on "OK" button.
Then " Cleaning all Projects " operation begins. In the middle of the operation I try to delete some file from my workspace.
the following dialog appears, "User operation is waiting" where the first operation which I did "Cleaning all operation" progress continues. And the second "Delete" operation will be blocked showing the "lock" symbol with message "Blocked: the user operation is waiting for cleaning all projects to complete". After completing the first operation only, the "Delete" operation dialog appears.
What I need?
I am trying to get the similar situation as above in my project.
I have created one job family for my project following the tutorial "On the Job eclipse".
I schedule the job to perform some operation in background.
as soon as the operation progresses, i tried to delete the file. As soon as I select "Delete" , Delete dialog appears. However, what I need is to Block this Delete operation until the first operation which I performed completes similar way as I told in the above example.
How it can be done using eclipse jobs.? I tried with job.join(), job.setPriority() and all....
If you have any idea please share
You use 'scheduling rules' to define which jobs can run at the same time. A scheduling rule is a class which implements the ISchedulingRule interface.
A simple rule would be:
public class MutexRule implements ISchedulingRule
{
#Override
public boolean isConflicting(ISchedulingRule rule)
{
return rule == this;
}
#Override
public boolean contains(ISchedulingRule rule)
{
return rule == this;
}
}
which will only allow one job with this rule to run at a time. Use like this:
ISchedulingRule rule = new MutexRule();
Job job1 = new ....
Job job2 = new ....
job1.setRule(rule);
job2.setRule(rule);
job1.schedule();
job2.schedule();
Note that IResource extends ISchedulingRule and implements a rule to stop two jobs accessing the same resources at a time.
So to have only one job modifying the workspace at a time you can use:
ISchedulingRule rule = ResourcesPlugin.getWorkspace().getRoot();
(since IWorkspaceRoot extends IResource). Eclipse uses this rule for many jobs.
You can also use IResourceRuleFactory to create rules for controlling access to resources.
IResourceRuleFactory factory = ResourcesPlugin.getWorkspace().getRuleFactory();
There is also a MultiRule class which allows you to combine several scheduling rules.

Sensu custom parameter in event data

I would like to add custom key/value pairs to the event data in sensu. I added the keys to the event definition, but it's not there by the time it gets to the handlers.
So what i want to achieve is to have the data behind the "custom_values" key at the point the check data is passed to the handler. (see example)
{
"checks": {
"check-disk": {
"command": "/etc/sensu/plugins/check-disk.rb",
"interval": 60,
"handlers": [
"default"
],
"subscribers": [
"default"
],
"standalone": false
"custom_values": {
"custom1": "somevalue"
}
}
}
}
Mutators won't help, AFAIK they can only work with the check data, which is not containing the custom key when the mutator gets the check result.
Thanks
Not much to go on as to how you're trying to use it, but there are a couple items you'll want to be sure of.
First off, the checks json provided is malformed, prior to defining your custom_values, you need a comma after "standalone": false
As such:
"standalone": false,
"custom_values": {
"custom1": "somevalue"
}
Second, when you go to use this custom_value data in your handler, make sure you're addressing it as part of the check:
#event['check']['custom_values']['custom1']
and not just trying to use it directly off the event, i.e.
#event['custom_values']['custom1']
This should work. Can you be sure that this check is not defined in on the client as well?
Additionally, did you remember to restart the sensu server to pick up the new definition?