Drools Content Based Routing with Camel (John Ellis)
by Mark Proctor
http://blog.athico.com/2011/01/drools-content-based-routing-with-camel.html
Drools Content Based Routing with Camel (John Ellis)
<http://blog.athico.com/2011/01/drools-content-based-routing-with-camel.html>
John Ellis has done a nice writeup of his work on improving Drools to
work with Camel for CBR. You'll need to use the latest version of Drools
from trunk, which can be found in the maven repository that's
5.2.0-SNAPSHOT,
https://repository.jboss.org/nexus/content/groups/public/org/drools/.
For bonus points I'd love to see a further Drools and Camel tutorial
around OSGi's EventAdmin, http://camel.apache.org/eventadmin.html <http://>.
One of Camel's greatest strengths is the explicit support for Enterprise
Integration Patterns <http://www.eaipatterns.com/toc.html>. Drools
itself is particularly well suited to work alongside Camel to implement
two commonly used integration patterns: the Content Based Router and the
Dynamic Router. Both patterns leverage the ability of a Drools Endpoint
to rapidly evaluate properties of a message, while the Dynamic Router
can also integrate the Drools Policy as a dynamic rule based on feedback
from a control channel.
The Camel routes required for message routing do not differ much from
the previous Drools Endpoint example. You may even be able to omit the
Drools Policy if you wish to inspect only the headers of messages being
routed instead of interrogating the body of each message. For example, a
DRL could be defined that takes action on inbound messages such as:
import org.apache.camel.Message;
rule "WriteOperations"
when
$message : Message(headers["OPERATION"] == "WRITE");
then
$message.setHeader("routingSlip", "activemq:queue:op.write");
end
rule "ReadOperations"
when
$message : Message(headers["OPERATION"] == "READ");
then
$message.setHeader("routingSlip", "activemq:queue:op.read");
end
Example 1: DRL for Routing Based on Message Headers
Here the custom header "OPERATION" is evaluated to see if it is set to
the value "WRITE" or "READ." Depending on the value of this header, a
routing slip is defined for the message. The Routing Slip is another
Enterprise Integration Pattern supported by Camel that may contain one
or more URIs. The message is then sequentially sent to each URI defined.
The Camel routing itself is simply defined as:
<route>
<from uri="activemq:queue:router"/>
<to uri="drools:brokerNode/cbrKSession?action=insertMessage"/>
<routingSlip uriDelimiter="#">
<header>routingSlip</header>
</routingSlip>
</route>
Example 2: Camel Routes for Content Based Routing
Here we explicitly inform Camel that routing slips are defined as values
within the "routingSlip" header and each URI is delimited by a #
character. The headers set within the DRL are then interpreted as each
message exits the Drools endpoint.
Content based routing with a Drools Endpoint offers several advantages
over Camel's default implementation. The DRL format itself allows
routing to be specified more succinctly than Sprint DSLs or Camel
RouteBuilders. Conditional operations are also evaluated more
efficiently within Drools and are thread-safe, allowing a high volume of
messages to be routed concurrently.
15 years, 5 months
Guvnor and dynamic classes...
by bob.breitling
Hello all,
We have a situation where we need the Guvnor to extend a classes getters and
setters dynamically using Reflection, so the list of fields in the
Constraints GUI will show many fields that are not part of the concrete
class.
Is there an API to modify the Guvnor in this way? or do we need to just get
the sources and start hacking? Is this something that could be done easily?
I already have the code to dynamically add the getters and setters to a
class on the fly. I just need to add it to the Guvnor.
Thanks in advance.
Bob
--
View this message in context: http://drools-java-rules-engine.46999.n3.nabble.com/Guvnor-and-dynamic-cl...
Sent from the Drools - User mailing list archive at Nabble.com.
15 years, 5 months
Integrating Guvnor with Oracle 11g
by ergh99
Has anyone tried this? I'm trying to configure Guvnor to store its
repository in an Oracle 11g database, but having no luck. Wanted to know if
anyone has had experience with this combination.
--
David Stern
Blaze & J2EE specialist
mobile: 904.874.2685
15 years, 5 months
Need help with Decision Table Conditions
by Jason Mihalick
I have a decision table with the conditions shown in the graphic below. When
Drools attempts to compile the spreadsheet I get the following errors:
nested exception is java.lang.RuntimeException: Unable to return Declaration
for identifier '$pgMeta' : [Rule name='Section Head Spacing_18']
Unable to create restriction '[VariableRestriction: == $pgMeta ]' for field
'pageMeta' in the rule 'Section Head Spacing_18' : [Rule name='Section Head
Spacing_18']
Unable to build expression for 'from' : [Error: Failed to compile: 2
compilation error(s):
- (1,7) unqualified type in strict mode for: $pgMeta
- (1,22) unable to resolve method using strict-mode:
java.lang.Object.getLineMetas()]
[Near : {... Unknown ....}]
^
[Line: 1, Column: 0] '$pgMeta.getLineMetas()' : [Rule name='Section Head
Spacing_18']
http://drools-java-rules-engine.46999.n3.nabble.com/file/n2195003/Picture...
The LHS of a hand-coded rule for this, is as follows:
when
$pageMeta : PageMeta()
$bodyLines : LineMeta( pageMeta == $pageMeta, lineType == LineType.BODY
)
from $pageMeta.getLineMetas()
$bodyLine : LineMeta( previousPageMetaComponent != null,
previousPageMetaComponent == previousLineMeta,
previousLineMeta.lineType ==
LineType.SECTION_HEAD,
verticalSpacingToPreviousPageMetaComponent <
5.9525 ) from $bodyLines
Can this rule be created in a Decision table or not? Your help is most
appreciated!
--
View this message in context: http://drools-java-rules-engine.46999.n3.nabble.com/Need-help-with-Decisi...
Sent from the Drools - User mailing list archive at Nabble.com.
15 years, 5 months
Grouping and Aggregation in Drools
by Manav
Hi,
I have a slightly tricky problem on my hand that i am trying to solve using
rules.
I am using version 5.1 of Drools.Appreciate if there are any suggestions /
pointers .
I have a customer who will have a shopping cart with various products. For
example
the shopping cart will be a list of products that belong to a certain
sub-category and
super category like
product-id= 'Noodles', sub-category='PackagedFood', super-category='FMCG-Food',
%value of total=3%
product-id= 'Cookies', sub-category='PackagedFood',super-category='FMCG-Food',
%value of total=6%
product-id= 'Pizza', sub-category='ReadyToEat',super-category='FMCG-Food',
%value of total=5%
product-id= 'Burgers', sub-category='ReadyToEat',super-category='FMCG-Food',
%value of total=7%
product-id= 'Shampoo', sub-category='Toiletaries',super-category='FMCG-NonFood',
%value of total=4%
product-id= 'Conditioner',
sub-category='Toiletaries',super-category='FMCG-NonFood', %value of total=8%
The customer will also have a suggested cart that serves as a reference at the
sub-category and supercategory level. The reference will tell what level of his
total purchase he can spend on the sub-category and super-category. The
reference will look something like
super-category='FMCG-Food', %value-suggested=20%
super-category='FMCG-NonFood', %value-suggested=15%
sub-category='PackagedFood',%value-suggested=10%
sub-category='ReadyToEat',%value-suggested=10%
sub-category='Toiletaries',%value-suggested=6%
Looking at this example the customer is going overboard in the FMCG-Food super
category as the suggested
limit is 20% and the actual grouped at the supsercategory is 21% . Also he is
crossing the limit at the
sub-category level for ReadyToEat (suggested is 10% vs actual is 12%) and
Toiletaries (suggested is 6% vs actual 12%)
My problem is how do i group the actual data at various supercategory level,
sum the %value and then compare it with the suggested in the when clause.
If they cross the limit i will then have some action taken in the then clause.
Similarly i will have to do the same at the sub-category level as well.
Regards,
Manav
15 years, 5 months
writing correct drool rule
by Odelya Holiday
Hi!
I am actually using jBPM5 but the rules are in drools.
I created the following DSL file:
[condition][]There is a new program request=$processInstance: WorkflowProcessInstance() AND $requestData: RequestData()
[consequence][]Select an officers for {requestData.genre} program=Collection<Officer> officers = Collection<Officer> officers.get(GenreType.{requestData.genre}))
[consequence][]Select an officer for {requestData.cost} program=
[consequence][]Initialize Process=$processInstance.setVariable("officers", officers);
Officer object looks like this:
Name
Mincost
Maxcost
So on the 1st consequence I get all the officers that their genre type is as in the request data
In the 2nd consequence I get all the officers that their mincost < requestData.cost and maxcost > requestData.cost
How can I write it in drools rule?
Thanks!
Odelya Holiday
15 years, 5 months
Why won't this work? (Conjunction + Disjunction over a set)
by OlliSee
Hello there and a happy new year to everyone reading :)
Why am I here again? Yep, got a problem. Don't know why it doesn't work. I'm
using the latest snapshot version.
So here it goes.
A simple rule with conjunction and disjunction but over a set of events.
when
$ldes : Set(size == 2) from collect(LoopDetectorEvent() over
window:length(2))
(or LoopDetectorEvent($t1 : transportation == "LKW", $id1 : eventID) from
$ldes
LoopDetectorEvent($t2 : transportation == "PKW", $id2 : eventID) from
$ldes)
LoopDetectorEvent($t3 : transportation == "BUS", $id3 : eventID) from
$ldes
So, what the rule says: fire when there's a BUS event plus either a LKW or
PKW event in the set.
But, instead I get a big exception. It's posted at the end.
Interestingly, it works if I don't use the Set, like this...
when
(or $e1 : LoopDetectorEvent($t1 : transportation == "PKW", $id1 : eventID)
over window:length(1)
$e2 : LoopDetectorEvent($t2 : transportation == "LKW", $id2 : eventID)
over window:length(1))
LoopDetectorEvent($t3 : transportation == "BUS", $id3 : eventID) over
window:length(1)
but that rule does not have the same meaning. So it's useless for me.
Besides, it DOES work with the set if I just cut the third event out (the
BUS event).
What is wrong here?
Thanks in advance.
Kind regards!
Oliver
Exception in thread "Thread-2" java.lang.ClassCastException:
org.drools.reteoo.InitialFactImpl cannot be cast to
trafficsys.domain.events.LoopDetectorEvent
at
org.drools.base.trafficsys.domain.events.LoopDetectorEvent446196$getTransportation.getValue(Unknown
Source)
at org.drools.base.ClassFieldReader.getValue(ClassFieldReader.java:91)
at
org.drools.base.evaluators.EqualityEvaluatorsDefinition$StringEqualEvaluator.evaluate(EqualityEvaluatorsDefinition.java:1961)
at org.drools.rule.LiteralRestriction.isAllowed(LiteralRestriction.java:92)
at org.drools.rule.LiteralConstraint.isAllowed(LiteralConstraint.java:109)
at
org.drools.reteoo.FromNode.checkConstraintsAndPropagate(FromNode.java:264)
at org.drools.reteoo.FromNode.assertLeftTuple(FromNode.java:138)
at
org.drools.reteoo.SingleLeftTupleSinkAdapter.doPropagateAssertLeftTuple(SingleLeftTupleSinkAdapter.java:189)
at
org.drools.reteoo.SingleLeftTupleSinkAdapter.propagateAssertLeftTuple(SingleLeftTupleSinkAdapter.java:64)
at
org.drools.reteoo.FromNode.checkConstraintsAndPropagate(FromNode.java:279)
at org.drools.reteoo.FromNode.assertLeftTuple(FromNode.java:138)
at
org.drools.reteoo.SingleLeftTupleSinkAdapter.doPropagateAssertLeftTuple(SingleLeftTupleSinkAdapter.java:189)
at
org.drools.reteoo.SingleLeftTupleSinkAdapter.propagateAssertLeftTuple(SingleLeftTupleSinkAdapter.java:64)
at
org.drools.reteoo.AccumulateNode.evaluateResultConstraints(AccumulateNode.java:662)
at org.drools.reteoo.AccumulateNode.assertObject(AccumulateNode.java:270)
at
org.drools.reteoo.CompositeObjectSinkAdapter.doPropagateAssertObject(CompositeObjectSinkAdapter.java:450)
at
org.drools.reteoo.CompositeObjectSinkAdapter.propagateAssertObject(CompositeObjectSinkAdapter.java:378)
at org.drools.reteoo.ObjectTypeNode.assertObject(ObjectTypeNode.java:190)
at org.drools.reteoo.EntryPointNode.assertObject(EntryPointNode.java:145)
at
org.drools.common.AbstractWorkingMemory.insert(AbstractWorkingMemory.java:1187)
at
org.drools.common.AbstractWorkingMemory.insert(AbstractWorkingMemory.java:1089)
at
org.drools.common.AbstractWorkingMemory.insert(AbstractWorkingMemory.java:893)
at
org.drools.impl.StatefulKnowledgeSessionImpl.insert(StatefulKnowledgeSessionImpl.java:238)
at trafficsys.SessionInterface.insertAndFire(SessionInterface.java:133)
--
View this message in context: http://drools-java-rules-engine.46999.n3.nabble.com/Why-won-t-this-work-C...
Sent from the Drools - User mailing list archive at Nabble.com.
15 years, 5 months
Guvnor - archival option
by Rob Fisher
I archived a rule, then deleted it within Administration\Archive (using
the "Delete selected asset" option). However, when trying to create a
rule with the same name, I receive the following message: "An asset with
that name already exists in the chosen package. Please use another
name". I do not see the rule under Archive any longer (since it was
deleted). It seems, however, to still be recognized within the
repository.
Anyone know how to solve this?
Thanks
Rob Fisher
15 years, 5 months