Integrate WebSphere ILOG JRules with IBM Content Manager Enterprise Edition

Developing a custom application based on an event framework with business rules

Automatic decision making is becoming more critical in content management systems. Externalizing decision logic from core application logic allows business rules to be managed and changed quickly to cope with dynamic business needs. IBM WebSphere ILOG JRules, a business rule management system (BRMS), provides the capabilities to author, deploy, and manage business rules so that managers can make better decisions, and make them more quickly. The integration of IBM WebSphere ILOG JRules and IBM Content Manager Enterprise Edition extends the reach of a content management solution for more effective management of business decisions within an organization.

This article describes how to integrate IBM Content Manager Enterprise Edition with IBM WebSphere ILOG JRules. Following an overview of the event framework and a brief introduction to ILOG JRules business rule management system, the article uses a loan scenario to illustrate how to write a custom event handler for integrating ILOG JRules with a content management application.

Share:

Alan Yaung (ayaung@us.ibm.com), Senior Software Engineer, IBM

Alan Yaung has extensive experiences in workflow and content management related products. He is the architect and lead developer of the event monitor and the event handler for the integration of IBM Content Manager Enterprise Edition and FileNet Business Process Manager. He is a contributing author to the IBM developerWorks Web site, where he has published several technical articles.



13 May 2010

Also available in Spanish

Introduction

The ability to make automatic decisions is becoming more critical in content management systems. However, for a growing number of use cases, the embedded decision rules in an application might not meet the complex requirements of a rapidly evolving business environment. Therefore, a dedicated business rule management system that supports business rule modeling, rule execution, and rule management becomes very important.

IBM WebSphere ILOG JRules is a business rule management system (BRMS) that offers the capabilities to author, deploy, and manage business rules in support of business agility and efficiency. The integration of ILOG JRules and IBM Content Manager Enterprise Edition Version 8.4.2 (hereafter referred to as Content Manager) is based on an event framework. This integration extends the reach of Content Manager to include more effective management of business decisions within an organization.

Content Manager supports an event infrastructure that enables the integration of external applications. This article describes how to develop a custom event handler that is driven by content-aware business logic with interaction to ILOG JRules.

The article provide an overview of the Content Manager event framework and an introduction of ILOG JRules business rule management system. Then a sample loan application scenario is introduced and used to illustrate how to develop a custom event handler that integrates ILOG JRules with Content Manager.


Understanding Content Manager event framework

Figure 1 illustrates the architecture of an event framework that supports the integration of Content Manager and external applications.

Figure 1. Event framework architecture
Flowchart depicting the relationships of the event framework architecture components. The following text explains the details.

As shown in the above figure, the event framework provides three main capabilities:

  • Event subscription allows the user to identify an item type and the events associated with that item type. During event subscription, the event subscription data is stored in the configuration tables in the Content Manager library server database. The configuration data is configured by using the Content Manager system administration client. Administrators subscribe the events to be monitored for a specific item type and its attributes.
  • Event monitoring logs the events when they occur and generates event messages that are sent to a Java Message Service (JMS) message queue. Event monitoring focuses on the event message generation. Through Java® and C++ API interfaces to Content Manager, applications can interact with the library server and generate event data in the database. The library server logs the events when they occur according to the configuration data. The logged events are placed into an event queue table in the library server database. An event contains event type, event ID, item information, and attribute data. The event monitor fetches event data from the event queue table based on the configuration data, converts the events into JMS messages, and puts the JMS messages on a JMS event queue.
  • Event processing retrieves the event messages from the JMS queue and processes the messages based on business logic. Event processing concentrates on the event message consumption. An event handler reads JMS messages, which carry the event data, from the JMS event queue. Event handlers provide the ability to integrate application logic with Content Manager document attributes. An event handler for process integration is provided with Content Manager for FileNet Business Process Manager, but for integration with other applications, you must develop custom event handlers.

Understanding ILOG JRules business rule management system

Automated business decisions can range from accepting a loan application to paying an auto insurance claim. These decisions are an integral element of business operations. IBM WebSphere ILOG JRules Business Rule Management System (BRMS) provides a flexible and predictable control over automated business decisions with a set of tools for business analysts, solution architects, and application developers.

Figure 2 illustrates the main components of ILOG JRules.

Figure 2. ILOG JRules overview
Rule Studio and Rule Team Server synchronize with one another. Both deploy to Rule Execution Server. The following text provides details.

As shown in the above figure, the ILOG JRules components are grouped into three areas:

  • Rule Studio is an Eclipse-based integrated development environment for business rule application development. Application developers can take advantage of the integration with Eclipse to develop Java projects along with rule projects. When developing a business rule project, the developer specifies the initial rules, designs rule templates, and organizes the folders for managing the rules. Using Decision Validation Services, developers can test rules against scenarios for validation and troubleshooting.
  • Rule Team Server is a Web-based rule management and authoring environment that allows business users to view, create, and modify rules. Business analysts work with Rule Team Server to write and maintain business rules during application development and after application deployment. From Rule Studio, the developer publishes rule projects to Rule Team Server, and then periodically synchronizes the work of the business users with the copy in Rule Studio.
  • Rule Execution Server provides administrators the access they need to monitor deployed rulesets, manage decision services, and perform auditing. Rule Execution Server is an execution environment for rules (Java SE and Java EE) interacting with the rule engine. Rule Execution Server handles the management, performance, security, and logging capabilities associated with the execution of business rules. A RuleApp is the format expected by Rule Execution Server. It contains the ruleset, which is packaged in a JAR file that contains everything necessary for execution (rules, ruleflow, and so on). Rulesets can be deployed from both Rule Studio and Rule Team Server.

A scenario

This section introduces a sample scenario that illustrates how to incorporate ILOG JRules with the event framework in a business context.

A mortgage unit of a regional bank is planning to automate a loan application process. The loan application process consists of three work baskets: SubmitLoan, Approved, and Rejected. When a loan application is submitted, it goes into the SubmitLoan work basket. It moves to the Approved work basket if it is approved, or it moves to the Rejected work basket if it is rejected. A loan application in the Rejected work basket can be resubmitted to the SubmitLoan work basket for reevaluation.

ILOG JRules is integrated into the SubmitLoan work basket to provide automatic decision making. During the loan application submission, a loan agent provides the loan information such as loan number, loan amount, interest rate, duration, etc. After the application arrives in the SubmitLoan work basket, the loan information is sent to the ILOG JRules rule engine for evaluation. If the assessment is positive, the loan application is automatically moved to the Approved work basket. Otherwise, it is automatically moved to the Rejected work basket. A loan application that goes to the Rejected work basket can be resubmitted to the SubmitLoan work basket. Once its loan information is updated, it is reevaluated. When a loan application moves to either the Approved or Rejected work basket, an e-mail notification is generated and sent to notify the interested parties of the loan application status.

The loan application process with the SubmitLoan, Approved, and Rejected work baskets described above is illustrated in Figure 3.

Figure 3. Loan application process
SubmitLoan basket leads to either Approved or Rejected basket. Rejected can either resubmit or go to stop. Approved goes to stop.

As shown in Figure 4, three worklists (SubmittedWL, ApprovedWL, and RejectedWL) are defined to monitor the work items in the respective work baskets.

Figure 4. Worklists for the loan application process
Screen shot shows the three worklists: SubmittedWL, ApprovedWL and RejectedWL

A Loan item type for loan application processing is defined in Content Manager. As shown in Figure 5, it consists of the following attributes:

  • LoanNumber — a unique identifier of the loan
  • LastName — last name of the loan applicant
  • FirstName — first name of the loan applicant
  • CreditScore — credit score of the loan applicant
  • YearlyIncome — yearly income of the loan applicant
  • LoanAmount — amount of the loan
  • InterestRate — interest rate of the loan
  • Duration — duration of the loan in months
  • Notification — e-mail addresses for the recipients of notifications
Figure 5. Loan item type
Loan item type shown with each of the attributes in the above list.

The Enable Event Subscription checkbox in the Library Server Configuration dialog (Figure 6) must be selected to enable the logging of events for a library server instance. At the item type level, Figure 7 shows an example of event subscription of an item type Loan. The events to be subscribed for this item type are Add Item and Update Item events. When the administrator clicks the Add button on the Event Subscription page, a Define Event Subscription dialog is displayed. The administrator would select the General integration option because the scenario is related to a general purpose external application. All document attributes of this Loan item type are selected to be monitored in the event monitoring for both the Add Item and Update Item events.

Figure 6. Library server configuration
Library Server Configuration dialog with Enable Event Subscription selected.
Figure 7. Event subscription
Define Event Subscription dialog with General integration selected.

The focus of this article is on the integration of ILOG JRules with Content Manager, and the business rules of a loan example. The loan example is borrowed from the "Getting started" section of the IBM WebSphere ILOG JRules information center (refer to the Resources section for a link to the information center).

Figure 8 shows the two sets of business rules used by the loan example:

  • Eligibility
    • Minimum credit score — ensures that the credit score is not less than 200.
    • Minimum income — ensures that the minimum yearly income is met.
    • Repayment and credit score comparison — ensures that the combination of the percentage of debt-to-income and credit score is acceptable.
  • Validation
    • Maximum loan amount — ensures that the maximum loan amount does not exceed $1,000,000.

In the figure, the two sets of rules are shown in the Explore tab of the ILOG Rule Team Server. For this scenario, the business rules are published into Rule Team Server from Rule Studio, and are deployed as a rule archive (with a jar format). Rule Execution Server is an environment for executing rules. For the simplicity of illustration, the Java SE rule session type is selected and a rule session embeds the Java SE execution unit.

Figure 8. ILOG JRules business rules
Screenshot of Explore tab of ILOG Rule Team Server showing two sets of Business Rules: Eligibility and Validation.

Figure 9 illustrates how a business rule is represented. It shows the content of the minimum credit score business rule in the Compose tab of the Rule Team Server. The rule specifies that if the borrower's credit score is less than 200, the loan application is rejected.

Figure 9. Minimum credit score
Screenshot of Compose tab of ILOG Rule Team Server showing detail of the credit score business rule.

Integration architecture

Products used in the example

The following products are used in the example described in this article:

  • IBM WebSphere ILOG JRules Version 7.0.2 (Trial version)
  • IBM Content Manager Enterprise Edition Version 8.4.2
  • IBM WebSphere MQ Version 6.0

This section describes the architecture that the loan application scenario is built on. The architecture integrates ILOG JRules with Content Manager. As shown in Figure 10, the architecture is comprised of three parts:

  • Content— Content Manager is the content repository. Its library server component supports both the data modeling of the loan application and the process modeling of the loan application process.
  • Event handling— The custom event handler implements the core application logic and integrates ILOG JRules with Content Manager. It receives loan application events from Content Manager and submits requests to ILOG JRules for evaluation. Based on the evaluation result, it takes proper actions and sends the appropriate e-mail notification.
  • Business rules— The business decision logic is separated from the core application logic. The business rules are run by the ILOG JRules rule engine. Those business rules can be modified by the business analysts through the Rule Team Server.
Figure 10. Content Manager / ILOG integration architecture
Diagrram depicting the three parts of the integration architecture: Content, Event handling, and Business rules.

Following is an overview of how a loan application scenario would flow through the integration architecture.

  • A loan agent creates a loan application document of item type Loan in Content Manager.
  • As soon as the loan application document is created, an instance of the loan application process is automatically started in a Content Manager server. The loan application stays in the SubmitLoan work basket for evaluation.
  • The administrator configured the Loan item type to monitor either an Add Item event or an Update Item event for document creation and revision respectively. Therefore, the library server inserts a row of event data into the event queue table. The event data includes attribute values such as LoanNumber, LoanAmount, and Notification.
  • An event monitor scans the event queue table for committed rows, and retrieves Add Item or Update Item events for a loan document. The event monitor converts the configuration information and the event data retrieved from the event queue table into a self-describing event message in a common base event (CBE) format. It then sends the event message to a Java Message Service (JMS) queue.
  • A custom event handler, which is listening to the JMS queue, retrieves the document creation event and revision event from the queue. The event handler parses the event data from the CBE format and then uses the loan information to submit a request to the ILOG JRules rule engine for evaluation.
  • When the request is received, the ILOG JRules rule engine executes the business rules and sends back the evaluation of the loan application.
  • After receiving the response from the ILOG JRules rule engine, the event handler routes the loan application to the proper work basket (Approved or Rejected) in the loan application process and sends an e-mail to the recipients on the notification list.

Design overview of the myEventHandler custom event handler

The basic functions of a custom event handler are to consume the event messages in the JMS queue and interact with external applications accordingly. For this article's scenario, the event handler must connect to a Content Manager server to retrieve the document attributes of the item referenced in the event message. Next, the handler establishes a rule session and sends a request to the ILOG JRules rule engine for evaluating the loan application. The event handler then uses the JavaMail API to compose an e-mail notification that is sent to the recipients.

The sample program available in the Download section defines a custom event handler that supports the business logic described in the scenario for this article. The custom event handler is a JMS application named myEventHandler. It uses an asynchronous messaging delivery mechanism. A message listener is implemented to receive new messages as they arrive in the JMS queue.

