Friday, January 16, 2009

JBoss Drools: Reasoning on QuickFIX-J data model

I just tried to make a simple JBoss Drools example which could probably handle QuickFIX-J messages. So I created the simplest rule flow, including one RuleSet node, mapped onto a ruleflow-group in a DRL file.

Simple Drools Flow Example
same in textual form:

<?xml version="1.0" encoding="UTF-8"?>
<process xmlns=""
xs:schemaLocation=" drools-processes-5.0.xsd"
type="RuleFlow" name="oms" id="my.oms" package-name="my.oms" >


<start id="1" name="Start" x="16" y="16" width="80" height="40" />
<actionNode id="2" name="Action" x="128" y="16" width="80" height="40" >
<action type="expression" dialect="java" >System.out.println("Action Start");</action>
<ruleSet id="3" name="RuleSet" x="240" y="16" width="80" height="40" ruleFlowGroup="my-oms" />
<actionNode id="4" name="Action" x="352" y="16" width="80" height="40" >
<action type="expression" dialect="java" >System.out.println("Action End");</action>
<end id="5" name="End" x="464" y="16" width="80" height="40" />

<connection from="1" to="2" />
<connection from="2" to="3" />
<connection from="3" to="4" />
<connection from="4" to="5" />


Next describe to rule in a DRL file:

package my.oms

import quickfix.fix44.NewOrderSingle
import quickfix.field.MinQty

rule "reset minqty"
dialect "mvel"
ruleflow-group "my-oms"
$order : NewOrderSingle($qty : minQty)
MinQty(value == 1.0 || value > 100.0) from $qty
System.out.println("reset order: " + $order);
$order.set(new MinQty(20));

What looks a little strange to me is the when part:

$order : NewOrderSingle($qty : minQty)
MinQty(value == 1.0 || value > 100.0) from $qty

I spent just quite a few minutes to figure out why my first version of the rule didn't work as I expected. It seemed to me that it would be more natural to make it just in one line, something like this:

NewOrderSingle(MinQty(value == 1.0 || value > 100.0))

With a Java code from the Drools examples (which may also are generated when you create a Drools Project with the Drools eclipse plug-in), I run the example and it works fine.

package my.oms;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.*;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.StatefulKnowledgeSession;

import quickfix.field.MinQty;
import quickfix.fix44.NewOrderSingle;

public class MyOms {

public static final void main(String[] args) {
try {
// load up the knowledge base
KnowledgeBase kbase = readKnowledgeBase();
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
// go !

NewOrderSingle order = new NewOrderSingle();
order.set(new MinQty(1.0));

NewOrderSingle order1 = new NewOrderSingle();
order1.set(new MinQty(111.0));

NewOrderSingle order2 = new NewOrderSingle();
order2.set(new MinQty(222.0));


} catch (Throwable t) {

private static KnowledgeBase readKnowledgeBase() throws Exception {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("oms.drl"), ResourceType.DRL);
kbuilder.add(ResourceFactory.newClassPathResource("oms.rf"), ResourceType.DRF);
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
for (KnowledgeBuilderError error: errors) {
throw new IllegalArgumentException("Could not parse knowledge.");
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
return kbase;


This example just shows that with Drools one may handle even quite complex data model, such as QuickFIX-J's one. Next, it would have real value if I'm able to make do the same via Guvnor.

No comments: