Wrox Home  
Professional BizTalk Server 2006
by Darren Jefford, Kevin B. Smith, Ewan Fairweather
May 2007, Paperback

Excerpt from Professional BizTalk Server 2006


by Darren Jefford

Although most systems today have some form of business rules implemented within them, they are typically implemented in code by developers and therefore require development resources and testing whenever changes are necessary. In contrast, BizTalk Server 2004 introduced the Business Rules Engine (BRE) as a core and stand-alone piece of the BizTalk architecture.

The BRE enables you to abstract these business rules from your solution and allow the owners of such business rules to control them. This abstraction is analogous to BizTalk orchestration, in which we abstract the process flow away from the code and into a business process.

In general, rules engines are highly efficient and can process many hundreds or even thousands of rules in a matter of milliseconds, making them highly desirable for BizTalk-style solutions, which typically process many messages a second.

The mechanics that underpin the BRE are incredibly complex and come across as being pretty inaccessible to almost everyone! So that you don't avoid BRE completely, perhaps to the detriment of a solution, this article covers the core BRE concepts that you need to understand before delving into practical examples.

Rule Expressions

BRE rules are expressed in this following format: IF <CONDITION> THEN <ACTION>. Note that there is no ability to express an ELSE clause. To implement such a clause, you just use an opposite rule.

Rete Analysis Network

A number of algorithms are available to implement rules engines. The BRE, the focus of our attention here, uses the Rete (Latin for "network") algorithm. The Rete alogorithm was designed by Dr. Charles Forgy in 1978, and is available in the public domain. Subsequent to the development of the original Rete algorithm, Rete II and Rete III have been developed. Both offer higher levels of performance but, unlike Rete, are not available in the public domain.

The Rete algorithm, a highly optimized and scalable rules engine algorithm, executes both small and large rulesets quickly (in most cases). It scales particularly well when dealing with a large ruleset.

You don't have to understand the intricacies of the Rete engine to appreciate and make full use of the BRE. Therefore, this discussion avoids the complexities and instead provides some examples that explain the fundamentals. If you must know more about Rete, you can find plenty of in-depth discussions on the Internet (but be prepared for some heavy reading).

So, how does the Rete algorithm work? Rules are first translated from their native expression form (IF <Condition> THEN <Action>) into a Rete analysis network. The analysis network in this case relates to an object graph containing four node types: class, select, join, and terminal.

Figure 1 shows an example analysis network for the following expression, which will help you understand these different node types:

IF Loan.Amount < 10,000
AND Customer.Age > 21
THEN Loan.Approved = true

A class node is a data type that will be used as part of the rule condition. Within the BRE, data types are represented as objects, and therefore data itself is represented as object instances. The example shows a Customer data type and an instance of this type, which the BRE will use when evaluating rules. (From this point on, we'll refer to such data as a fact, the term used by the BRE.)

A select node defines the conditions applied to that class type (or fact) which make up the <Condition> part of the rule. Figure 1 shows two select nodes, each containing a straightforward and familiar condition.

As the name implies, a join node joins up multiple (and therefore successful) flows within a network and passes them on to a terminal node. A terminal node then performs the action associated with the rule, thus completing the rule (in Figure 1, setting the Approved flag on the Loan object to True).

Let's now walk through the processing steps in Figure 1:

  1. The facts required for the rule to execute are Customer and Loan. These must be passed into the BRE. This step is typically referred to as asserting facts.
  2. Once asserted, the Customer and Loan facts flow into the network, the Customer fact flowing to the Customer class node and the Loan fact flowing to the Loan class node. They then pass on to the select nodes for their respective type.
  3. The Customer class will flow to the select node, and the expression Customer.Age > 21 will be evaluated against the Customer fact. If the result of this and the Loan evaluation return True, execution will flow to the join node and then on to the terminal node, where the rule action will be performed. In this case, the Approved flag is set to True on the Loan fact.
Professional BizTalk Server 2006 : Figure 1
Figure 1

Now consider what happens to the analysis network if we introduce the following extra rule:

IF Customer.Age > 21
THEN Customer.Risk = "Low"

You might have noticed that this rule uses the same Customer.Age > 21 condition (shares the condition) as the rule in Figure 1. Figure 2 shows the resulting analysis network. Only the shaded shapes are evaluated as part of the rule's execution.

Professional BizTalk Server 2006 : Figure 2
Figure 2

Comparing this analysis network with the first example, you can see that the same select node is used because the conditions are the same. Because only one condition is used in this rule expression, there is no need for a join node. Therefore, the network moves straight to the terminal node, which in turn sets the Loan Risk to Low.

This sharing is particularly important because the Rete algorithm is optimized for such scenarios in which there are shared conditions. Through sharing, an expression is evaluated only one time, rather than for each rule. If both of the following rules were part of a rules policy, for instance, the select node for the Customer.Age > 21 expression would only be evaluated once:

"IF Loan.Amount < 10,000 AND Customer.Age > 21 THEN Loan.Approved = true"
"IF Customer.Age > 21 THEN Loan.Risk = "Low"

The Rete algorithm sharing capability thus clearly provides a performance improvement over traditional condition evaluation when you have many rules sharing conditions.

Now consider a slightly more complex sharing example in which an extra fact type, Promotion, is introduced. This example also introduces a new select node to the Loan type. Figure 3 shows this example:

IF Loan.Amount < 20,000
AND Promotion.EndDate > Loan.ApplicationDate
THEN Loan.APR = 3%
Professional BizTalk Server 2006 : Figure 3
Figure 2

Introducing this rule to the analysis network has extended the network further. When we introduce a new condition for the Loan fact (Loan.Amount < 20,000), it is added beneath the class node Loan as a select node.

We have also introduced a new fact type called Promotion that is connected straight to a join node. A select node was not created for the Promotion condition (Promotion.EndDate > Loan.ApplicationDate), because the condition is also dependent on the class node Loan, which will be available only following successful evaluation of the Loan.Amount < 20,000 condition.

A new terminal node has been added to update the APR amount on the Loan object to 3 percent.

As you can see from the previous examples, BRE rules execution is pretty intelligent and shortcuts rules evaluation as appropriate to reduce duplicate condition evaluations. In addition, BRE rules execution avoids parts of the analysis network that are not required to execute rules (particularly important if you have many hundreds of rules).

This article is excerpt from Chapter 7, "Business Rules Engine," from Professional BizTalk Server 2006 (Wrox, 2007, ISBN: 978-0-470-04642-5), by Darren Jefford, Kevin B. Smith, and Ewan Fairweather. Darren, a Principal Consultant with the Microsoft UK Application Development Consulting (ADC) team, has extensive real-world experience with BizTalk Server and the broader Microsoft platform.