This article is the second part of a detailed business rule beans (BRBeans) overview. The first part, Develop business rules with WebSphere business rule beans, is a continuation of the mediated exchange scenario series, which examines the technologies used to implement a travel broker solution.
As you learned in Part 1, you can introduce business rules into a business process to eliminate the need for hard-coded or static logic, which allows for more customizable processes. By using WebSphere BRBeans, decision logic can be made external to the primary business component. Input parameters for this logic can later be modified dynamically with APIs or through a product-provided rule management utility. This architecture is ideal for a mediated exchange offering where a template solution must be customizable to meet the needs of various customers.
For more information on the mediated exchange scenario, see the first two articles in the series, Integrate business processes among service consumers, brokers, and providers and Develop a customizable application using business rules. These articles provide overviews of the mediator business model and give you useful background information about how our travel policy will function.
In Part 1 of this overview, you also learned the required steps to set up a development workspace to begin BRBeans development. In this article, you get further details for developing external rules and the rule interfaces that will be integrated into a business process.
In the mediated exchange travel industry scenario discussed in the two previous articles, Develop a customizable application using business rules and Develop business rules with WebSphere business rule beans, Part 1, we simulate a company that provides travel reservation services to business customers. The mediator has travel industry expertise, which lets it serve as a mediator between customers with travel needs and airlines that provide travel services. Our mediator will provide a standard travel policy template that allows for template-based customization for each customer.
Several methods in this travel policy template are required to support the individual business needs of travel consumers accessing the broker services. In our code examples, we'll implement two interfaces:
- getPreferredAirProviders
- isApprovalRequired
These interfaces support the travel policy by identifying an appropriate set of air carriers and whether special approval is required for a given class of consumers. In a real-life implementation, other methods would also be required, but this limited example shows key features of BRBeans. The following table summarizes the rules that are demonstrated in this article.
| Rule | Employee | Manager |
| Preferred air carriers | EconomyAirlineA EconomyAirlineB | <Employee Airlines> LuxuryAirlineC |
| Approval required | Price > $400 | Price > $800 |
Understand product requirements
Resource requirements for BRBeans development and this travel policy scenario are not complicated. The development environment needs to be provisioned with the following components:
| Product | Notes |
| Microsoft® Windows® 2000 or Windows XP operating system | Our examples are demonstrated from a Windows platform. (Although not tested, these examples are also relevant on other platforms.) |
| WebSphere Studio Application Developer (Application Developer) Integration Edition Version 5.1 | This is the Eclipse-based development workbench we use to develop and test our BRBeans application. |
| IBM DB2® Universal Database™ Express Version 7 or Version 8 | A DB2 database is used for the entity beans in the BRBeans framework. (Other database types, such as IBM Cloudscape™, can be used to support BRBeans, but for this article, DB2 is used.) |
Get started with rule implementation
We've completed the preparatory configuration steps for BRBeans development and verified proper execution of the rules management application as outlined in Part 1. Now we can begin with the more interesting aspects of BRBeans and actually develop some required business rules. First we'll explain the mechanics of implementing a BRBeans rule. As mentioned, two sample interfaces are used in our mediated exchange scenario; both interfaces host trigger points that reference external rules. However, the implementation of each rule will be somewhat varied, letting us show available BRBeans features.
The following tasks are a high-level overview of what we need to do to implement our rule interfaces:
- Create a trigger point in the client code to invoke the defined business rule.
- Create the BRBeans rule object in the BRBeans database using the rule management utility. (The rule name is defined here, the RuleImplementor class for the rule is specified, and parameters and dependent rules are also defined.)
- Create a custom RuleImplementor Java™ class containing the relevant business logic. (If a BRBeans-provided, built-in RuleImplementor class already exists that meets the business logic needs, this step is not necessary.)
The remaining sections of this article are a roadmap of our development activities, with the following steps:
- Implement the Preferred Air Providers interface by filling in the Java code using BRBeans trigger points.
- Create two required custom RuleImplementor classes to implement the BRBeans-provided RuleImplementor interface.
- Create a Preferred Air Providers rule object for regular employees in the BRBeans DB2 database to provide a reference to one of the newly created custom RuleImplementor classes.
- Create a Preferred Air Providers rule object for managers in the BRBeans DB2 database to provide a reference to both of the newly created custom RuleImplementor classes.
- Implement the isApprovalRequired interface by filling in the Java code using BRBeans trigger points.
- Create a required custom RuleImplementor class to implement the BRBeans-provided RuleImplementor interface.
- Create an isApprovalRequired rule object for regular employees in the BRBeans DB2 database to provide a reference to a built-in RuleImplementor class.
- Test and debug our rule interfaces with the Universal Test Client (UTC).
In an upcoming article, you'll learn how to incorporate the trigger point interfaces within our travel Business Process Execution Language (BPEL) business process and get a more complete picture of how the external rules are accessed and used in our travel process.
Implement the Preferred Air Providers interface
First we'll develop the travel policy interface method that supplies a list of airlines an employee can use for air travel. This interface uses BRBeans trigger points to invoke business rules defined by a business analyst. The dependent-rule feature provided by BRBeans, where the invoked rule triggers and receives results from other rules defined as dependents, is also demonstrated in this example.
To start our implementation for determining preferred providers:
- Start Application Developer and specify the workspace directory where the BRBeans project was previously set up.
- Within the Java 2 Platform, Enterprise Edition (J2EE) perspective, ensure the Project Navigator view is displayed, and open the TravelPolicyEJBBean.java file (under the com.friendlydestinations.policy package).
- Add the code displayed in Listing 1 to
getPreferredAirProviders(). The extra method in this listing, calledgetRole(), is a simple method that simulates security logic and passes back a user's security role. This should also be added to the TravelPolicyEJBBean.java file just abovegetPreferredAirProviders().Listing 1.
getPreferredAirProvidersmethodprivate String getRole() { return "Manager"; } public String[] getPreferredAirProviders() { String [] airProviders = null; // Call method to get security role (Employee or Manager) // For demo, this article simply returns "Manager". Realistic // implementation would perform actual security principal lookup. String secRole = new String(getRole()); // The rule name that needs to be called will vary based on // the role of the user who is invoking this method. For // our travel scenario, we will only have an 'Employee' role // and a 'Manager' role. String ruleName = "com/friendlydestinations/policy/ getPreferredAirProviders"+secRole; try { //Create new trigger point TriggerPoint tp = new TriggerPoint(); System.out.println("DEMO-New TriggerPoint Object Created"); // We will disable caching for our trigger point call // since this might prevent changes in the rules from // being recognized immediately. tp.disableCaching(); //Call the rule Object resultObject = tp.trigger(null, null, ruleName); if (resultObject != null) { //Rule successfully called airProviders = (String[])((Object[])resultObject)[0]; } } catch (BusinessRuleBeansException e) { System.out.println("Exception Caught: ["+e.getMessage()+"]"); } return airProviders; } - After filling in the
getPreferredProvidersmethod, you'll get several errors as a result of missing package import statements. Resolve the errors by right-clicking anywhere in the source file and selecting Source > Organize Imports, which adds the required package import statements and eliminates errors in the Tasks view.
The method should emphasize these areas:
- The user security role (secRole) is obtained from our dummy method, which currently just returns the string
Manager. In a real implementation, actual security APIs would be used to determine the security role and would return eitherManagerorEmployee. (We're assuming only these two roles are required.) The role is used in this scenario to determine which business rule to call. We can deduce that managers typically have more privileges or access than regular employees. You'll see how BRBeans can help us support this hierarchical access. - Local caching for this TriggerPoint has been turned off to avoid missing any dynamic changes that may be made to the business rule. For example, the rule is modified by an administrator in the middle of the day using the rule management utility.
- Within this trigger call, no target object the first parameter in
tp.trigger()method, or firing parameters, the second parameter intrigger()method, are passed into the business rule. The use of firing parameters is discussed in the next business rule example. The use of a target parameter is not common and can be set to null. - The
resultObjectreturned from the trigger call should contain an object array. We will expect only one object populated in the return array forgetPreferredAirProviders, which will be a string array containing names of air carriers.
Now we need to create custom RuleImplementor classes to support the rules we require. Because we're supporting a hierarchy of users -- employees and managers -- we need to create two rules.
- For regular employees
- This rule will be associated with a customized class that we'll write. The customized class, when executed, will pass back one or more initialization parameters to the calling trigger client. This allows us to add the names of valid air carriers for regular employees to the rule as initialization parameters. (Initialization parameters are defined in Create database rule object for getPreferredAirProviders.)
- For managers
- This custom rule is slightly more complicated, but lets us demonstrate the flexibility of BRBeans. The most significant aspect of the manager rule is that it will contain the employee air carrier rule as a dependent rule. Under this architecture, managers automatically inherit access to all standard carriers that have been defined for regular employees as well as to the more restricted carriers.
This hierarchical rule structure is well suited for many types of business situations.
For implementation, two primary steps are required.
- Write our custom classes: one for the employee variation of the rule and one for the manager version.
- Use the BRBeans rule management utility to create and configure the rule object persisted in the BRBDEMO database.
Create custom RuleImplementor classes
- In the J2EE perspective (Project Navigator view), highlight the ejbModule directory under the TravelPolicyEJB project. Right-click and select New > Package. Enter
com.friendlydestinations.policy.brb.rule.implementorsas the Source Folder value. This is where we add all of our customRuleImplementorclasses. - Highlight this new package, right-click and select New > Class. In the Name field, enter
ConstantsRuleImplas the name for the class. Click Add to the right of the Interfaces section. TypeRuleImplementorin the Interfaces dialog and click OK. Your New Java Class dialog should look like Figure 1. Click Finish.
Figure 1. CustomRuleImplementorclass
- Cut and paste the code in Listing 2 into the skeleton methods just created. Save and close the file.
Listing 2.
ConstantsRuleImplclasspublic class ConstantsRuleImpl implements RuleImplementor { // Variable below will hold list of preferred air carriers. String[] stringObjects = null; public Object fire(TriggerPoint tp, Object target, IRuleCopy rule, Object[] firingParms) throws BusinessRuleBeansException { return stringObjects; } public String getDescription() { return null; } public void init(Object[] initParams, String[] dependentRules, String userDefinedData, IRuleCopy rule) throws BusinessRuleBeansException { // If no iniitalization parameters are passed, just return. if (initParams == null || initParams.length == 0) return; else { stringObjects = new String[initParams.length]; //Store each init param in our stringObjects array for (int i = 0; i < initParams.length; i++) { stringObjects[i] = (String)initParams[i]; } } } } - Right-click anywhere in the source file. Select Source > Organize Imports to add necessary package import statements and eliminate any errors in the class.
- Repeat the preceding steps to create a second
RuleImplementatorclass to be called on behalf of managers. We'll call this classMergeConstantsRuleImpl. The code inRuleImplementorwill merge or inherit any air carriers already specified for regular employees. Add the code shown in Listing 3 to the class.Listing 3.
MergeConstantsRuleImplclasspublic class MergeConstantsRuleImpl implements RuleImplementor { String[] myDependentRules = null; String[] initObjects = null; public Object fire(TriggerPoint tp, Object target, IRuleCopy rule, Object[] firingParms) throws BusinessRuleBeansException { // Variable below will hold list of carriers. Sized to 10 // to keep sample simplistic. String[] stringObjects = new String[10]; Object result = null; int initParamCnt = stringObjects.length; int j=0; // Add params from dependend rules for(int i=0; myDependentRules!=null && i<myDependentRules.length; i++) { result = tp.trigger(null, null, myDependentRules[i]); if ( ((Object[])(result))[0] != null ) { String[] dependResults = (String[])((Object[])(result))[0]; for (; j < dependResults.length; j++) stringObjects[j] = dependResults[j]; } } // Add params from this rule for (int k=0; initObjects!=null && k<initObjects.length; k++) { stringObjects[k+j] = (String)initObjects[k]; } return stringObjects; } public String getDescription() { return null; } public void init(Object[] initParams, String[] dependentRules, String userDefinedData, IRuleCopy rule) throws BusinessRuleBeansException { // Keep track of dependent rules for fire() method if (dependentRules != null) { myDependentRules = dependentRules; } // If no iniitalization parameters are passed, just return. if (initParams == null || initParams.length == 0) return; else { initObjects = new String[initParams.length]; for (int i=0; i < initParams.length; i++) initObjects[i] = (String)initParams[i]; } } }
Process for custom implementor classes
For the execution of ConstantsRuleImpl:
- The
init()method is called immediately after the class is instantiated. It is passed the initialization parameters defined in our rule object. (These parameters are added in the next section.) The initialization parameters are saved in a string array. - The
fire()method will subsequently be called each time the rule is executed. In this implementor class, thefiremethod simply passes the string array back to the trigger point called by the client. - We could use the built-in class
RuleConstantto return a string initialization parameter, but this class only returns the first initialization parameter and doesn't let us specify multiple air carriers for the rule.
For the execution of MergeConstantsRuleImpl:
- The
init()method is called again, immediately after the class is instantiated. It is passed the initialization parameters that we will add to our rule object and a list of dependent rules configured through the rule management utility. - The
fire()method is subsequently, triggering all dependent rules and adding received results to a string array. All initialization parameters for this rule are also added to the string array. - This combined list is passed back to the trigger point invoked by the client.
- An important, but not so obvious, point is that the dependent rules are not automatically triggered by the BRBeans framework. The framework provides the implementation class with the names of the dependent rules, but expects the developer of the implementation class to trigger the dependent rules and interpret or handle the results as required by the application.
Create database rule object for getPreferredAirProviders
This section covers rule objects for employees and managers.
Next, the rule objects that are stored in the BRBDEMO database and are referenced and triggered in getPreferredAirProviders need to be created. You'll use the rule management utility to create these objects.
- Start the server1 Universal Test Environment (UTE) server created and configured in Develop business rules with WebSphere business rule beans, Part 1.
- Bring up the rule management utility (also called Rule Browser) by selecting Run > Run from the Application Developer main menu. Highlight RuleManagement in the Run window, as shown in Figure 2, and click Run.
Figure 2. Starting rule management utility
- Highlight the com folder in the Rule Browser, right-click and select New > Folder. Type
friendlydestinationsfor the folder name. Highlight this new folder. Again, right-click and select New > Folder. Typepolicyfor this folder name. - Highlight the com/friendlydestinations/policy folder. Right-click and select New > Rule. The New Rule dialog appears. Type
getPreferredAirProvidersEmployeein the Name field under the General tab. - Enter
01/01/04 12:00 AMin the Start date field. - Switch to the Implementation tab and enter
com.friendlydestinations.policy.brb.rule.implementors.ConstantsRuleImplas the Java rule implementor. This is the custom class we wrote earlier. - Change the Firing location field to Remote, which specifies that the custom rule implementor class should be executed on the application server where the BRBeans component is installed. Although there's a minor performance penalty associated with this execution mode, it eliminates the need to keep the most current custom rule implementor classes on the same system where the client trigger point code is running. In our scenario, the client code is running in the same application server. The remote firing location setting makes it easier to move the trigger point code to another application server, which means you don't have to copy updated rules to all client servers when code changes are made. While you do get minor performance degradation, the trade-off is ease of maintenance.
- Click Add to the right of the Initialization Parameters section. Ensure the Type field is set to String and enter
Employee Air Carriersin the Description field andEconomyAirlineAin the Value field. Click Add. Repeat this process to add a second initialization parameter with value EconomyAirlineB, as shown in Figure 3. Click Close to close the Add Initialization Parameter dialog, and click OK again to close the New Rule dialog.
Figure 3. Initialization parameters forConstantsRuleImpl
The rule object for manager is configured with a different rule implementor class and is also set up with a dependent rule. Configure this rule as follows:
- Highlight the policy folder in the Rule Browser. Right-click and select New > Rule. The New Rule dialog appears. Type
getPreferredAirProvidersManagerin the Name field in the General tab. - Enter
01/01/04 12:00 AMin the Start date field. - Click the Implementation tab and type in
com.friendlydestinations.policy.brb.rule.implementors.MergeConstantsRuleImplas the Java rule implementor. Click Add to the right of the Initialization Parameters section. Ensure the Type field is set to String, and enterManager Air Carriersin the Description field and LuxuryAirlineC in the Value field. Click Add then Close. - Select the Dependent Rules tab. Click Browse, go to the com/friendlydestinations/policy folder, and select getPreferredAirProvidersEmployee. Click Add, then Close, to add this dependent rule, as shown in Figure 4. Click OK to close the New Rule dialog.
Figure 4. Dependent rules
Implement the isApprovalrequired interface
The isApprovalRequired() method, a part of our travel policy interface, is the other point of variability (POV) that we highlight in this article. This POV would typically be interjected in our business process prior to the actual submissions of air, car, or hotel reservation confirmations. For our scenario, the isApprovalRequired travel policy method calls an associated BRBeans rule, also known as isApprovalRequired. Within the implementation class for this rule, the TripSelection information and security role of the caller is received and used to determine whether the purchase price for the trip is within limits for the user's role.
Two additional BRBeans rules need to be configured for defining spending limits:
- AirSpendingLimitEmployee
- AirSpendingLimitManager
To verify spending limits, they are accessed by the IsApprovalRequired RuleImplementor as dependent rules. The limits specified in the dependent rules can then be changed dynamically by a business analyst using the rule management utility or through a custom application that uses BRBeans rules APIs. If a requested trip exceeds the defined price limit, a true Boolean value is returned indicating that approval is required. (A complete version of this method would also check for car and hotel limits.)
Implement this interface and the required rules as follows:
- Within the J2EE perspective, ensure the Project Navigator view is displayed, and open the TravelPolicyEJBBean.java file (under the com.friendlydestinations.policy package).
- Add the code shown in Listing 4 to the
isApprovalRequired()interface. - Right-click anywhere in the source file and select Source > Organize Imports to add the import statement for the required TripSelection class.
Listing 4. isApprovalRequired method
public boolean isApprovalRequired(TripSelection tripSelection) {
// Start out assuming approval is required
boolean approvalRequired = true;
String ruleName = "com/friendlydestinations/policy/isApprovalRequired";
try {
//Create new trigger point
TriggerPoint tp = new TriggerPoint();
// We will disable caching for our trigger point call
// since this might prevent changes in the rules from
// being recognized immediately.
tp.disableCaching();
// Setup parameter to pass in tripSelection and security role
Object[] plist = new Object[2];
plist[0] = tripSelection;
// Call method to get security role (Employee or Manager)
// For demo, this article simply returns "Manager". Realistic
// implementation would perform actual security principal lookup.
String secRole = new String(getRole());
plist[1] = secRole;
//Call the rule
Object resultObject = tp.trigger(null, plist, ruleName);
System.out.println("DEMO-trigger method called");
if (resultObject != null)
{
//Rule successfully called
approvalRequired = ((Boolean)((Object[])resultObject)[0]).
booleanValue();
}
}
catch (BusinessRuleBeansException e) {
System.out.println("Exception Caught: ["+e.getMessage()+"]");
}
return approvalRequired;
}
|
Again, the logic that defines this class is straightforward:
- A trigger point is set up to invoke the com/friendlydestinations/policy/isApprovalRequired rule. The trip information and the security role identity are also set up as parameters for the rule.
- The security role is used to determine what airfare-spending limit rule should apply for this user. There will be one setup for employees and one for managers.
- The appropriate limit rule is called with trip price information passed as a parameter. Based on results from this limit rule,
trueis returned to the policy interface method to indicate that the airfare exceeds the limit and requires approval; otherwise,falseis returned indicating approval is not required. - Since the
RuleImplementatorclass is external to the business process, it can be conveniently modified to meet any unique approval requirements for a given customer. Other conditions and rule triggers can easily be added, if needed. - In a full-blown implementation, you would also be checking on car and hotel limits.
Create a required custom RuleImplementor class
- Create the
IsApprovalRequiredImplclass under the com.friendlydestinations.policy.brb.rule.implementors directory, implementing theRuleImplementorinterface in the same manner as theConstantsRuleImpl classdescribed earlier. - Cut and paste the approval-determination logic into the class, as shown in Listing 5. Save and close the file.
Listing 5. IsApprovalRequiredImpl class
public class IsApprovalRequiredImpl implements RuleImplementor {
String[] myDependentRules = null;
Object[] initParms = null;
public Object fire(TriggerPoint tp, Object target, IRuleCopy rule,
Object[] firingParms)
throws BusinessRuleBeansException {
boolean approvalRequired = true; // Default to require approval
Double spendingLimit = null;
TripSelection tripSelection = (TripSelection)firingParms[0];
String secRole = (String)firingParms[1];
// Add params from dependend rules
for(int i=0; myDependentRules!=null && i<myDependentRules.length; i++)
{
if ( myDependentRules[i].indexOf(secRole) != -1 ) {
// Setup parameter to pass in tripSelection and security role
Object[] plist = new Object[1];
plist[0] = tripSelection.getAirCarrierPrice();
Object result = tp.trigger(null, plist, myDependentRules[i]);
// The rule we triggered should have one init
// parameter (Double) specifying spending limit.
if ( ((Object[])(result))[0] != null ) {
boolean underLimit =
((ConstraintReturn)((Object[])(result))[0]).result();
// If amount is under limit, change approvalRequired
// to false (since we are within role limits).
if ( underLimit ) approvalRequired=false;
}
}
}
return (new Boolean(approvalRequired));
}
public String getDescription() {
// TODO Auto-generated method stub
return null;
}
public void init(Object[] initParams, String[] dependentRules, String
userDefinedData, IRuleCopy rule)
throws BusinessRuleBeansException {
// Keep track of dependent rules for fire() method
if (dependentRules != null) {
myDependentRules = dependentRules;
}
}
}
|
Process for custom implementor class
For the execution of IsApprovalRequiredImpl:
- The
init()method is called immediately after the class is instantiated. It is passed the list of dependent-spending limit rules configured through the rule management utility. - The
fire()method is subsequently called and passed the TripSelection information and the user's security role. Based on the user's security role, the appropriate dependent-spending limit rule is triggered (employee or manager) and passed the amount of the requested trip. - The dependent-spending limit rule returns a
trueif the purchase amount is within the defined spending limits, or afalseis returned. - The
IsApprovalRequiredImplimplementor passes back a Boolean class that is set to false, indicating approval is not needed if the spending limit rule indicates the purchase is within limits. Otherwise, a Boolean set to true is sent back to the travel policy interface. - The dependent rules are not automatically triggered by the BRBeans framework. Logic must be inserted into the custom
RuleImplementorclass to trigger the appropriate dependent rule.
Create database rule object for isApprovalRequired
This section discusses the rule objects for AirSpendingLimitEmployee and isApprovalRequired, and the database rule object for AirSpendingLimitManager.
Rule object for AirSpendingLimitEmployee
Since the IsApprovalRequiredImpl class checks a spending limit rule for the employee or manager, we need to add these rules to the database. They will use built-in implementor classes, so no custom RuleImplementor class has to be written. To configure these rules:
- Highlight the policy folder. Right-click and select New > Rule. The New Rule dialog appears. Type
AirSpendingLimitEmployeein the Name field in the General tab. - Enter
01/01/04 12:00 AMin the Start date field. - Switch to the Implementation tab, and select the com.ibm.websphere.brb.implementor.RuleLessThanEqual built-in implementation class as the Java rule implementor.
- Click Add to the right of the Initialization Parameters section. Change the Type field to Double, enter
SpendingLimitin the Description field, and400.0in the Value field. Click Add, and click Close. - Keep the Pass firing parameters from trigger point unchanged radio button selected in the Firing parameters section, as shown in Figure 5.
- Click OK on the bottom of the New Rule dialog to save the rule in the database.
Figure 5. Spending limit rule
Database rule object for AirSpendingLimitManager
Repeat the preceding process for the AirSpendingLimitManager rule. Set the SpendingLimit parameter for the manager to 800.0.
Rule object for isApprovalRequired
The travel policy interface will directly interact with the isApprovalRequired rule object. This rule object references the appropriate spending limit rule to determine whether a requested purchase is over the limit. It is configured with the rule management utility, as follows:
- Highlight the com/friendlydestinations/policy folder in the Rule Browser. Right-click and select New > Rule. The New Rule dialog appears. Type in
isApprovalRequiredin the Name field under the General tab. - Enter
01/01/04 12:00 AMin the Start date field. - Switch to the Implementation tab and enter
com.friendlydestinations.policy.brb.rule.implementors.IsApprovalRequiredImplas the Java rule implementor. Change the Firing location to Remote. Click OK at the bottom of the New Rule dialog to save the rule in the database. - Select the Dependent Rules tab. Click Browse and go to the com/friendlydestinations/policy folder. Select AirSpendingLimitEmployee and click Add. With the Select Rules dialog still open, select AirSpendingLimitManager and click Add.
- Click Close to close the Select Rules window, then select OK in the New Rule dialog to close this dialog and save the new rule. After all these rule objects are added, the end result should resemble Figure 6.
Figure 6. Travel policy rules
Before integrating the BRBeans rule with our travel process, we need to unit test it in an isolated environment. Because trigger points for our rules are contained in remotely accessible session bean methods, we can easily test them with the UTC. UTC is a feature provided with Application Developer that lets you unit test Enterprise JavaBeans (EJB) technology in the test environment server and view Java Naming and Directory Interface (JNDI) namespace entries.
- Be sure the test server is started, and highlight server1 in the Servers view. Right-click and select Run universal test client.
- Select JNDI Explorer on the UTC homepage, as shown in Figure 7.
Figure 7. UTC home page
This displays a page filled with various directories and objects existing within the test server. Follow the links to the ejb.com.friendlydestinations policy folder, and click on TravelPolicyEJBHome, as shown in Figure 8.
Figure 8. TravelPolicyEJBHome link in UTC
- The UTC panel is now changed to allow navigation to and creation of an instance of the TravelPolicyEJB session bean. Create this instance and continue to navigate to invoke the
getPreferredAirProvidersmethod. - Click Invoke on the right panel. You should see a string array returned to UTC. Click WorkwithObject under the UTC results section, click the String[10] link, then click the Inspect Fields link on the left panel under Object References.
- As shown in Figure 9, you should now see three strings containing
EconomyAirlineA,EconomyAirlineB, andLuxuryAirlineC.
Figure 9. Carrier results from UTC test
If the test server is restarted in debug mode and breakpoints are added, the secRole variable can be changed to employee (set breakpoint at call to getRole() method in getPreferredAirProviders, and double-click on secRole in the Debug Variables view to change value), as shown in Figures 10 and Figure 11.
Figure 10. Debug breakpoint set in
getPreferredAirProviders
Figure 11. Changing secRole variable in debug mode

Execution with this variable change lets us see that only the employee air providers are returned, as shown in Figure 12. This provides verification that the rule hierarchy is functioning properly.
Figure 12. Restricted air providers returned for employee

You can use an additional test to bring up the rule management utility and change or add an air carrier. Without shutting down the test server or the UTC application, run the getPreferredAirProviders test again, leaving the secRole variable as manager, and verify that the modified or newly added carrier is reflected in the test results. This demonstrates the ability to dynamically modify these external rules.
Similar tests can also be run against the isApprovalRequired interface. UTC lets you enter values for the TripSelection class and pass that to the isApprovalRequired method, as shown in Figure 13. A resulting true Boolean response should be received when you enter an airCarrierPrice greater than 800.0; otherwise, a false response should be received.
Figure 13. Testing
isApprovalRequired with UTC
Discover additional BRBeans capabilities
In addition to the rule management utility, business rules can also be accessed and modified with a set of BRBeans APIs. The APIs facilitate the development of custom interfaces that business analysts can use to dynamically alter business rules. In our travel mediator exchange example, a Web interface is supplied for the mediator customers, allowing their analyst to alter the rules defining air carriers that regular employees or managers can use for travel or to adjust price limits for approval determination.
Another feature associated with BRBeans is contained in the rule management utility. Rules created in a development or test database can be exported into an XML file using the rules management tool. You can then use the same utility to import all these rules into a production database, providing a simplistic method for backing up the BRBeans database. See Figure 14 for an example of the Rule Export dialog.
Figure 14. Rules Export dialog

In this two-part BRBeans development overview, you learned about the setup requirements, implementation features, and development techniques for BRBeans. Through our examples of the full BRBeans development cycle, you should now have a foundation to begin your own BRBeans development.
BPEL is another important framework you'll learn about later in this series. BPEL has become an industry-accepted standard and is supported with tooling in WebSphere Studio Application Developer Integration Edition Version 5.1 and run-time support in WebSphere Business Integration Server Foundation Version 5.1. The next article in this series explores BPEL technology and how it can be integrated with our BRBeans components.
Upcoming articles in this series
Our introductory article, "Integrate business processes among service consumers, brokers, and providers," describes a 5-stage roadmap for enabling the mediated exchange solution. Stay tuned to this series, which discusses each stage in detail and includes a set of articles describing how the capabilities required in each of these stages are designed, implemented, and deployed.
The authors would like to thank Liz Dettman and Jon Peterson for their contributions as technical reviewers.
- Download a
free trial version of WebSphere Studio Application Developer Integration Edition.
- Read Chapter 10 of the IBM Redbook WebSphere Application Server Enterprise Version 5 and Programming Model Extensions for more information on business rule beans planning, design, development, unit testing, assembly, deployment, problem determination, and security considerations.
- Visit the
WebSphere Studio zone on
developerWorks WebSphere for information about WebSphere Studio Application Developer Integration Edition.
- Browse for books on these and other technical topics.
Michael McMahon is an Advisory Software Engineer currently working as a scenario solution developer and tester in the IBM Software Group System House in Raleigh, North Carolina. Previously, he worked in the IBM WebSphere Edge Server team on load balancing and video streaming technology, and on a mix of video and database projects prior to that. You can contact Michael at mmcmaho@us.ibm.com.
Zeynep Latif is a software engineer currently working as an application developer in the IBM Software Group Horizontal Integration Analysis Lab in Research Triangle Park, NC. Along with her teammates, she is responsible for validating selected customer-based business scenarios to improve the customer experience with IBM Software Group products, especially the integration of those products. Prior to this position, she was a developer of the IBM VisualAge® Generator project. You can reach Zeynep at zeynep@us.ibm.com.
