Chapter 5. Understanding KIE Sessions

So far, we have covered what Kie Sessions are and how to create them and interact with them. In this chapter, we are going to dive deeper into some of the advanced configuration options and components available in Drools 6, when configuring and defining a Kie Session.

Before going deeper though, we are going to cover the two flavors of Kie Sessions that are present in Drools: stateless and stateful. The type of Kie Session that we choose for our applications has its advantages and disadvantages, which will eventually determine the way we interact with them—whether it's storing information between calls or satisfying a single use case for our business rules.

Once we have a better understanding of the different types of Kie Sessions provided by Drools, we will move on to some of their configuration aspects. In this section, topics such as globals, channels, and event listeners will be covered. All these elements will allow us to create better applications where dependencies with external services and monitoring over the Kie Sessions can be easily decoupled.

The last section of this chapter will focus on the options that we have to enhance the DRL language by creating functions, custom operators, and accumulate functions. These features are one of the most powerful tools we have in Drools to create customized rules without affecting their readability or maintainability.

The following topics will be covered in this chapter:

  • Stateless and stateful Kie Sessions
  • Globals, channels, and event listeners
  • Queries both on-demand and live
  • Functions
  • Custom operators and accumulate functions

This chapter has a corresponding module in the chapter-05 code bundle. Most of the examples described in this chapter, and more, can be found in this module in the form of unit tests.

Stateless and stateful Kie Sessions

As we already know, Kie Sessions come in two different flavors: stateless and stateful. Most of the examples we covered so far involved only stateful Kie Sessions; and there is a good reason why, stateful Kie Sessions are, by far, the most powerful type of sessions supported by Drools.

Before we can decide which kind of session we want to use for a particular situation, we need to understand the differences and similarities between these two type of sessions. In order to do so, we are going to start with the most simple type of session: the stateless Kie Session.

Stateless Kie Sessions

From a development perspective, the type of session we want to use for a particular scenario is not determined by the rules—or any other asset type—we want to use. The type of session is determined either when we define it in the kmodule.xml file or when we programmatically instantiate it in our code. In most of the cases, the same set of assets (.drl files, decision tables, and so on) can be executed inside either a stateless or a stateful session.

So, what is a stateless Kie Session? One of the best analogies to understand what a stateless Kie Session is would be to describe this kind of session as a function.

Typically, a function is something that receives a set of predefined parameters, processes them, and generates an output or result. In many programming languages, the result of a function can be the return value itself, or it can also be the modification of some of the input parameters. Ideally, a function shouldn't have any collateral effect, meaning that if it is invoked multiple times with the same set of parameters, the result should be the same.

A stateless Kie Session shares some of the concepts we described for functions: it has some loosely defined set of input parameters, it processes these parameters in a way, and generates a response. In the same way as a function does, different invocations on the same stateless Kie Session don't interfere with each other.

In order to get a stateless Kie Session, we first need to define the Kie Base we want to use to instantiate it. One way to do this is by creating a kmodule.xml file, as follows:

<kmodule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://jboss.org/kie/6.0.0/kmodule">
<kbase name="KBase1">
    <ksession name="KSession1" type="stateless" default="true/">
</kbase>

The important thing to notice in the previous code is that we are specifically defining KSession1 as a stateless session.

Tip

If not specified, the default type of a Kie Session is stateful.

The next step is to get an instance of the Ksession1 session. For this, we may use the following code snippet:

KieServices kieServices = KieServices.Factory.get();
KieContainer kContainer = kieServices.getKieClasspathContainer();
StatelessKieSession statelessKsession = kContainer.newStatelessKieSession("KSession1");

The API exposed by the StatelessKieSession class is a subset of the one exposed by its stateful counterpart, KieSession. The way we usually interact with a stateful session is that we insert a set of facts into it, execute any activated rule, and then we extract the response we are looking for in some way. In a stateful session, the insertion and execution is separated into two different methods: insert() and fireAllRules(). In the case of a stateless session, these two operations are combined in a single method called execute(). The execute() method of StatelessKieSession comes in the following three versions:

execute(Object fact)
execute(Iterable facts)
execute(Command command)

