Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Designing and implementing a mediated exchange solution: Develop business rules with WebSphere business rule beans, Part 2

Michael McMahon (mmcmaho@us.ibm.com), Advisory Software Engineer, IBM, Software Group
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 (zeynep@us.ibm.com), Software Engineer, IBM, Software Group
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.

Summary:  Part of the mediated exchange series, this article is the second in an overview focusing on IBM® WebSphere® business rules beans (BRBeans). WebSphere business rule beans architecture -- part of WebSphere Business Integration Server Foundation -- provides developers with a flexible mechanism for integrating external rules with a business process. In Part 1, you learned how to do the initial setup and configuration of business rules beans in a development environment. In this article, you learn how to integrate this technology with the mediated travel policy scenario. Find out about the development activities and required code samples you need to implement rules that support two travel policy interfaces.

Date:  01 Sep 2004
Level:  Intermediate

Activity:  2634 views
Comments:  

Introduction

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.


Revisit the business scenario

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.

RuleEmployeeManager
Preferred air carriersEconomyAirlineA
EconomyAirlineB
<Employee Airlines>
LuxuryAirlineC
Approval requiredPrice > $400Price > $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:

ProductNotes
Microsoft® Windows® 2000 or Windows XP operating systemOur 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.1This is the Eclipse-based development workbench we use to develop and test our BRBeans application.
IBM DB2® Universal Database™ Express Version 7 or Version 8A 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:

  1. Create a trigger point in the client code to invoke the defined business rule.
  2. 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.)
  3. 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.)

Roadmap

The remaining sections of this article are a roadmap of our development activities, with the following steps:

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:

  1. Start Application Developer and specify the workspace directory where the BRBeans project was previously set up.
  2. 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).
  3. Add the code displayed in Listing 1 to getPreferredAirProviders(). The extra method in this listing, called getRole(), 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 above getPreferredAirProviders().

    Listing 1. getPreferredAirProviders method

      private 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;	
    }
    

  4. After filling in the getPreferredProviders method, 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 either Manager or Employee. (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 in trigger() 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 resultObject returned from the trigger call should contain an object array. We will expect only one object populated in the return array for getPreferredAirProviders, 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.

  1. Write our custom classes: one for the employee variation of the rule and one for the manager version.
  2. Use the BRBeans rule management utility to create and configure the rule object persisted in the BRBDEMO database.

Create custom RuleImplementor classes

  1. 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.implementors as the Source Folder value. This is where we add all of our custom RuleImplementor classes.
  2. Highlight this new package, right-click and select New > Class. In the Name field, enter ConstantsRuleImpl as the name for the class. Click Add to the right of the Interfaces section. Type RuleImplementor in the Interfaces dialog and click OK. Your New Java Class dialog should look like Figure 1. Click Finish.
    Figure 1. Custom RuleImplementor class
    Figure 1. Custom RuleImplementor class
  3. Cut and paste the code in Listing 2 into the skeleton methods just created. Save and close the file.

    Listing 2. ConstantsRuleImpl class

    public 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];
                }
            }
        }
    }
    

  4. Right-click anywhere in the source file. Select Source > Organize Imports to add necessary package import statements and eliminate any errors in the class.
  5. Repeat the preceding steps to create a second RuleImplementator class to be called on behalf of managers. We'll call this class MergeConstantsRuleImpl. The code in RuleImplementor will merge or inherit any air carriers already specified for regular employees. Add the code shown in Listing 3 to the class.

    Listing 3. MergeConstantsRuleImpl class

    public 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, the fire method simply passes the string array back to the trigger point called by the client.
  • We could use the built-in class RuleConstant to 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.

Rule object for employee

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.

  1. Start the server1 Universal Test Environment (UTE) server created and configured in Develop business rules with WebSphere business rule beans, Part 1.
  2. 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
    Figure 2. Starting rule management utility
  3. Highlight the com folder in the Rule Browser, right-click and select New > Folder. Type friendlydestinations for the folder name. Highlight this new folder. Again, right-click and select New > Folder. Type policy for this folder name.
  4. Highlight the com/friendlydestinations/policy folder. Right-click and select New > Rule. The New Rule dialog appears. Type getPreferredAirProvidersEmployee in the Name field under the General tab.
  5. Enter 01/01/04 12:00 AM in the Start date field.
  6. Switch to the Implementation tab and enter com.friendlydestinations.policy.brb.rule.implementors.ConstantsRuleImpl as the Java rule implementor. This is the custom class we wrote earlier.
  7. 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.
  8. Click Add to the right of the Initialization Parameters section. Ensure the Type field is set to String and enter Employee Air Carriers in the Description field and EconomyAirlineA in 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 for ConstantsRuleImpl
    Figure 3. Initialization parameters for ConstantsRuleImpl

