Deploying

KnowledgePackage and Knowledge Definitions

A Knowledge Package is a collection of Knowledge Definitions, such as rules and processes. It is created by the Knowledge Builder, as described in the chapter "Building". Knowledge Packages are self-contained and serializable, and they currently form the basic deployment unit.

Figure 3.4. KnowledgePackage

KnowledgePackage

Knowledge Packages are added to the Knowledge Base. However, a Knowledge Package instance cannot be reused once it's added to the Knowledge Base. If you need to add it to another Knowledge Base, try serializing it first and using the "cloned" result. We hope to fix this limitation in future versions of Drools.

KnowledgeBase

The Knowlege Base is a repository of all the application's knowledge definitions. It may contain rules, processes, functions, and type models. The Knowledge Base itself does not contain instance data, known as facts; instead, sessions are created from the Knowledge Base into which data can be inserted and where process instances may be started. Creating the Knowlege Base can be heavy, whereas session creation is very light, so it is recommended that Knowledge Bases be cached where possible to allow for repeated session creation.

Figure 3.5. KnowledgeBase

KnowledgeBase

A KnowledgeBase object is also serializable, and some people may prefer to build and then store a KnowledgeBase, treating it also as a unit of deployment, instead of the Knowledge Packages.

The KnowlegeBase is created using the KnowledgeBaseFactory.

Figure 3.6. KnowledgeBaseFactory

KnowledgeBaseFactory

A KnowledgeBase can be created using the default configuration.

Example 3.12. Creating a new KnowledgeBase

KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();

If a custom class loader was used with the KnowledgeBuilder to resolve types not in the default class loader, then that must also be set on the KnowledgeBase. The technique for this is the same as with the KnowledgeBuilder.

Example 3.13. Creating a new KnowledgeBase with a custom ClassLoader

KnowledgeBaseConfiguration kbaseConf =
    KnowledgeBaseFactory.createKnowledgeBaseConfiguration( null, cl );
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase( kbaseConf );

In-Process Building and Deployment

This is the simplest form of deployment. It compiles the knowledge definitions and adds them to the Knowledge Base in the same JVM. This approach requires drools-core.jar and drools-compiler.jar to be on the classpath.

Example 3.14. Add KnowledgePackages to a KnowledgeBase

Collection<KnowledgePackage> kpkgs = kbuilder.getKnowledgePackages();

KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages( kpkgs );

Note that the addKnowledgePackages(kpkgs) method can be called iteratively to add additional knowledge.

Building and Deployment in Separate Processes

Both the KnowledgeBase and the KnowledgePackage are units of deployment and serializable. This means you can have one machine do any necessary building, requiring drools-compiler.jar, and have another machine deploy and execute everything, needing only drools-core.jar.

Although serialization is standard Java, we present an example of how one machine might write out the deployment unit and how another machine might read in and use that deployment unit.

Example 3.15. Writing the KnowledgePackage to an OutputStream

ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream( fileName ) );
out.writeObject( kpkgs );
out.close();

Example 3.16. Reading the KnowledgePackage from an InputStream

ObjectInputStream in = new ObjectInputStream( new FileInputStream( fileName ) );
// The input stream might contain an individual
// package or a collection.
@SuppressWarnings( "unchecked" )
Collection<KnowledgePackage> kpkgs =
    ()in.readObject( Collection<KnowledgePackage> );
in.close();

KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages( kpkgs );

The KnowledgeBase is also serializable and some people may prefer to build and then store the KnowledgeBase itself, instead of the Knowledge Packages.

Drools Guvnor, our server side management system, uses this deployment approach. After Guvnor has compiled and published serialized Knowledge Packages on a URL, Drools can use the URL resource type to load them.

StatefulknowledgeSessions and KnowledgeBase Modifications

Stateful Knowledge Sessions will be discussed in more detail in section "Running". The KnowledgeBase creates and returns StatefulKnowledgeSession objects, and it may optionally keep references to those. When KnowledgeBase modifications occur those modifications are applied against the data in the sessions. This reference is a weak reference and it is also optional, which is controlled by a boolean flag.

KnowledgeAgent

The KnowlegeAgent provides automatic loading, caching and re-loading of resources and is configured from a properties files. The Knowledge Agent can update or rebuild this Knowlege Base as the resources it uses are changed. The strategy for this is determined by the configuration given to the factory, but it is typically pull-based using regular polling. We hope to add push-based updates and rebuilds in future versions. The Knowledge Agent will continuously scan all the added resources, using a default polling interval of 60 seconds. If their date of the last modification is updated it will rebuild the cached Knowledge Base using the new resources.

Figure 3.7. KnowledgeAgent

KnowledgeAgent

The KnowlegeBuilder is created using a KnowledgeBuilderFactory object. The agent must specify a name, which is used in the log files to associate a log entry with the corresponding agent.

