DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • How To Handle 100k Rows Decision Table in Drools (Part 3)
  • How To Handle 100k Rows Decision Table in Drools (Part 2)
  • Using Maven and Without Drools Eclipse Plugin

Trending

  • Developers Beware: Slopsquatting and Vibe Coding Can Increase Risk of AI-Powered Attacks
  • Scalable, Resilient Data Orchestration: The Power of Intelligent Systems
  • Medallion Architecture: Efficient Batch and Stream Processing Data Pipelines With Azure Databricks and Delta Lake
  • How AI Agents Are Transforming Enterprise Automation Architecture

Drools With Mule 4

Implementing Drools requires two things: authoring and runtime.

By 
Susmit Dey user avatar
Susmit Dey
DZone Core CORE ·
Jan. 07, 19 · Tutorial
Likes (4)
Comment
Save
Tweet
Share
16.3K Views

Join the DZone community and get the full member experience.

Join For Free

Drools is a business rule management system with a forward-chaining and backward-chaining inference-based rules engine, allowing fast and reliable evaluation of business rules and complex event processing. A rule engine is also a fundamental building block to create an expert system, which, in artificial intelligence, is a computer system that emulates the decision-making ability of a human expert.

Implementing Drools requires two things: authoring and runtime. Authoring is the creation of rules files, and runtime involves working memory to execute the rules.

In Mule 3.x, embedded Drools rule definitions (*.drl) could be executed by bpm:drools component however in Mule 4, Drools module has been dropped.

Ref: https://docs.mulesoft.com/mule-runtime/4.1/mule-4-changes

The recommendation is to use Drools as a standalone installation and expose the rules execution interface as REST APIs to integrate with the Mule flow, however, that requires a separate infrastructure and installation efforts. As an alternative, we can implement a custom Java code to execute the embedded Drools rule definitions and call it from our Mule flow. The implementation can be done as described in the diagram:

Image title

Please note: to update the rules definition, the Mule application needs to be redeployed. Here's an example of the Java implementation in the Mule 4 flow:

Mule Runtime - 4.1.4

Anypoint Studio - 7.3.0

Purpose: To implement the below rules in Drools to assign a Job to a particular supplier:

Rule 1: If Job is of type "Food Supply" and status is "New" then assign to "Farmer's Food Supply Pvt Ltd." and set status to "Assigned"

Rule 2: If Job is of type "Water Supply" and status is "New" then assign to "Ocean Water  Supply Pvt Ltd." and set status to "Assigned"

Step 1: Create a new Mule 4 project in Anypoint Studio, name it drools-example

Step 2: Create the Java class representing the POJO for Job to be assigned.

Create package com.drools.example in folder: drools-example\src\main\java

Create Job.java POJO inside the package: com.drools.example

package com.drools.example;

public class Job {

String jobName;
String jobType;
String jobLocation;
String jobDateTime;
long jobCost;
String jobOwner;
String jobStatus;

public String getJobStatus() {
return jobStatus;
}
public void setJobStatus(String jobStatus) {
this.jobStatus = jobStatus;
}
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public String getJobType() {
return jobType;
}
public void setJobType(String jobType) {
this.jobType = jobType;
}
public String getJobLocation() {
return jobLocation;
}
public void setJobLocation(String jobLocation) {
this.jobLocation = jobLocation;
}
public String getJobDateTime() {
return jobDateTime;
}
public void setJobDateTime(String jobDateTime) {
this.jobDateTime = jobDateTime;
}
public long getJobCost() {
return jobCost;
}
public void setJobCost(long jobCost) {
this.jobCost = jobCost;
}
public String getJobOwner() {
return jobOwner;
}
public void setJobOwner(String jobOwner) {
this.jobOwner = jobOwner;
}
}

Step 3: Create the drools rule definition and add to the project

Create a new file job.drl in folder: drools-example\src\main\resources\rules\job

package rules.job

import com.drools.example.Job;

dialect "mvel"

rule "Food Supply Rule"
when
j : Job( jobType.equals("Food Supply") , jobStatus.equals("New"), jn : jobName )
then
j.setJobOwner( "Farmer's Food Supply Pvt Ltd." );
j.setJobStatus( "Assigned" );
update( j );
end

rule "Water Supply Rule"
when
j : Job( jobType.equals("Water Supply") , jobStatus.equals("New"), jn : jobName )
then
j.setJobOwner( "Ocean Water Supply Pvt Ltd." );
j.setJobStatus( "Assigned" );
update( j );
end

Additionally, create a file called kmodule.xml inside drools-example\src\main\resources\META-INF (create the META-INF folder inside resources). The kmodule.xml file is the descriptor that selects resources to knowledge bases and configures those knowledge bases and sessions.

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
  <kbase packages="rules.job" name="job-rules">
     <ksession name="ksession-job-rules"/>
  </kbase>
</kmodule>

Step 4: We need to edit the POM.xml file generated for the Mule project to include the dependencies for Drools; we are going to use Drools version 7.0.0.Final

Add properties in the <properties> block:

<drools.version>7.0.0.Final</drools.version>

Add dependencies in the <dependencies> block:

    <!-- Drools Dependencies -->
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-workbench-models-guided-dtable</artifactId>
        <version>${drools.version}</version>
    </dependency>
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-compiler</artifactId>
        <version>${drools.version}</version>
    </dependency>
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-core</artifactId>
        <version>${drools.version}</version>
    </dependency>
    <dependency>
        <groupId>org.kie</groupId>
        <artifactId>kie-api</artifactId>
        <version>${drools.version}</version>
    </dependency>
    <dependency>
        <groupId>org.kie</groupId>
        <artifactId>kie-ci</artifactId>
        <version>${drools.version}</version>
    </dependency>

