Stephen Masters logo
  1. Home
  2. Blogs
  3. A Minimal Spring Boot Drools Web Service

A Minimal Spring Boot Drools Web Service

Posted on February 6, 2015 • 4 min read • 776 words
Share via

A little while back, I knocked up Qzr to demonstrate using Spring Boot with the Drools rules engine. However, I also wanted to play around with a few more technologies (AngularJS and Spring HATEOAS), so it’s a bit large for just demonstrating exposing Drools rules as an HTTP web service.

A few folks found it difficult to pick out the essentials of running Drools in a Spring Boot application, so I thought I’d have a go at creating a simpler application, which does nothing more than that.

Hence, the Bus Pass Web Service

As might be guessed from the project name, for the rules, I took my cues from the Drools Bus Pass example in the Drools project. I cut the rules down a little bit and reduced the code by replacing some of the Java fact classes with DRL declared types. I prefer this for facts which are only referenced from within the DRL.

Assuming that you have a reasonably recent install of Maven and the JDK (I have tested with 8), you should be able to do the following from the command line.

Build the application:

mvn clean package

Run the application:

java -jar target/buspass-ws-1.0.0-SNAPSHOT.jar

Then send a request to the API using curl or your favourite web browser. The rules state that if you request a bus pass for a person with age less than 16, you should see a ChildBusPass. For someone 16 or over, you should see an AdultBusPass.

For example, opening http://127.0.0.1:8080/buspass?name=Steve&age=15 gives me:

{"person":{"name":"Steve","age":15},"busPassType":"ChildBusPass"}

… and opening http://127.0.0.1:8080/buspass?name=Steve&age=16 gives me:

{"person":{"name":"Steve","age":16},"busPassType":"AdultBusPass"}

The full source code is on GitHub, so that you can browse through it. I don’t intend to change it much now, other than to add a few comments. The following are some of the key features, that you should know about.

First of all, it’s a Maven project, so I hope you’re familiar with that. The following XML is extracted from the pom.xml. Note that to enable Spring Boot, I have imported the Spring platform Bill of Materials and defined spring-boot-starter-web as a dependency. By including the spring-boot-maven-plugin, the Maven build will generate an executable jar, which will run up an embedded Tomcat instance to host the web application. You don’t need to have a web server installed on your machine, to run this application.

The Drools functionality is enabled by defining kie-ci as a dependency. This brings in the Drools API, and sets up classpath scanning so that it can find the rules in your application.

<!-- Transitively bring in the Spring IO Platform Bill-of-Materials `pom.xml` -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>1.1.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- ... -->
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-ci</artifactId>
<version>${kie.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
view raw spring-platform-bom.xml hosted with ❤ by GitHub

Having kie-ci in the project means that Drools will scan for rules based on certain conventions. It will look for a file called kmodule.xml in src/main/resources/META-INF/.

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<kbase name="BusPassKbase" packages="com.sctrcd.buspassws.rules">
<ksession name="BusPassSession" />
</kbase>
</kmodule>
view raw kmodule.xml hosted with ❤ by GitHub

The kmodule.xml defines the package where the rules for your knowledge base can be found. Based on the definition above, it will scan for rules (.drl files and others) in src/main/resources/com/sctrcd/buspassws/rules. I won’t explain the rules. Feel free to go take a look at them yourself. As can be seen in the XML, this also defines a knowledge session called BusPassSession. This means that you can now start a knowledge session like so:

KieContainer kieContainer = KieServices.Factory.get().getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("BusPassSession");
view raw gistfile1.java hosted with ❤ by GitHub

The heart of a Spring Boot application is its main class, which causes your application to be bootstrapped.

@SpringBootApplication
public class BusPassApp {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(BusPassApp.class, args);
}
@Bean
public KieContainer kieContainer() {
return KieServices.Factory.get().getKieClasspathContainer();
}
}
view raw BusPassApp.java hosted with ❤ by GitHub

This is standard Spring Boot stuff, but the addition we have here is to define a bean, which references the Drools KieClasspathContainer. In doing this, we have a reference to the container, which we can inject into our application beans. This is exactly what we do with the BusPassService.

@Service
public class BusPassService {
private final KieContainer kieContainer;
@Autowired
public BusPassService(KieContainer kieContainer) {
log.info("Initialising a new bus pass session.");
this.kieContainer = kieContainer;
}
/**
* Create a new session, insert a person's details and fire rules to
* determine what kind of bus pass is to be issued.
*/
public BusPass getBusPass(Person person) {
KieSession kieSession = kieContainer.newKieSession("BusPassSession");
kieSession.insert(person);
kieSession.fireAllRules();
BusPass busPass = findBusPass(kieSession);
kieSession.dispose();
return busPass;
}
// ...
}
view raw BusPassService.java hosted with ❤ by GitHub

As you can see, we are now exposing Drools functionality in our Spring Boot application. A service bean is injected with a reference to the Drools KieContainer. Subsequently, whenever a call is made to the getBusPass method, we instantiate a new KieSession (note the session name, which matches that defined in kmodule.xml), insert details about a person, fire rules, and see what kind of bus pass they should be given.

Finally, we need a controller.

@RestController
public class BusPassController {
private static Logger log = LoggerFactory.getLogger(BusPassController.class);
private final BusPassService busPassService;
@Autowired
public BusPassController(BusPassService busPassService) {
this.busPassService = busPassService;
}
@RequestMapping(value = "/buspass",
method = RequestMethod.GET, produces = "application/json")
public BusPass getBusPass(
@RequestParam(required = true) String name,
@RequestParam(required = true) int age) {
Person person = new Person(name, age);
log.debug("Bus pass request received for: " + person);
BusPass busPass = busPassService.getBusPass(person);
return busPass;
}
}
view raw BusPassController.java hosted with ❤ by GitHub

By annotating the controller class as @RestController, Spring will set it up as a bean and ensure that anything returned from a method is marshalled. As the getBusPass method has been defined as producing application/json, Spring will automatically use Jackson to marshal the response to JSON.

The @RequestMapping annotation indicates that you can reach the URL at /buspass. For instance, if you run up the application as it is, this means that you can send GET requests to http://127.0.0.1:8080/buspass. The @RequestParam annotations indicate that you need to send querystring arguments, providing values for “name” and “age”.

All that remains is to try it out. Please do let me know if you spot anything that you think could be improved.

 Multiple Databases With Spring Boot and Spring Data Jpa
A Web Service Powered by Spring and Drools 
Copyright © 2024 Stephen Masters All rights reserved. Powered by Hinode.
Stephen Masters
Link copied to clipboard
Stephen Masters
Code copied to clipboard