KieModule configurations (KieBases, KieSessions & StatelessKieSessions)

The kmodule.xml file is used to customize the KieModule configurations. In this file, we can define how the rules are grouped together in different KieBases that can be loaded for different purposes. It also allows us to define more fine-grained configurations for the rule engine instance that will be created.

In this section, we will cover the basic configurations for KieBases, KieSessions, and StatelessKieSessions. In the end, we will also review a mechanism that we can use to include other KieBases from other KieModules in our KieModule.

Let's start simple with the kmodule.xml file defined in the chapter-03-classpath-tests/src/test/resources/META-INF/ directory, as follows:

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://jboss.org/kie/6.0.0/kmodule">
    <kbase name="rules.cp.discount">
        <ksession name="rules.cp.discount.session" type="stateful"/>
    </kbase>
</kmodule>

Using the concepts of KieBase and KieSession, we can define the granularity of how the rules will need to be loaded. A KieBase represents a compiled version of a set of assets, and a KieSession represents an instance of the rule engine containing the rules in the KieBase. For this reason, it makes sense to have multiple sessions defined with different configurations for the same KieBase. In other words, we can use the same rules, but have a session configured in a different way for different needs.

In this case, we are defining a KieBase called rules.cp.discount. Notice that the name attribute of the KieBase is the same as the directory structure that we are using under the /src/test/resources/ directory, where the rules are stored. In the KieBase, we are defining a KieSession called rules.cp.discount.session. This KieSession will represent the Rule Engine instance containing all the rules defined in the KieBase. In Drools 6, similar to the previous versions of Drools, there are two types of KieSessions (previously called KnowledgeSession): Stateful and Stateless.

The stateful KieSession allows us to keep the state between several interactions with the Rule Engine. In Drools 6, Stateful Knowledge Sessions were renamed to KieSessions, as there are the most common type of session, the name was kept short. In contrast, StatelessKieSession only allows us to interact once, take the results out, and no state is stored for the next interaction. We will see more about KieSessions in Chapter 5, Understanding KIE Sessions.

If you take a look at the tests, for example, loadingRulesFromDependencyParentKieModule() in the KieContainerClasspathTests class, you will notice that we are using a (Stateful) KieSession as we insert a set of facts, then call the fireAllRules() method, and then we keep inserting more facts and call fireAllRules() again. Between the two calls to the fireAllRules() method, the state (meaning the facts and the rules evaluations) are kept. There will be cases where the second set of facts triggers new rules in conjunction with the first set of facts, as follows:

...
KieSession kieSession = kContainer.newKieSession("rules.discount.all");
Customer customer = new Customer();
customer.setCustomerId(1L);
customer.setCategory(Customer.Category.SILVER);

Order order = new Order();
order.setCustomer(customer);

kieSession.insert(customer);
kieSession.insert(order);

int fired = kieSession.fireAllRules();

assertThat(1, is(fired));
assertThat(10.0, is(order.getDiscount().getPercentage()));
        
Customer customerGold = new Customer();
customerGold.setCustomerId(2L);
customerGold.setCategory(Customer.Category.GOLD);

Order orderGold = new Order();
orderGold.setCustomer(customerGold);

kieSession.insert(customerGold);
kieSession.insert(orderGold);

fired = kieSession.fireAllRules();

assertThat(1, is(fired));
assertThat(20.0, is(orderGold.getDiscount().getPercentage()));

As you can see, the Silver Order and customer are still in the KieSession when we insert the Gold Customer and Order. In the next chapter, you will learn how to write more complex rules that, for example, evaluate two orders and their relationships. In such cases, more than one rule can be fired.

Now, we can take a look at the statelessSessionTest() test, which shows the interaction against a StatelessKieSession in contrast to a KieSession (which is Stateful). Notice that we need to define the session as stateless in the kmodule.xml file, as follows:

<ksession name="rules.simple.sl.discount" type="stateless"/>

Now we can get a new StatelessKieSession from our kContainer, as shown in the following:

...
StatelessKieSession statelessKieSession = kContainer.newStatelessKieSession("rules.simple.sl.discount");
 
Customer customer = new Customer();
customer.setCategory(Customer.Category.SILVER);

Order order = new Order();
order.setCustomer(customer);

Command newInsertOrder = ks.getCommands().newInsert(order, "orderOut");
Command newInsertCustomer = ks.getCommands().newInsert(customer);
Command newFireAllRules = ks.getCommands().newFireAllRules("outFired");

List<Command> cmds = new ArrayList<Command>();
cmds.add(newInsertOrder);
cmds.add(newInsertCustomer);
cmds.add(newFireAllRules);

ExecutionResults execResults = statelessKieSession.execute(ks.getCommands().newBatchExecution(cmds));
        
order = (Order)execResults.getValue("orderOut");
int fired = (Integer)execResults.getValue("outFired");

assertThat(1, is(fired));
assertThat(10.0, is(order.getDiscount().getPercentage()));

Notice that now we need to use the newStatelessKieSession() method to create a new StatelessKieSession. In this type of session, we don't have the insert() or fireAllRules() methods, instead we have the execute() method that allows us to send a command or a set of commands to be executed. From this execution, you can get the ExecutionResults object that will contain all the results that we will want to collect after the rule execution. After the interaction (execute and get the results), there is no state hold in the StatelessKieSession and if we call the execute() method again, all the rules will be evaluated only against the facts that we send for this interaction.

Finally, if we want to aggregate KieModules, we can use the includes option in the KieBases configuration. You can take a look at chapter-03-kjar-parent/src/main/resources/kmodule.xml, as follows:

<kmodule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://jboss.org/kie/6.0.0/kmodule">
    <kbase name="discount" default="true" includes="rules.premium, rules.simple">
        <ksession name="rules.discount.all" type="stateful"/>
    </kbase>
</kmodule>

As we can see, the includes property of the kbase tag is making reference to other KieBases defined in other modules. If these KieBases are available at the initialization time, they will be included and now the KieSession called rules.discount.all will contain all the resources defined in these two KieBases.

Just for the sake of completeness, here is the full schema for the kmodule.xml file:

https://github.com/droolsjbpm/droolsjbpm-knowledge/blob/master/kie-api/src/main/resources/org/kie/api/kmodule.xsd

We will be using most of the options provided to configure our KieBases and KieSession in the book. Now, it is time to look at one of the most required features provided by Drools to dynamically load changes that we make in our business assets. The second half of this chapter will cover the KieScanner and how to use it in our applications.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.36.71