ServiceMix Drools
The ServiceMix Drools component provides JBI integration to the Drools Rules Engine.
It can be used to deploy a rules set that will implement a router or an actual service.
A router will mostly act as a transparent proxy between the consumer and the target service provider mad will mostly be implemented by the jbi.route(uri)
method below. This method creates a new exchange identical to the one received by the component and will send it to the specified destination. You can also send back a Fault
if needed. A router can also be implemented by using directly the JBI Apis (available with the jbi
helper) by using the provided client.
This component can also be used to implement a real service, as shown in the Fibonnacci example. The service can act as a consumer and create / send exchanges by using the client provided by the jbi
helper.
Maven Archetype
You can create a Drools Service Unit using the servicemix-drools-service-unit Maven archetype:
mvn archetype:create \ -DarchetypeGroupId=org.apache.servicemix.tooling \ -DarchetypeArtifactId=servicemix-drools-service-unit \ -DarchetypeVersion=2010.01 \ -DgroupId=your.group.id \ -DartifactId=your.artifact.id \ -Dversion=your-version
Once you've customized the service unit, simply install the SU:
mvn install
Remember that to be deployable in ServiceMix, the ServiceUnit has to be embedded in a Service Assembly: only the Service Assembly zip file can be deployed in ServiceMix.
To add your SU in a SA, you need to define it in the dependency sets:
<dependency> <groupId>your.group.id</groupId> <artifactId>your.artifact.id</artifactId> <version>your-version</version> </dependency>
Endpoint Configuration
<beans xmlns:drools="http://servicemix.apache.org/drools/1.0" xmlns:replaceMe="http://servicemix.apache.org/replaceMe"> <drools:endpoint service="replaceMe:serviceName" endpoint="drools" ruleBaseResource="classpath:router.drl" namespaceContext="#nsContext"/> <drools:namespace-context id="nsContext"> <drools:namespaces> <drools:namespace prefix="bar">http://servicemix.apache.org/bar</drools:namespace> </drools:namespaces> </drools:namespace-context> </beans>
Endpoint Attributes
Name |
Type |
Description |
Required |
|
---|---|---|---|---|
endpoint |
String |
JBI Endpoint Name |
no (will be auto-generated if not specified |
|
service |
QName |
JBI Server Name |
no (will be auto-generated if not specified) |
|
ruleBaseResource |
URL |
DRL File |
The path to the DRL file |
yes |
namespaceContext |
namespace-context bean |
Drool Namespace Context |
no |
JBI Helper
DRL files deployed to the servicemix-drools
engine have access to a JbiHelper
class in a global variable named jbi
which provides the following attributes and methods:
Attribute |
Description |
---|---|
jbi.getEndpoint() |
The |
jbi.getContent() |
A |
jbi.getChannel() |
A |
jbi.getClient() |
A |
jbi.getExchange() |
The |
jbi.getLogger() |
A |
Methods |
Description |
---|---|
jbi.route(uri) |
Route the current exchange to the given uri |
jbi.fault(content) |
Returns a fault using the given string as the xml fault |
jbi.answer(content) |
Sends an Out message using the given string as the xml content |
The received exchange is added as a fact to the working memory.
Note that, due to Drools limited support for non simple java beans accessors, the JBI MessageExchange and NormalizedMessage are wrapped with simple beans.
Injecting additional beans in the rules
The JbiHelper is injected by the component itself so that you can access the current exchange and handle it. However, there are cases where you need to add your own beans and inject them in the rules definition. Starting from ServiceMix 3.2, this is now possible using the following syntax:
<drools:endpoint service="test:service" endpoint="endpoint" ruleBaseResource="classpath:router.drl" globals="#globals" /> <util:map id="globals"> <entry key="helper" value-ref="helper" /> </util:map> <bean id="helper" class="org.example.Helper" />
In the rules definition, just add:
global org.example.Helper helper;
Don't forget to add the namespace for the util element.
xmlns:util="http://www.springframework.org/schema/util"
Then you can use it from your rules ...
Router
<drools:endpoint service="test:service" endpoint="endpoint" ruleBaseResource="classpath:router.drl" />
package org.apache.servicemix.drools import org.apache.servicemix.drools.model.Exchange; global org.apache.servicemix.drools.model.JbiHelper jbi; rule "Unspecified id" when me : Exchange( status == Exchange.ACTIVE, in : in != null ) eval( in.xpath("/test/@id <= 0") ) then jbi.fault( "<fault>Id must be > 0</fault>" ); end rule "Route to target1" when me : Exchange( status == Exchange.ACTIVE, in : in != null ) eval( in.xpath("/test/@id = 1") ) then jbi.route( "service::target1" ); end rule "Route to target2" when me : Exchange( status == Exchange.ACTIVE, in : in != null ) eval( in.xpath("/test/@id = 2") ) then jbi.route( "service::target2" ); end rule "Route to target3" when me : Exchange( status == Exchange.ACTIVE, in : in != null ) eval( in.getProperty("prop") != null ) then jbi.route( "service::target3" ); end