These first two versions of execute() will insert the facts passed as arguments, fire all the activated rules, and dispose the created session. Successive invocations of these methods will execute all these three steps again. Remember that everything related to any previous invocation will be discarded after execute() ends.

The third version of execute() allows us to interact with the session using a command pattern (http://en.wikipedia.org/wiki/Command_pattern). Drools already comes with a predefined set of available commands such as InsertObjectCommand, SetGlobalCommand, FireAllRulesCommand, and so on. All the available commands can be instantiated using the CommandFactory class. Commands can be grouped together using an instance of the BatchExecutionCommand interface.

A typical use of a stateless Kie Session would be as shown in the following code:

List<Command> cmds = new ArrayList<>();
cmds.add( CommandFactory.newSetGlobal( "list1", new ArrayList(), true ) );
cmds.add( CommandFactory.newInsert( new CustomerBuilder().withId(1L).build(), "customer1" ) );
cmds.add( CommandFactory.newQuery( "Get Customers" "getCustomers" );
ExecutionResults results = ksession.execute( CommandFactory.newBatchExecution( cmds ) );
results.getValue( "list1" ); // returns the ArrayList
results.getValue( "customer1" ); // returns the inserted Customer fact
results.getValue( "Get Customers" );// returns the query as a QueryResults instance

If stateless sessions provide a subset of the operations present in the stateful counterpart, why do we need them? Well, technically, we don't. Everything that could be done by StatelessKIESession, can be also done using a stateful one. Using a stateless session is more like an explicit statement saying that we just want to use a single-shot session that it is going to be used just for a one-time evaluation. Stateless sessions are ideal for stateless scenarios such as data validation, calculations (such as risk evaluation or mortgage rate), and data filtering.

Due to its stateless nature, a stateless Kie Session doesn't need to be disposed. After each invocation of any of the execute() methods, the resources used for the execution are freed. At this point, the same stateless Kie Session is ready for another execution round if required. Each execute() invocation will then be independent from the previous one.

Summing up, stateless Kie Sessions are ideal for stateless evaluations such as:

  • Data validation
  • Calculations
  • Data filtering
  • Message routing
  • Any complex function or formula could be described as rules

Stateful Kie Sessions

We have already covered stateful Kie Sessions in great detail in the previous chapters. This kind of session is the most powerful type of session supported by Drools. Whenever we read or hear about a session in Drools, 99% chances are that it refers to a stateful one. In fact, the stateful Kie Session is so common that they changed its class name from StatefulKnowledgeSession in Drools 5 to simply KieSession in Drools 6.

The main advantage of a stateful session over a stateless one is that the former keeps its state between interactions. We already explained how different invocations to the execute() method on a StatelessKieSession object are isolated from each other. For stateful scenarios, this is not enough. These kinds of scenarios require a session to span across multiple invocations. A common example for these type of scenarios is a session that we are using to monitor a process. Ideally, we would like to insert any incoming event from the process that we are monitoring as soon as we can. We also want to detect a problem as soon as possible. In these situations, we can't wait until we have all the incoming events (maybe they never end) so that we can create our BatchExecutionCommand object to execute it against a stateless session. A better approach here would be to insert each event as soon as it arrives, execute an activated rule, get a generated result, and then wait for the next event to arrive. When the next event arrives, we don't want to treat it in a new session, we want to use the same session where any previous event already is.

When we don't want to use a KieSession anymore, we must explicitly state this by invoking its dispose() method. The dispose method will free any resource the session may have acquired and release any memory it may have allocated. After dispose() is invoked, the session stays in an invalid state, further interactions with this session will throw a exception as java.lang.IllegalStateException.

Just like StatelessKieSession, the KieSession interface also supports the command pattern-like interaction via its execute() method. This command pattern-like interaction is relevant when we are dealing with persistent sessions. In this situation, all the commands passed in a single execute() call are executed in a single transaction. More about the persistent session can be found in Chapter 10, Integrating Rules and Processes.

Now that we have a better understanding about the different type of sessions provided by Drools, let's take a look at some advanced configuration options we have for them.

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

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