Example 3.17. Creating the KnowledgeAgent

KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent( "MyAgent" );

Figure 3.8. KnowledgeAgentFactory

KnowledgeAgentFactory

The following example constructs an agent that will build a new KnowledgeBase from the specified ChangeSet. (See section "Building" for more details on the ChangeSet format.) Note that the method can be called iteratively to add new resources over time. At the moment the remove and modify elements of the ChangeSet XML are not implemented, but future versions will provide this as well, giving you more control over those incremental changes. The Knowledge Agent polls the resources added from the ChangeSet every 60 seconds, the default interval, to see if they are updated. Whenever changes are found it will construct a new Knowledge Base. If the change set specifies a resource that is a directory its contents will be scanned for changes, too.

Example 3.18. Writing the KnowledgePackage to an OutputStream

KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent( "MyAgent" );
kagent.applyChangeSet( ResourceFactory.newUrlResource( url ) );
KnowledgeBase kbase = kagent.getKnowledgeBase();

Resource scanning is not on by default, it's a service and must be started, and the same is true for notification. Both can be done via the ResourceFactory.

Example 3.19. Starting the Scanning and Notification Services

ResourceFactory.getResourceChangeNotifierService().start();
ResourceFactory.getResourceChangeScannerService().start();

The default resource scanning period may be changed via the ResourceChangeScannerService. A suitably updated ResourceChangeScannerConfiguration object is passed to the service's configure() method, which allows for the service to be reconfigured on demand.

Example 3.20. Changing the Scanning Intervals

ResourceChangeScannerConfiguration sconf =
    ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration();
// Set the disk scanning interval to 30s, default is 60s.
sconf.setProperty( "drools.resource.scanner.interval", "30" ); 
ResourceFactory.getResourceChangeScannerService().configure( sconf );

Knowledge Agents can take an empty Knowledge Base or a populated one. If a populated Knowledge Base is provided, the Knowledge Agent will run an iterator from Knowledge Base and subscribe to the resources that it finds. While it is possible for the Knowledge Builder to build all resources found in a directory, that information is lost by the Knowledge Builder so that those directories will not be continuously scanned. Only directories specified as part of the applyChangeSet(Resource) method are monitored.

One of the advantages of providing KnowledgeBase as the starting point is that you can provide it with a KnowledgeBaseConfiguration. When resource changes are detected and a new KnowledgeBase object is instantiated, it will use the KnowledgeBaseConfiguration of the previous KnowledgeBase object.

Example 3.21. Using an existing KnowledgeBase

KnowledgeBaseConfiguration kbaseConf =
    KnowledgeBaseFactory.createKnowledgeBaseConfiguration( null, cl );
KnowledgeBase kbase KnowledgeBaseFactory.newKnowledgeBase( kbaseConf );
// Populate kbase with resources here.

KnowledgeAgent kagent =
    KnowledgeAgentFactory.newKnowledgeAgent( "MyAgent", kbase );
KnowledgeBase kbase = kagent.getKnowledgeBase();

In the above example getKnowledgeBase() will return the same provided kbase instance until resource changes are detected and a new Knowledge Base is built. When the new Knowledge Base is built, it will be done with the KnowledgeBaseConfiguration that was provided to the previous KnowledgeBase.

As mentioned previously, a ChangeSet XML can specify a directory and all of its contents will be added. If this ChangeSet XML is used with the applyChangeSet() method it will also add any directories to the scanning process. When the directory scan detects an additional file, it will be added to the Knowledge Base; any removed file is removed from the Knowledge Base, and modified files will, as usual, force the build of a new Knowledge Base using the latest version.

Example 3.22. ChangeSet XML which adds a directories contents

<change-set xmlns='http://drools.org/drools-5.0/change-set'
            xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'
            xs:schemaLocation='http://drools.org/drools-5.0/change-set.xsd' >
   <add>
      <resource source='file:/projects/myproject/myrules' type='PKG' />
   </add>
</change-set>

Note that for the resource type PKG the drools-compiler dependency is not needed as the Knowledge Agent is able to handle those with just drools-core.

The KnowledgeAgentConfiguration can be used to modify a Knowledge Agent's default behavior. You could use this to load the resources from a directory, while inhibiting the continuous scan for changes of that directory.

Example 3.23. Change the Scanning Behavior

KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();

KnowledgeAgentConfiguration kaconf =
    KnowledgeAgentFactory.newKnowledgeAgentConfiguation();
// Do not scan directories, just files.
kaconf.setProperty( "drools.agent.scanDirectories", "false" );
KnowledgeAgent kagent =
    KnowledgeAgentFactory.newKnowledgeAgent( "test agent", kaconf );

Previously we mentioned Drools Guvnor and how it can build and publish serialized Knowledge Packages on a URL, and that the ChangeSet XML can handle URLs and Packages. Taken together, this forms an importanty deployment scenario for the Knowledge Agent.