Chapter 19. Executing rules

After you identify example rules or create your own rules in Business Central, you can build and deploy the associated project and execute rules locally or on KIE Server to test the rules.

Prerequisites

Procedure

  1. In Business Central, go to MenuDesignProjects and click the project name.
  2. In the upper-right corner of the project Assets page, click Deploy to build the project and deploy it to KIE Server. If the build fails, address any problems described in the Alerts panel at the bottom of the screen.

    For more information about project deployment options, see Packaging and deploying an Red Hat Decision Manager project.

    Note

    If the rule assets in your project are not built from an executable rule model by default, verify that the following dependency is in the pom.xml file of your project and rebuild the project:

    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-model-compiler</artifactId>
      <version>${rhpam.version}</version>
    </dependency>

    This dependency is required for rule assets in Red Hat Decision Manager to be built from executable rule models by default. This dependency is included as part of the Red Hat Decision Manager core packaging, but depending on your Red Hat Decision Manager upgrade history, you may need to manually add this dependency to enable the executable rule model behavior.

    For more information about executable rule models, see Packaging and deploying an Red Hat Decision Manager project.

  3. Create a Maven or Java project outside of Business Central, if not created already, that you can use for executing rules locally or that you can use as a client application for executing rules on KIE Server. The project must contain a pom.xml file and any other required components for executing the project resources.

    For example test projects, see "Other methods for creating and executing DRL rules".

  4. Open the pom.xml file of your test project or client application and add the following dependencies, if not added already:

    • kie-ci: Enables your client application to load Business Central project data locally using ReleaseId
    • kie-server-client: Enables your client application to interact remotely with assets on KIE Server
    • slf4j: (Optional) Enables your client application to use Simple Logging Facade for Java (SLF4J) to return debug logging information after you interact with KIE Server

    Example dependencies for Red Hat Decision Manager 7.13 in a client application pom.xml file:

    <!-- For local execution -->
    <dependency>
      <groupId>org.kie</groupId>
      <artifactId>kie-ci</artifactId>
      <version>7.67.0.Final-redhat-00024</version>
    </dependency>
    
    <!-- For remote execution on KIE Server -->
    <dependency>
      <groupId>org.kie.server</groupId>
      <artifactId>kie-server-client</artifactId>
      <version>7.67.0.Final-redhat-00024</version>
    </dependency>
    
    <!-- For debug logging (optional) -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-simple</artifactId>
      <version>1.7.25</version>
    </dependency>

    For available versions of these artifacts, search the group ID and artifact ID in the Nexus Repository Manager online.

    Note

    Instead of specifying a Red Hat Decision Manager <version> for individual dependencies, consider adding the Red Hat Business Automation bill of materials (BOM) dependency to your project pom.xml file. The Red Hat Business Automation BOM applies to both Red Hat Decision Manager and Red Hat Process Automation Manager. When you add the BOM files, the correct versions of transitive dependencies from the provided Maven repositories are included in the project.

    Example BOM dependency:

    <dependency>
      <groupId>com.redhat.ba</groupId>
      <artifactId>ba-platform-bom</artifactId>
      <version>7.13.5.redhat-00002</version>
      <scope>import</scope>
      <type>pom</type>
    </dependency>

    For more information about the Red Hat Business Automation BOM, see What is the mapping between Red Hat Process Automation Manager and the Maven library version?.

  5. Ensure that the dependencies for artifacts containing model classes are defined in the client application pom.xml file exactly as they appear in the pom.xml file of the deployed project. If dependencies for model classes differ between the client application and your projects, execution errors can occur.

    To access the project pom.xml file in Business Central, select any existing asset in the project and then in the Project Explorer menu on the left side of the screen, click the Customize View gear icon and select Repository Viewpom.xml.

    For example, the following Person class dependency appears in both the client and deployed project pom.xml files:

    <dependency>
      <groupId>com.sample</groupId>
      <artifactId>Person</artifactId>
      <version>1.0.0</version>
    </dependency>
  6. If you added the slf4j dependency to the client application pom.xml file for debug logging, create a simplelogger.properties file on the relevant classpath (for example, in src/main/resources/META-INF in Maven) with the following content:

    org.slf4j.simpleLogger.defaultLogLevel=debug
  7. In your client application, create a .java main class containing the necessary imports and a main() method to load the KIE base, insert facts, and execute the rules.

    For example, a Person object in a project contains getter and setter methods to set and retrieve the first name, last name, hourly rate, and the wage of a person. The following Wage rule in a project calculates the wage and hourly rate values and displays a message based on the result:

    package com.sample;
    
    import com.sample.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

    To test this rule locally outside of KIE Server (if needed), configure the .java class to import KIE services, a KIE container, and a KIE session, and then use the main() method to fire all rules against a defined fact model:

    Executing rules locally

    import org.kie.api.KieServices;
    import org.kie.api.builder.ReleaseId;
    import org.kie.api.runtime.KieContainer;
    import org.kie.api.runtime.KieSession;
    import org.drools.compiler.kproject.ReleaseIdImpl;
    
    public class RulesTest {
    
      public static final void main(String[] args) {
        try {
          // Identify the project in the local repository:
          ReleaseId rid = new ReleaseIdImpl("com.myspace", "MyProject", "1.0.0");
    
          // Load the KIE base:
          KieServices ks = KieServices.Factory.get();
          KieContainer kContainer = ks.newKieContainer(rid);
          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();
          kSession.dispose();
        }
    
        catch (Throwable t) {
          t.printStackTrace();
        }
      }
    }

    To test this rule on KIE Server, configure the .java class with the imports and rule execution information similarly to the local example, and additionally specify KIE services configuration and KIE services client details:

    Executing rules on KIE Server

    package com.sample;
    
    import java.util.ArrayList;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    
    import org.kie.api.command.BatchExecutionCommand;
    import org.kie.api.command.Command;
    import org.kie.api.KieServices;
    import org.kie.api.runtime.ExecutionResults;
    import org.kie.api.runtime.KieContainer;
    import org.kie.api.runtime.KieSession;
    import org.kie.server.api.marshalling.MarshallingFormat;
    import org.kie.server.api.model.ServiceResponse;
    import org.kie.server.client.KieServicesClient;
    import org.kie.server.client.KieServicesConfiguration;
    import org.kie.server.client.KieServicesFactory;
    import org.kie.server.client.RuleServicesClient;
    
    import com.sample.Person;
    
    public class RulesTest {
    
      private static final String containerName = "testProject";
      private static final String sessionName = "myStatelessSession";
    
      public static final void main(String[] args) {
        try {
          // Define KIE services configuration and client:
          Set<Class<?>> allClasses = new HashSet<Class<?>>();
          allClasses.add(Person.class);
          String serverUrl = "http://$HOST:$PORT/kie-server/services/rest/server";
          String username = "$USERNAME";
          String password = "$PASSWORD";
          KieServicesConfiguration config =
            KieServicesFactory.newRestConfiguration(serverUrl,
                                                    username,
                                                    password);
          config.setMarshallingFormat(MarshallingFormat.JAXB);
          config.addExtraClasses(allClasses);
          KieServicesClient kieServicesClient =
            KieServicesFactory.newKieServicesClient(config);
    
          // Set up the fact model:
          Person p = new Person();
          p.setWage(12);
          p.setFirstName("Tom");
          p.setLastName("Summers");
          p.setHourlyRate(10);
    
          // Insert Person into the session:
          KieCommands kieCommands = KieServices.Factory.get().getCommands();
          List<Command> commandList = new ArrayList<Command>();
          commandList.add(kieCommands.newInsert(p, "personReturnId"));
    
          // Fire all rules:
          commandList.add(kieCommands.newFireAllRules("numberOfFiredRules"));
          BatchExecutionCommand batch = kieCommands.newBatchExecution(commandList, sessionName);
    
          // Use rule services client to send request:
          RuleServicesClient ruleClient = kieServicesClient.getServicesClient(RuleServicesClient.class);
          ServiceResponse<ExecutionResults> executeResponse = ruleClient.executeCommandsWithResults(containerName, batch);
          System.out.println("number of fired rules:" + executeResponse.getResult().getValue("numberOfFiredRules"));
        }
    
        catch (Throwable t) {
          t.printStackTrace();
        }
      }
    }

  8. Run the configured .java class from your project directory. You can run the file in your development platform (such as Red Hat CodeReady Studio) or in the command line.

    Example Maven execution (within project directory):

    mvn clean install exec:java -Dexec.mainClass="com.sample.app.RulesTest"

    Example Java execution (within project directory)

    javac -classpath "./$DEPENDENCIES/*:." RulesTest.java
    java -classpath "./$DEPENDENCIES/*:." RulesTest
  9. Review the rule execution status in the command line and in the server log. If any rules do not execute as expected, review the configured rules in the project and the main class configuration to validate the data provided.