Chapter 5. 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 Decision Server to test the rules.
Prerequisites
- Business Central and Decision Server are installed and running. For installation options, see Planning a Red Hat Decision Manager installation.
Procedure
-
In Business Central, go to Menu
Design Projects and click the project name. In the upper-right corner of the project Assets page, click Deploy to build the project and deploy it to Decision 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 a Red Hat Decision Manager project.
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 Decision 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".
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 usingReleaseId
-
kie-server-client
: Enables your client application to interact remotely with assets on Decision Server -
slf4j
: (Optional) Enables your client application to use Simple Logging Facade for Java (SLF4J) to return debug logging information after you interact with Decision Server
Example dependencies for Red Hat Decision Manager 7.3 in a client application
pom.xml
file:<!-- For local execution --> <dependency> <groupId>org.kie</groupId> <artifactId>kie-ci</artifactId> <version>7.18.0.Final-redhat-00002</version> </dependency> <!-- For remote execution on Decision Server --> <dependency> <groupId>org.kie.server</groupId> <artifactId>kie-server-client</artifactId> <version>7.18.0.Final-redhat-00002</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.
NoteInstead 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 projectpom.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.3.0.GA-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 Decision Manager and the Maven library version?.
-
Ensure that the dependencies for artifacts containing model classes are defined in the client application
pom.xml
file exactly as they appear in thepom.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 projectpom.xml
files:<dependency> <groupId>com.sample</groupId> <artifactId>Person</artifactId> <version>1.0.0</version> </dependency>
If you added the
slf4j
dependency to the client applicationpom.xml
file for debug logging, create asimplelogger.properties
file on the relevant classpath (for example, insrc/main/resources/META-INF
in Maven) with the following content:org.slf4j.simpleLogger.defaultLogLevel=debug
In your client application, create a
.java
main class containing the necessary imports and amain()
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 followingWage
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 Decision Server (if desired), configure the
.java
class to import KIE services, a KIE container, and a KIE session, and then use themain()
method to fire all rules against a defined fact model:Executing rules locally
import org.kie.api.KieServices; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; public class RulesTest { public static final void main(String[] args) { try { // Identify the project in the local repository: ReleaseId rid = new ReleaseId(); rid.setGroupId("com.myspace"); rid.setArtifactId("MyProject"); rid.setVersion("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 Decision 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 Decision 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(); } } }
Run the configured
.java
class from your project directory. You can run the file in your development platform (such as Red Hat JBoss Developer 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
- 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.
5.1. Executable rule models
Executable rule models are embeddable models that provide a Java-based representation of a rule set for execution at build time. The executable model is a more efficient alternative to the standard asset packaging in Red Hat Decision Manager and enables KIE containers and KIE bases to be created more quickly, especially when you have large lists of DRL (Drools Rule Language) files and other Red Hat Decision Manager assets. The model is low level and enables you to provide all necessary execution information, such as the lambda expressions for the index evaluation.
Executable rule models provide the following specific advantages for your projects:
-
Compile time: Traditionally, a packaged Red Hat Decision Manager project (KJAR) contains a list of DRL files and other Red Hat Decision Manager artifacts that define the rule base together with some pre-generated classes implementing the constraints and the consequences. Those DRL files must be parsed and compiled when the KJAR is downloaded from the Maven repository and installed in a KIE container. This process can be slow, especially for large rule sets. With an executable model, you can package within the project KJAR the Java classes that implement the executable model of the project rule base and re-create the KIE container and its KIE bases out of it in a much faster way. In Maven projects, you use the
kie-maven-plugin
to automatically generate the executable model sources from the DRL files during the compilation process. -
Run time: In an executable model, all constraints are defined as Java lambda expressions. The same lambda expressions are also used for constraints evaluation, so you no longer need to use
mvel
expressions for interpreted evaluation nor the just-in-time (JIT) process to transform themvel
-based constraints into bytecode. This creates a quicker and more efficient run time. - Development time: An executable model enables you to develop and experiment with new features of the decision engine without needing to encode elements directly in the DRL format or modify the DRL parser to support them.
For query definitions in executable rule models, you can use up to 10 arguments only.
For variables within rule consequences in executable rule models, you can use up to 12 bound variables only (including the built-in drools
variable). For example, the following rule consequence uses more than 12 bound variables and creates a compilation error:
... then $input.setNo13Count(functions.sumOf(new Object[]{$no1Count_1, $no2Count_1, $no3Count_1, ..., $no13Count_1}).intValue()); $input.getFirings().add("fired"); update($input);
5.1.1. Embedding an executable rule model in a Maven project
You can embed an executable rule model in your Maven project to compile your rule assets more efficiently at build time.
Prerequisite
You have a Mavenized project that contains Red Hat Decision Manager business assets.
Procedure
In the
pom.xml
file of your Maven project, ensure that the packaging type is set tokjar
and add thekie-maven-plugin
build component:<packaging>kjar</packaging> ... <build> <plugins> <plugin> <groupId>org.kie</groupId> <artifactId>kie-maven-plugin</artifactId> <version>${rhdm.version}</version> <extensions>true</extensions> </plugin> </plugins> </build>
The
kjar
packaging type activates thekie-maven-plugin
component to validate and pre-compile artifact resources. The<version>
is the Maven artifact version for Red Hat Decision Manager currently used in your project (for example, 7.18.0.Final-redhat-00002). These settings are required to properly package the Maven project.NoteInstead 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 projectpom.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.3.0.GA-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 RHDM product and maven library version?.
Add the following dependencies to the
pom.xml
file to enable rule assets to be built from an executable model:-
drools-canonical-model
: Enables an executable canonical representation of a rule set model that is independent from Red Hat Decision Manager -
drools-model-compiler
: Compiles the executable model into Red Hat Decision Manager internal data structures so that it can be executed by the decision engine
<dependency> <groupId>org.drools</groupId> <artifactId>drools-canonical-model</artifactId> <version>${rhdm.version}</version> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-model-compiler</artifactId> <version>${rhdm.version}</version> </dependency>
-
In a command terminal, navigate to your Maven project directory and run the following command to build the project from an executable model:
mvn clean install -DgenerateModel=<VALUE>
The
-DgenerateModel=<VALUE>
property enables the project to be built as a model-based KJAR instead of a DRL-based KJAR.Replace
<VALUE>
with one of three values:-
YES
: Generates the executable model corresponding to the DRL files in the original project and excludes the DRL files from the generated KJAR. -
WITHDRL
: Generates the executable model corresponding to the DRL files in the original project and also adds the DRL files to the generated KJAR for documentation purposes (the KIE base is built from the executable model regardless). -
NO
: Does not generate the executable model.
Example build command:
mvn clean install -DgenerateModel=YES
-
For more information about packaging Maven projects, see Packaging and deploying a Red Hat Decision Manager project.
5.1.2. Embedding an executable rule model in a Java application
You can embed an executable rule model programmatically within your Java application to compile your rule assets more efficiently at build time.
Prerequisite
You have a Java application that contains Red Hat Decision Manager business assets.
Procedure
Add the following dependencies to the relevant classpath for your Java project:
-
drools-canonical-model
: Enables an executable canonical representation of a rule set model that is independent from Red Hat Decision Manager -
drools-model-compiler
: Compiles the executable model into Red Hat Decision Manager internal data structures so that it can be executed by the decision engine
<dependency> <groupId>org.drools</groupId> <artifactId>drools-canonical-model</artifactId> <version>${rhdm.version}</version> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-model-compiler</artifactId> <version>${rhdm.version}</version> </dependency>
The
<version>
is the Maven artifact version for Red Hat Decision Manager currently used in your project (for example, 7.18.0.Final-redhat-00002).NoteInstead 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 projectpom.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.3.0.GA-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 RHDM product and maven library version?.
-
Add rule assets to the KIE virtual file system
KieFileSystem
and useKieBuilder
withbuildAll( ExecutableModelProject.class )
specified to build the assets from an executable model:import org.kie.api.KieServices; import org.kie.api.builder.KieFileSystem; import org.kie.api.builder.KieBuilder; KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem() kfs.write("src/main/resources/KBase1/ruleSet1.drl", stringContainingAValidDRL) .write("src/main/resources/dtable.xls", kieServices.getResources().newInputStreamResource(dtableFileStream)); KieBuilder kieBuilder = ks.newKieBuilder( kfs ); // Build from an executable model kieBuilder.buildAll( ExecutableModelProject.class ) assertEquals(0, kieBuilder.getResults().getMessages(Message.Level.ERROR).size());
After
KieFileSystem
is built from the executable model, the resultingKieSession
uses constraints based on lambda expressions instead of less-efficientmvel
expressions. IfbuildAll()
contains no arguments, the project is built in the standard method without an executable model.As a more manual alternative to using
KieFileSystem
for creating executable models, you can define aModel
with a fluent API and create aKieBase
from it:Model model = new ModelImpl().addRule( rule ); KieBase kieBase = KieBaseBuilder.createKieBaseFromModel( model );
For more information about packaging projects programmatically within a Java application, see Packaging and deploying a Red Hat Decision Manager project.