Give power users more control over areas of your BizTalk Orchestration. With Business Rules, you can wrap your .NET classes and XML document elements in easy-to-understand language.
Have your users ever asked for an easier way to control aspects of your BizTalk Orchestration? If so, you should investigate BizTalk Business Rules. Business Rules allow you to wrap .NET objects and XML document elements in plain language for use by non-developers. By using Business Rules, a non-developer can much more clearly view the execution logic behind portions of your Orchestrations or even make small changes to portions of your Orchestration.
Business Rules Engine is a new tool in BizTalk 2004. Its development tool is an application called Business Rules Composer. When you develop Business Rules, you describe the rules by using readable descriptive text and configure the rules to utilize underlying .NET objects, database information, and XML elements. When you are finished, the rules resemble bullet points in a memo rather than programming code.
The book BizTalk Server 2004 Unleashed devotes an entire chapter to Business Rules development. This article ties elements of the book and BizTalk product documentation together so you can begin building your own Business Rules. It looks at portions of a fictitious expense-approval process that performs various tests to determine the validity of the employee number before approving an expense.
First, you should learn some terminology so that you can follow along with the text. In BizTalk 2004 Business Rules, a Vocabulary maps all of the .NET classes, XML elements, and database information to user-friendly readable text. (More about how to perform the mapping comes later in the article.) You use a Vocabulary when you develop a rule. A rule closely resembles an if/then statement that you would see in traditional development. The "if" part of a rule is called a condition, and the "then" part of a rule is called an action.
Unlike their traditional "if/then" brethren, rules do not have an "else" section. Rules are grouped together in a policy. When a policy executes, .NET classes and XML documents pass into the Policy from the Orchestration. Classes and XML information loaded in the memory of an executing policy are called facts.
To summarize: Policies are groups of rules; rules contain conditions and actions; rules are developed using vocabularies, and vocabularies are user-friendly mappings to underlying .NET classes and XML elements. With this understanding of the basic terminology, you're now ready to examine the Business Rules development tool.
Business Rules Composer
Most of your business rules development will be done in the Business Rules Composer, which you access from the BizTalk 2004 menu. Business Rules Composer saves all of its data to a SQL Server database on the BizTalk 2004 database server. As Figure 1 shows, you browse policies, vocabularies, and .NET classes in the left panes and develop rules in the right pane.
Figure 1. The Business Rules Composer Interface
Vocabularies and policies are versioned and, like many other things in the BizTalk world, have a number of degrees of activation. Both vocabularies and policies must be published to make them available to Orchestrations and other parts of BizTalk. Policies have a third state called Deployed, which allows activation by an Orchestration.
Development is simple: right-click on the policy or vocabulary version to create a new rule or policy. You'll delve more deeply into development, beginning with vocabulary.
You can develop rules without building a vocabulary, but you decrease the readability of your Business Rules if you don't use a vocabulary. As stated earlier, a vocabulary maps your .NET classes, XML elements, and database information to user-friendly text. Navigating to the policy version and selecting "Add new Definition" invoke the Vocabulary Definition Wizard shown in Figure 2.
Figure 2. The Vocabulary Definition Wizard
The vocabulary definition options will change depending on the radio button selected. Look at each definition option independently, beginning with XML Document Elements.
Figure 3 shows the XML Document Element options.
Figure 3. The XML Document Element Options
As you would expect, you must supply an XML schema definition. After selecting the schema, the tool automatically fills in the XPath and the appropriate field type. Selecting the "Set" option configures the vocabulary item to be used in assignment operations. The "Get" option works a lot like the Get options in languages such as Visual Basic. Choosing it configures the item for read-only operations. (Coverage of the "Display Name" option accompanies the upcoming Rule development discussion.) Now, on to the "Database Table Option."
Figure 4 shows the "Database Table Option" wizard.
Figure 4. The "Database Table Option" Wizard
Like the XML Document Element definition dialog, you browse to the field defining the item to which you want to map. You have two options for binding type: data table/data row and data connection. Deciding whether to select a row over a connection depends on how you are going to use the vocabulary and the number of records in the table. When the data table/data row option is used in a rule, all data will go into memory. Using a vocabulary defined as a data connection will query the underlying table. Finish the vocabulary definition with the .NET Class option.
After you select the .NET Class option, you are prompted to select the assembly containing the class. You are restricted to Assemblies loaded in the Global Assembly Cache (GAC), so any Assembly you use must be signed and loaded in the GAC. After selecting the .NET class, class method, or property, the dialog shown in Figure 5 allows you to add more descriptive text to method arguments, which are displayed when the .NET class is used in Rule Definition.
Figure 5. Add More Descriptive Text to Method Arguments
There are only two real limits to the classes you can employ. The first is that classes cannot have a variable number of parameters. An easy workaround is to use an ArrayList collection or some other object collection. In the example, the vocabulary definition EmployeeInfoObjectArray is an ArrayList member variable in the class MyArrayList class. The definition appears in Figure 6.
Figure 6. The Class MyArrayList Class
The second limitation is really more of a different mindset than a limitation. Non-developers normally don't refer to a property on an object as ObjectName.PropertyName. So, if you plan to use an object and an object's property or method, you must declare both the object and the property separately in the vocabulary.
Finally, unlike other .NET components implemented in a BizTalk Orchestration, business rules classes need not be serializable.
Now that you have a vocabulary, you can begin building your policy.
Before delving into rule development, reviewing what each rule in the sample does in the order that the rule executes would be helpful:
- AssignEmployeeObjectValues runs first and always runs, because 1 equals 1 is always true. In the underlying execution of the rule, a function is called in a .NET object.
- CheckEmployeeNumber compares the employee number to a list of employee numbers in a database table and sets the ValidApprover to "Valid".
- ConfirmValidApprover performs another test to determine if the employee number is a Valid Approver. If the rule is true, ValidApprover is set to "Valid".
- CheckEmployeeNumber runs a second time because AssignEmployeeObjectValue performs an action to change the facts in memory.
Now that you know what the Rules do, you can look at how to develop rules.
As stated previously, policies are groups of rules. Rule definition works differently from vocabulary definition. Vocabulary development utilizes a wizard. Rule definition employs drag-and-drop. To define a rule, right-click on the version of the rule and select "Add New Rule." The right side of the screen will be populated with an IF (condition section) and a THEN (action section). Next, you populate the IF section by dragging-and-dropping a predicate from the predicate section on the vocabulary tab (see Figure 7).
Figure 7. Populate the If Section by Dragging-And-Dropping
Now, you drag-and-drop vocabulary definitions into the "argument" sections in the predicate and actions. A completed Rule appears in Figure 8.
Figure 8. A Completed Rule
In the "IF" section of the sample above, CheckEmployeeNumber maps to the CheckEmployeeNumber method in the CheckEmployee.class inside the Rule.Test assembly. CheckEmployeeNumber accepts an ArrayList class parameter and returns a Boolean value. The EmployeeInfoObjectArray vocabulary definition maps to an ArrayList member variable inside the MyArrayList class. In the "THEN" section, ValidEmployee maps to the ValidEmpNo Element in the XML document and assigns the text "Valid" to the ValidEmpNo Element.
You must declare properties and methods separate from the class vocabulary definition. As you can see above, if you don't declare properties and methods separately, you reduce the natural readability of the rule. As stated previously, natural readability is one of the goals of Business Rules.
You also must enter a "Display Name" if you configure a vocabulary definition with the "Get" option. In the sample, the GetValidEmployee and the ValidEmployee vocabulary definition both map to the ValidEmpNo element. To make the Business Rule readable, both definitions must display the same name. Therefore, one of the definitions must display a name that is different from the actual name of the definition. Thus, the "Get" option requires a separate Display Name, which can be configured to match the name of the "Set" option.
The example above used the text "Valid" to assign a value to the XML element. You could have created a "Constant Values Range" vocabulary definition and used the constant in lieu of the text.
It's now time to learn how the policy you created executes.
When you are ready to test a policy, you right-click on it and select "Test Policy." You will be prompted with the dialog in Figure 9.
Figure 9. "Test Policy" Dialog
When a Policy executes from a BizTalk Orchestration, you must pass the classes and XML documents you use in the rules into the policy. Therefore, you must do the same thing when you test the policy. To load an instance of an XML document, select a document on the file system. To load a database fact, you must select a database table.
Loading a .NET class is different. You must create a class called a FactCreator, which follows the IFactCreator interface in the Microsoft.RuleEngine namespace. The FactCreator class assembly must be signed and loaded in the GAC. Business Rules Composer invokes the CreateFacts method in the FactCreator. CreateFacts creates all of the appropriate objects and returns the objects as an Object array. See the example below:
public object CreateFacts (RuleSetInfo ruleSetInfo)
objs = new object;
objs = new Rule.Test.CheckEmployee ();
objs = new Rule.TestArrayList.MyArrayList ();
return ( objs );
Asserting is the act of loading facts (.NET objects, XML Documents, and so on) into the memory of the executing policy. As the rules engine executes the policy, it builds something called an agenda. The rules engine scans all rules and adds any rule that can be evaluated to the agenda. A rule can be evaluated as long as all of the appropriate vocabulary definitions have been asserted. After a rule has been evaluated, it is removed from the agenda. After evaluation, if the "IF" section evaluates to "true", the action part of the rule is executed, or in Business Rules vernacular, "fired."
After a rule is evaluated, it will not be evaluated again unless its facts are updated. In the sample code, the CheckEmployeeNumber evaluates to "false" and the rule is not fired. Subsequently, the AssignEmployeeObjectValues rule is fired and the EmployeeInfoObject is updated. When the EmployeeInfoObject is updated, the CheckEmployeeNumber rule is reevaluated, found to be "true", and the rule is fired. You can view the execution of your Business Rules in the rule engine trace. Trace is updated when you press the "Test" button. The BizTalk product documentation explains how to interpret the trace output.
You are not limited to using a BizTalk Orchestration or the Business Rules Composer to execute your policy. You can access the policy API and execute a policy programmatically.
As for debugging classes used in your executing policy, you can debug classes from Visual Studio by selecting the "Debug" Processes option and attaching to the Microsoft.RuleComposer.exe process (see Figure 10).
Figure 10. Debugging Classes from Visual Studio
When you test the policy, the debugger will pause whenever it encounters a breakpoint.
This completes the introduction to vocabulary development, policy development, and policy execution. You have just one final topic to learn: deployment.
To move policies and vocabularies from one server to another, you must access another tool called Rules Engine Deployment Wizard (see Figure 11).
Figure 11. Rules Engine Deployment Wizard
Data is saved in an XML format called Business Rules Language (BRL). Business Rules Deployment Wizard also can import a BRL file. Although Business Rules Composer has no built-in integration with version control software such as SourceSafe, it does maintain multiple versions of vocabularies and policies. You can always export the BRL file and check the file into the version control software of your choosing.
Give Users More BizTalk Orchestration Control
If you want to give systems analysts or power users more control over areas of a BizTalk Orchestration, Business Rules might be the answer. With Business Rules, you can wrap your .NET classes and XML document elements in easy-to-understand language that systems analysts and developers alike can use.
About the Author
Jeffrey Juday is a software developer with Crowe Chizek in South Bend, Indiana. He has been developing software with Microsoft tools for more than 12 years in a variety of industries. Jeff currently builds solutions using BizTalk 2004, ASP.NET, Sharepoint, and SQL Server 2000. You can reach Jeff at firstname.lastname@example.org.