Using JBoss Drools to Implement a E-commerce Promotion Rule Engine – Part I

In this and the following articles, I will demonstrate how to implement a basic promotion engine using JBoss Drools framework. The objective here is not to provide a complete implementation but to show how Drools and business rule engine in general can be used to solve common ecommerce problems. Also to demonstrate some of the features provided by Drools Rule Engine.


From a software system prospective, a business rule engine allows business to define their business rules declaratively. The system can then, via its inference engine, to match the rules defined with the “facts” it observes at run time. Some of the major advantages of using a rule engine are:

  1. Declarative Programming
  2. Separation of Data and Logic
  3. Centralization of Knowledge
  4. Explanation of outcomes or actions

A more comprehensive list of advantages and more detailed explanation can be found here.

E-commerce Promotion Rules

I define the following business rules for a ecommerce or brick-and-mortar store to decide when and what promotional discount(s) should  be applied for an order. They are fictitious rules that should be commonly understandable.

  1. Large order discount
    1. 5% discount for order total over $1000 and less than $2000
    2. 10% discount for order total over $2000
  2. Clearance products – 10% off from a list of defined products
  3. Time based sales – 10% off from a list of defined products within a certain date range, e.g. Christmas sales between 1/12 to 31/12.
  4. Special Tuesday – everything 5% off on Tuesday

Domain Objects (Facts)

The first step to do is to define the business domain objects which will act as the facts to be processed by the rule engine. Our domain consists of the following classes:

  • Order – represents a single sales order
  • OrderLine – represents an item in an order
  • ClearanceProductList – represents a list of discounted products
  • TimeBasedSales – represented a list of products to apply discount to when date of order falls within the defined date range.

A discount can be applied to each item (i.e. OrderLine) of an order. On top of that, an order discount can then be applied on the order total.

I include the code snippets below:

public class Order {

private double orderDiscountAmount; // order discount amount

private List<OrderLine> lines = new ArrayList<OrderLine>();

// calculate discounted total amount of all the items in this order
public double getLineTotal() {
double lineTotal = 0;
for (OrderLine line : lines) {
lineTotal += line.getLineAmount();
return lineTotal;

// getter and setter methods below omitted here

public class OrderLine {

private String sku;
private int qty; // quantity bought
private double unitPrice; // price for each unit
private double lineDiscountAmount; // discount applied to this item

public double getLineAmount() {
return unitPrice * qty – lineDiscountAmount;

// getter and setter methods below omitted here


public class ClearanceProductList {

private List<String> skus = new ArrayList<String>();

// getter and setter methods below omitted here


public class TimeBasedSales {

private Date fromDate;
private Date toDate;
private List<String> products = new ArrayList<String>();

// getter and setter methods below omitted here

JUnit Test class

Include below is the unit test class snippets that I will use to run various facts (i.e. orders) against the rule engine. It also demonstrates how to set up Drools.

public class BlogRuleTest {

private Logger logger = Logger.getLogger(getClass());
private StatefulKnowledgeSession ksession;

public void setUp() {
KnowledgeBuilder knowledgeBuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
knowledgeBuilder.add (

ResourceFactory.newClassPathResource(“com/drools/blog/blog.drl”,  getClass()),                                                  ResourceType.DRL);

// verify rule file has no errors

if (knowledgeBuilder.hasErrors()) {
Iterator<KnowledgeBuilderError> iterator = knowledgeBuilder.getErrors().iterator();
while (iterator.hasNext()) {
fail(“Rule file has error”);

KnowledgeSessionConfiguration config =                                                              KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
config.setOption( ClockTypeOption.get(“pseudo”) );

KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();

ksession = kbase.newStatefulKnowledgeSession(config, null);

// Default to a non-Tuesday


public void after() {


  1. The rule file blog.drl is expected to be in folder com/drools/blog/blog.drl under the classpath, e.g. under /src/main/resources.
  2. I create stateful knowledge session above. This is not really required for the task at hand. See Drools documentation for an explanation of the difference between stateless and stateful knowledge sessions.
  3. SessionPseudoClock is used here to allow us to test time based rule. More on this later when we define the “Special Tuesday” rule
  4. The session is disposed after each unit test is run in the after() method.

On to Drools Rules

OK. We are ready to implement the Drools rules. Let do this in the next post.