The focus of this chapter will be on various integration points of the Drools engine with other systems.
We'll start with a discussion of having Drools artifacts change their own life cycle that is independent from the application. We'll see how to build and dynamically load Drools artifacts.
We'll look at how to run rules remotely from a lightweight client. A simple client will be written in Ruby that will be talking to a Drools camel server.
Finally, we'll cover integration with the Spring framework and some rule standards will be discussed.
In almost all examples in this book the Drools artifacts were packaged together with the application. However, rules, processes, and other Drools artifacts often have different life cycles than applications that use them. These artifacts tend to change more often than the rest of the application. It would be more beneficial if we could build, release, and deploy them separately. In order to achieve this we need to build the KnowledgeBase
instance independently from the application. The application should be able to dynamically reload this KnowledgeBase
instance at runtime.
Guvnor (Business Rules Management Server) meets our first requirement. It can build, release KnowledgePackages
, and make them available through a URL. Later on in this chapter we'll also show how we can use a general build tool such as Ant for this task.
For the second requirement we'll now look at KnowledgeAgent
.
KnowledgeAgent
allows us to load Drools artifacts dynamically as they change. It is designed to support both poll and push models. However, only the polling model is implemented in Drools (the KnowledgeAgent
listener periodically scans resources for changes).
The following figure shows how it works in more detail:
A resource can represent a single .drl
file (see org.drools.builder.ResourceType
enum for all supported resources) or a directory (it can contain multiple resources). ResourceChangeMonitor
monitors these resources for changes. When a change is detected a ChangeSet
resource is created that holds all information about this change. The ChangeSet
resource holds resources that were added, modified, and removed. ResourceChangeScanner
extends the ResourceChangeMonitor
interface to provide the "poll type" monitoring. It can be configured to scan for changes in predefined intervals. The default is 60 seconds.
When the monitor detects a change, it triggers the ResourceChangeNotifier
method, which is responsible for sending notifications to listeners. All listeners must implement the ResourceChangeListener
interface.
KnowledgeAgent
is a type of listener that caches one knowledge base. The knowledge base can be accessed through the getKnowledgeBase
method. The agent keeps this knowledge base up-to-date as the resources change. It can update the knowledge base instance or create a new one (the default behavior). When updating a knowledge base, all associated knowledge sessions will get updated as well, so take care. The following code listing shows how to use the KnowlegeAgent
listener:
ResourceFactory.getResourceChangeScannerService().start(); ResourceFactory.getResourceChangeNotifierService().start(); KnowledgeAgentConfiguration conf = KnowledgeAgentFactory .newKnowledgeAgentConfiguration(); conf.setProperty("drools.agent.scanDirectories", "true"); final KnowledgeAgent agent = KnowledgeAgentFactory .newKnowledgeAgent("validation agent", knowledgeBase, conf);
Code listing 1: KnowledgeAgent usage – creating new knowledge base on every change
The first two lines are starting the monitor and notifier services. They must be started explicitly.
Next, a KnowledgeAgentConfiguration
listener is created that provides some configuration options for the knowledge agent. It can specify whether the agent should scan resources or whole directories and other settings. Code listing 1 shows how to enable the scanDirectories
setting, that is, aconf.setProperty("drools.agent.scanDirectories", "true");
.
The KnowledgeAgentFactory
interface is then used to create an instance of the KnowledgeAgent
listener using our configuration conf
(see javadoc
for other ways to create the KnowledgeAgent
listener). The factory method also takes knowledgeBase
as an argument. We can create this knowledge base as we normally do.
Note that the knowledge base retains the locations of its resources. This is possible only when it is created from a file, URL, or a resource on the classpath (as can be seen in the following example). The location information is lost when the knowledge base is created from a byte array, InpuStream
, or a Reader
resource.
The agent subscribes for notifications to all resources this knowledge base contains. When a resource is changed, the agent recreates the knowledge base. In our application we have to get this knowledge base by calling KnowledgeAgent.getKnowledgeBase()
before every stateless/stateful session creation.
In the previous chapter we've mentioned that Drools Guvnor can also build artifacts. Artifacts are grouped into packages. Packages can be built and then accessed via a URL. Our application can then use this URL for creating the KnowledgeBase
instance. If we'd like to load the validation KnowledgeBase
from Guvnor, we could add it to the KnowledgeBuilder
instance like this:
kbuilder.add(ResourceFactory.newUrlResource( "http://localhost:8080/guvnor-5.5.0.Final-tomcat-6.0/org.drools.guvnor.Guvnor/package/droolsbook.validation/LATEST"), ResourceType.PKG);
Code listing 2: Adding a validation package built by Guvnor
We're specifying the URL where the package is accessible. The package name is droolsbook.validation
, and we're using the LATEST
snapshot of this package. With this configuration change we don't even need the drools-compiler
library on the classpath, because the package is already compiled. The KnowledgeAgent
listener will periodically poll this URL for changes and will recreate its locally cached KnowledgeBase
instance.
3.21.233.41