Developing Adapters
This section contains information about the following subjects:
The ResourceAdapter interface is new in WebLogic Integration 8.1. It serves as a single object to unify both event and service handling. In prior WebLogic Integration releases, the event adapter and service adapter were treated as separate adapter components. Each was deployed and configured separately.
In WebLogic Integration 8.1, the event and service adapters are unified under the ResourceAdapter
interface, and the adapter's implementation of that interface. It provides access to 0 or 1 event connection (created by the event adapter), and 0 or more service connections (sometimes referred to as connection factories, and created by the service adapter)
Configuration of event and service connections are now done under the umbrella of the ResourceAdapter
interface. You will see the term Resource Adapter used in the Application Integration Design Console to represent a container of event and service connections.
WebLogic Integration defines an extension to the generic ResourceAdapter
interface (called WLIResourceAdapter
) that contains enhancements designed to improve usability and adds methods needed to support optional features of event adapters. The optional features enabled by these added methods are:
Each adapter must implement WLIResourceAdapter
in a concrete class in order to operate within WebLogic Integration 8.1. The ADK provides an abstract base implementation of the WLIResourceAdapter
class in com.bea.adapter.spi.AbstractWLIResourceAdapter
. WebLogic Integration also provides an adapter repackaging utility that allows existing adapters to be utilized in WebLogic Integration 8.1. This utility code generates the required WLIResourceAdapter
implementation for any repackaged adapter.
The WLIResourceAdapter
implementation should be implemented according to the JavaBeans specification. This means WebLogic Integration should be able to instantiate an instance of the WLIResourceAdapter
implementation, and set properties on that instance via simple setter/getter pairs of methods (one pair per property). The properties defined for a WLIResourceAdapter
implementation can be used support event connections, service connections or both. In most cases, however, properties on the WLIResourceAdapter
implementation are used to support event connections, whereas service connections are usually supported by properties of the ManagedConnectionFactory
implementation in the service adapter.
The flow of events is roughly the same as that for the development of a service adapter.
The behavior of a resource adapter in a run-time environment is depicted in Figure 8-1.
Figure 8-1 Resource Adapters in a Run-time Environment
Before you start developing a resource adapter, 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:
WLIResourceAdapter
implementation for each property used to support an event connection.WLIResourceAdapter
implementation for each property used to support a service connection. In this step you must take into account the properties required for service connections that are already designated to reside directly on the ManagedConnectionFactory
implementation for the service adapter. You generally will want to have a given property stored in only one place.
This step involves completing a five-step procedure to prepare your computer for adapter development:
The file structure needed for an event connection development environment is the same as that required for developing service connections. For detailed information on setting up the file structure, see Step 2a: Set Up the Directory Structure.
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:
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.
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
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.
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 8-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.
To implement a resource adapter, you must complete the following two-step procedure:
WLIResourceAdapter
implementation. This process implements the unified resource adapter implementation and the WLIResourceAdapter
interface. (The latter interface is used by the application integration engine to control the lifecycle of the resource adapter.) This step is described in Step 3a: Create a Resource Adapter.The GenerateAdapterTemplate
utility does most of the work necessary to implement your resource adapter class. What remains is to implement the setter/getter methods for each property you chose to define on your WLIResourceAdapter
implementation. By way of example, we list below the WLIResourceAdapter
implementation for the Sample adapter. This code should look nearly identical to the code you now have in your adapter development project. The difference in your project is that your adapter logical name, package names, and other identifiers will have the values you specified in the GenerateAdapterTemplate
utility.
Listing 8-2 Sample WLIResourceAdapter Implementation
package sample.spi;
import com.bea.adapter.spi.AbstractWLIResourceAdapter;
import javax.resource.ResourceException;
// Sample Resource Adapter Implementation
public class ResourceAdapterImpl
extends AbstractWLIResourceAdapter
{
// NOTE: If the class named here implements ISuspendableEventGenerator
// then the AbstractWLIResourceAdapter implementation will handle
// advertising this WLIResourceAdapter instance as suspendable, and
// will handle calling suspend/resume on the EventGenerator
public static String EVENT_GENERATOR_CLASS_NAME = "sample.event.EventGenerator";
// Sample Adapter specific members
private String m_userName = null;
private String m_password = null;
private String m_sleepCount = "4000";
public ResourceAdapterImpl()
throws ResourceException
{
super();
// Tell AbstractWLIResourceAdapter what EventGenerator we're using
setEventGeneratorClassName(EVENT_GENERATOR_CLASS_NAME);
// Set properties that never change
setAdapterName("BEA_WLS_SAMPLE_ADK Adapter");
setAdapterDescription("__BEA_Sample_Description__");
setAdapterVersion("__MAJOR_V__.__MINOR_V__");
setAdapterVendorName("__BEA__");
// Set default values for standard properties
setRootLogContext("BEA_WLS_SAMPLE_ADK");
setLogConfigFile("BEA_WLS_SAMPLE_ADK.xml");
setMessageBundleBase("BEA_WLS_SAMPLE_ADK");
setLogLevel("WARN");
}
public String getUserName()
{
return m_userName;
}
public void setUserName(String userName)
{
m_userName = userName;
}
public String getPassword()
{
return m_password;
}
public void setPassword(String password)
{
m_password = password;
}
public String getSleepCount()
{
return m_sleepCount;
}
public void setSleepCount(String sleepCount)
{
m_sleepCount = sleepCount;
}
/**
* TODO: Modify this method to do the proper checking for your adapter's
* properties. This method is key in forcing users to give you valid
* configuration for the ResourceAdapter instance.
*/
protected void internalValidate()
throws ResourceException
{
if (m_userName == null || m_userName.trim().length() < 1 ||
m_sleepCount == null || m_sleepCount.trim().length() < 1)
{
throw new ResourceException("UserName and SleepCount properties are
required");
}
try
{
int sleepCount = Integer.parseInt(m_sleepCount);
if (sleepCount < 1)
{
throw new IllegalArgumentException("sleepCount");
}
}
catch (Exception e)
{
throw new ResourceException("SleepCount '" + m_sleepCount + "' is
invalid");
}
}
}
Note that the constructor of the ResourceAdapterImpl
calls several setter methods from the AbstractWLIResourceAdapter
base class. These setters establish default values for the standard properties defined by WebLogic Integration. These standard properties are as follows. For more information on logging properties, see Using the Logging Toolkit.
EventGeneratorClassName
—the name of the class you define to implement the event generator for your event adapter (optional). If you will not be implementing an event adapter, you can skip setting this property. This will leave its value as the default of null.AdapterName
—adapter display nameAdapterVersion
—version to display for the adapterAdapterVendorName
—name of the vendor for this adapterRootLogContext
—logging configurationLogConfigFile
—logging configurationMessageBundleBase
—logging configurationLogLevel
—logging configurationAs you can see, the sample adapter's ResourceAdapterImpl
class is comprised of a simple constructor, and setter/getter methods to define the following properties:
These three properties are used to support event connections in the sample adapter. Thus, the ResourceAdapterImpl
class defines a setUserName
/getUserName
pair of methods, a setPassword
/getPassword
set of methods and a setSleepCount
/getSleepCount
set of methods. Each of these sets of methods operate on a single property. These methods can do simple validity checking such as ensuring an integer value doesn't exceed some set minimum or maximum value, or a string property doesn't exceed some maximum length of violate some syntactical conventions.
However, sometimes individual properties must be compared with other properties on the same object. With individual setter/getter methods, this can become difficult, as you must take into account the order in which properties have been set, and account for properties that have not yet been given valid values.
For this reason, the WLIResourceAdapter
interface defines a validate method that is called after all properties have been set on the WLIResourceAdapter
instance. This method gives you the opportunity to inspect and validate the values of all properties at one time. The AbstractWLIResourceAdapter
base class (which implements WLIResourceAdapter
) defines the validate method, and makes a call to a method called internalValidate
to allow subclasses to hook into the validation process. You should implement internalValidate
such that it checks all properties for validity and throws ResourceException
if any invalid properties are encountered.
For a complete description of how to develop an event adapter, see Developing an Event Adapter. For a complete description of how to develop a service adapter, see Developing a Service 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.