Listing 1 shows the overall structure of the myEventHandler sample program. Following is a high level description of what the program does:

  • The program imports the following required packages:
    • JMS and Java Naming and Directory Interface (JNDI) packages for accessing a JMS queue
    • JavaMail package for sending e-mail
    • SAX API package for parsing the event message
    • Content Manager API package for retrieving content data
    • ILOG API package for establishing a rule session
  • The myEventHandler class implements two JMS listeners:
    • The onMessage method for the javax.jms.MessageListener interface listens to the JMS queue.
    • The onException method for the javax.jms.ExceptionListener interface handles JMS exceptions.
  • Two inner classes are defined for parsing the event messages:
    • The myContentHandler class extends the DefaultHandler class of SAX API to parse the event message.
    • The myErrorHandler class implements the ErrorHandler interface of SAX API.
  • The sendMail method constructs the e-mail and uses the JavaMail API to send the notification to recipients. It is called by the onMessage method when an event message is received.
  • The executeILOGRules method sends a request to the ILOG JRules rule engine for rule execution. The rule engine evaluates the loan application and returns the response to the caller.
  • The waitForQUIT method is called when the myEventHandler class is instantiated. It prompts the user for the quit command. The myEventHandler class exits when a quit command is received.
Listing 1. Program structure
// JMS API
import javax.jms.*;
// JNDI API
import javax.naming.*;
// Java IO and utility
import java.io.*;
import java.util.*;
// SAX abd XML parsing
import org.xml.sax.*;
import org.xml.sax.helpers.*;
// JavaMail API
import javax.mail.*;
import javax.mail.internet.*;
// CM API
import com.ibm.mm.sdk.server.*;
import com.ibm.mm.sdk.common.*;
// ILOG API
import ilog.rules.res.session.*;
import ilog.rules.res.model.*;
import ilog.rules.res.session.ruleset.*;

public class myEventHandler extends Thread 
             implements javax.jms.MessageListener, javax.jms.ExceptionListener
{

    static class myContentHandler extends DefaultHandler
    {
        // methods in the myContentHandler class
    }
    
    static class myErrorHandler implements ErrorHandler
    {
        // methods in the myErrorHandler
    }   
            
    public void run() 
    {      
        this.waitForQUIT();       
    }
    
    private void waitForQUIT() throws Throwable
    {
        // prompt for the QUIT command to exit     
    }     
    
    public myEventHandler(String database, String userid, String pw) throws Throwable
    { 
        // set up JMS connection
        // initialize SAX parser  
        // start the thread for waiting the QUIT command to exit   
    }
    
    public static void main(String[] argv)
    {
        // start the myEventHandler instance
        myEventHandler eh = new myEventHandler(argv[0], argv[1], argv[2]);
    }
    
    public void onMessage(javax.jms.Message message) 
    { 
        // listen to the JMS queue
        // retrieve a JMS message 
        // parse the JMS message to obtain the event data
        // process the event data
        // compose an e-mail
        // call the sendMail function to send out an e-mail notification
    }  

    public void onException(JMSException exc)
    {
        // print the error message when a JMS exception occurs 
    }

    public void sendMail(String mailhost, String from, String[] to, 
                        String subject, String text) 
    {
        // send an e-mail notification to the claim reviewers
    }
    
    public IlrSessionResponse executeILOGRules(String firstName,
                String lastName, int loanAmount, int duration, 
                float interestRate, int creditScore, int yearlyIncome)
    {
        // send a request to ILOG JRules rule engine for rule execution
        // an IlrSessionResponse object is returned with the evaluation result
    }
}

The following sections of the article examine the main portions of the sample program in more detail:

  • Connecting to a JMS queue
  • Retrieving the event data in an event message
  • Parsing the event data in an event message
  • Retrieving content data referenced by the event from a Content Manager server
  • Performing rule execution
  • Moving the loan application in the process
  • Sending the e-mail to the recipients to be notified

Connecting to a JMS queue

Listing 2 shows the part of the myEventHandler sample program that sets up the access to a JMS queue.

First, the program retrieves a queue connection factory by looking up the context object with a queue connection factory name. From the queue connection factory, a queue connection is created. Next, a queue session is created from a queue connection and a queue is retrieved by looking up the context object with a queue name. Then a queue receiver is created for a specified queue as a consumer of messages. The queue receiver listens to the queue with a message selector APPLICATION = 'none', which indicates that the message is from general integration. Only the messages with a message property APPLICATION and a property value of 'none' are retrieved from the JMS queue.

After the queue receiver is available, the program sets the message listener in the queue receiver. The exception listener is set in the queue connection. Before starting the JMS connection, the program performs two additional tasks:

  • Initializes the SAX parser for parsing the event message
  • Connects to the Content Manager for retrieving the content data

The last step starts the JMS connection. After the JMS connection is started, the onMessage message listener and the onException exception listener are ready for the incoming messages from the JMS queue.

