Chapter 5. Other methods for creating DRL files

As an alternative to creating and managing DRL files within the Decision Central interface, you can create DRL files in external standalone projects using Red Hat Developer Studio, Java objects, or Maven archetypes. These standalone projects can then be integrated as knowledge JAR (kJAR) dependencies in existing Red Hat Decision Manager projects in Decision Central. The DRL files in your standalone project must contain at minimum the required package specification, import lists, and rule definitions. Any other DRL components, such as global variables and functions, are optional. All data objects related to a DRL rule must be included with your standalone DRL project or deployment.

5.1. Creating DRL files in Red Hat JBoss Developer Studio

You can use Red Hat JBoss Developer Studio to create DRL files with rules and integrate the files with your Red Hat Decision Manager decision service. This method of creating DRL rules is helpful if you already use Red Hat Developer Studio for your decision service and want to continue with the same work flow. If you do not already use this method, then the Decision Central interface of Red Hat Decision Manager is recommended for creating DRL files and other rule assets.

Prerequisite

Red Hat JBoss Developer Studio has been installed from the Red Hat Customer Portal.

Procedure

  1. In the Red Hat JBoss Developer Studio, click FileNewProject.
  2. In the New Project window that opens, select DroolsDrools Project and click Next.
  3. Click the second icon to Create a project and populate it with some example files to help you get started quickly. Click Next.
  4. Enter a Project name and select the Maven radio button as the project building option. The GAV values are generated automatically. You can update these values as needed for your project:

    • Group ID: com.sample
    • Artifact ID: my-project
    • Version: 1.0.0-SNAPSHOT
  5. Click Finish to create the project.

    This configuration sets up a basic project structure, class path, and sample rules. The following is an overview of the project structure:

    my-project
     `-- src/main/java
        | `-- com.sample
        |    `-- DecisionTable.java
        |    `-- DroolsTest.java
        |    `-- ProcessTest.java
        |
     `-- src/main/resources
        | `-- dtables
        |    `-- Sample.xls
        | `-- process
        |    `-- sample.bpmn
        | `-- rules
        |    `-- Sample.drl
        | `-- META-INF
        |
     `-- JRE System Library
        |
     `-- Maven Dependencies
        |
     `-- Drools Library
        |
     `-- src
        |
     `-- target
        |
     `-- pom.xml

    Notice the following elements:

    • A Sample.drl rule file in the src/main/resources directory, containing an example Hello World and GoodBye rules.
    • A DroolsTest.java file under the src/main/java directory in the com.sample package. The DroolsTest class can be used to execute rules.
    • The Drools Library directory, which acts as a custom class path containing JAR files necessary for execution.
  6. Create a fact model with all necessary data objects for the DRL file.

    The DroolsTest.java file contains a sample Java object Message with getter and setter methods. You can edit this class or create a different Java object. In this example, a class Person containing methods to set and retrieve the first name, last name, hourly rate, and wage of a person is used.

    public static class Person {
    
      private String firstName;
      private String lastName;
      private Integer hourlyRate;
      private Integer wage;
    
      public String getFirstName() {
        return firstName;
      }
    
      public void setFirstName(String firstName) {
        this.firstName = firstName;
      }
    
      public String getLastName() {
        return lastName;
      }
    
      public void setLastName(String lastName) {
        this.lastName = lastName;
      }
    
      public Integer getHourlyRate() {
        return hourlyRate;
      }
    
      public void setHourlyRate(Integer hourlyRate) {
        this.hourlyRate = hourlyRate;
      }
    
      public Integer getWage(){
        return wage;
      }
    
      public void setWage(Integer wage){
        this.wage = wage;
      }
    }
  7. Update the main() method to pass the Java object to a rule.

    The DroolsTest.java file contains a main() method that loads the knowledge base, inserts facts, and executes rules. The following method update passes the object Person to a rule:

    public static final void main(String[] args) {
      try {
        // Load the knowledge base:
        KieServices ks = KieServices.Factory.get();
        KieContainer kContainer = ks.getKieClasspathContainer();
        KieSession kSession = kContainer.newKieSession("ksession-rules");
    
        // Go!
        Person p = new Person();
        p.setWage(12);
        p.setFirstName("Tom");
        p.setLastName("Summers");
        p.setHourlyRate(10);
    
        kSession.insert(p);
        kSession.fireAllRules();
      }
    
      catch (Throwable t) {
        t.printStackTrace();
      }
    }

    To load the knowledge base, get a KieServices instance and a class-path-based KieContainer and build the KieSession with the KieContainer. In the previous example, a session ksession-rules matching the one defined in kmodule.xml file is passed.

  8. Create a DRL file containing at minimum a package specification, an import list of data objects to be used by the rule or rules, and one or more rules with when conditions and then actions.

    The rule file Sample.drl contains an example of two rules. You can edit this file or create a new one.

    package com.sample
    
    import com.sample.DroolsTest.Person;
    
    dialect "java"
    
    rule "Wage"
      when
        Person(hourlyRate * wage > 100)
        Person(name : firstName, surname : lastName)
      then
        System.out.println("Hello" + " " + name + " " + surname + "!");
        System.out.println("You are rich!");
    end
  9. Go to FileSave to save the file.
  10. After you create and save all DRL assets in your project, right-click your project folder and select Run AsJava Application to build the project. If the project build fails, address any problems described in the Problems tab of the lower window in Developer Studio, and try again to validate the project until the project builds.
If the Run AsJava Application option is not available

If Java Application is not an option when you right-click your project and select Run As, then go to Run AsRun Configurations, right-click Java Application, and click New. Then in the Main tab, browse for and select your Project and the associated Main class. Click Apply and then click Run to test the project. The next time you right-click your project folder, the Java Application option will appear.

To integrate the new rule assets with an existing project in Red Hat Decision Manager, you can compile the new project as a knowledge JAR (kJAR) and add it as a dependency in the pom.xml file of the project in Decision Central.

5.2. Creating DRL files using Java

You can use Java objects to create DRL files with rules and integrate the objects with your Red Hat Decision Manager decision service. This method of creating DRL rules is helpful if you already use external Java objects for your decision service and want to continue with the same work flow. If you do not already use this method, then the Decision Central interface of Red Hat Decision Manager is recommended for creating DRL files and other rule assets.

Procedure

  1. Create a Java object on which the rule or rules will operate.

    In this example, a Person.java file in a directory my-project is created. The Person class contains getter and setter methods to set and retrieve the first name, last name, hourly rate, and the wage of a person:

      public class Person {
        private String firstName;
        private String lastName;
        private Integer hourlyRate;
        private Integer wage;
    
        public String getFirstName() {
          return firstName;
        }
    
        public void setFirstName(String firstName) {
          this.firstName = firstName;
        }
    
        public String getLastName() {
          return lastName;
        }
    
        public void setLastName(String lastName) {
          this.lastName = lastName;
        }
    
        public Integer getHourlyRate() {
          return hourlyRate;
        }
    
        public void setHourlyRate(Integer hourlyRate) {
          this.hourlyRate = hourlyRate;
        }
    
        public Integer getWage(){
          return wage;
        }
    
        public void setWage(Integer wage){
          this.wage = wage;
        }
      }
  2. Create a rule file in .drl format under the my-project directory.

    The following Person.drl rule calculates the wage and hourly rate values and displays a message based on the result:

    dialect "java"
    
    rule "Wage"
      when
        Person(hourlyRate * wage > 100)
        Person(name : firstName, surname : lastName)
      then
        System.out.println("Hello" + " " + name + " " + surname + "!");
        System.out.println("You are rich!");
    end
  3. Create a main class and save it to the same directory as the Java object that you created. The main class will load the knowledge base and execute rules.
  4. In the main class, add the required import statements to import KIE services, a KIE container, and a KIE session. Then load the knowledge base, insert facts, and execute the rule from the main() method that passes the fact model to the rule.

    In the following example, the required imports are listed and a main class DroolsTest.java is created:

    import org.kie.api.KieServices;
    import org.kie.api.runtime.KieContainer;
    import org.kie.api.runtime.KieSession;
    
    public class DroolsTest {
      public static final void main(String[] args) {
        try {
          // Load the knowledge base:
          KieServices ks = KieServices.Factory.get();
          KieContainer kContainer = ks.getKieClasspathContainer();
          KieSession kSession = kContainer.newKieSession();
    
          // Go!
          Person p = new Person();
          p.setWage(12);
          p.setFirstName("Tom");
          p.setLastName("Summers");
          p.setHourlyRate(10);
    
          kSession.insert(p);
          kSession.fireAllRules();
        }
    
        catch (Throwable t) {
          t.printStackTrace();
        }
      }
    }
  5. Download the Red Hat Decision Manager 7.0 Core Engine ZIP file from the Red Hat Customer Portal and extract it under my-project/dm-engine-jars/.
  6. In the my-project/META-INF directory, create a kmodule.xml metadata file with the following content:

    <?xml version="1.0" encoding="UTF-8"?>
    <kmodule xmlns="http://www.drools.org/xsd/kmodule">
    </kmodule>

    This kmodule.xml file is a descriptor that selects resources to knowledge bases and configures sessions. This file enables you to define and configure one or more KIE bases, and to include DRL files from specific packages in a specific KIE base. You can also create one or more KIE sessions from each KIE base.

    The following example shows a more advanced kmodule.xml file:

    <?xml version="1.0" encoding="UTF-8"?>
    <kmodule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.drools.org/xsd/kmodule">
      <kbase name="KBase1" default="true" eventProcessingMode="cloud" equalsBehavior="equality" declarativeAgenda="enabled" packages="org.domain.pkg1">
        <ksession name="KSession1_1" type="stateful" default="true" />
        <ksession name="KSession1_2" type="stateless" default="false" beliefSystem="jtms" />
      </kbase>
      <kbase name="KBase2" default="false" eventProcessingMode="stream" equalsBehavior="equality" declarativeAgenda="enabled" packages="org.domain.pkg2, org.domain.pkg3" includes="KBase1">
        <ksession name="KSession2_1" type="stateful" default="false" clockType="realtime">
          <fileLogger file="debugInfo" threaded="true" interval="10" />
          <workItemHandlers>
            <workItemHandler name="name" type="new org.domain.WorkItemHandler()" />
          </workItemHandlers>
          <listeners>
            <ruleRuntimeEventListener type="org.domain.RuleRuntimeListener" />
            <agendaEventListener type="org.domain.FirstAgendaListener" />
            <agendaEventListener type="org.domain.SecondAgendaListener" />
            <processEventListener type="org.domain.ProcessListener" />
          </listeners>
        </ksession>
      </kbase>
    </kmodule>

    This example defines two KIE bases. Two KIE sessions are instantiated from the KBase1 KIE base, and one KIE session from KBase2. Specific packages of rule assets are included with both KIE bases. When you specify packages in this way, you must organize your DRL files in a folder structure that reflects the specified packages.

  7. After you create and save all DRL assets in your Java object, navigate to the my-project directory in the command line and run the following command to build your Java files. Replace DroolsTest.java with the name of your Java main class.

    javac -classpath "./dm-engine-jars/*:." DroolsTest.java

    If the build fails, address any problems described in the command line error messages, and try again to validate the Java object until the object passes.

  8. After your Java files build successfully, run the following command to execute the rules. Replace DroolsTest with the prefix of your Java main class.

    javac -classpath "./dm-engine-jars/*:." DroolsTest
  9. Review the rules to ensure that they executed properly, and address any needed changes in the Java files.

To integrate the new rule assets with an existing project in Red Hat Decision Manager, you can compile the new Java project as a knowledge JAR (kJAR) and add it as a dependency in the pom.xml file of the project in Decision Central.

5.3. Creating DRL files using Maven

You can use Maven archetypes to create DRL files with rules and integrate the archetypes with your Red Hat Decision Manager decision service. This method of creating DRL rules is helpful if you already use external Maven archetypes for your decision service and want to continue with the same work flow. If you do not already use this method, then the Decision Central interface of Red Hat Decision Manager is recommended for creating DRL files and other rule assets.

Procedure

  1. Navigate to a directory where you want to create a Maven archetype and run the following command:

    mvn archetype:generate -DgroupId=com.sample.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

    This creates a directory my-app with the following structure:

    my-app
    |-- pom.xml
    `-- src
        |-- main
        |   `-- java
        |       `-- com
        |           `-- sample
        |               `-- app
        |                   `-- App.java
        `-- test
            `-- java
                `-- com
                    `-- sample
                        `-- app
                            `-- AppTest.java

    The my-app directory contains the following key components:

    • A src/main directory for storing the application sources
    • A src/test directory for storing the test sources
    • A pom.xml file with the project configuration
  2. Create a Java object on which the rule or rules will operate within the Maven archetype.

    In this example, a Person.java file in the directory my-app/src/main/java/com/sample/app is created. The Person class contains getter and setter methods to set and retrieve the first name, last name, hourly rate, and the wage of a person:

    package com.sample.app;
    
      public class Person {
    
        private String firstName;
        private String lastName;
        private Integer hourlyRate;
        private Integer wage;
    
        public String getFirstName() {
          return firstName;
        }
    
        public void setFirstName(String firstName) {
          this.firstName = firstName;
        }
    
        public String getLastName() {
          return lastName;
        }
    
        public void setLastName(String lastName) {
          this.lastName = lastName;
        }
    
        public Integer getHourlyRate() {
          return hourlyRate;
        }
    
        public void setHourlyRate(Integer hourlyRate) {
          this.hourlyRate = hourlyRate;
        }
    
        public Integer getWage(){
          return wage;
        }
    
        public void setWage(Integer wage){
          this.wage = wage;
        }
      }
  3. Create a rule file in .drl format under the my-app/src/main/resources/rules directory.

    The following Person.drl rule imports the Person class and calculates the wage and hourly rate values and displays a message based on the result:

    package com.sample.app;
    import com.sample.app.Person;
    
    dialect "java"
    
    rule "Wage"
      when
        Person(hourlyRate * wage > 100)
        Person(name : firstName, surname : lastName)
      then
        System.out.println("Hello " + name + " " + surname + "!");
        System.out.println("You are rich!");
    end
  4. In the my-app/src/main/resources/META-INF directory, create a kmodule.xml metadata file with the following content:

    <?xml version="1.0" encoding="UTF-8"?>
    <kmodule xmlns="http://www.drools.org/xsd/kmodule">
    </kmodule>

    This kmodule.xml file is a descriptor that selects resources to knowledge bases and configures sessions. This file enables you to define and configure one or more KIE bases, and to include DRL files from specific packages in a specific KIE base. You can also create one or more KIE sessions from each KIE base.

    The following example shows a more advanced kmodule.xml file:

    <?xml version="1.0" encoding="UTF-8"?>
    <kmodule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.drools.org/xsd/kmodule">
      <kbase name="KBase1" default="true" eventProcessingMode="cloud" equalsBehavior="equality" declarativeAgenda="enabled" packages="org.domain.pkg1">
        <ksession name="KSession1_1" type="stateful" default="true" />
        <ksession name="KSession1_2" type="stateless" default="false" beliefSystem="jtms" />
      </kbase>
      <kbase name="KBase2" default="false" eventProcessingMode="stream" equalsBehavior="equality" declarativeAgenda="enabled" packages="org.domain.pkg2, org.domain.pkg3" includes="KBase1">
        <ksession name="KSession2_1" type="stateful" default="false" clockType="realtime">
          <fileLogger file="debugInfo" threaded="true" interval="10" />
          <workItemHandlers>
            <workItemHandler name="name" type="new org.domain.WorkItemHandler()" />
          </workItemHandlers>
          <listeners>
            <ruleRuntimeEventListener type="org.domain.RuleRuntimeListener" />
            <agendaEventListener type="org.domain.FirstAgendaListener" />
            <agendaEventListener type="org.domain.SecondAgendaListener" />
            <processEventListener type="org.domain.ProcessListener" />
          </listeners>
        </ksession>
      </kbase>
    </kmodule>

    This example defines two KIE bases. Two KIE sessions are instantiated from the KBase1 KIE base, and one KIE session from KBase2. Specific packages of rule assets are included with both KIE bases. When you specify packages in this way, you must organize your DRL files in a folder structure that reflects the specified packages.

  5. In the my-app/pom.xml configuration file, specify the libraries that your application requires. Provide the Red Hat Decision Manager dependencies as well as the group ID, artifact ID, and version (GAV) of your application.

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.sample.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1.0.0</version>
    <repositories>
      <repository>
        <id>jboss-ga-repository</id>
        <url>http://maven.repository.redhat.com/ga/</url>
      </repository>
    </repositories>
    <dependencies>
      <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-compiler</artifactId>
        <version>VERSION</version>
      </dependency>
      <dependency>
        <groupId>org.kie</groupId>
        <artifactId>kie-api</artifactId>
        <version>VERSION</version>
      </dependency>
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
      </dependency>
    </dependencies>
    </project>

    For the Maven artifact version supported in Red Hat Decision Manager, see Installing Red Hat Decision Manager on premise.

  6. Use the testApp method in my-app/src/test/java/com/sample/app/AppTest.java to test the rule. The AppTest.java file is created by Maven by default.
  7. In the AppTest.java file, add the required import statements to import KIE services, a KIE container, and a KIE session. Then load the knowledge base, insert facts, and execute the rule from the testApp() method that passes the fact model to the rule.

    In the following example, the required imports are listed and a fact model DroolsTest.java is created:

    import org.kie.api.KieServices;
    import org.kie.api.runtime.KieContainer;
    import org.kie.api.runtime.KieSession;
    
    public void testApp() {
    
      // Load the knowledge base:
      KieServices ks = KieServices.Factory.get();
      KieContainer kContainer = ks.getKieClasspathContainer();
      KieSession kSession = kContainer.newKieSession();
    
      // Set up the fact model:
      Person p = new Person();
      p.setWage(12);
      p.setFirstName("Tom");
      p.setLastName("Summers");
      p.setHourlyRate(10);
    
      // Insert the person into the session:
      kSession.insert(p);
    
      // Fire all rules:
      kSession.fireAllRules();
    }
  8. After you create and save all DRL assets in your Maven archetype, navigate to the my-app directory in the command line and run the following command to build your files:

    mvn clean install

    The first time you run this command, the build process can take more time than usual. After the build completes, the results are displayed in the command line:

    ...
    
    Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.194 sec
    
    Results :
    
    Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
    
    [INFO]
    ...
    [INFO] --------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] --------------------------------------------------------------
    [INFO] Total time: 6.393 s
    ...
    [INFO] --------------------------------------------------------------
  9. Review the build results to ensure that the build ran properly, and address any errors in the files.

To integrate the new rule assets with an existing project in Red Hat Decision Manager, you can compile the new Maven project as a knowledge JAR (kJAR) and add it as a dependency in the pom.xml file of the project in Decision Central.