Developing Adapters

     Previous  Next    Open TOC in new window  Open Index in new window  View as PDF - New Window  Get Adobe Reader - New Window
Content starts here

Developing an Event Adapter

This section contains information about the following subjects:

 


Introduction to Event Connections

Event connections propagate information from an EIS to the WebLogic Integration environment; they can be described as publishers of information.

All WebLogic Integration event connections perform the following functions:

WebLogic Integration implements the aspects of the first three functions that are common to all event connections, allowing you to focus on only the EIS-specific aspects of your adapter. WebLogic Integration provides framework support for the four optional functions, but no direct implementation.

 


Event Adapters in a Run-Time Environment

The behavior of an event in a run-time environment is depicted in Figure 7-1.

Figure 7-1 Event Connections in a Run-time Environment

Event Connections in a Run-time Environment

 


Flow of Events

Figure 7-2 outlines the steps required to develop an Event Connection.

Figure 7-2 Event Connection Flow of Events

Event Connection Flow of Events

 


Step 1: Define the Adapter

Before you start developing an event connection, you must define your requirements for it. For a complete list of the information you need to do so, see Adapter Setup Worksheet. This section provides a summary of the most important tasks to be completed for step 1:

  1. Define an event in terms of the following questions:
    • What will be the contents of the event?
    • How will the event be defined in the XML schema?
    • What will trigger the event?
  2. Select one of the following data extraction methods:
    • Push—The EIS notifies the adapter of an event. Use this method when your adapter needs to poll the EIS to determine a change of state. This is the most efficient implementation for event generators, but involves EIS-side configuration and may not be possible with all EIS types.
    • Pull—The adapter polls the EIS and pulls event data from it. Use this method when you want to implement event generation that works like a publish-and-subscribe model. This is less efficient than the push model above, but is often easier to implement, is less dependent on the capabilities of the EIS, and doesn't generally required EIS-side configuration.
  3. Decide if you will allow your event generator to be suspended and resumed.
    • Allow this if your EIS holds event information persistently, and it can be retrieved at a later time.
    • Do not allow this if your EIS cannot store event information for later retrieval (for example, event information is delivered via a non-persistent remote call)
  4. Decide if you will indicate your event generator's status and the status of your EIS instance to the event router.
    • BEA strongly recommends you consider implementing this support. Implementing it greatly enhances the manageability of your adapter.
    • Implement this support if you can clearly determine the internal state of your event generator (for example, Healthy if your connection to the EIS is established and working properly) and/or you can clearly determine the status of the EIS instances (for example, Available if you have an active connection to the EIS).
  5. Decide if you will implement event generator instance support.
    • BEA strongly recommends you consider implementing this support. Implementing it greatly enhances the manageability of your adapter with regards to load balancing and fault tolerance within a WebLogic Integration cluster.
    • If your event generator can coexist with other event generators using the same EIS instance without conflicting with the operation of the other generators, you should consider implementing generator instance support. For example, the DBMS sample adapter is capable of sharing a single set of events within a DBMS instance with multiple generator instances. It has implemented generator instance support to enable it to be managed effectively in a WebLogic Integration cluster.
    • If your event generator cannot coexist with other event generators using the same EIS instance, you do not need to implement event generator instance support.
  6. Decide if you will implement environment variable support.
    • Environment variables allow adapters to isolate information that is specific to a given deployment environment such that it can be updated by a WLI administrator when the adapter instances using that adapter are moved between environments.
    • Adapters that require environment specific information in their interaction spec object or in the request document for services or the event definition for events, should consider implementing environment variable support. Examples of environment specific information are resource identifiers like table names for a DBMS adapter, or email folder names for an email adapter.
    • Note: Environment specific information does not include the information used to create a connection to the EIS. This information is almost always, by its nature, environment specific.
    • Adapters that contain no environment specific information in their interaction spec object, request documents, or event definitions, need not implement environment variable support.

 


Step 2: Configure the Development Environment

This step involves completing a five-step procedure to prepare your computer for adapter development:

Step 2a: Set Up the File Structure

The file structure needed for an event connection development environment is the same as that required for developing service connections. For details, see Step 2a: Set Up the Directory Structure in Developing a Service Adapter.

Step 2b: Assign a Logical Name to the Adapter

Assign a logical name to your adapter. By convention, this name comprises the vendor name, the type of EIS connected to the adapter, and the version number of the EIS, and it is expressed as vendor_EIS-type_EIS version. For example:

BEA_WLS_SAMPLE_ADK

This name includes the following components:

Step 2c: Set Up the Build Process

WebLogic Integration employs a build process based on Ant, a 100% pure Java-based build tool. For more information about how Ant works, see Ant-Based Build Process. For more information about how to use Ant, go to:


http://jakarta.apache.org/ant/index.html

The sample adapter provided by WebLogic Integration contains an Ant build file: WLI_HOME/adapters/sample/project/build.xml. This file, in turn, contains the tasks needed to build a J2EE-compliant adapter. When you run the GenerateAdapterTemplate utility to clone a development tree for your adapter, a build.xml file is created specifically for that adapter. Because this file is generated automatically, you do not need to customize the sample build.xml file and you can be sure that the code is correct. For information about using the GenerateAdapterTemplate utility, see Creating a Custom Development Environment.

For more information about the build process, see Step 2c: Set Up the Build Process in Developing a Service Adapter.

Step 2d: Create the Message Bundle

Any message destined for an end-user should be placed in a message bundle: a .properties text file containing key=value pairs that allow you to internationalize messages. When a geographic locale and a natural language are specified for a message at run time, the contents of the message are interpreted on the basis of the key=value pair, and the message is presented to the user in the specified language.

For instructions on creating a message bundle, see the JavaSoft tutorial on internationalization at:

http://java.sun.com/docs/books/tutorial/i18n/index.html

Step 2e: Configure Logging

Logging is performed with a logging tool called Log4j, which was developed as part of the Apache Jakarta project.

Before you begin this step, we recommend that you read more about logging in Basic Development Concepts, and about how to use Log4j in Using the Logging Toolkit.

Create an Event Generation Logging Category

If you are planning to use an event connection, you must create a logging category specifically for event generation. (For more information about logging categories, see Message Categories.) To edit the logging configuration file for a specific adapter (WLI_HOME/adapters/YOUR_ADAPTER/src/adapter_logical_name.xml), add the code shown in the following listing.

Listing 7-1 Sample Code for Creating an Event Generation Logging Category
<category name='BEA_WLS_SAMPLE_ADK.EventGenerator' class='com.bea.
logging.LogCategory'>
</category>

Replace BEA_WLS_SAMPLE_ADK with the logical name of your adapter.

If you do not set any parameters for this category, it inherits all the property settings of the parent category. In this example, the parent category is BEA_WLS_SAMPLE_ADK. Although you are not required to use the adapter logical name as the root category, you must use a unique identifier so that there is no impact on other adapters in a multi-adapter environment.

 


Step 3: Implement the Adapter

To implement an event connection, you must complete the following two-step procedure:

  1. Create an event generator. This process implements the data extraction method (in either push or a pull mode) and the IEventGenerator interface. (The latter interface is used by the event router to drive the event generation process.) This step is described in Step 3a: Create an Event Generator.
  2. Implement the data transformation method. This step is described in Step 3b: Implement the Data Transformation Method.

Step 3a: Create an Event Generator

Event generation provides an adapter with a mechanism to either receive notification from an EIS or poll an EIS for a specific occurrence of an event. The WebLogic Integration engine provides a powerful event generator that can support multiple types of events. An event type is defined by the configuration properties for an event.

Typically event properties are defined by the properties associated with an event at design time. When configuring an event connection, keep in mind that you may designate one or more Web pages from which the adapter will collect event properties. These properties are saved with the application view descriptor and passed back to the event at run time. The WebLogic Integration engine uses the properties and the source application view to determine how to route back to the listeners. For instance, if two separate deployments of the same event generator with identical properties are used, only one IEventDefinition is created by the WebLogic Integration engine. If different properties are specified, however, a single IEventDefinition is created for each deployment of a single event connection. The event generator must determine which IEventDefinition to use in the routing process. This determination is typically made on the basis of property values and specific event occurrences.

IEventDefinition objects are used by your implementation of the event generator to route specific events back to their listener. As discussed elsewhere, the WebLogic Integration engine creates IEventDefinition objects for deployed application views containing events. IEventDefinition objects can be used to extract specific properties associated with the deployment of an application view, or to access schema and routing objects. You must employ these attributes when routing an event.

How the Data Extraction Mechanism Is Implemented

WebLogic Integration supports two modes of data extraction:

Pull Mode

Pull mode relies on a polling technique to determine whether an event has taken place. To implement it, you must derive your event generator from the AbstractPullEventGenerator in the com.bea.adapter.event package.

Note: The adk-eventgenerator.jar file contains the ADK base classes required to implement an event generator. It must be included in your WAR make file.

In the AbstractPullEventGenerator, the ADK supplies several abstract methods that you must override in your implementation. These methods are described in the following table.

Table 7-1 AbstractPullEventGenerator Methods 
Method
Description
postEvents()
Control method for the remainder of your event generation, message transformation, and routing code; allows you to add polling and routing code. Called from the run method in the AbstractPullEventGenerator at an interval determined by the Event Router configuration files.
setupNewTypes()
Method for preprocessing any IEventDefinition object being deployed. Only valid new IEventDefinition objects can be passed to this method.
removeDeadTypes()
Handles any cleanup required for IEventDefinition objects being undeployed. The WebLogic Integration engine calls this method when application views with associated events are being undeployed.
doInit()
Method called while the event generator is being constructed. During the initialization process the event generator can use predefined configuration values to set up the necessary state or connections for the event generation process.
doCleanUpOnQuit()
Frees resources allocated by your event generation process. Called before the thread driving the event generation process is ended.

Push Mode

Push mode uses notification to trigger the routing of an event. To implement it, you must derive your event generator from the AbstractPushEventGenerator class in the com.bea.adapter.event package. Several other supporting classes are included in the event package. These classes are described in Table 7-2.

Note: The adk-eventgenerator.jar file contains the WebLogic Integration base classes required to implement an event generator. It must be included in your WAR make file.

Table 7-2 AbstractPushEventGenerator Classes 
Class
Description
AbstractPushEventGenerator
Class containing the same abstract and concrete methods as the AbstractPullEventGenerator. The methods in both implementations (AbstractPullEventGenerator and AbstractPushEventGenerator) are intended to be used in the same manner. For a list of the methods and responsibilities associated with each, see Table 7-1.
IPushHandler
Interface provided primarily to abstract the generation of an event from the routing of an event. It is not required for the implementation of the push mode of data extraction. The IPushHandler is designed to be tightly coupled with the PushEventGenerator. The PushEventGenerator initializes, subscribes, and cleans up the PushHandler implementation. The IPushHandler provides a simple interface to abstract the generation logic. The interface provides methods to initialize, subscribe to push events, and clean up resources.
PushEvent
PushEvent is an event object derived from java.util.EventObject. The PushEvent object is designed as a wrapper for an EIS notification, which is sent to any IPushEventListener objects.
EventMetaData
The EventMetaData class is intended to wrap any data necessary for event generation. The EventMetaData class is passed to the IPushHandler on initialization.

How the Event Generator Is Implemented

An event generator typically implements the following flow of control:

  1. The doInit() method creates and validates connections to the EIS.
  2. The setupNewTypes() method processes IEventDefinition objects, creating any structures required for processing.
  3. The postEvents() method iteratively invokes one of the two modes of data extraction:
    • Push—The postEvents() method polls the EIS for an event and, if an event exists, postEvent() determines which IEventDefinition objects will receive it. The method then transforms the event data into an IDocument object, using the associated schema, and routes the IDocument object using the IEvent associated with the IEventDefinition object.
    • Pull—The postEvents() method waits for notification of an event. When it receives such notification, it extracts the event data from the PushEvent object and transforms it into an IDocument object in accordance with the schema associated with the event connection. When all the necessary event data has been put into the IDocument, the IDocument is routed to the correct IEventDefinition objects.
  4. The removeDeadTypes() method removes dead IEventDefinition objects from any data structures being used for event processing. Any resources associated with those objects are also freed. IEventDefinition objects are considered dead when the application view to which they belong is undeployed.
  5. The doCleanUpOnQuit() method removes any resources allocated during event processing.

Listing 7-2 shows the class declaration for the sample adapter's (pull-mode) event generator.

Listing 7-2 Sample Implementation of the Pull Mode of Data Extraction
public class EventGenerator
extends AbstractPullEventGenerator
Note: The AbstractPullEventGenerator implements the Runnable interface, which enables it to run on its own thread.

The remaining sections in Step 3a: Create an Event Generator provide more code examples that show how an event generator is implemented with the pull mode of data extraction.

Sample EventGenerator

Listing 7-3 shows a simple constructor for an event generator. You must invoke the parent's constructor so that the parent's members get initialized correctly. The listing then shows how the doInit() method receives configuration information from the map variable and validates the parameters. The sample contains any parameters associated with the event generator at design time.

Listing 7-3 Sample Constructor for an EventGenerator
public EventGenerator()
{
super();
}
protected void doInit(Map map)
throws java.lang.Exception
{
ILogger logger = getLogger();
    m_strUserName = (String)map.get("UserName");
if (m_strUserName == null || m_strUserName.length() == 0
{
String strErrorMsg =
logger.getI18NMessage("event_generator_no_UserName");
logger.error(strErrorMsg);
throw new IllegalStateException(strErrorMsg);
}
m_strPassword = (String)map.get("Password");
if (m_strPassword == null || m_strPassword.length() == 0)
{
String strErrorMsg = logger.getI18NMessage
("event_generator_no_Password");
logger.error(strErrorMsg);
throw new IllegalStateException(strErrorMsg);
}

postEvents() is called from the run method of the parent class, as shown in Listing 7-4. This method polls the EIS to detect the occurrence of a new event. This method is invoked at a fixed interval, which is defined in the web.xml file for the event router.

Listing 7-4 Sample Implementation of postEvents()
  protected void postEvents(IEventRouter router)
throws java.lang.Exception
{
    ILogger logger = getLogger();
    // TODO: a real adapter would need to call into the EIS to
// determine ifany new events occured since the last time
// this method was invoked. For the sake of example, we'll just
// post a single event every time this method gets invoked...
// event data will be the current time on the
// The system formatted according to the event definition...
// we'll look for several event types...
    Iterator eventTypesIterator = getEventTypes();
if (eventTypesIterator.hasNext())
    {
do
{
       // The event router is still interested in this type of event
       IEventDefinition eventDef = (IEventDefinition)
eventTypesIterator.next();
logger.debug("Generating event for " + eventDef.getName());
       // Create a default event (just blank/default data)
       IEvent event = eventDef.createDefaultEvent();
       // Get the format for the event
      java.util.Map eventPropertyMap = eventDef.
getPropertySet();
String strFormat = (String)eventPropertyMap.get
("Format");
if( logger.isDebugEnabled() )
logger.debug("Format for event type '"+eventDef.
getName()+"' is '"+strFormat+"'");
java.text.SimpleDateFormat sdf =
new java.text.SimpleDateFormat(strFormat);
IDocument payload = event.getPayload();
payload.setStringInFirst("/SystemTime", sdf.format(new
Date()));
        // let's log an audit message for this...
        try
{
logger.audit(toString() + ": postEvents >>> posting event
["+payload.toXML()+"] to router");
}
          catch (Exception exc)
        {
logger.warn(exc);
}
          // This call actually posts the event to the IEventRouter        
        router.postEvent(event);
} while (eventTypesIterator.hasNext());
}
    }// end of postEvents 

A real adapter must query the EIS to determine whether any new events have occurred since the last time this method was invoked. A concrete example of such a call, available in the DBMS sample adapter included with the ADK, is the postEvent() method in the EventGenerator.java file:

WLI_HOME/adapters/dbms/src/com/bea/adapter/dbms/event/EventGenerator.java
Adding New Event Types

setupNewTypes() is called during refresh to handle any new event types. Typically, an event generator needs to allocate resources in the EIS in order to be able to receive events from the EIS. In the DBMS sample adapter, for example, a trigger is created in the DBMS in order to handle a new event type. The setupNewTypes() method allows you to set up any definitions required to handle a new type. The parent class has already performed (and logged) a sanity-check on the listOfNewTypes() file, so you do not need to perform those tasks.

Listing 7-5 Sample Template for setupNewTypes()
protected void setupNewTypes(java.util.List listOfNewTypes)
{
Iterator iter = listOfNewTypes.iterator();
while (iter.hasNext())
{
IEventDefinition eventType = (IEventDefinition)iter.next();
}
}
Removing Event Types for Undeployed Application Views

removeDeadTypes() is called during refresh to remove any event types for application views that have been undeployed.

You must execute a cleanup process

To ensure that obsolete event types are no longer handled, you must perform a cleanup process. You should, for example, close resources needed to handle the obsolete event type. Listing 7-6 shows how removeDeadTypes() is implemented.

Listing 7-6 Sample Code Based on removeDeadTypes() Template
protected void removeDeadTypes(java.util.List listOfDeadTypes)
{
Iterator iter = listOfDeadTypes.iterator();
while (iter.hasNext())
{
IEventDefinition eventType = (IEventDefinition)iter.next();
Removing Resources

doCleanUpOnQuit() is called during shutdown of the event generator. This method removes any resources allocated during event processing. The sample adapter stubs in this method. The template for implementing this method is shown in the following listing.

Listing 7-7 Sample doCleanUpOnQuit() Method Call
protected void doCleanUpOnQuit()
throws java.lang.Exception
{
ILogger logger = getLogger();
logger.debug(this.toString() + ": doCleanUpOnQuit");
}
}

Step 3b: Implement the Data Transformation Method

Data transformation is the process of taking data from the EIS and transforming it into an XML schema that can be read by the application server. For each event, a schema defines the appearance of the XML output, using the SOM and IDocument class libraries. The following code listings show the sequence of events during the data transformation process:

Step 3c: Implement Suspend/Resume Support

This is an optional step. Suspend/resume support allows your event generator to respond to requests from the event router to suspend or resume generation of events. The event router makes these requests when an administrator indicates event delivery from your adapter should be suspended. If you do not implement suspend/resume support directly, the WebLogic Integration engine will store any events generated by your event generator during the time your adapter is suspended.

Whether you implement suspend/resume support in your adapter depends on whether your EIS instance can store event information for later retrieval. If your EIS can store this information, you should implement suspend/resume support in your adapter. This allows you to store events (possibly) more efficiently on the EIS than if WebLogic Integration were to store them for you.

If your EIS cannot effectively store event information for later retrieval, you should not implement suspend/resume support directly in your event generator. Rather, you should just allow WebLogic Integration to store the events for you.

If you decide to implement suspend/resume support, simply implement the com.bea.wlai.event.ISuspendableEventGenerator interface on your event generator implementation class. If you subclass AbstractPullEventGenerator, you can simply delegate the suspend() and resume() calls back to the superclass. The following code listing shows how the DBMS sample adapter implements ISuspendableEventGenerator.

Listing 7-11 Sample Adapter
import com.bea.adapter.event.AbstractPullEventGenerator;
import com.bea.wlai.event.ISuspendableEventGenerator;

public class EventGenerator
extends AbstractPullEventGenerator
implements ISuspendableEventGenerator {

...

  /**
    * Suspend (temporarily) the generation of events. Any events that occur
    * on the EIS instance must be preserved either on the EIS instance itself,
    * or within some EventGenerator-specific store. This method simply delegates
    * the call back to its superclass.
  */
  public void suspend()
    throws Exception
  {
    super.suspend();
  }

  /**
    * Resume the generation of events. Any events that have occurred while this
    * EventGenerator was suspended, should now be delivered as soon as possible
    * to the EventRouter. This method simply delegates the call back to its
    * superclass.
  */
  public void resume()
    throws Exception
  {
    super.resume();
  }

...

}

If your event generator does not extend from AbstractPullEventGenerator, you will need to determine for yourself the proper way to implement ISuspendableEventGenerator.

Step 3d: Implement Event Generator and EIS Status Reporting

This is an optional step. WebLogic Integration 8.1 adds the ability for event generators to indicate their own status and the status of their EIS instance back to their event router. This ability greatly enhances the manageability of your event generator. BEA strongly recommends adapter developers implement this support in their adapters.

Status reporting provides two important benefits to the WebLogic Integration administrator:

To implement status reporting, you will use the following methods on the IEventRouter interface.

Note: You are passed an IEventRouter instance in the call to postEvents, setupNewTypes and removeDeadTypes.

Step 3e: Implement Event Generator Instance Support

Note that as of WebLogic Integration 8.1Service Pack 2, you must set event generator targets when in a clustered environment. A blank target ("") does not trigger events on any node in the cluster. (In a single node environment, no entry is needed; a blank event generator target value kicks off events for the one server.)

WebLogic Integration 8.1 has added the ability to distribute event generators among nodes in a WebLogic Integration cluster. This improves load balancing and fault tolerance of event generation. However, the ability to do this is predicated in the requirements and implementation of the adapter itself.

Some event generators assume that they own any resources in the EIS they use to detect the occurrence of an event. Such event generators cannot coexist with other event generators using the same EIS instance, as resource usage conflicts will arise. An example of this is the WebLogic Integration 7.0 DBMS sample adapter. It assumed that it owned the information in the event staging tables within the DBMS. Because of this it could not coexist with other WebLogic Integration 7.0 DBMS sample adapter event generators, because they would each compete for the event information in the event staging tables, often causing starvation of one or more generators or database locking/update conflicts.

Note: Even event generators that do not implement event generator instance support can benefit from the new event generation targeting capabilities. However, the WebLogic Integration administrator is only able to designate nodes in cluster to have a single instance (or no instance) of the event generator. Implementing event generator instance support allows the adapter to have finer control over event generation and greater manageability.

Example: DBMS Sample Adapter

In WebLogic Integration 8.1, the DBMS sample adapter has been enhanced to allow the coexistence of multiple event generators using the same DBMS instance. It does this by implementing a concept know as event generator instance support. The DBMS sample adapter recognizes any number of administrator defined generator instances. This section provides an example of what generator instances are and how they are used in the DBMS sample adapter.

We have a 3 node WebLogic Integration cluster. The cluster nodes are named Server1, Server2, and Server3. The administrator wishes to evenly distribute event generation responsibilities for a single adapter instance (and by convention a single EIS instance) among the nodes. Before this can be done, the administrator must know if the adapter supports multiple event generators or not. This information is included in the adapter documentation.

If the adapter does not support multiple generator instances, a single event generator must be associated with a single node in the cluster. This is done by specifying the following value for the Event Generation Targets field in the WebLogic Integration Administration Console (Event Connection Details page).

Event Generation Targets: Server1

If the adapter does support multiple generator instances, event generators can be distributed to each node in the cluster. This is done by specifying the Event Generation Targets field as follows:

Event Generation Targets: Server1,Server2,Server3

This allows 3 event generators to share the work of generating events for the given EIS instance.

In the case of the DBMS sample adapter, having multiple event generators selecting/deleting/updating in the same tables caused database locking conflicts. To overcome this, we define a way to identify each generator instance such that the individual events are destined to a specific generator instance. This allows multiple event generators to coexist because they each have their own set of events to handle. The use of generator instance identifiers effectively partitions the single set of event staging tables for the DBMS sample adapter into multiple logical sets of tables.

For the DBMS sample adapter, a generator instance has a numeric identifier, or ID. The system administrator, knowing that the DBMS sample adapter supports event generator instances, can define a set of generator instances by defining a list of numeric identifiers. He can then distribute these generator instances among the nodes in the cluster by associating the generator instance's numeric ID with the server name in the Event Generation Targets field value.

A typical Event Generation Targets setting for our example 3 node cluster, for the DBMS sample adapter is as follows:

Event Generation Targets: Server1=[1/3],Server2=[2/3],Server3=[3/3]

This specification defines one generator instance per node in the cluster. Each instance specification is represented as:

=[instance_id/number_of_instances]

The instance specification follows the name of the server to which the instances are to be associated.

Note: The instance_id/number_of_instances format is specific to the DBMS sample adapter. You are free to define the format of the generator instance however you wish. However, the list of instances is always enclosed in square brackets [] and each instance is separated from the others by one more space characters. Because of this, your instance format cannot allow the following characters:

Why Implement Event Generator Instance Support?

To see why event generator instance support is a powerful feature, let us consider a single-node failure scenario within the WebLogic Integration cluster, using the DBMS sample adapter. Let's assume that the administrator has configured the three nodes to have one generator instance each, and that the generators have been initialized and are steadily processing, and delivering events. Let's assume that sometime later, Server2 fails.

In this case, since the administrator assigned generator instance 2 to Server2, all events destined for instance 2 simply stop being processed when Server2 fails. When the administrator detects the failure of Server2, they can use the WebLogic Integration Administration Console to reset the Event Generation Targets field to retarget instance 2 to a live node in the cluster:

Event Generation Targets: Server1=[1/3 2/3],Server3=[3/3]

By making this change, the administrator has migrated the event generation responsibilities for instance 2 from the failed Server2 to the live Server1. In the next section, we describe how the event generator will detect changes to the generator instance specification, and how it should respond to those changes.

Detecting and Responding to Changes in Event Generator Instance Specifications

Any time the WebLogic Integration administrator changes the value of Event Generation Targets, the event generator receives a call to refresh(). This is the generator's opportunity to refresh the list of generator instance IDs it has been made responsible for.

The DBMS sample adapter extends AbstractPullEventGenerator. AbstractPullEventGenerator intercepts the call to refresh(), collates the current event types for the event generator, and calls setupNewTypes() or removeDeadTypes() only as needed. To make generator instance handling work reliably, we override the refresh() method as shown in Listing 7-13.

Listing 7-13 Getting List of Generator Instance IDs in the refresh() Method
/**
  * Refresh this generator, taking into account the current list of event
  * types (definitions) this router is responsible for, and also the list
  * of event router instance IDs its responsible for.

  */
public void refresh()
  throws Exception
{
// See what instance IDs we're being asked to handle
refreshEventRouterInstanceIDs();

  // Make sure the EVENT_GENERATOR table reflects our new max count (this   // call is a no-op if we're not the 'primary' generator instance
  // (e.g. instance id 1).
  updateGeneratorID(getConnection(), true);
  
  // Let our super class decide whether the event types for this router have
  // changed.
  super.refresh();
  }

private void refreshEventRouterInstanceIDs()
{
  m_isPrimaryInstance = false;
  String[] eventRouterInstanceIDs =
    getRouter().getEventRouterInstanceIDs();

... Store the new list of instance IDs, and if we see instance `1', we have
become the `primary' instance. The `primary' instance is responsible for
certain singleton lifecycle updates. The concept of principal instance
allows us to avoid collisions that might result if more than one instance
attempted these lifecycle operations ...
}

Note that we call the superclass refresh() method at the end of the overridden method. This ensures proper calls to setupNewTypes() and removeDeadTypes() if needed. Note also that within the call to refresh() we retrieve the current list of generator instance IDs this generator is responsible for. The DBMS sample adapter event generator will then begin selecting events from the event staging tables destined for any generator instance it has found in the new list.

Note: The DBMS sample adapter event generator only uses the one thread created for it by AbstractPullEventGenerator. A powerful way to scale the processing power of your event generator would be to allocate one processing thread per generator instance ID. This way, in our single-node failure scenario above, you could have two threads processing events on Server1 instead of just one. In addition, having more threads as more generator instances are associated with an event generator provides a way for the administrator to increase event processing throughput. He can simply define a larger number of generator instances (say two or more per node in the cluster), and distribute them among the nodes.

Step 3f: Implement Environment Variable Support

This is an optional step. Environment variables allow adapters to isolate information that is specific to a given deployment environment such that it can be updated by a WLI administrator when the adapter instances using that adapter are moved between environments.

Adapters that require environment specific information in their interaction spec object, service request documents, or event definitions, should consider implementing environment variable support. Examples of environment specific information are resource identifiers like table names for a DBMS adapter, or email folder names for an email adapter.

Note: Environment specific information does not include the information used to create a connection to the EIS. This information is almost always, by its nature, environment specific.

Adapters that contain no environment specific information in their interaction spec object, request documents, or event definitions, need not implement environment variable support.

Environment variables are defined for a given application view at design-time in the Application Integration Design Console. The set of variable definitions created there are propagated to the event adapter instance, event router, and finally event generator by way of the IEventDefinition object used to represent an event subscription in the event generator.

For more information on how environment variables are defined at design-time, see Developing a Design-Time GUI.

You get a set of event definitions in each call to IEventGenerator.refresh() or AbstractEventGenerator.setupNewTypes() or AbstractEventGenerator.removeDeadTypes().

An environment variable at runtime is represented as an instance of the IVariable interface. The IVariable interface is as follows:

/**
* Contains an adapter defined environment variable
*/
public interface IVariable
  extends java.io.Serializable
{
  public String getName();
  public String getType();
  public String getDescription();
  public String getDefaultValue();
  public String getValue();
}

The variables are contained in a variable set defined as follows:

/**
* Contains a set of adapter defined environment variables for an adapter
*/
public interface IVariableSet
  extends java.io.Serializable
{
  public void addListener(VariableChangeListener listener);
  public void removeListener(VariableChangeListener listener);
  public String[] listVariableNames();
  public IVariable getVariable(String name);
  public IVariable[] listVariables();
}

Event generator instances will likely only be interested in the name and value of variables. How you use variables in your event generator implementation is up to you. It depends on the format of the metadata your design-time component places into the event definition for an event. Typically, adapters will place marker fields into the text for an event definition property indicating a replaceable variable value.

For example, the DBMS sample adapter allows application view designers to use environment variables when defining the table, catalog, and schema names for an event. The DBMS sample adapter treats events as any insert/delete/update on a designated table. A table is identified by its name, and the name of the catalog and schema that contain it. These names often vary between environments, and thus using variables to represent them allows the administrator an easy way to change those names as he moves the application view between environments. A typical event descriptor for the DBMS sample adapter contains the following property name/value pairs:

Notice the curly braces enclosing the mySchema and myCatalog values. These braces are used by the DBMS sample adapter to indicate a variable value. The variables in this case are mySchema, and myCatalog. With this event definition, the DBMS sample adapter event generator expects the event definition to be accompanied at runtime by a set of variables containing two variables named mySchema and myCatalog. At runtime, the event generator retrieves the variable values in effect at the time, and substitutes those values for the {mySchema} and {myCatalog} text in the schemaName and catalogName property values, respectively. Here is the code from the DBMS sample adapter:

IEventDefinition eventDef = ... One of the event defs passed in setupNewTypes() ...

IClientData clientData = eventDef.getClientData();
if (clientData != null)
{
  IVariableSet varSet = clientData.getVariableSet();
  catalogName = DBMSSQLUtils.applyVariables(varSet, catalogName);
  schemaName = DBMSSQLUtils.applyVariables(varSet, schemaName);
  tableName = DBMSSQLUtils.applyVariables(varSet, tableName);
}

DBMSSQLUtils.applyVariables() simply does a string replacement of the variables it find in the given property with the value of the corresponding variable.

 


Step 4: Test the Adapter

You can test the adapter by using the adapter test harness provided with WebLogic Integration. For a complete description of this tool and instructions for using it, see Step 6: Test the Adapter in Developing a Service Adapter.

 


Step 5. Deploy the Adapter

After rebuilding the new adapter, deploy it in a WebLogic Integration environment. You can deploy an adapter either manually or from the WebLogic Server Administration Console. For complete information, see Deploying Adapters.


  Back to Top       Previous  Next