Listing 2. Connect to a JMS queue
        // obtain the queue connection factory
        factory = (QueueConnectionFactory)ctx.lookup(_qcf_name);
        // create a queue connection
        connection = factory.createQueueConnection();
        System.out.println("Queue connection created");
        // create a queue session
        qSession = connection.createQueueSession(false, 
                                                 javax.jms.Session.AUTO_ACKNOWLEDGE);
        System.out.println("Queue session created");
        // create a queue
        testQueue = (javax.jms.Queue)ctx.lookup(_queue_name);
        System.out.println("Queue = [" + _queue_name + "]");
        // create a consumer listening to the specified queue 
        // for message property APPLICATION = 'none' (general integration)
        qReceiver = (QueueReceiver)qSession.createConsumer(testQueue, 
                                                           "APPLICATION = 'none'");
        // set the message listener
        qReceiver.setMessageListener(this);
        // set the exception listener        
        connection.setExceptionListener(this);

        // initialize the SAX parser
        try {
            _parser = initParser(_dh);          
        } catch (SAXException se) {
            System.out.println("SAXException - " + se.getMessage());
            throw se;
        }
        
        // connect to the Content Manager
        dsICM = new DKDatastoreICM();
        dsICM.connect(database, userid, pw, "");
        System.out.println("datastore connected.");        
                
        // start the JMS connection
        connection.start();       
        System.out.println("Queue connection started");

Retrieving the event data

After the JMS connection starts, the onMessage message listener retrieves the messages from the JMS queue on a first-in/first-out basis. A JMS message is first cast to a TextMessage object.

Listing 3 shows the part of the myEventHandler sample program that retrieves the event data. The program retrieves the message string from the TextMessage object along with the following six message properties:

  • DATABASE is the name of the Content Manager server generating the event.
  • TYPE is the type of the event (for example, "item-create").
  • LAUNCH indicates whether or not the message requests to launch a workflow. This property's value can be either "true" or "false". For general integration, the value is "false".
  • ID is the identifier of the event (for example, "A1001001A10B19B12751I284680000000000000000225000").
  • APPLICATION is the application associated with a workflow launch. For process integration with FileNet Business Process Manager (BPM), the value is "BPM". For general integration, the value is "none".
  • COUNT indicates how many data elements are contained in the event. If the length of the event is less than or equal to 1024, only one context data element exists in the event. Otherwise, if the count is greater than 1, the custom event handler needs to concatenate the multiple context data elements together.

Next, the program parses the message string, which is represented in a common base event (CBE) format. The following variables are used to pass information from the CBE-formatted message string to the program:

  • strGlobalInstanceId is the global instance ID of the event (for example, "A1001001A10B19B12751I284680000000000000000225000", which is the same as the message ID).
  • strReturnMsg contains the event data from the Content Manager content repository.
  • strReturnTime is the creation time of the event in GMT (for example, "2010-03-19T01:03:11.256Z").
  • strApplication is the name of the application generating the event (for example, "Content Manager Event Monitor").
  • strComponent is the name of the component generating the event (for example, "Content Manager 8.4.02.000").
  • strExecutionEnvironment indicates the operating system and architecture of the execution environment (for example, "Windows XP[x86]").
  • strLocation is the hostname and IP address of the event monitor (for example, "myhost/1.11.22.33").
  • strSubComponent is the name of the subcomponent (for example, "Event Monitor").
Listing 3. Retrieve the event data
            // cast the message to the TextMessage object
            msg = (TextMessage) message;
            // retrieve the raw string from a JMS message
            rawString = msg.getText();

            System.out.println("Reading message: " + rawString);
        
            // retrieve the message properties from a JMS message
            msgDatabase = msg.getStringProperty("DATABASE");
            msgType = msg.getStringProperty("TYPE");
            msgLaunch = msg.getStringProperty("LAUNCH");
            msgID = msg.getStringProperty("ID");
            msgApplication = msg.getStringProperty("APPLICATION");
            msgCount = msg.getStringProperty("COUNT");
        
            // create an input source from the raw string
            ByteArrayInputStream bais = new ByteArrayInputStream
                                        (rawString.getBytes("UTF-8"));
            InputSource is = new InputSource(bais);
            bais.close();
            
            // parse the string
            try {
              _parser.parse(is);
            } catch (SAXParseException se) {
              System.out.println("Encountered a SAX parser error" 
                                 + " - " + se.getMessage());
              se.printStackTrace();
              throw se;
            }
            
            // retrieve the information from a CBE-formatted string
            strGlobalInstanceId = ((myContentHandler)_dh).getGlobalInstanceId();
            strReturnMsg = ((myContentHandler)_dh).getReturnMsg();
            strReturnTime = ((myContentHandler)_dh).getReturnTime();
            strApplication = ((myContentHandler)_dh).getApplication();
            strComponent = ((myContentHandler)_dh).getComponent();
            strExecutionEnvironment = ((myContentHandler)_dh).getExecutionEnvironment();
            strLocation = ((myContentHandler)_dh).getLocation();
            strSubComponent = ((myContentHandler)_dh).getSubComponent();

