JBoss Drools is a rules engine. It executes statements that might modify the state of the objects, depending on which rules satisfy the input. Within Mule, input is fed to the rules engine from within a flow, and the rules execute to modify the state of that input.
Here is some terminology associated with rules engines:
Facts: stored in a working memory (similar to an in-memory database). A fact is some data, for example: “age = 40”. In an object-oriented rules engine, a fact is represented by a Java object, where the values are stored within the properties of that Java object.
Rules: defined in a knowledge base. A rule consists of conditions (which typically depend on facts in the working memory), and actions, which are executed when the conditions are true (similar to an “if-then” statement). The action executed by a rule may change facts in the working memory which then cause other rules to fire.
JBoss Drools is perfect for applications that have a lot of business rules, and need to separate the business rules from the model, views and any other logic.
Integration with Mule
To integrate JBoss Drools with Mule, we need to do a couple of things:
1. Import the XML schema as follows:
2. Declare Drools as the rules engine to use with Mule as a global element:
Unfortunately, this is not supported by Anypoint Studio yet, so we have to do the above configuration manually. Once completed, Mule is ready to start a JBoss Drools engine and execute the declared rules against our payloads. We still need to configure the facts for our example.
Example of World Cup Application
We have made a couple of assumptions for you to be able to follow this blog post, that you are familiar with Mule, and with Log4j.
Our example is based on a world cup application that keeps track of the team statistics. This application saves the number of times that a team lost and won. We modify our statistics based on the input, that is information about the match. We used JBoss Drools for that.
In our application, we have defined 2 classes: Match and Team.
Every Match will contain an array of 2 teams, and an array containing the result scores. The team will have his result score in the results.
We will create the rules in a file worldcup.drl, and save it in src/main/resources/rules. The rules are defined as follows.
We started off by defining the package, followed by an obligatory global element for the integration between Mule and Drools.
Finally, our rules are defined in the form of when … then … statements. For example, our first rule will kick if the score of the first team is greater than the score of the second team.
The entry in the when block is stating that the input has to be an object of type Match, and checking the results by accessing the array results. Drools does that by executing the getter statement automatically on the input getResults().
$m is the result of the when clause. If the input matches the all the criteria, $m will be populated by that input. This will be accessible also from the then block.
Since we are basing our example on a stateless execution of the rules, we have to supply the rules engine with an empty list of facts.
The Mule flow is trivial. We designed a flow that accepts Match objects on a VM inbound endpoint and executes the rules against the input using Drools. The flow looks like this:
We are using loggers at TRACE level for “com.ricston.worldcup.ruleFlow” category, so you can easily modify the log4j.properties to hide or show the logs.
The focus of this flow is the message processor where we ask Mule to execute the rules.
This will apply the rules to the payload and will use the facts “noFactsBean” for the execution.
I hope that you found this blog interesting and that it helps you with your integration of Mule and JBoss Drools.