Excerpt from Professional BizTalk Server 2006
BIZTALK SERVER 2006 BUSINESS RULES ENGINE
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.
BRE rules are expressed in this following format:
> 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 (
> THEN <Action
>) into a Rete analysis network. The analysis network in this case relates to an object graph containing four node types:
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
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.)
select node defines the conditions applied to that class type (or fact) which make up the
> 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
Let's now walk through the processing steps in Figure 1:
- The facts required for the rule to execute are
Loan. These must be passed into the BRE. This step is typically referred to as asserting facts.
- Once asserted, the
Loanfacts flow into the network, the
Customerfact flowing to the
Customerclass node and the
Loanfact flowing to the
Loanclass node. They then pass on to the select nodes for their respective type.
Customerclass will flow to the
selectnode, and the expression
Customer.Age > 21will be evaluated against the
Customerfact. If the result of this and the
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
Approvedflag is set to
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.
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
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%
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
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.
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.