Parsing the event data

Listing 4 shows the part of the myEventHandler sample program that parses the event data retrieved from the message string. This code obtains the PID string and ITEMTYPE name from the event data. The PID string and ITEMTYPE name are used later to retrieve the content data and compose an e-mail notification.

A StringTokenizer object is instantiated with the event data and the delimiter ";". A while loop iterates through the tokens until either the "ICMEMEND" is found or no more tokens are available. Each token is represented as a 3-tuple element with <tag>, =, and <value>. The token with the ITEMTYPE tag contains the name of the item type of the document referenced in the event data. Similarly, the token with the PID tag carries the persistent ID string of the document referenced in the event data.

Listing 4. Parse the event data
            // Use the StringTokenizer to parse the event message           
            StringTokenizer tokenizer = new StringTokenizer(strReturnMsg, ";");
 
            // variable for PID
            String pid = "";
            // variable for itemtype
            String itemtype = "";
             
            String strPart = ""; 
            int pos = 0;
            String tagPart = "";
            
            // retrieve pid and itemtype from the event message
            while (true) {
              strPart = tokenizer.nextToken();
              if (strPart.equalsIgnoreCase("ICMEMEND")
                  || strPart == null || strPart.equals("")) break;

              pos = strPart.indexOf('=');
              tagPart = "";
 
              if (pos > 0) {      
                  tagPart = strPart.substring(0, pos);
              }
              else continue;
 
              if (tagPart.equalsIgnoreCase("ITEMTYPE")) {
                  pos = strPart.indexOf('=');
 
                  if (pos > 0) {
                      itemtype = strPart.substring(pos + 1);
                  }
              }
              else {
                if (tagPart.equalsIgnoreCase("PID")) {
                    pos = strPart.indexOf('=');
 
                    if (pos > 0) {
                        pid = strPart.substring(pos + 1);
                    }
                }
              }
            } // end while

Retrieving the content data

Given the PID string retrieved from the event data, the document metadata can be retrieved from a Content Manager repository. Listing 5 shows the part of the myEventHandler sample program that retrieves a dynamic data object (DDO object) and its attributes from a Content Manager server. First, a DDO object is created with the PID string from the event data. A retrieve call populates the DDO object with attribute values.

Next, the following attributes are retrieved:

  • InterestRate is the interest rate of the loan (for example, "0.05").
  • FirstName is the first name of the loan applicant.
  • LastName is the last name of the loan applicant.
  • LoanAmount is the amount of the loan (for example, "500000").
  • Duration is the duration of the loan in months.
  • CreditScore is the credit score of the applicant (for example, "310").
  • YearlyIncome is the annual income of the applicant.
  • Notification is a child component that contains a list of e-mail addresses with an EMailAddress attribute for the recipients (for example, "user@host.com").

The attribute values from the DDO object are used later to compose an e-mail notification.

Listing 5. Retrieve the content data
            // retrieve the DDO object with the pid string
            DKDDO ddo  = (DKDDO)dsICM.createDDO(pid);	        
            ddo.retrieve();
            // retrieve the LoanNumber attribute
            short dataId = (short)ddo.dataId("LoanNumber");              
            String loanId = (String)ddo.getData(dataId);
            // retrieve the InterestRate attribute
            dataId = (short)ddo.dataId("InterestRate");                
            float interestRate = ((java.math.BigDecimal)
                                 (ddo.getData(dataId))).floatValue();
            // retrieve the FirstName attribute
            dataId = (short)ddo.dataId("FirstName");              
            String firstName = (String)ddo.getData(dataId);
            // retrieve the LastName attribute
            dataId = (short)ddo.dataId("LastName");              
            String lastName = (String)ddo.getData(dataId);           
            // retrieve the LoanAmount attribute
            dataId = (short)ddo.dataId("LoanAmount");   
            int loanAmount = ((Integer)(ddo.getData(dataId))).intValue();
            // retrieve the Duration attribute
            dataId = (short)ddo.dataId("Duration");   
            short duration = ((Short)(ddo.getData(dataId))).shortValue();
            // retrieve the CreditScore attribute
            dataId = (short)ddo.dataId("CreditScore");   
            short creditScore = ((Short)(ddo.getData(dataId))).shortValue();
            // retrieve the YearlyIncome attribute
            dataId = (short)ddo.dataId("YearlyIncome");   
            int yearlyIncome = ((Integer)(ddo.getData(dataId))).intValue();
            // retrieve the Notification component
            DKChildCollection notification = (DKChildCollection) ddo.getData(
                     (short)ddo.dataId(DKConstant.DK_CM_NAMESPACE_CHILD, 
                     "Notification"));
            dkIterator iterNotification = notification.createIterator();
            int count = notification.cardinality();
            // variable for Notification
            String[] notificationList = new String[count];
            int index = -1;
            // construct the array of e-mail addresses
            while (iterNotification.more()) {
              DKDDO ddoEmail = (DKDDO) iterNotification.next();
              ddoEmail.retrieve();
              dataId = (short) ddoEmail.dataId("EMailAddress");
              String email = (String) ddoEmail.getData(dataId);
              if (email == null || email.trim().equals("")) continue;
              else {
                  index++;              
                  notificationList[index] = email.trim();
              }
            }

Performing rule execution

Because the integration architecture externalizes the decision making to an ILOG JRules rule engine, the custom event handler is required to establish a session connecting to ILOG JRules. Next, the loan information is passed to the rule engine for evaluation. The evaluation response is then returned to the custom event handler for further actions.

Listing 6 shows the part of the myEventHandler sample program that contains the detailed steps for performing rule execution. At a high level, this code does the following:

  • Creates a J2SE rule session to be used by the sample program.
  • Creates a session request that allows the event handler to set the rule path and the input parameters.
  • Sets the rule path in the request according to the syntax: "/{RuleApp name}[/{version}]/{ruleset name}[/{version}]".
  • Sets the borrower and loan input parameters in the request.
  • Sends the request to the ILOG JRules rule engine for execution, and an IlrSessionResponse object is returned with the evaluation response.
Listing 6. Performing rule execution
        // create a J2SE session 
        IlrSessionFactory factory = new IlrJ2SESessionFactory();
        IlrStatelessSession session = factory.createStatelessSession();
        // create a session request
        IlrSessionRequest sessionRequest = factory.createRequest();
        
        //  The rule path is composed of: 
        //      /{RuleApp name}[/{version}]/{ruleset name}[/{version}]
        //
        //  Note that the rule archive is deployed in the file system 
        //  under the res_data subdirectory.
        String rulesetpath = "/miniloanruleapp/1.0/miniloanrules/1.0";

        sessionRequest.setRulesetPath(IlrPath.parsePath(rulesetpath));

        // ensure correct version of the ruleset is taken in account
        sessionRequest.setForceUptodate(true);
        sessionRequest.setTraceEnabled(true);
        sessionRequest.getTraceFilter().setInfoAllFilters(true);

        // set the input parameters for the execution of the rules
        Map inputParameters = new HashMap ();
       
        // miniloan.Borrower borrower = new miniloan.Borrower("Tom", 500, 50000);
        // This expression sets the input parameter to a borrower named Tom
        // with a credit score of 500 and yearly income of 50000.
        miniloan.Borrower borrower = new miniloan.Borrower(lastName+", "+firstName, 
                                                           creditScore, yearlyIncome);

        // miniloan.Loan loan = new miniloan.Loan(500000, 240, 0.05);
        // This expression creates a new loan with an amount of 500000,
        // a duration of 240 months, and an interest rate of 5%.
        miniloan.Loan loan = new miniloan.Loan(loanAmount, duration, interestRate);

        inputParameters.put("borrower", borrower);
        inputParameters.put("loan", loan);

        sessionRequest.setInputParameters(inputParameters);
        // execute the rules
        IlrSessionResponse sessionResponse = session.execute(sessionRequest);
        return sessionResponse;

Moving the loan application in the process

Listing 7 shows the part of the myEventHandler sample program that selects the correct route in the loan process to move the loan application forward from the SubmitLoan work basket. If the loan is approved, it is moved from the SubmitLoan work basket to the Approved work basket. If the loan is rejected, it is moved from the SubmitLoan work basket to the Rejected work basket.

Listing 7. Advancing the loan application
            // Locate the workpackage referenced by the pid string
            String[] wpList = drICM.listWorkPackagePidStringsWithItem(pid);
            for (int i = 0; i < wpList.length; i++)
            {
                if ((drICM.retrieveWorkPackage(wpList[i], true))
                    .getWorkNodeName().equalsIgnoreCase("SubmitLoan"))
                {
                  if (approved) {
                     // Advance the workpackage to the "Approved" work basket, 
                     // if the workpackage is located at the "SubmitLoan" work basket 
                     // and approved = true.
                     drICM.continueProcess(wpList[i], "Approve", "ICMADMIN");
                  }
                  else
                  {
                     // Advance the workpackage to the "Rejected" work basket, 
                     // if the workpackage is located at the "SubmitLoan" work basket 
                     // and approved = false.
                     drICM.continueProcess(wpList[i], "Reject", "ICMADMIN");
                  }                 
                  ...
                }
                ...                 
            }

Sending the e-mail notification

Listing 8 shows the part of the myEventHandler sample program that uses the JavaMail API to send an e-mail via the simple mail transport protocol (SMTP) and displays an excerpt of the program's sendMail method. First, an SMTP server name is specified and a session object is instantiated. Next, the From address and an array of To addresses are set. The program also sets the subject of the e-mail, the mailer, and the sent date. Finally, the program calls the Transport.send method to send the e-mail to the specified SMTP server to deliver the e-mail to the recipients.

Listing 8. Send the e-mail notification
        Properties props = System.getProperties();
        
        // use SMTP 
        if (mailhost != null) props.put("mail.smtp.host", mailhost);

        // get a Session object
        javax.mail.Session session = javax.mail.Session.getInstance(props, null);
        if (debug) session.setDebug(true);

        // construct the message
        javax.mail.Message msg = new MimeMessage(session);
        // set From address 
        if (from != null)
            msg.setFrom(new InternetAddress(from));
        else
            msg.setFrom();
        
        InternetAddress[] toAddresses = new InternetAddress[to.length];
        for (int i = 0; i < to.length; i++) {
            toAddresses[i] = new InternetAddress(to[i]);
        }
        // set To address
        msg.setRecipients(javax.mail.Message.RecipientType.TO, toAddresses);
        
        // optional
        if (cc != null)
            msg.setRecipients(javax.mail.Message.RecipientType.CC, 
                              InternetAddress.parse(cc, false));
        if (bcc != null)
            msg.setRecipients(javax.mail.Message.RecipientType.BCC, 
                              InternetAddress.parse(bcc, false));
        // set Subject 
        msg.setSubject(subject);
        // set e-mail text
        msg.setText(text);

        msg.setHeader("X-Mailer", mailer);
        msg.setSentDate(new Date());
        // send out the e-mail
        Transport.send(msg);

Exploring the sample loan application

This section steps through a specific loan application example to demonstrate the functionality of the sample program and the integration between Content Manager and ILOG.

The example begins with a loan agent creating a loan application document. The document creation triggers an item-create event, which flows from the event monitor to the customer event handler through a JMS queue. As shown in Figure 11, the custom event handler consults with the ILOG JRules rule engine to determine whether to approve or reject the loan application. The event handler then advances the loan application in the loan process according to whether it is approved or rejected, and sends the appropriate e-mail notification to recipients.

Figure 11. Loan scenario
Diagrram depicting an event flowing through the Content Manager / ILOG integration architecture.

When the loan agent submits a loan application for his client, the submission automatically creates an event that triggers the custom event handler to act upon the application. Figure 12 depicts a completed entry screen where the loan agent has entered the following information:

  • Loan number: 01-234-5678-8
  • Last name: Doe
  • First name: John
  • Credit score: 310
  • Yearly income: 30000
  • Loan amount: 500000
  • Interest rate: 0.05
  • Duration: 240
  • Notification: user@host.com
Figure 12. Loan application information
Loan application entry screen filled out with data listed above.

In this particular case, based on the evaluation response from ILOG JRules rule engine, the loan application is rejected due to:

  • Debt-to-income too high compared to credit score
  • Debt-to-income ratio is to big

As a result, the custom event handler moves the loan application from the SubmitLoan work basket to the Rejected work basket. Figure 13 shows that the RejectedWL worklist now contains the loan application for this loan.

Figure 13. The RejectedWL worklist
Screenshot of RejectedWL. The worklist contains the example loan application with number 01-234-5678-8

Figure 14 is an example of an event notification, which in this case is an e-mail sent by the custom event handler. The event notification includes the following information:

  • Event information, such as host name, database, event type, message ID, and item type
  • Loan information, such as loan number, last name, first name, credit score, yearly income, loan amount, interest rate, and duration
  • Approval status with assessment details
Figure 14. E-mail notification
Screenshot of a sample e-mail that is generated by the event handler.

Conclusion

IBM Content Manager Enterprise Edition supports an event infrastructure that enables the integration of external applications. This article described a scenario and the design of a custom event handler that integrates IBM WebSphere ILOG JRules with Content Manager. The sample code provided in the Download section illustrates the interaction between Content Manager and ILOG JRules through a custom event handler. With the ability to manage business rules in a fast evolving environment, solution developers can develop more effective business applications in the enterprise content management area.


Download

DescriptionNameSize
Sample program for this articlemyEventHandler.zip10KB

Resources

Learn

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


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. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

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.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

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

 


All information submitted is secure.

Dig deeper into Information management on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Information Management, WebSphere
ArticleID=489182
ArticleTitle=Integrate WebSphere ILOG JRules with IBM Content Manager Enterprise Edition
publish-date=05132010