Event processing in camel-drools

In a previous post about camel-drools I’ve introduced camel-drools component and implemented some simple task-oriented process using rules inside Camel route. Today I’ll show how to extend this example by adding event processing.

So how to describe an event? Each event occur at some time and lasts for some duration, events happen in some particular order. We have then a ‘cloud of events’ from which we want to identify those, which form some interesting correlations. And here the usage of Drools becomes reasonable – we don’t have to react for each event, just describe set of rules and consequences for those interesting correlations. Drools engine will find them and fire matching rules.

Suppose our system has to monitor execution of task assigned to users. After a task is created, user has 10 days to complete it. When he doesn’t – an e-mail remainder should be sent.

Rule definition may look like this:

import org.apache.camel.component.drools.stateful.model.*
global org.apache.camel.component.drools.CamelDroolsHelper helper

declare TaskCreated
    @role( event )
    @expires( 365d )
end

declare TaskCompleted
    @role( event )
    @expires( 365d )
end

rule "Task not completed after 10 days"
    when
       $t : TaskCreated()
       not(TaskCompleted(name==$t.name, this after [-*, 10d] $t))
    then
       helper.send("direct:escalation", $t.getName());
end 

As you can see, there are two types of events: TaskCreated – when system assigns task to users, and TaskCompleted – when user finishes task. We correlate those two by the ‘name’ property. Firstly, we need to declare our model classes as events by adding @role(event) and @expires annotations. Then we describe rule: ‘when there are is no TaskCompleted event after 10 days of TaskCreated event, send task name to direct:escalation route’. Again, this could be example of declarative programming – we don’t event have to specify actual names of tasks, just correlate TaskCreated with TaskCompleted events by name.

In this example, I used ‘after’ temporal operator. For description of others – see Drools Fusion documentation.

And finally, here is JUnit test code snippet:

public class TaskEventsTest extends GenericTest {

    DefaultCamelContext ctx;

    @Test
    public void testCompleted() throws Exception {
        insertAdvanceDays(new TaskCreated("Task1"), 4);
        assertContains(0);
        insertAdvanceDays(new TaskCompleted("Task1"), 4);
        advanceDays(5);
        assertContains(0);
    }

    @Test
    public void testNotCompleted() throws Exception {
        insertAdvanceDays(new TaskCreated("Task1"), 5);
        assertContains(0);
        advanceDays(5);
        assertContains("Task1");
    }

    @Test
    public void testOneNotCompleted() throws Exception {
        ksession.insert(new TaskCreated("Task1"));
        insertAdvanceDays(new TaskCreated("Task2"), 5);
        assertContains(0);
        insertAdvanceDays(new TaskCompleted("Task1"), 4);
        assertContains(0);
        advanceDays(1);
        assertContains("Task2");
        advanceDays(10);
        assertContains("Task2");
    }

    @Override
    protected void setUpResources(KnowledgeBuilder kbuilder) throws Exception {
        kbuilder.add(new ReaderResource(new StringReader(
                IOUtils.toString(getClass()
                 .getResourceAsStream("/stateful/task-event.drl")))), 
                 ResourceType.DRL);
    }

    @Override
    public void setUpInternal() throws Exception {
        this.ctx = new DefaultCamelContext();
        CamelDroolsHelper helper = new CamelDroolsHelper(ctx, 
                new DefaultExchange(ctx)) {
            public Object send(String uri, Object body) {
                sentStuff.add(body.toString());
                return null;
            };
        };
        ksession.setGlobal("helper", helper);
    }
}
  • You can find source code for this example here.

 

Reference: Event processing in camel-drools from our JCG partner Piotr Jagielski at the Full stack JVM development… blog.
Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

Leave a Reply


five + 6 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close