Monday, December 28, 2009

An update on BPMN 2.0

A few months ago we announced that we would be supporting the Business Process Modeling Notation (BPMN) 2.0 specification as the underlying XML format for our business processes. This blog will give you an update on the work that has been performed so far.

Those that know the BPMN 2.0 specification know that it defines a rather extensive set of constructs that can be used to model business processes, both how they should be visualized and represented using XML. The Drools team has decided, after carefull evaluation of the BPMN 2.0 draft, that using this standardized (yet extensible) XML format could only benefit our users (compared to our proprietary XML format), so we started creating a parser that could read in BPMN 2.0 XML, translate it into our internal process model and execute it. Note that our BPMN 2.0 engine is nothing new! It's simply a different parser for our existing Drools Flow process model (which has proven to be quite powerful already, since we did not have to add new features to the Drools Flow engine yet).

Anyway, these are the BPMN 2.0 constructs that are current included:

  • Activities
    • Script Task (Java or MVEL expression language)
    • Task
    • Service Task
    • User Task
    • Business Rule Task
    • Manual Task
    • Send Task
    • Receive Task
    • Reusable Sub-Process (Call Activity)
    • Embedded Sub-Process
  • Events
    • Start Event (None, Conditional, Signal)
    • End Event (None, Terminate, Error, Escalation, Signal, Message)
    • Intermediate Catch Event (Signal, Timer, Conditional)
    • Intermediate Throw Event (None, Signal, Escalation)
    • Non-interrupting Boundary Event (Escalation, Timer)
    • Interrupting Boundary Event (Escalation, Error, Timer)
  • Gateways
    • Diverging
      • Exclusive (Java, MVEL or XPath expression language)
      • Inclusive (Java, MVEL or XPath expression language)
      • Parallel
    • Converging
      • Exclusive
      • Parallel

For those that might not be familiar with the BPMN2 specification, this means that

  • almost all activity types are currently supported, the ad-hoc sub-process is still under development and the transaction has not been implemented yet
  • most of the event types are supported as well, cancel and compensation are the missing ones, and the aggregation of different types as multiple or parallel multiple
  • events can be used in all the various situations where they can be used (i.e. as start, intermediate or end event, interrupting or non-interrupting boundary events, etc.) except event sub-processes which are not yet supported

There is still a list of issues to be resolved before we can claim full process execution compatibility with the BPMN2 specification, but the most used (and thus most important) process constructs are already supported. Thanks to our community support and contributions, we hope to complete this as soon as possible. The latest code and lots of examples can be found on our SVN repository.

But, more importantly, BPMN2 processes are integrated in the entire Drools tool chain. This means that the entire life cycle of a business process (from modeling, deployment and execution to monitoring and analysis) is supported. For those who want to have a more detailed understanding of all these different phases and how Drools Flow helps you in each of those, I have recently created some web pages that contain a detailed description of each of these phases and how Drools can help you in each of those, including a lot of screenshots and screencasts to give you a first impression.

So if you're looking for a BPMN 2.0 engine, this is what we can offer you:

  • extensive set of BPMN 2.0 constructs
  • tool chain that supports the entire life cycle of the process
  • integration and unification with business rules and complex event processing
  • domain-specific processes

Planning the traveling tournament problem

One of the older examples in Drools Planner is the Traveling Tournament Problem as defined by Trick et al. I haven't improved/optimized on it much in the last couple of years, but recently I made a diagram to explain the problem more clearly:

We need to schedule matches between N teams while respecting the following hard constraints:

  • Each team plays twice against every other team: once home and once away.

  • Each team has exactly 1 match on each playing day.

  • No team must have more than 3 consecutive home or 3 consecutive away matches.

  • No repeaters: no 2 consecutive matches of the same 2 opposing teams.

There's only one soft constraint:

  • Minimize the total distance traveled by all teams.

This might look like a really easy problem, but even for low N's (12 <= N <= 24) they haven't found (or at least proven) the optimal solution yet. Regularly better solutions are found for the larger N's.

Still, those N's are embarrassingly small compared to real-world planning problems such as examination timetabling (N >= 1000), shift rostering or bin packaging.

Tuesday, December 15, 2009

Screencasts on some FAQ

We regularly see the same questions pop up on the mailing list or on our irc channel. While we try to write documentation on how to do all these things, some things might be easier to explain using a quick example. I have recently created screencast for two such issues.

Debugging your Drools application in Eclipse

The Drools Eclipse plugin contains various debug views that allow you to do advanced debugging of your Drools application, showing the object in your session, the agenda, etc. Check out section 7.10 of the Drools Expert documentation. This screencast shows you how to get these debug views working for a simple Hello World rule. It also shows how to use breakpoints inside a rule.

Domain-specific nodes in Drools Flow

Drools Flow allows you to create your own domain-specific nodes. Such nodes have their own icon, properties and possibly even a custom editor. This screencast shows how you can create your custom work item node, use it in your process, and then register a handler to execute it at runtime.

Enjoy!

Thursday, December 10, 2009

Cisco ANA - "Drools Inside" :)

The Cisco ANA PDF is online, showing their Drools integration for their Advanced Network Abstraction (ANA) product. You can download the PDF here. So maybe Cisco products should have a new badge "Drools Inside" :)


click to enlarge


If anyone from Cisco reads my blog and wants to chat about Drools, feel free to contact me mproctor at gmail d0t com.

Wednesday, December 09, 2009

Calendar support with Drools

Last week I blogged about 'cron' and 'int' (interval) based timer support:
"Cron and Interval based timers for rule firing and re-firing"

This week I've added Calendaring support. Calendaring allows you to provide a Set of Calendar implementations that specify allowed and disallowed time segments. With this you could create a "week day" Calendar which would specify Monday to Friday as the included time segments, leaving Saturday and Sunday as not included. I can then specify that Calendar in a rule. Monday to Friday if the rule activates it will fire, over the weekend if the rule activates it will ignored.

