Red Hat JBoss BPM Suite - Accessing Process Context Variables From a Rule
Join the DZone community and get the full member experience.
Join For FreeWe will be using a simple demo project that can be found in our demo collections on github, which will allow you to view and experiment with the final working example in a JBoss BPM Suite installation.
The JBoss BPM Suite installation you will have to set up yourself, but you can leverage our JBoss BPM Suite installation project we have to save you some trouble.
The goal
The basic goal of this article and demo project is to show you exactly how to design a process that uses a rule that if it fires will then access and modify one of the process variables. This communication between a process and a rule is an often asked question.The setup
Start by unzipping the demo project repository and copy it into the JBoss BPM Suite installation projects directory.# Start by cloning project at # https://github.com/eschabell/demo-collections. # $ git clone git@github.com:eschabell/demo-collections.git $ cd demo-collections $ unzip niogit-rule-procvar.zip # Follow instructions and install JBoss BPM Suite # via https://github.com/eschabell/bpms-install-demo. # # Then copy the demo repository into the JBoss BPM Suite server. # $ cp -rv .niogit bpms-install-demo/target/jboss-eap-6.1/bin # Start the JBoss BPM Suite server. # $ ./bpms-install-demo/target/jboss-eap-6.1/bin/standalone.sh # Login with user 'erics' and password 'bpmsuite' to get started.
Now we can take a look at the process, how it is configured to be deployed by default, what the rule is, what we have to do to modify a process variable, and look at the output.
The initial output
Our process consists of a simple run through that prints a log statement at the first node, then runs a rule (which we want to modify a process variable), then a gateway where we decide if the rule fired or not, and then the path where the rule fired (we log that) or the path where the rule did not fire (we log that too).
![]() |
Test process for rule modifying a process variable. |
What we want to test is that a rule with a Left Hand Side or Condition that evaluates to TRUE, will trigger its corresponding Right Hand Side or Action to print a log statement that the rule fired.
On our initial attempt we had a process that only had the first two nodes, then ended. We expected to see something like this in the logs if we ran three instances of the process:
17:29:46,315 INFO [stdout] (http-localhost/127.0.0.1:8080-5) Execute Java Step 17:29:46,330 INFO [stdout] (http-localhost/127.0.0.1:8080-5) Tested Rule 17:29:46,315 INFO [stdout] (http-localhost/127.0.0.1:8080-5) Execute Java Step 17:29:46,330 INFO [stdout] (http-localhost/127.0.0.1:8080-5) Tested Rule 17:29:46,315 INFO [stdout] (http-localhost/127.0.0.1:8080-5) Execute Java Step 17:29:46,330 INFO [stdout] (http-localhost/127.0.0.1:8080-5) Tested Rule
What we ended up with was this:
17:29:46,315 INFO [stdout] (http-localhost/127.0.0.1:8080-5) Execute Java Step 17:29:46,330 INFO [stdout] (http-localhost/127.0.0.1:8080-5) Tested Rule 17:29:46,315 INFO [stdout] (http-localhost/127.0.0.1:8080-5) Execute Java Step 17:29:46,315 INFO [stdout] (http-localhost/127.0.0.1:8080-5) Execute Java Step
At this point we modified the process you see above, adding two debug nodes that report if the rule fired or not, making the outcome clearer. We expected to see something like this in the logs if we ran three instances of the process:
20:51:22,491 INFO [stdout] (http-localhost/127.0.0.1:8080-2) Execute Java Step 20:51:22,494 INFO [stdout] (http-localhost/127.0.0.1:8080-2) Tested Rule 20:51:22,497 INFO [stdout] (http-localhost/127.0.0.1:8080-2) Rule fired! 20:51:35,615 INFO [stdout] (http-localhost/127.0.0.1:8080-2) Execute Java Step 20:51:35,618 INFO [stdout] (http-localhost/127.0.0.1:8080-2) Tested Rule 20:51:35,621 INFO [stdout] (http-localhost/127.0.0.1:8080-2) Rule fired! 20:51:43,312 INFO [stdout] (http-localhost/127.0.0.1:8080-2) Execute Java Step 20:51:43,316 INFO [stdout] (http-localhost/127.0.0.1:8080-2) Tested Rule 20:51:43,320 INFO [stdout] (http-localhost/127.0.0.1:8080-2) Rule fired!
What we ended up with was this:
20:51:22,491 INFO [stdout] (http-localhost/127.0.0.1:8080-2) Execute Java Step 20:51:22,494 INFO [stdout] (http-localhost/127.0.0.1:8080-2) Tested Rule 20:51:22,497 INFO [stdout] (http-localhost/127.0.0.1:8080-2) Rule fired! 20:51:35,615 INFO [stdout] (http-localhost/127.0.0.1:8080-2) Execute Java Step 20:51:35,618 INFO [stdout] (http-localhost/127.0.0.1:8080-2) Rule did not fire... 20:51:43,312 INFO [stdout] (http-localhost/127.0.0.1:8080-2) Execute Java Step 20:51:43,316 INFO [stdout] (http-localhost/127.0.0.1:8080-2) Rule did not fire...
What happened to the rule firing the second and third time? Not only that, the rule never even triggers in the second and third time through, why?
To find out we need to look at the session strategy that is applied by default.
The deployment
Taking a closer look at how this process is deployed, we see that it makes use of the default session strategySINGLETON which means it will run all process instances in a single ksession.
![]() |
Deployment by default is using SINGLETON runtime strategy |
This means that the process would put any facts into working memory and then run through our process and at the rule task it would evaluate the rule. This was the first time through an instance.
The second (and all consecutive) time through the working memory was not being modified so the rule is never evaluated, it just passes over it.
To fix this we need to make the process clearer, so we added a process variable to be updated when the rule fired, a gateway to check the process variable, and if set to log that the rules had fired. Remember, the rule firing sets the process variable.
Let's see how that looks.
The rule
We took our initial stab at the rule by setting it up to always match the condition so that the action would fire:
rule "update-procvar" ruleflow-group "fire-always" when eval(true) then System.out.println("Tested Rule"); end
Remember with the single ksession the first time through it fired, but after that it never gets evaluated again. To fix this we will need to make sure that some form of object or fact is added into the working memory each time this process instance is run.
Luckily this is provided for in a rule task, where you can create Data Assignments and map your DataInputSets. This is done by selecting the rule task and expanding the Properties sidebar to show you that we have created afired variable and assigned it the value null, then we are inserting it into the working memory as our DataInputSet.
![]() |
Mapping the fired variable into the working memory every time. |
import org.kie.api.runtime.process.WorkflowProcessInstance; rule "update-procvar" ruleflow-group "fire-always" when $pi: WorkflowProcessInstance() String() then $pi.setVariable("fired", "true"); end
This should cause the rule to evaluate and then using the process instance we can set the process variablefired to true, which is exactly the check that is done at the following gateway node.
Let's run it a few times and see what happens?
The Output
Now that we have sorted out the issues and understand what it means to have a single ksession in which our rules will only fire on a new instance if there has been some fact change in the working memory, we are ready to test our solution.
This is what you will see when you run three instances of the demo process:
21:06:32,767 INFO [stdout] (http-localhost/127.0.0.1:8080-5) Execute Java Step 21:06:32,774 INFO [stdout] (http-localhost/127.0.0.1:8080-5) Tested Rule 21:06:32,777 INFO [stdout] (http-localhost/127.0.0.1:8080-5) Rule fired! 21:06:41,646 INFO [stdout] (http-localhost/127.0.0.1:8080-5) Execute Java Step 21:06:41,654 INFO [stdout] (http-localhost/127.0.0.1:8080-5) Tested Rule 21:06:41,656 INFO [stdout] (http-localhost/127.0.0.1:8080-5) Rule fired! 21:06:47,559 INFO [stdout] (http-localhost/127.0.0.1:8080-5) Execute Java Step 21:06:47,565 INFO [stdout] (http-localhost/127.0.0.1:8080-5) Tested Rule 21:06:47,567 INFO [stdout] (http-localhost/127.0.0.1:8080-5) Rule fired!
We hope you now understand how a process is deployed using a rule, how to access and update a process variable from a rule in your project, and can put this knowledge to use in your own projects.
Published at DZone with permission of Eric D. Schabell, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
What Is mTLS? How To Implement It With Istio
-
Web Development Checklist
-
Auto-Scaling Kinesis Data Streams Applications on Kubernetes
-
Redefining DevOps: The Transformative Power of Containerization
Comments