bea.com | products | dev2dev | support | askBEA |
![]() |
![]() |
|
![]() |
e-docs > WebLogic Platform > WebLogic Integration > AI Topics > Developing Adapters > Developing an Event Adapter |
Developing Adapters
|
Developing an Event Adapter
This section contains information about the following subjects:
Introduction to Event Adapters
Event adapters propagate information from an EIS to the WebLogic Integration environment; they can be described as publishers of information.
All WebLogic Integration event adapters perform the following three functions:
WebLogic Integration implements the aspects of these three functions that are common to all event adapters, allowing you to focus on only the EIS-specific aspects of your adapter.
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 Adapters in a Run-time Environment
Flow of Events
Figure 7-2 outlines the steps required to develop an Event Adapter.
Figure 7-2 Event Adapter Flow of Events
Step 1: Define the Adapter
Before you start developing an event 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:
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 adapter development environment is the same as that required for developing service adapters. 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 adapter, 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 enviroment.
Step 3: Implement the Adapter
To implement an event adapter, you must complete the following two-step procedure:
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 adapter, 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 adapter. 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.
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.
How the Event Generator Is Implemented An event generator typically implements the following flow of control:
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:
Listing 7-8 Sample Code for Transforming EIS Data into XML Schema
SOMSchema schema = new SOMSchema();
SOMElement root = new SOMElement("SENDINPUT");
SOMComplexType mailType = new SOMComplexType();
root.setType(mailType);
SOMSequence sequence = mailType.addSequence();
SOMElement to = new SOMElement("TO");
to.setMinOccurs("1");
to.setMaxOccurs("unbounded");
sequence.add(to);
SOMElement from = new SOMElement("FROM");
from.setMinOccurs("1");
from.setMaxOccurs("1");
sequence.add(from);
SOMElement cc = new SOMElement("CC");
cc.setMinOccurs("1");
cc.setMaxOccurs("unbounded");
sequence.add(cc);
SOMElement bcc = new SOMElement("BCC");
bcc.setMinOccurs("1");
bcc.setMaxOccurs("unbounded");
sequence.add(bcc);
SOMElement subject = new SOMElement("SUBJECT");
subject.setMinOccurs("1");
subject.setMaxOccurs("1");
sequence.add(bcc);
SOMElement body = new SOMElement("BODY");
if (template == null)
{ body.setMinOccurs("1");
body.setMaxOccurs("1");
}else
{ Iterator iter = template.getTags();
if (iter.hasNext())
{ SOMComplexType bodyComplex = new SOMComplexType();
body.setType(bodyComplex);
SOMAll all = new SOMAll();
while (iter.hasNext())
{ SOMElement eNew = new SOMElement((String)iter.next());
all.add(eNew);
}//endwhile
bodyComplex.setGroup(all);
}//endif
}//endif
sequence.add(body);
schema.addElement(root);
Listing 7-9 XML Schema Created by Code in Listing 7-8
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="SENDINPUT">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="TO" maxOccurs="unbounded"
type="xsd: string"/>
<xsd:element name="FROM" type="xsd:string"/>
<xsd:element name="CC" maxOccurs="unbounded"
type="xsd:string"/>
<xsd:element name="BCC" maxOccurs=
"unbounded" type= "xsd:string"/>
<xsd:element name="BCC" maxOccurs="unbounded"
type="xsd:string"/>
<xsd:element name="BODY" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
Listing 7-10 Valid XML Document Created by Schema in Listing 7-9
</xsd:schema>
<?xml version="1.0"?>
<!DOCTYPE SENDINPUT>
<SENDINPUT>
<TO/>
<FROM/>
<CC/>
<BCC/>
<BCC/>
<BODY/>
</SENDINPUT> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
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 5: 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.
![]() |
![]() |
![]() |
![]() |
||
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |