Using the Drools Operator

This topic explains how to use the Drools operator, how to prepare a rules file and Java Interface file, and how to install the optional Drools Core plug-in into StreamBase Studio.

Introduction

The Drools operator is a member of the Java Operator group in the Palette view in StreamBase Studio. Select the Drools operator from the Insert an Operator or Adapter dialog, which you invoke with one of the following methods:

  • Drag the Adapters, Java Operators token from the Operators and Adapters drawer of the Palette view to the canvas.

  • Click in the canvas where you want to place the operator, and invoke the keyboard shortcut O V

  • From the top-level menu, invoke InsertOperatorJava.

From the Insert an Operator or Adapter dialog that opens, select Drools and double-click or press OK.

The Drools operator is a Java operator that provides a way for StreamBase applications to implement rule-based decision-making in the course of an EventFlow application. This operator embeds version 5.0 of the Drools Core rules engine, also known as JBoss Rules. The Drools operator currently only supports a Stateless Knowledge Session, as described in the Drools Core documentation.

Drools Core is available as an Eclipse plug-in that can be installed in StreamBase Studio (or in an independent installation of Eclipse) for assistance while authoring rules. See Studio Integration with JBoss Drools Core for installation instructions.

Integration with Drools Core

Drools Core is a Java-based rules engine, and allows rules to be expressed against facts represented as Java objects. The StreamBase Drools operator supports loading one or more rules from a rules file with .drl extension that you generate with the assistance of Drools Core. The Drools operator does not support the use of a user-defined Domain Specific Language as part of the rules file.

The Drools operator creates a unique stateless session for each operator instance, and asserts every input tuple into the session, causing all registered rules to fire. The rules defined in the rules file associated with a Drools operator are allowed to access fields in the input tuple, and can change the value of fields, but cannot add or remove fields.

Accessing Input Fields in Your Rules File

To allow access to fields in the input tuple in a way compatible with the Drools rules language syntax, you must provide a wrapper Java Interface, which must be written to match the fields you want to access in your rules definitions. This Interface must be declared to the Drools operator using the Tuple Java Interface property, and must:

  • Declare a zero-argument getter method for every tuple field whose value you wish to access from a rule. The getter method must start with get and end in the exact field name, case sensitively, as declared in the StreamBase schemas. (For example, for a field named price, you must provide the method getprice; for a field named Symbol, you must provide the method getSymbol.) Your getter methods must always be declared to return an Object, not the actual type of the tuple field.

    Note

    While field names must exactly match the StreamBase schema field names in the Java interface file, the same rule does NOT apply in your rules file. See the Important note below.

  • Declare a single-argument setter method for every tuple field whose value you wish to modify from a rule. The naming convention is the same as that for the getter methods. For example, declare the setRoutable method for a field named Routable. The setter method must be declared to return void, and its single argument must be of type Object.

The following example interface is named com.streambase.sample.drools.IOrder, and allows the Drools rules engine to access the fields Routable, price, Volume, PM, and MaRkEt in the input tuple, and to modify the field Routable:

package com.streambase.sample.drools;

public interface IOrder {
    public void setRoutable(Object o);
    public Object getprice();
    public Object getVolume();
    public Object getPM();
    public Object getMaRkEt();
}

Use your Interface as follows:

  • Specify the qualified name of the interface in the Properties view for the Drools operator, in the Operator Properties tab, the Tuple Java Interface field.

  • Import the Interface in the rules file. For example, a rules file that uses the example Interface above must contain the line:

    import com.streambase.sample.drools.IOrder
  • Use the interface's data type to access tuple field values in your rules file. For example, a rules file might contain the following as part of a rule:

    when
        IOrder( volume > 1000 )

    This rule fragment retrieves the current tuple's value for field Volume and compares it to one thousand.

    Important

    Observe the following rules for tuple field names in your rules file:

    • If the field name has mixed case in the StreamBase schema, convert the first letter to lowercase, but otherwise preserve the case of the field name in your rules file.

    • If the tuple field name is all uppercase in the schema, preserve all uppercase in your rules file.

    • If the tuple field name is all lowercase in the schema, preserve all lowercase in your rules file.

    For example, use the following field names in a rules file associated with the IOrder interface example above:

    Field Name in StreamBase Schema Interface getter method Field Name in Rules File
    Routable getRoutable() routable
    price getprice() price
    Volume getVolume() volume
    PM getPM() PM
    MaRkEt getMaRkEt() maRkEt

Limitations when accessing fields:

  • Nested fields cannot be accessed by using the usual StreamBase dotted name notation, because doing so would break the syntax allowed by the rules file. Instead, use two underscores instead of a period to access sub-fields.

    For example, to access the tuple field Metadata.LastPrice, declare a method in the interface named getMetadata__LastPrice. Then access this field in the rules file as metadata__LastPrice.

  • Blobs are not supported.

  • Lists, when accessed via the Java Interface, are reflected to the Drools Core rules engine as a Java Collection, which allows you to use the contains keyword (and other keywords). However, you must declare the list as a list of longs to prevent the Drools engine from comparing list values against a constant in a way that fails.

    For example, consider the following Drools statement:

    MyInterface( MyList contains 1979 ) 

    This rule fragment succeeds only if MyList is declared in StreamBase as a list of type long. A list of integers or doubles, even if it contains the numeric value 1979 in the list, does not match the condition shown.

  • The matches and not matches Drools keywords only operate on string values. StreamBase tuple field values are not automatically coerced to strings when using these keywords. Instead, use the toString method of the field object in your rules file. For example:

    InputFields ( symbol.toString matches "(A).*" )

Studio Integration with JBoss Drools Core

StreamBase Studio needs no additional configuration or installation in order to make use of the Drools operator in an EventFlow or StreamSQL application. To use the operator, you only need to provide a valid rules file with .drl extension and a valid Java Interface file, as described above.

However, there is one reason to consider installing the JBoss Drools Core Eclipse plug-in into StreamBase Studio:

  • Without the plug-in, Studio provides only a plain text editor for authoring your rules files. The Drools Core plug-in provides a rich rules file editor with color syntax highlighting, auto-completion, syntax validation, and other features.

For these reasons, Studio supports the installation of the JBoss Drools Core Eclipse plug-in. Follow these steps:

  1. Go to the Drools download page on the JBoss Tools site.

    1. In the Update Sites section, select the link in the Stable Releases column for the Eclipse version that forms the basis of StreamBase Studio — either Eclipse 3.5.2 for StreamBase 6.x or Eclipse 3.6.2 for StreamBase 7.x.

    2. Preserve the URL provided in the selected link. (For example, in Firefox, right-click the link and select Copy Link Location from the context menu.) Do not download the plug-in from the linked page, just copy the URL.

  2. In Studio, invoke HelpInstall New Software. Use the Add button to set up an Eclipse update site named JBoss Tools, using the URL you obtained in step 1.

  3. In the Work with field, select the newly added JBoss Tools site. After a moment, this displays a list of tool categories available from the site.

  4. In the search field, enter Drools to narrow the options to the selections containing the word Drools.

  5. Select JBoss Drools Core from one category. The Drools Core plug-in may appear in more than one category, but you only need to select one instance.

  6. Click Next and continue through the steps to download and install the plug-in. Restart Studio when prompted.

  7. The rules file editor now provides syntax validation and other features, and it verifies that your Java wrapper Interface provides the correct methods.

The following shows the limitations of using the Drools Core plug-in as part of StreamBase Studio:

  • The Drools rules editor cannot verify that the Java wrapper Interface and the StreamBase input schema match in any way. It can only verify a match between the Interface methods and the property names used in the rules text.

  • Studio provides no support for testing or debugging rules files authored for an EventFlow application using the Drools Rules plug-in's debugger.

  • StreamBase supports Drools Core 5.0, and the base StreamBase installation includes version 5.0 of the Drools JAR files. By contrast the Drools Core plug-ins from JBoss Tools 3.1 includes Drools 5.1 JAR files, while JBoss Tools 3.2 includes Drools 5.2 JAR files.

    Studio can interoperate cleanly with the Drools Core plug-in as long as you follow a few rules:

    • Do not run ConfigureConvert to Drools Projecton any StreamBase project in Studio. Doing so attempts to add the Drools Core plug-in's Drools JAR files to the Java Build Path, and the plug-in's JAR files conflict with the Drools JAR files already embedded with your StreamBase installation.

    • To use features of the Drools Core plug-in other than the rules file editor, set up an independent project in Studio that does not include any StreamBase files. You are free to run ConfigureConvert to Drools Project on such independent project folders. For this to work, you must configure the location of a separate set of Drools JAR files, using the WindowPreferencesDroolsInstalled Drools Runtime preference page. Click the Add button and use the Create a new Drools 5 Runtime button to copy the plug-in's JAR files to a local file system location such as C:\Drools or /home/sbuser/droolsruntime.

    • If you configure a separate set of runtime Drools JAR files as above, remember to clear the checkbox in the WindowPreferencesDroolsInstalled Drools Runtime preferences page before running a StreamBase module that uses the Drools operator.

Deployment Considerations

The StreamBase Drools operator includes the necessary Drools 5 runtime libraries to execute without additional end-user configuration in Studio. The Drools 5 libraries are provided in the lib/ext directory of your StreamBase installation.

For deployment of an application that uses the Drools operator, TIBCO recommends creating and running a StreamBase bundle file as described in Application Bundling. A bundle file created in Studio contains everything required to invoke the Drools rules engine at runtime from within StreamBase Server.

If you prefer to run the sbd server using a manually-edited server configuration file, you are responsible for placing the Tuple Wrapper Interface on the classpath of StreamBase Server.

Drools Operator Sample

StreamBase includes a sample for the Drools operator, which includes a dynamic rule port. See Drools Operator Sample for instructions on locating and running the sample.

Properties View Settings

This section describes the properties you can set for a Drools operator, using the various tabs of the Properties view in StreamBase Studio.

General Tab

This section describes the properties on the General tab in the Properties view for the Drools operator.

Name: Use this required field to specify or change the name of this instance of this component, which must be unique in the current EventFlow module. The name must contain only alphabetic characters, numbers, and underscores, and no hyphens or other special characters. The first character must be alphabetic or an underscore.

Operator: A read-only field that shows the formal name of the operator.

Start with application: If this field is set to Yes (default) or to a module parameter that evaluates to true, this instance of this operator starts as part of the JVM engine that runs this EventFlow module. If this field is set to No or to a module parameter that evaluates to false, the operator instance is loaded with the engine, but does not start until you send an sbadmin resume command, or until you start the component with StreamBase Manager.

Class: Shows the fully qualified class name that implements the functionality of this operator. If you need to reference this class name elsewhere in your application, you can right-click this field and select Copy from the context menu to place the full class name in the system clipboard.

Enable Error Output Port: Select this check box to add an Error Port to this component. In the EventFlow canvas, the Error Port shows as a red output port, always the last port for the component. See Using Error Ports to learn about Error Ports.

Description: Optionally enter text to briefly describe the component's purpose and function. In the EventFlow canvas, you can see the description by pressing Ctrl while the component's tooltip is displayed.

Operator Properties Tab

This section describes the properties on the Operator Properties tab in the Properties view for the Drools operator. There are two properties, both required.

Property Description
Tuple Java Interface Select or enter the fully qualified name of a Java Interface type that is used to wrap each input tuple as they are added to the Drools rules engine session. This Interface must be present on the project's Build Path. See Integration with Drools Core for more information on writing this Interface.
Enable dynamic rule port check box, cleared by default. If selected, the operator gains a second input port to be used for dynamic input of rules without restarting the application. This port's required schema is described in the Ports section above; use the port as described in Dynamic Input of Rules.
Enable status port check box, cleared by default. If selected, the operator gains a second output port used convey the status of rules dynamically entered rules.
Rules File Select or enter the initial rules file with .drl extension that contains the rules to evaluate against input tuples. See Integration with Drools Core for more information on authoring a valid rules file.
Log Level Controls the level of verbosity the adapter uses to send notifications to the console. This setting can be higher than the containing application's log level. If set lower, the system log level is used. Available values, in increasing order of verbosity, are: OFF, ERROR, WARN, INFO, DEBUG, TRACE.

Concurrency Tab

Use the Concurrency tab to specify parallel regions for this instance of this component, or multiplicity options, or both. The Concurrency tab settings are described in Concurrency Options, and dispatch styles are described in Dispatch Styles.

Caution

Concurrency settings are not suitable for every application, and using these settings requires a thorough analysis of your application. For details, see Execution Order and Concurrency, which includes important guidelines for using the concurrency options.

Ports

By default, the Drools operator has a single input port and a single output port. If you check the Enable dynamic rule port control, the operator gains a second input port. If you check the Enable status port control, the operator gains a second output port.

On the primary input port, there are no restrictions on the input schema (except that field values of type blob are not supported). On the first output port, the output schema is always the same as the input schema. The embedded Drools rules engine can read and modify field values from its input, but cannot add or remove fields.

The dynamic rule input port, if enabled, must be connected to an input stream whose schema has a field of type string with field name NewRules. A typecheck error results if this condition is not met. The dynamic rules port can have other fields, but the operator ignores them.

The status port, if enabled, conveys the status of dynamically entered rules. It has three fields:

  • RulesAccepted, a boolean that contains true if the rule entered on the control port was accepted and false otherwise

  • ErrorString, which contains the reason a rule was rejected and null otherwise

  • InputTuple, which contains a copy of the tuple received by the adapter on the dynamic rule input port

You can also add an optional Error Output port, which outputs a StreamBase error tuple for any error thrown by the operator, as described in General Tab.

Dynamic Input of Rules

You can optionally enable a dynamic rules input port that allows you to specify a new set of rules for the Drools operator without restarting the application. A valid new rule set replaces the initial rule set and takes effect immediately. The replacement is comprehensive, so you must replace all currently running rules, even if you intend to update only one rule of a set.

Use the Enable dynamic rule port check box on the Operator Properties page to enable a rules port. Connect an input stream to this port, whose schema includes a string field named NewRules.

Specify one or more new Drools rules on this port by enqueuing a rules string (not a file name). New rules must be specified in a continuous string with no embedded newlines. Be sure to include any import lines in your rules string, just as you would use in a .drl file.

For example, the following rules string represents the same rule in the Drools sample rules file, except the volume > 1000 portion is replaced with volume > 500. This example is shown for publication clarity on multiple lines, but should be entered as one continuous string:

import com.streambase.sample.drools.IOrder; rule "large-orders" 
no-loop true when $t : IOrder( volume > 500 ) then modify( $t )
{ setRoutable(false) } end 

A new set of rules entered on the rules port, if valid, completely replaces the previous set of rules. If you enqueue an invalid rules string, an exception is thrown and the previous rule set remains in force. If you enable the optional status port, the validity of the rules string is reported on the status port.