Templates in JBoss Drools

    Terms and definitions

    DRL is short for Drools Rules Language, a format for drools rules writing.
    KIE is a public API developed by JBoss, it includes several technologies, including Droоls.
    MVEL is a hybrid dynamically/statically typed, embedded expression language in the runtime environment for the Java platform.

    Introduction

    Drools rules templates are a way to generate rules “at once” using files template and tabular data sources. By tabular data sources we mean data that can be presented in a table. Typical examples of this kind of data sources are spreadsheets and tables in databases.

    One of the most common problems when working with Drools is rules generation, if they have an equivalent structure but different values ​​in when and/or then blocks. One of the ways to solve this scenario is to use templates.

    Templates have several advantages over regular rules:

    • allow storing data used in a rule, in a database (or other format);
    • generate rules based on values ​​in data sources;
    • use data for any part of the rule (for example, property name, template name, etc.);
    • run different templates using the same data.

    Another big advantage of rule templates is that data and structure of rules are completely separate from each other. The same template can be used for different data, and the same data set can be used for different templates. This provides flexibility over conventional rules.

    Template structure

    power-for-gpu.drl

    Line 1: all templates begin with a header – “template header”

    Lines 2-4: a list of template variables in the order they appear from the source.

    Line 5: an empty line defining the end of the field declaration from the template.

    Line 6-9: declarations standard for drools.

    Line 10: the keyword “template” signaling the start of the rule template. A template file can have multiple templates. A template must have a unique name.

    Line 12-19: template body. Rules templates are built on MVEL to substitute variables inside the rule using the syntax @ {token_name}, where token_name is the name of the template variable. In this example, the expression @ {row.rowNumber} is used, using which we can get the number of the data line, which allows us to generate a unique name for the rule.

    Line 20: “end template” signals the end of the rule template.

    For each data line, a rule will be generated with data values, replaced for tokens in the template.

    One of the advantage of templates over another similar parameterization mechanism in Drools is decision table, means that the variables in the rule template can be used anywhere in the rule: the name of the template, the name of the property, etc. Variables can also be used in any order and used several times if necessary.

    Creating of a dataset for a template

    To create data sets used in templates, drools templates classes are defined in the Drools library. These classes are required to analyse the template and create a DRL from a dataset. The following things are supported as a source for a dataset: arrays, objects, spreadsheets, and SQL result sets.

    Working with rule templates

    For templates used on the basis of spreadsheets, Drools supports their definition in the kmodule.xml file using a special configuration element based on KIE Base:

    The given code snippet above shows how power-for-gpu.drt template with a data source from spreadsheet named template-data.xls is included in template-KBase KIE Base.

    Next programmatic approach will be used to fill templates. In the following examples, the DRL template is filled, and then a KIE session is created on its basis.

    The following examples will use helper method to create a KIE session based on a DRL string:

    The specified method based on DRL string as a parameter, using KieHelper class, compiles and creates KIE base. This method also checks for errors or warnings during DRL compilation. As soon as KIE base is built, the method returns new KIE session.

    Spreadsheets as a data source

    Rather popular and convenient solution is use of spreadsheets as a data source for template, as to fill it out, a person does not need to have deep technical skills and change code, work happens directly in the spreadsheet.

    The table below uses only necessary data for template and useful headers for the person who needs to edit the table. The table does not contain any information about the template to be used and the structure of the rules to be created.

    To convert this to a DRL table, we use a template file created earlier (power-for-gpu.drl) and createKieSessionFromDRL helper method.

    The first two lines of code get a template and a data source file, like InputStream objects. The fourth line uses the object of the ExternalSpreadsheetCompiler helper class to convert the template file and data to a DRL table. Compile method from ExternalSpreadsheetCompile takes four arguments: data source, template, line, and column inside the table where data begins.

    Array as a data source

    Another way of providing data to a template is a two-dimensional string array. In this case, the first dimension of array is used as a line, and the second dimension as a column.

    The above code shows how an instance of DataProviderCompiler class can be used to process a template using a two-dimensional array of strings as a data source. Data is encapsulated inside an arrayDataProvider instance. ArrayDataProvider class implements DataProvider interface. If you need to create a special, customizable source of information that you need to upload into a rule template, you must implement your own DataProvider and associate it with template using DataProviderCompiler.

    Objects as a data source

    A more objectively oriented approach to providing data in a template is the use of objects as a model. Instead of a two-dimensional array of strings, sets of objects are used to store the data required by our templates.

    As an example, we will create a data storage class for our scenario:

    When objects are used as a template data source, names of the variables declared in the template header must match the field names in the model class.

    The above code shows how the collection of PowerForGPUModel objects is used as the data source for the template.

    SQL result set as a data source

    The final data source option for templates is SQL result sets. SQL result set refers to java.sql.ResultSet class. An instance of this class can be obtained in various ways, for example, using JDBC.

    Let’s suppose we have a table named GPU in database:

    If we want to use the information from this table to create a DRL using a rule template, we can use the following code:

    The above example uses the standard JDBC classes: Connection, Statement, and ResultSet. First, a query is made to the GPU table and receives its result as a ResultSet. Then, using the class from the Drools library – ResultSetGenerator, we convert the ResultSet and the template to DRL.

    Conclusion

    Rule templates are a useful mechanism for generating rules that have a similar structure but different values in the “when” and/or “then” blocks. Using templates in Drools, the parameterization problem is solved. Also, the Drools library allows you to use different structures as data sources for the template, which facilitates the work of developers.