Add Jboss Repository in <repositories> block:

<repository>
    <id>jboss-public-repository-group</id>
    <name>JBoss Public Repository Group</name>
    <url>http://repository.jboss.org/nexus/content/groups/public/</url>
    <releases>
        <enabled>true</enabled>
        <updatePolicy>never</updatePolicy>
    </releases>
    <snapshots>
        <enabled>true</enabled>
        <updatePolicy>daily</updatePolicy>
    </snapshots>
</repository>

Step 5: Now we are ready to implement the Rules engine, which will create KIESession to execute the drools rule definition.

For that, create the RulesEngine.java in the package com.drools.example

package com.drools.example;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;

import com.etech.drools.knowledge.Job;

public class RulesEngine {

public static void executeJobRules(Job inputJob)
{
try {
// load up the knowledge base
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("ksession-job-rules");

kSession.insert(inputJob);
kSession.fireAllRules();
kSession.dispose();

} catch (Throwable t) {
t.printStackTrace();
}

}
}

Step 6: In this step, we will invoke the static method in RulesEngine class from the Mule flow and pass the Job POJO instance as argument to it. The flow takes JSON input payload and transforms it into a Job POJO instance and assigns it to a flow variable. Then, the RuleEngine is called, which updates the flow variable accordingly with the result Finally, the flow variable is transformed back to JSON and returned as output.

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" xmlns:java="http://www.mulesoft.org/schema/mule/java" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd http://www.mulesoft.org/schema/mule/java http://www.mulesoft.org/schema/mule/java/current/mule-java.xsd">
    <http:listener-config name="HTTP_Listener_config" doc:name="HTTP Listener config" doc:id="bd540e0b-0f60-44fe-9d33-c176a5827250">
        <http:listener-connection host="0.0.0.0" port="8081" />
    </http:listener-config>
    <flow name="drools-exampleFlow" doc:id="d544ce83-d6d6-41d5-a0d9-cfb6af089540">
        <http:listener doc:name="Listener" doc:id="0d88ede3-b2c4-4fe9-8a94-1f3cb1e160d0" config-ref="HTTP_Listener_config" path="/drools-example" allowedMethods="POST" outputMimeType="application/json" />
        <ee:transform doc:name="Transform Message" doc:id="81815fdf-2f64-4015-85ca-422b86309eda">
            <ee:message>
                <ee:set-payload><![CDATA[%dw 2.0
output application/java
---
{
jobCost: payload.jobCost as Number,
jobDateTime: payload.jobDateTime,
jobLocation: payload.jobLocation,
jobName: payload.jobName,
jobOwner: payload.jobOwner,
jobStatus: payload.jobStatus,
jobType: payload.jobType
} as Object {
class : "com.drools.example.Job"
}]]></ee:set-payload>
            </ee:message>
        </ee:transform>
        <set-variable value="#[payload as Object {  class : &quot;com.drools.example.Job&quot; }]" doc:name="Set Variable" doc:id="88cce3e3-3373-4c8f-ace3-280467feb78b" variableName="flowJob" mimeType="application/java" />
        <java:invoke-static doc:name="Invoke static" doc:id="b7ddcbd9-8d9a-43fb-aa72-bf0205dc1f65" class="com.drools.example.RulesEngine" method="executeJobRules(Job)">
            <java:args><![CDATA[#[{
arg0 : vars.flowJob
}]]]></java:args>
        </java:invoke-static>
        <ee:transform doc:name="Transform Message" doc:id="e271d4aa-4f8b-4ab1-a65a-0e07060c7892">
            <ee:message>
                <ee:set-payload><![CDATA[%dw 2.0
output application/json
---
{
jobName: vars.flowJob.jobName as String,
jobType: vars.flowJob.jobType as String,
jobLocation: vars.flowJob.jobLocation as String,
jobDateTime: vars.flowJob.jobDateTime as String,
jobCost: vars.flowJob.jobCost as String,
jobOwner: vars.flowJob.jobOwner as String,
jobStatus: vars.flowJob.jobStatus as String
}]]></ee:set-payload>
            </ee:message>
        </ee:transform>
    </flow>
</mule>

Note the invoke static method component of the Java module; it takes arguments as argx (arg0, arg1 etc.) 

Mule Flow

Image title

Testing:

URL: http://localhost:8081/drools-example

Input:

{
"jobName": "My Test Job",
"jobType": "Food Supply",
"jobLocation": "Kolkata India",
"jobDateTime": "24-12-18 14:00:00 PM",
"jobCost": "100.00",
"jobOwner": "To Be Assigned",
"jobStatus": "New"
}

Output: 

{
"jobName": "My Test Job",
"jobType": "Food Supply",
"jobLocation": "Kolkata India",
"jobDateTime": "24-12-18 14:00:00 PM",
"jobCost": "100.00",
"jobOwner": "Farmer's Food Supply Pvt Ltd.",
"jobStatus": "Assigned"
}

The Owner and Status of the Job have been updated as per the Drools rule definition. 

Conclusion

Drools is a collection of tools that allows us to separate and reason over logic and data found within business processes. The two important keywords we need to notice are Logic and Data. The logic can be implemented in the Drools rules definitions while the data can be passed into the rules from the Mule Flow.

To know more about Drools, please go through the Drools documentation here.

Please share your comments or feedback. Cheers!

Drools

Opinions expressed by DZone contributors are their own.

Related

  • How To Handle 100k Rows Decision Table in Drools (Part 3)
  • How To Handle 100k Rows Decision Table in Drools (Part 2)
  • Using Maven and Without Drools Eclipse Plugin

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: