JBoss.orgCommunity Documentation
Camel provides a light weight bus framework for getting information into and out of Drools.
Drools introduces two elements to make easy integration.
It is possible to not specify the session in the drools endpoint uri, and instead "multiplex" based on an attribute or header. In this example the policy will check either the header field "DroolsLookup" for the named session to execute and if that isn't specified it'll check the "lookup" attribute on the incoming payload. It then attempts to "lookup" the session from the execution-node context and execute against it.
Example 1.2. Drools EndPoint configured with the CXFRS producer
<bean id="droolsPolicy" class="org.drools.camel.component.DroolsPolicy" />
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="cxfrs://bean://rsServer"/>
<policy ref="droolsPolicy">
<unmarshal ref="xstream" />
<to uri="drools:node1" />
<marshal ref="xstream" />
</policy>
</route>
Example 1.3. Java Code to execute against Route from a Spring and Camel Context
public class MyTest extends CamelSpringTestSupport { @Override protected AbstractXmlApplicationContext createApplicationContext() { return new ClassPathXmlApplicationContext("org/drools/camel/component/CxfRsSpring.xml"); } public void test1() throws Exception { String cmd = ""; cmd += "<batch-execution lookup=\"ksession1\">\n"; cmd += " <insert out-identifier=\"salaboy\">\n"; cmd += " <org.drools.pipeline.camel.Person>\n"; cmd += " <name>salaboy</name>\n"; cmd += " </org.drools.pipeline.camel.Person>\n"; cmd += " </insert>\n"; cmd += " <fire-all-rules/>\n"; cmd += "</batch-execution>\n"; Object object = this.context.createProducerTemplate().requestBody("direct://client", cmd); System.out.println( object ); }
The following urls show sample script examples for jaxb, xstream and json marshalling using:
http://fisheye.jboss.org/browse/JBossRules/trunk/drools-camel/src/test/resources/org/drools/camel/component/jaxb.mvt?r=HEAD
http://fisheye.jboss.org/browse/JBossRules/trunk/drools-camel/src/test/resources/org/drools/camel/component/jaxb.mvt?r=HEAD
http://fisheye.jboss.org/browse/JBossRules/trunk/drools-camel/src/test/resources/org/drools/camel/component/xstream.mvt?r=HEAD
In this section we will explain the drools namespace.
Execution nodes are a context to register ksessions and kbases against for lookup.
Example 2.1. resource definition example
<drools:resource source="classpath:org/drools/IntegrationExampleTest.xls"
type="DTABLE">
<drools:decisiontable-conf input-type="XLS" worksheet-name="Tables_2" />
</drools:resource>
advanced-process-rule-integration
enabled = true : false
multithread
enabled = true : false
max-threads = 1..n
mbeans
enabled = true : false
event-processing-mode
mode = STREAM : CLOUD
accumulate-functions
accumulate-function 0..n
name = String
ref = String
evaluators
evaluator 0..n
name = String
ref = String
assert-behavior
mode = IDENTITY : EQUALITY
Figure 2.1. Knowledge Base Configuration Options
Table 2.5.
Attribute | Description | Required |
---|---|---|
id | Bean's id is the name to be referenced from other beans. | Yes |
type | is the session stateful or stateless? | Yes |
name | No; defaults to id when omitted. | |
node | Execution-Node context to register the ksession with | no |
listeners | Specifies the reference to the event listeners group (see 'Defining a Group of listeners' section below). | no |
Example 2.3. ksession definition example
<drools:ksession id="ksession1" type="stateless"
name="stateless1" kbase="kbase1"/>
<drools:ksession id="ksession2" type="stateful" kbase="kbase1"/>
<drools:ksession id="ksession3" type="stateful" kbase="kbase2>
<drools:batch>
<drools:insert-object ref="person" />
<drools:set-global identifier="list1">
<bean class="java.util.ArrayList" />
</drools:set-global>
<drools:startProcess process-id="start fire">
</drools:batch>
<drools:configurations>
<drools:keep-reference enabled="false" />
<drools:clock-type type="PSEUDO" />
</drools:configurations>
</drools:ksession>
keep-reference
enabled = true : false
clock-type
type = REALTIME : PSEUDO
jpa-persistence
transaction-manager
ref = String
entity-manager-factory
ref = String
Figure 2.2. Knowledge Session Configuration Options
insert-object
ref = String (optional)
Anonymous bean
set-global
identifier = String (required)
reg = String (optiona)
Anonymous bean
fire-all-rules
max : n
fire-until-halt
start-process
parameter
identifier = String (required)
ref = String (optional)
Anonymous bean
signal-event
ref = String (optional)
event-type = String (required)
process-instance-id =n (optional)
Figure 2.3. Initialization Batch Commands
Example 2.4. ksession JPA configuration example
<drools:kstore id="kstore" /> <!-- provides KnowledgeStoreService implementation -->
<bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="ds" />
<property name="persistenceUnitName" value="org.drools.persistence.jpa.local" />
</bean>
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="myEmf" />
</bean>
<drools:ksession id="jpaSingleSessionCommandService" type="stateful" kbase="kbProcessWorkItems">
<drools:configuration>
<drools:jpa-persistence>
<drools:transaction-manager ref="txManager" />
<drools:entity-manager-factory ref="myEmf" />
</drools:jpa-persistence>
</drools:configuration>
</drools:ksession>
Example 2.5. Listener configuration example - using a bean:ref.
<drools:resource id="resource1" type="DRL" source="classpath:org/drools/container/spring/testSpring.drl"/>
<drools:kbase id="kbase1">
<drools:resources>
<drools:resource ref="resource1"/>
</drools:resources>
</drools:kbase>
<bean id="mock-agenda-listener" class="org.drools.container.spring.MockAgendaEventListener" />
<bean id="mock-wm-listener" class="org.drools.container.spring.MockWorkingMemoryEventListener" />
<bean id="mock-process-listener" class="org.drools.container.spring.MockProcessEventListener" />
<drools:ksession id="statefulSession" type="stateful" kbase="kbase1" node="node1">
<drools:agendaEventListener ref="mock-agenda-listener"/>
<drools:processEventListener ref="mock-process-listener"/>
<drools:workingMemoryEventListener ref="mock-wm-listener"/>
</drools:ksession>
The jBPM human task server can be configured to use Spring persistence. Example 2.11, “Configuring Human Task with Spring” is an example of this which uses local transactions and Spring's thread-safe EntityManager proxy.
The following diagram shows the dependency graph used in Example 2.11, “Configuring Human Task with Spring”.
A TaskService
instance is dependent on two other bean types:
a drools SystemEventListener
bean as well as a
TaskSessionSpringFactoryImpl
bean. The
TaskSessionSpringFactoryImpl
bean is howerver not
injected into the TaskService
bean because this would cause a
circular dependency. To solve this problem, when the TaskService
bean is injected into the TaskSessionSpringFactoryImpl
bean,
the setter method used secretly injects the TaskSessionSpringFactoryImpl
instance back into the TaskService
bean and initializes the
TaskService
bean as well.
The TaskSessionSpringFactoryImpl
bean is responsible for
creating all the internal instances in human task that deal with transactions
and persistence context management. Besides a TaskService
instance,
this bean also requires a transaction manager and a persistence context to
be injected. Specifically, it requires an instance of a
HumanTaskSpringTransactionManager
bean (as a transaction manager)
and an instance of a SharedEntityManagerBean
bean (as a persistence
context instance).
We also use some of the standard Spring beans in order to configure
persistence: there's a bean to hold the EntityManagerFactory
instance as well as the SharedEntityManagerBean
instance. The
SharedEntityManagerBean
provides a shared, thread-safe proxy
for the actual EntityManager
.
The HumanTaskSpringTransactionManager
bean serves as a
wrapper around the Spring transaction manager, in this case the
JpaTransactionManager
. An instance of a
JpaTransactionManager
bean is also instantiated because of this.
Example 2.11. Configuring Human Task with Spring
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jbpm="http://drools.org/schema/drools-spring"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://drools.org/schema/drools-spring org/drools/container/spring/drools-spring-1.2.0.xsd">
<!-- persistence & transactions-->
<bean id="htEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="org.jbpm.task" />
</bean>
<bean id="htEm" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="htEmf"/>
</bean>
<bean id="jpaTxMgr" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="htEmf" />
<!-- this must be true if using the SharedEntityManagerBean, and false otherwise -->
<property name="nestedTransactionAllowed" value="true"/>
</bean>
<bean id="htTxMgr" class="org.drools.container.spring.beans.persistence.HumanTaskSpringTransactionManager">
<constructor-arg ref="jpaTxMgr" />
</bean>
<!-- human-task beans -->
<bean id="systemEventListener" class="org.drools.SystemEventListenerFactory" factory-method="getSystemEventListener" />
<bean id="taskService" class="org.jbpm.task.service.TaskService" >
<property name="systemEventListener" ref="systemEventListener" />
</bean>
<bean id="springTaskSessionFactory" class="org.jbpm.task.service.persistence.TaskSessionSpringFactoryImpl"
init-method="initialize" depends-on="taskService" >
<!-- if using the SharedEntityManagerBean, make sure to enable nested transactions -->
<property name="entityManager" ref="htEm" />
<property name="transactionManager" ref="htTxMgr" />
<property name="useJTA" value="false" />
<property name="taskService" ref="taskService" />
</bean>
</beans>
When using the SharedEntityManagerBean
instance, it's important
to configure the Spring transaction manager to use nested transactions. This is
because the SharedEntityManagerBean
is a transactional
persistence context and will close the persistence context after every operation.
However, the human task server needs to be able to access (persisted) entities
after operations. Nested transactions allow us to still have access to entities
that otherwise would have been detached and are no longer accessible, especially
when using an ORM framework that uses lazy-initialization of entities.
Also, while the TaskSessionSpringFactoryImpl
bean takes
an “useJTA” parameter, at the moment, JTA transactions with
Spring have not yet been fully tested.
Inside the war file you will find a few XML configuration files.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://camel.apache.org/schema/cxf"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<!--
! If you are running on JBoss you will need to copy a camel-jboss.jar into the lib and set this ClassLoader configuration
! http://camel.apache.org/camel-jboss.html
! <bean id="jbossResolver" class="org.apache.camel.jboss.JBossPackageScanClassResolver"/>
-->
<!--
! Define the server end point.
! Copy and paste this element, changing id and the address, to expose services on different urls.
! Different Camel routes can handle different end point paths.
-->
<cxf:rsServer id="rsServer"
address="/kservice/rest"
serviceClass="org.drools.jax.rs.CommandExecutorImpl">
<cxf:providers>
<bean class="org.drools.jax.rs.CommandMessageBodyReader"/>
</cxf:providers>
</cxf:rsServer>
<!-- Leave this, as it's needed to make Camel "drools" aware -->
<bean id="droolsPolicy" class="org.drools.camel.component.DroolsPolicy" />
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<!--
! Routes incoming messages from end point id="rsServer".
! Example route unmarshals the messages with xstream and executes against ksession1.
! Copy and paste this element, changing marshallers and the 'to' uri, to target different sessions, as needed.
!-->
<route>
<from uri="cxfrs://bean://rsServer"/>
<policy ref="droolsPolicy">
<unmarshal ref="xstream" />
<to uri="drools:node1/ksession1" />
<marshal ref="xstream" />
</policy>
</route>
</camelContext>
</beans>
<cxf:rsServer id="rsServer"
address="/kservice/rest"
serviceClass="org.drools.jax.rs.CommandExecutorImpl">
<cxf:providers>
<bean class="org.drools.jax.rs.CommandMessageBodyReader"/>
</cxf:providers>
</cxf:rsServer>
After all this initial configuration, you can start config your own Knowledge Services.
But you don’t need to know more internal details, only instantiate this bean:
<bean id="droolsPolicy" class="org.drools.camel.component.DroolsPolicy" />
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="cxfrs://bean://rsServer"/>
<policy ref="droolsPolicy">
<unmarshal ref="xstream" />
<to uri="drools:node1/ksession1" />
<marshal ref="xstream" />
</policy>
</route>
</camelContext>
The drools endpoint creation has the next arguments
<!-- XML : generated by JHighlight v1.0 (http://jhighlight.dev.java.net) --> <span class="xml_tag_symbols"><</span><span class="xml_tag_name">to</span><span class="xml_plain"> </span><span class="xml_attribute_name">uri</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"drools:{1}/{2}"</span><span class="xml_plain"> </span><span class="xml_tag_symbols">/></span><span class="xml_plain"></span><br />
Both parameters are configured in knowledge-services.xml file.
The next step is create the Knowledge Sessions that you are going to use.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:drools="http://drools.org/schema/drools-spring"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://drools.org/schema/drools-spring http://drools.org/schema/drools-spring.xsd">
<drools:execution-node id="node1" />
<drools:kbase id="kbase1" node="node1">
<drools:resources>
<drools:resource type="XSD" source="classpath:model.xsd"/>
<drools:resource type="DRL" source="classpath:test.drl"/>
</drools:resources>
</drools:kbase>
<drools:ksession id="ksession1" type="stateless" kbase="kbase1" node="node1"/>
</beans>
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="direct://kservice"/>
<policy ref="droolsPolicy">
<to uri="cxfrs://http://localhost:8080/drools-server-app/kservice/rest"/>
</policy>
</route>
</camelContext>
declare Message text : String end rule "echo" dialect "mvel" when $m : Message(); then $m.text = "echo:" + $m.text; end
The following urls show sample script examples for jaxb, xstream and json marshalling using:
Currently, the following commands are supported:
In the next examples, to marshall the commands we have used the next snippet codes:
String xml = BatchExecutionHelper.newXStreamMarshaller().toXML(command);
String xml = BatchExecutionHelper.newJSonMarshaller().toXML(command);
Marshaller marshaller = jaxbContext.createMarshaller();
StringWriter xml = new StringWriter();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(command, xml);
Description: The command that contains a list of commands, which will be sent and executed.
BatchExecutionCommand command = new BatchExecutionCommand();
command.setLookup("ksession1");
InsertObjectCommand insertObjectCommand = new InsertObjectCommand(new Person("john", 25));
FireAllRulesCommand fireAllRulesCommand = new FireAllRulesCommand();
command.getCommands().add(insertObjectCommand);
command.getCommands().add(fireAllRulesCommand);
<batch-execution lookup="ksession1">
<insert>
<org.drools.test.Person>
<name>john</name>
<age>25</age>
</org.drools.test.Person>
</insert>
<fire-all-rules/>
</batch-execution>
{"batch-execution":{"lookup":"ksession1","commands":[{"insert":{"object":{"org.drools.test.Person":{"name":"john","age":25}}}},{"fire-all-rules":""}]}}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<batch-execution lookup="ksession1">
<insert>
<object xsi:type="person" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<age>25</age>
<name>john</name>
</object>
</insert>
<fire-all-rules max="-1"/>
</batch-execution>
List<Command> cmds = ArrayList<Command>();
Command insertObjectCommand = CommandFactory.newInsert(new Person("john", 25), "john", false, null);
cmds.add( insertObjectCommand );
BatchExecutionCommand command = CommandFactory.createBatchExecution(cmds, "ksession1" );
<batch-execution lookup="ksession1">
<insert out-identifier="john" entry-point="my stream" return-object="false">
<org.drools.test.Person>
<name>john</name>
<age>25</age>
</org.drools.test.Person>
</insert>
</batch-execution>
{"batch-execution":{"lookup":"ksession1","commands":{"insert":{"entry-point":"my stream", "out-identifier":"john","return-object":false,"object":{"org.drools.test.Person":{"name":"john","age":25}}}}}}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<batch-execution lookup="ksession1">
<insert out-identifier="john" entry-point="my stream" >
<object xsi:type="person" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<age>25</age>
<name>john</name>
</object>
</insert>
</batch-execution>
Command creation: we have two options, with the same output result:
Create the Fact Handle from a string
BatchExecutionCommand command = new BatchExecutionCommand();
command.setLookup("ksession1");
RetractCommand retractCommand = new RetractCommand();
retractCommand.setFactHandleFromString("123:234:345:456:567");
command.getCommands().add(retractCommand);
Set the Fact Handle that you received when the object was inserted
BatchExecutionCommand command = new BatchExecutionCommand();
command.setLookup("ksession1");
RetractCommand retractCommand = new RetractCommand(factHandle);
command.getCommands().add(retractCommand);
<batch-execution lookup="ksession1">
<retract fact-handle="0:234:345:456:567"/>
</batch-execution>
{"batch-execution":{"lookup":"ksession1","commands":{"retract":{"fact-handle":"0:234:345:456:567"}}}}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<batch-execution lookup="ksession1">
<retract fact-handle="0:234:345:456:567"/>
</batch-execution>
Description: Allows you to modify a previously inserted object in the knowledge session.
BatchExecutionCommand command = new BatchExecutionCommand();
command.setLookup("ksession1");
ModifyCommand modifyCommand = new ModifyCommand();
modifyCommand.setFactHandleFromString("123:234:345:456:567");
List<Setter> setters = new ArrayList<Setter>();
setters.add(new SetterImpl("age", "30"));
modifyCommand.setSetters(setters);
command.getCommands().add(modifyCommand);
<batch-execution lookup="ksession1">
<modify fact-handle="0:234:345:456:567">
<set accessor="age" value="30"/>
</modify>
</batch-execution>
{"batch-execution":{"lookup":"ksession1","commands":{"modify":{"fact-handle":"0:234:345:456:567","setters":{"accessor":"age","value":30}}}}}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<batch-execution lookup="ksession1">
<modify fact-handle="0:234:345:456:567">
<set value="30" accessor="age"/>
</modify>
</batch-execution>
BatchExecutionCommand command = new BatchExecutionCommand();
command.setLookup("ksession1");
GetObjectCommand getObjectCommand = new GetObjectCommand();
getObjectCommand.setFactHandleFromString("123:234:345:456:567");
getObjectCommand.setOutIdentifier("john");
command.getCommands().add(getObjectCommand);
<batch-execution lookup="ksession1">
<get-object fact-handle="0:234:345:456:567" out-identifier="john"/>
</batch-execution>
{"batch-execution":{"lookup":"ksession1","commands":{"get-object":{"fact-handle":"0:234:345:456:567","out-identifier":"john"}}}}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<batch-execution lookup="ksession1">
<get-object out-identifier="john" fact-handle="0:234:345:456:567"/>
</batch-execution>
List<Command> cmds = ArrayList<Command>();
List<Object> objects = new ArrayList<Object>();
objects.add(new Person("john", 25));
objects.add(new Person("sarah", 35));
Command insertElementsCommand = CommandFactory.newInsertElements( objects );
cmds.add( insertElementsCommand );
BatchExecutionCommand command = CommandFactory.createBatchExecution(cmds, "ksession1" );
<batch-execution lookup="ksession1">
<insert-elements>
<org.drools.test.Person>
<name>john</name>
<age>25</age>
</org.drools.test.Person>
<org.drools.test.Person>
<name>sarah</name>
<age>35</age>
</org.drools.test.Person>
</insert-elements>
</batch-execution>
{"batch-execution":{"lookup":"ksession1","commands":{"insert-elements":{"objects":[{"containedObject":{"@class":"org.drools.test.Person","name":"john","age":25}},{"containedObject":{"@class":"org.drools.test.Person","name":"sarah","age":35}}]}}}}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<batch-execution lookup="ksession1">
<insert-elements return-objects="true">
<list>
<element xsi:type="person" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<age>25</age>
<name>john</name>
</element>
<element xsi:type="person" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<age>35</age>
<name>sarah</name>
</element>
<list>
</insert-elements>
</batch-execution>
Description: Allow execution of the rules activations created.
BatchExecutionCommand command = new BatchExecutionCommand();
command.setLookup("ksession1");
FireAllRulesCommand fireAllRulesCommand = new FireAllRulesCommand();
fireAllRulesCommand.setMax(10);
fireAllRulesCommand.setOutIdentifier("firedActivations");
command.getCommands().add(fireAllRulesCommand);
<batch-execution lookup="ksession1">
<fire-all-rules max="10" out-identifier="firedActivations"/>
</batch-execution>
{"batch-execution":{"lookup":"ksession1","commands":{"fire-all-rules":{"max":10,"out-identifier":"firedActivations"}}}}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<batch-execution lookup="ksession1">
<fire-all-rules out-identifier="firedActivations" max="10"/>
</batch-execution>
BatchExecutionCommand command = new BatchExecutionCommand();
command.setLookup("ksession1");
StartProcessCommand startProcessCommand = new StartProcessCommand();
startProcessCommand.setProcessId("org.drools.task.processOne");
command.getCommands().add(startProcessCommand);
<batch-execution lookup="ksession1">
<start-process processId="org.drools.task.processOne"/>
</batch-execution>
{"batch-execution":{"lookup":"ksession1","commands":{"start-process":{"process-id":"org.drools.task.processOne"}}}}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<batch-execution lookup="ksession1">
<start-process processId="org.drools.task.processOne">
<parameter/>
</start-process>
</batch-execution>
BatchExecutionCommand command = new BatchExecutionCommand();
command.setLookup("ksession1");
SignalEventCommand signalEventCommand = new SignalEventCommand();
signalEventCommand.setProcessInstanceId(1001);
signalEventCommand.setEventType("start");
signalEventCommand.setEvent(new Person("john", 25));
command.getCommands().add(signalEventCommand);
<batch-execution lookup="ksession1">
<signal-event process-instance-id="1001" event-type="start">
<org.drools.pipeline.camel.Person>
<name>john</name>
<age>25</age>
</org.drools.pipeline.camel.Person>
</signal-event>
</batch-execution>
{"batch-execution":{"lookup":"ksession1","commands":{"signal-event":{"process-instance-id":1001,"@event-type":"start","event-type":"start","object":{"org.drools.pipeline.camel.Person":{"name":"john","age":25}}}}}}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<batch-execution lookup="ksession1">
<signal-event event-type="start" process-instance-id="1001">
<event xsi:type="person" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<age>25</age>
<name>john</name>
</event>
</signal-event>
</batch-execution>
BatchExecutionCommand command = new BatchExecutionCommand();
command.setLookup("ksession1");
CompleteWorkItemCommand completeWorkItemCommand = new CompleteWorkItemCommand();
completeWorkItemCommand.setWorkItemId(1001);
command.getCommands().add(completeWorkItemCommand);
<batch-execution lookup="ksession1">
<complete-work-item id="1001"/>
</batch-execution>
{"batch-execution":{"lookup":"ksession1","commands":{"complete-work-item":{"id":1001}}}}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<batch-execution lookup="ksession1">
<complete-work-item id="1001"/>
</batch-execution>
BatchExecutionCommand command = new BatchExecutionCommand();
command.setLookup("ksession1");
AbortWorkItemCommand abortWorkItemCommand = new AbortWorkItemCommand();
abortWorkItemCommand.setWorkItemId(1001);
command.getCommands().add(abortWorkItemCommand);
<batch-execution lookup="ksession1">
<abort-work-item id="1001"/>
</batch-execution>
{"batch-execution":{"lookup":"ksession1","commands":{"abort-work-item":{"id":1001}}}}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<batch-execution lookup="ksession1">
<abort-work-item id="1001"/>
</batch-execution>
BatchExecutionCommand command = new BatchExecutionCommand();
command.setLookup("ksession1");
QueryCommand queryCommand = new QueryCommand();
queryCommand.setName("persons");
queryCommand.setOutIdentifier("persons");
command.getCommands().add(queryCommand);
<batch-execution lookup="ksession1">
<query out-identifier="persons" name="persons"/>
</batch-execution>
{"batch-execution":{"lookup":"ksession1","commands":{"query":{"out-identifier":"persons","name":"persons"}}}}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<batch-execution lookup="ksession1">
<query name="persons" out-identifier="persons"/>
</batch-execution>
BatchExecutionCommand command = new BatchExecutionCommand();
command.setLookup("ksession1");
SetGlobalCommand setGlobalCommand = new SetGlobalCommand();
setGlobalCommand.setIdentifier("helper");
setGlobalCommand.setObject(new Person("kyle", 30));
setGlobalCommand.setOut(true);
setGlobalCommand.setOutIdentifier("output");
command.getCommands().add(setGlobalCommand);
<batch-execution lookup="ksession1">
<set-global identifier="helper" out-identifier="output">
<org.drools.test.Person>
<name>kyle</name>
<age>30</age>
</org.drools.test.Person>
</set-global>
</batch-execution>
{"batch-execution":{"lookup":"ksession1","commands":{"set-global":{"identifier":"helper","out-identifier":"output","object":{"org.drools.test.Person":{"name":"kyle","age":30}}}}}}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<batch-execution lookup="ksession1">
<set-global out="true" out-identifier="output" identifier="helper">
<object xsi:type="person" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<age>30</age>
<name>kyle</name>
</object>
</set-global>
</batch-execution>
BatchExecutionCommand command = new BatchExecutionCommand();
command.setLookup("ksession1");
GetGlobalCommand getGlobalCommand = new GetGlobalCommand();
getGlobalCommand.setIdentifier("helper");
getGlobalCommand.setOutIdentifier("helperOutput");
command.getCommands().add(getGlobalCommand);
<batch-execution lookup="ksession1">
<get-global identifier="helper" out-identifier="helperOutput"/>
</batch-execution>
{"batch-execution":{"lookup":"ksession1","commands":{"get-global":{"identifier":"helper","out-identifier":"helperOutput"}}}}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<batch-execution lookup="ksession1">
<get-global out-identifier="helperOutput" identifier="helper"/>
</batch-execution>
Description: Returns all the objects from the current session as a Collection.
BatchExecutionCommand command = new BatchExecutionCommand();
command.setLookup("ksession1");
GetObjectsCommand getObjectsCommand = new GetObjectsCommand();
getObjectsCommand.setOutIdentifier("objects");
command.getCommands().add(getObjectsCommand);
<batch-execution lookup="ksession1">
<get-objects out-identifier="objects"/>
</batch-execution>
{"batch-execution":{"lookup":"ksession1","commands":{"get-objects":{"out-identifier":"objects"}}}}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<batch-execution lookup="ksession1">
<get-objects out-identifier="objects"/>
</batch-execution>
The following modules should work with OSGi;
The following Services can be located as OSGi Bundles
The TestComponent will only be activated when all of the referenced services are available and injected into the pojo. You'll also notice the "target" attribute for the KnowledgeBuilderFactoryService. The reason for this is that OSGi DS has no built in way to declaratively say which optional services must be present to satisfy your component. As a work around I made any Drools service that has optional services set a property if/when the optional service is available. Filters can then be applied, via the target attribute, to make sure the Service is in a desired state before consuming it. And that is pretty much it :)
Example 5.2. Basic Rule Compilation
ServiceReference serviceRef = bundleContext.getServiceReference( ServiceRegistry.class.getName() ); ServiceRegistry registry = (ServiceRegistry) bundleContext.getService( serviceRef ); KnowledgeBuilderFactoryService knowledgeBuilderFactoryService = registry.get( KnowledgeBuilderFactoryService.class ); KnowledgeBaseFactoryService knowledgeBaseFactoryService = registry.get( KnowledgeBaseFactoryService.class ); ResourceFactoryService resourceFactoryService = registry.get( ResourceFactoryService.class ); KnowledgeBuilderConfiguration kbConf = knowledgeBuilderFactoryService.newKnowledgeBuilderConfiguration( null, getClass().getClassLoader() ); KnowledgeBuilder kbuilder = knowledgeBuilderFactoryService.newKnowledgeBuilder( kbConf ); ResourceFactoryService resource = resourceFactoryService; kbuilder.add( resource.newByteArrayResource( string.getBytes() ), ResourceType.DRL ); if ( kbuilder.hasErrors() ) { System.out.println( kbuilder.getErrors() ); throw new RuntimeException( kbuilder.getErrors().toString() ); } KnowledgeBaseConfiguration kbaseConf = knowledgeBaseFactoryService.newKnowledgeBaseConfiguration( null, getClass().getClassLoader() ); KnowledgeBase kbase = knowledgeBaseFactoryService.newKnowledgeBase( kbaseConf ); kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() ); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
Example 5.3. Decision Table Example
ServiceReference serviceRef = bundleContext.getServiceReference( ServiceRegistry.class.getName() ); ServiceRegistry registry = (ServiceRegistry) bundleContext.getService( serviceRef ); KnowledgeBuilderFactoryService knowledgeBuilderFactoryService = registry.get( KnowledgeBuilderFactoryService.class ); KnowledgeBaseFactoryService knowledgeBaseFactoryService = registry.get( KnowledgeBaseFactoryService.class ); ResourceFactoryService resourceFactoryService = registry.get( ResourceFactoryService.class ); KnowledgeBaseConfiguration kbaseConf = knowledgeBaseFactoryService.newKnowledgeBaseConfiguration( null, getClass().getClassLoader() ); KnowledgeBuilderConfiguration kbConf = knowledgeBuilderFactoryService.newKnowledgeBuilderConfiguration( null, getClass().getClassLoader() ); KnowledgeBuilder kbuilder = knowledgeBuilderFactoryService.newKnowledgeBuilder( kbConf ); kbuilder.add( resourceFactoryService.newClassPathResource( "changeset1Test.xml", Dummy.class ), ResourceType.CHANGE_SET ); kbaseConf = knowledgeBaseFactoryService.newKnowledgeBaseConfiguration( null, getClass().getClassLoader() ); KnowledgeBase kbase = knowledgeBaseFactoryService.newKnowledgeBase( kbaseConf ); kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() ); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
-Dcom.sun.management.jmxremote.port=19988 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
To enable it in the command line, use:
-Ddrools.mbeans=enabled
To enable id using the API, use:
KnowledgeBaseConfiguration conf = ...
conf.setOption( MBeansOption.ENABLED );
The following sequence of steps can be used to configure JON to monitor a Drools application: