JBoss.org Community Documentation

- Prev
- Next

## Chapter 2. Spring Integration

## 2.1. Integration with Drools Expert

In this section we will explain the drools namespace.

### 2.1.1. Define a Resource

Execution nodes are a context to register ksessions and kbases against for lookup.

#### 2.1.1.1. <drools:execution-node>'s parameters as attributes:

Table 2.1.

Attribute | Description | Required
--- | --- | ---
id | Bean's id is the name to be reference from other beans. | Yes

#### 2.1.1.2. <drools:resource>'s parameters as attributes:

Table 2.2.

Attribute | Description | Required
--- | --- | ---
id | Bean's id is the name to be reference from other beans. | Yes, but can be omitted when this tag is nested.
source | The path to the file containing the actual resource. | Yes
type | Type of the Resource as is defined in class `ResourceType`. | No, default to DRL

#### 2.1.1.3. <drools:resource>'s parameters as nested elements:

When configuring a decision table resource you can nest a <drools:decisiontable-conf> tag to configure the resource.

Table 2.3.

Attribute | Description | Required
--- | --- | ---
input-type | Decision Table input type: XLS or CSV | No
worksheet-name | The worksheet name to be used in the when using an XLS | No

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>

#### 2.1.1.4. Define a KnowledgeBase

##### 2.1.1.4.1. <drools:kbase>'s parameters as attributes:

Table 2.4.

Attribute | Description | Required
--- | --- | ---
id | Bean's id is the name to be referenced from other beans. | Yes
node | Execution-Node context to register the kbase with | no

##### 2.1.1.4.2. <drools:kbase>'s parameters as nested elements:

A Knowledge Base has a 0..n resources. Has two nested elements, resources and configurations. Those resources can be inner elements or references, using the "ref" attribute.

Example 2.2. kbase definition example

    <drools:kbase id="kbase1" node="node1">

       <drools:resources>

          <drools:resource source="classpath:org/drools/spring/IntegrationExampleTest.xls"

                        type="DTABLE">

             <drools:decisiontable-conf input-type="XLS" worksheet-name="Table_2" />

          </drools:resource>

          <drools:resource ref="resource1"/>

          <drools:resource source="classpath:org/drools/container/spring/model.xsd" />

       </drools:resources>

       <drools:configuration>

           <drools:mbeans enabled="true" />

          <drools:accumulate-functions>

             <drools:accumulate-function name="func1" ref="func1Instance" />

             <drools:accumulate-function name="func1" ref="func2Instance" />

          </drools:accumulate-functions>

       </drools:configuration>

    </drools:kbase>

- 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

#### 2.1.1.5. Define KnowledgeSessions

##### 2.1.1.5.1. <drools:ksession>'s parameters as attributes:

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>

##### 2.1.1.5.2. <drools:ksession>'s parameters as nested elements:

When configuring a Event Listener resource you can nest a <drools:eventListener> tag to configure the listener.

### 2.1.2. Event Listeners

Drools supports adding 3 types of listeners to KnowledgeSessions - AgendaListener, WorkingMemoryListener, ProcessEventListener

The drools-spring module allows you to configure these listeners to KnowledgeSessions using XML tags. These tags have identical names as the actual listener interfaces i.e., <drools:agendaEventListener....>, <drools:workingMemoryEventListener....> and <drools:processEventListener....>.

drools-spring provides features to define the listeners as standalone (individual) listeners and also to define them as a group.

#### 2.1.2.1. Defining Stand alone Listeners:

##### 2.1.2.1.1. Attributes:

Table 2.6.

Attribute | Required | Description
--- | --- | ---
ref | No | A reference to another declared bean.

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>

##### 2.1.2.1.2. Nested Elements:

- bean

  - class = String

  - name = String (optional)

Example 2.6. Listener configuration example - using nested bean.

      <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>

      <drools:ksession id="statefulWithNestedBean" type="stateful" kbase="kbase1" node="node1">

        <drools:agendaEventListener>

          <bean class="org.drools.container.spring.MockAgendaEventListener"/>

        </drools:agendaEventListener>

        <drools:workingMemoryEventListener>

          <bean class="org.drools.container.spring.MockWorkingMemoryEventListener"/>

        </drools:workingMemoryEventListener>

        <drools:processEventListener>

          <bean class="org.drools.container.spring.MockProcessEventListener"/>

        </drools:processEventListener>

      </drools:ksession>

##### 2.1.2.1.3. Empty Tag : Declaration with no 'ref' and without a nested bean

When a listener is defined without a reference to a implementing bean and does not contain a nested bean, <drools:workingMemoryEventListener/> the underlying implementation adds the Debug version of the listener defined in the API.

The debug listeners print the corresponding Event toString message to System.err.

Example 2.7. Listener configuration example - defaulting to the debug versions provided by the Knowledge-API .

      <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>

      <drools:ksession id="statefulWithDefault" type="stateful" kbase="kbase1" node="node1">

        <drools:agendaEventListener/> <!-- attaches the org.drools.event.rule.DebugAgendaEventListener -->

        <drools:workingMemoryEventListener/> <!-- attaches the org.drools.event.rule.DebugWorkingMemoryEventListener -->

        <drools:processEventListener/> <!-- attaches the org.drools.event.DebugProcessEventListener -->

      </drools:ksession>

##### 2.1.2.1.4. Mix and Match of different declaration styles

The drools-spring module allows you to mix and match the different declarative styles within the same KnowledgeSession. The below sample provides more clarity.

Example 2.8. Listener configuration example - mix and match of 'ref'/nested-bean/empty styles.

      <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" />

      <drools:ksession id="statefulWithMixAndMatchOfStyles" type="stateful" kbase="kbase1" node="node1">

         <drools:workingMemoryEventListener>

          <bean class="org.drools.container.spring.MockWorkingMemoryEventListener"/>

        </drools:workingMemoryEventListener>

        <drools:agendaEventListener ref="mock-agenda-listener"/>

        <drools:processEventListener/> <!-- attaches the org.drools.event.DebugProcessEventListener -->

      </drools:ksession>

##### 2.1.2.1.5. Defining multiple listeners of the same type

It is also valid to define multiple beans of the same event listener types for a KnowledgeSession.

Example 2.9. Listener configuration example - multiple listeners of the same type.

      <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-wm-listener" class="org.drools.container.spring.MockWorkingMemoryEventListener" />

      <drools:ksession id="statefulWithMultipleSameType" type="stateful" kbase="kbase1" node="node1">

        <!-- 2 different implementations of the same listener attached to one ksession -->

        <drools:workingMemoryEventListener>

          <bean class="org.drools.container.spring.ConsoleWorkingMemoryEventListener"/>

        </drools:workingMemoryEventListener>

        <drools:workingMemoryEventListener ref="mock-wm-listener"/>

      </drools:ksession>

#### 2.1.2.2. Defining a Group of listeners:

drools-spring allows for grouping of listeners. This is particularly useful when you define a set of listeners and want to attach them to multiple sessions. The grouping feature is also very useful, when we define a set of listeners for 'testing' and then want to switch them for 'production' use.

##### 2.1.2.2.1. Attributes:

Table 2.7.

Attribute | Required | Description
--- | --- | ---
ID | yes | Unique identifier

##### 2.1.2.2.2. Nested Elements:

- drools:agendaEventListener...

- drools:workingMemoryEventListener...

- drools:processEventListener...

## Note

The above mentioned child elements can be declared in any order. Only one declaration of each type is allowed in a group.

##### 2.1.2.2.3. Example:

Example 2.10. Group of listeners - example

      <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-wm-listener" class="org.drools.container.spring.MockWorkingMemoryEventListener" />

      <drools:ksession id="statelessWithGroupedListeners" type="stateless" kbase="kbase1" node="node1" listeners="

    mockListeners
    "/>

      <drools:eventListeners id="mockListeners">

        <drools:agendaEventListener ref="mock-agenda-listener"/>

        <drools:processEventListener ref="mock-process-listener"/>

        <drools:workingMemoryEventListener ref="mock-wm-listener"/>

      </drools:eventListeners>

      <drools:eventListeners id="debugListeners">

        <drools:agendaEventListener/>

        <drools:processEventListener/>

        <drools:workingMemoryEventListener/>

      </drools:eventListeners>

## 2.2. Integration with jBPM Human Task

This chapter describes the infrastructure used when configuring a human task server with Spring as well as a little bit about the infrastructure used when doing this.

### 2.2.1. How to configure Spring with jBPM Human task

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”.

Figure 2.4. Spring Human Task integration injection dependencies

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.

- PrevChapter 1. Apache Camel Integration
- Top of page
- Front page
- NextChapter 3. Drools Camel Server