Rule object for manager

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:

  1. Highlight the policy folder in the Rule Browser. Right-click and select New > Rule. The New Rule dialog appears. Type getPreferredAirProvidersManager in the Name field in the General tab.
  2. Enter 01/01/04 12:00 AM in the Start date field.
  3. Click the Implementation tab and type in com.friendlydestinations.policy.brb.rule.implementors.MergeConstantsRuleImpl as the Java rule implementor. Click Add to the right of the Initialization Parameters section. Ensure the Type field is set to String, and enter Manager Air Carriers in the Description field and LuxuryAirlineC in the Value field. Click Add then Close.
  4. 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
    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:

  1. Within the J2EE perspective, ensure the Project Navigator view is displayed, and open the TravelPolicyEJBBean.java file (under the com.friendlydestinations.policy package).
  2. Add the code shown in Listing 4 to the isApprovalRequired() interface.
  3. 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, true is returned to the policy interface method to indicate that the airfare exceeds the limit and requires approval; otherwise, false is returned indicating approval is not required.
  • Since the RuleImplementator class 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

  1. Create the IsApprovalRequiredImpl class under the com.friendlydestinations.policy.brb.rule.implementors directory, implementing the RuleImplementor interface in the same manner as the ConstantsRuleImpl class described earlier.
  2. 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 true if the purchase amount is within the defined spending limits, or a falseis returned.
  • The IsApprovalRequiredImpl implementor 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 RuleImplementor class 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:

  1. Highlight the policy folder. Right-click and select New > Rule. The New Rule dialog appears. Type AirSpendingLimitEmployee in the Name field in the General tab.
  2. Enter 01/01/04 12:00 AM in the Start date field.
  3. Switch to the Implementation tab, and select the com.ibm.websphere.brb.implementor.RuleLessThanEqual built-in implementation class as the Java rule implementor.
  4. Click Add to the right of the Initialization Parameters section. Change the Type field to Double, enter SpendingLimit in the Description field, and 400.0 in the Value field. Click Add, and click Close.
  5. Keep the Pass firing parameters from trigger point unchanged radio button selected in the Firing parameters section, as shown in Figure 5.
  6. Click OK on the bottom of the New Rule dialog to save the rule in the database.
    Figure 5. Spending limit rule
    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:

  1. Highlight the com/friendlydestinations/policy folder in the Rule Browser. Right-click and select New > Rule. The New Rule dialog appears. Type in isApprovalRequired in the Name field under the General tab.
  2. Enter 01/01/04 12:00 AM in the Start date field.
  3. Switch to the Implementation tab and enter com.friendlydestinations.policy.brb.rule.implementors.IsApprovalRequiredImpl as 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.
  4. 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.
  5. 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
    Figure 6. Travel policy rules

Test and debug

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.

  1. Be sure the test server is started, and highlight server1 in the Servers view. Right-click and select Run universal test client.
  2. Select JNDI Explorer on the UTC homepage, as shown in Figure 7.
    Figure 7. UTC home page
    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
    Figure 8. TravelPolicyEJBHome link in UTC
  3. 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 getPreferredAirProviders method.
  4. 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.
  5. As shown in Figure 9, you should now see three strings containing EconomyAirlineA, EconomyAirlineB, and LuxuryAirlineC.
    Figure 9. Carrier results from UTC test
    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 10. Debug breakpoint set in getPreferredAirProviders

Figure 11. Changing secRole variable in debug mode
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
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
Figure 14. Rules Export dialog

Summary

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.


Next steps

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.


Acknowledgments

The authors would like to thank Liz Dettman and Jon Peterson for their contributions as technical reviewers.


Resources

About the authors

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.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Sample IT projects
ArticleID=58829
ArticleTitle=Designing and implementing a mediated exchange solution: Develop business rules with WebSphere business rule beans, Part 2
publish-date=09012004
author1-email=mmcmaho@us.ibm.com
author1-email-cc=
author2-email=zeynep@us.ibm.com
author2-email-cc=

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).