The Calendar api is modelled on Quartz :
public interface Calendar {    
boolean isTimeIncluded(long timestamp);
}
Quartz provides several good Calendar implementations, so it makes sense to leverage those, for this we we provide an adapter helper method:
Calendar QuartzHelper.quartzCalendarAdapter(org.quartz.Calendar quartzCal)
Calendars are registered with the StatefulKnowledgeSession:
ksession.getCalendars().set( "week day", weekDayCal );
Which means they can now be used in rules. They can be used in conjunction with normal rules and rules including timers.
rule "weekdays are high priority"
calendars "weekday"
when
Alarm()
then
send( "priority high - we have an alarm );
end

rule "weekend are low priority"
calendars "weekend"
when
Alarm()
then
send( "priority low - we have an alarm );
end
Now I can already imagine some of you are thinking, well that's kinda cool and it's nice the semantics of Calendars and a Calendaring api supported out of the box. But I could achieve much the same thing by asserting Calendars as facts, placing the Calendar constraint as the last pattern and it'll block activations that are not included in the required time. While this is true, it would not work with Timer based rules. As we can now do this:
rule "weekdays are high priority"
calendars "weekday"
timer (int:0 1h)
when
Alarm()
then
send( "priority high - we have an alarm );
end

rule "weekend are low priority"
calendars "weekend"
timer (int:0 4h)
when
Alarm()
then
send( "priority low - we have an alarm );
end
The above rules use an interval based timer, a cron timer is also supported. On weekdays while there is an alarm it will trigger the rule initially straight away (delay of 0) and then every hour. At the weekends it will trigger the rule every four hours. If we had inserted the Calendar as a fact, we'd have to find some additional way to re-trigger the evaluation. Calendars themselves do not have mutable state, instead it's more like a function that tells you if the specified date is included or not. While this is not impossible to solve, it's getting messy very quickly. You'll need additional trigger facts, that will force Calendar evaluation at required points in time, that are managed by your own scheduler. This way it's efficient (no network propagation), clear syntax and intent and works out of the box. I should add that it'll work out of the box with our simulation api, thanks to our unified clock implementation.

So what we have now is conditional rule based timers and calendaring. The cool thing here is we can use this for Drools Flow, using it to start processes or trigger wait states. While process centric implementations do have timer and calendaring support, the conditional rule integration adds a whole new level of power to this.

Monday, December 07, 2009

Drools Planner (AKA Drools Solver) Devoxx presentation movie

Thanks to Parleys Beta, I am proud to present:
Examination timetabling with Drools Planner - the movie
Actually, it's not as much a movie as it is a Devoxx 2009 presentation.

Click here to watch it full screen at beta.parleys.com

I made a few updates since the live presentation at Devoxx, such as the rename from Drools Solver to Drools Planner.

Just before posting this blog, David alerted me of a small (but embarrassing) calculation mistake in one of the slides. Can you find it?

Thursday, December 03, 2009

Some Tohu videos

Tohu is the project which ads Q&A and "smart form" intelligence on top of drools (and provides a very nice CSS stylable and embeddable jquery based ajax front end as well). (see project page here).

Some interesting demo videos made by solnet here explaining how it works:
Example 1

(In case you are wondering, the accent you can here is New Zealand - or Middle Earth as I prefer to refer to it - perhaps only NZ and Australian citizens can tell the difference between !).

Enjoy !



Wednesday, December 02, 2009

Drools Spring improvements

Bauna (Pablo Nussembaum) and I have been working on improving the Drools Spring integration that Mark committed some weeks ago. We have changed the approach a little bit to make it more Spring friendly and to use the ServiceManager(SM) from Drools-vsm. in that way, you will be able to create local or remote instances of kbases and ksessions transparently depending on the SM implementation configured.

So let's dive directly into the new bean.xml:

<bean id="sm1" class="org.drools.vsm.local.ServiceManagerLocalClient" />

<drools:kbase id="kbase1" serviceManager="sm1">
<drools:resource type="DRL" source="classpath:org/drools/container/spring/testSpring.drl"/>
<drools:resource source="classpath:org/drools/container/spring/IntegrationExampleTest.xls" type="DTABLE">
<drools:decisiontable-conf input-type="XLS" worksheet-name="Tables_2" />
</drools:resource>
</drools:kbase>

<drools:ksession id="ksession1" type="stateless" name="stateless1" kbase="kbase1" serviceManager="sm1"/>
<drools:ksession id="ksession2" type="stateful" kbase="kbase1" serviceManager="sm1"/>

As we can see the first change is that instead of registering sessions inside an SM, the SM is injected into kbases and ksessions.
in the case of defining a kbase you need to provide an SM from which it will be created. But now we've made serviceManager optional, when an SM isn't provided it'll create a ServiceManagerLocalClient internally.
Another change we've made is that ksessions are auto-registered into the SM when one is provided. You also have the option of providing a name if you don't want to use the bean id when registering it to an SM. As such the above example can be rewritten as:

<drools:kbase id="kbase1">
<drools:resource type="DRL" source="classpath:org/drools/container/spring/testSpring.drl"/>
<drools:resource source="classpath:org/drools/container/spring/IntegrationExampleTest.xls" type="DTABLE">
<drools:decisiontable-conf input-type="XLS" worksheet-name="Tables_2" />
</drools:resource>
</drools:kbase>

<drools:ksession id="ksession1" type="stateless" kbase="kbase1"/>
<drools:ksession id="ksession2" type="stateful" kbase="kbase1"/>

As a working demonstration we updated the camel pipeline example to make use of the changes we've made.

Enjoy!


Download the updated example project: Drools Camel Spring

Cron and Interval based timers for rule firing and re-firing

At ORF I did a presentation on ideas I'd like to do to improve our language. You can see that presentation here:
"Drools "Where do we go from here" - presented at ORF09"

In this presentation I discussed the idea of "cron" based rules. Drools has supported the "duration" attribute for a long time now. When a rule is activated it does not fire straight away, instead it is scheduled to fire based on the given duration. If the rule is still true on or after that duration lapses it fires, otherwise if it becomes false before the duration lapses it is cancelled and unscheduled.

The problem here is the duration is a single value and the rule fires just once. This is useful, but somewhat limited. Instead wouldn't it better if we could support various time based semantics for rule firing and re-firing (if the rule is still true).

While not exposed to the user I created pluggable Time semantics. This introduces the Timer interface:
interface Timer {
/**
* Creates a Trigger for this Timer, based on the provided current timestamp.
*/
Trigger createTrigger(long timestamp);
}
The Trigger interface already existed as part of our unified clock and scheduling framework in Drools. Trigger tells the scheduler the next date to trigger the current job on. If we have multiple Timer semantics, not just duration, each Timer must be responsible for providing it's own Trigger to handle the execution of those semantics.

The 'duration' keyword has now been renamed to 'timer', although backwards compatability has been kept. We now support two different timers 'cron' and 'interval'. The 'timer' keyword takes a colon delimited prefix, using 'cron:' and 'int:' respectively. If no protocol is given, it assumes 'int'.

We use the standard cron syntax (thank you quartz), with added support for seconds. And interval has two parameters and obeys the JDK Timer semantics of delay and period. Where delay is the initial delay and period is the period of time between each iteration.

So now we can do the following which will send an SMS to a give mobile number every 0, 15, 30 and 45 minutes past each hour, while the alarm remains true:
rule "Send SMS every 15 minutes"
timer (cron:* 0/15 * * * ?)
when
$a : Alarm( on == true )
then
exitPoint[ "sms" ].insert( new Sms( $a.mobileNumber, "The alarm is still on" );
end