4 Programming Tasks

The following sections discuss programming tasks for WebLogic Server resource adapters:

Required Classes for Resource Adapters

A resource adapter requires the following Java classes, in accordance with the J2CA 1.5 Specification:

  • ManagedConnectionFactory

  • ConnectionFactory interface

  • ConnectionFactory implementation

  • Connection interface

  • Connection implementation

These classes are specified in the ra.xml file. For example:

<managedconnectionfactory-class>
com.sun.connector.blackbox.LocalTxManagedConnectionFactory
</managedconnectionfactory-class>

<connectionfactory-interface>
javax.sql.DataSource
</connectionfactory-interface>

<connectionfactory-impl-class>
com.sun.connector.blackbox.JdbcDataSource
</connectionfactory-impl-class>

<connection-interface>
java.sql.Connection
</connection-interface>

<connection-impl-class>
com.sun.connector.blackbox.JdbcConnection
</connection-impl-class>

In addition, if the resource adapter supports inbound messaging, the resource adapter will require an ActivationSpec class for each supported inbound message type. See Chapter 7, "Message and Transactional Inflow."

The specifics of these resource adapter classes depend on the nature of the resource adapter you are developing.

Programming a Resource Adapter to Perform as a Startup Class

As an alternative to using a WebLogic Server startup class, you can program a resource adapter with a minimal resource adapter class that implements javax.resource.ResourceAdapter, which defines a start() and stop() method.

Note:

Because of the definition of the ResourceAdapter interface, you must also define the endpointActivation(), Deactivation() and getXAResource() methods.

When the resource adapter is deployed, the start() method is invoked. When it is undeployed, the stop() method is called. Any work that the resource adapter initiates can be performed in the start() method as with a WebLogic Server startup class.

Because resource adapters have access to the Work Manager through the BootstrapContext in the start() method, they should submit Work instances instead of using direct thread management. This enables WebLogic Server to manage threads effectively through its self-tuning Work Manager.

Once a Work instance is submitted for execution, the start() method should return promptly so as not to interfere with the full deployment of the resource adapter. Thus, a scheduleWork() or startWork() method should be invoked on the Work Manager rather than the doWork() method.

The following is an example of a resource adapter having a minimum resource adapter class. It is the absolute minimum resource adapter that you can develop (other than removing the println statements). In this example, the only work performed by the start() method is to print a message to stdout (standard out).

Example 4-1 Minimum Resource Adapter

import javax.resource.spi.ResourceAdapter;
import javax.resource.spi.endpoint.MessageEndpointFactory;
import javax.resource.spi.ActivationSpec;
import javax.resource.ResourceException;
import javax.transaction.xa.XAResource;
import javax.resource.NotSupportedException;
import javax.resource.spi.BootstrapContext;
/**
* This resource adapter is the absolute minimal resource adapter that anyone can build (other than removing the println's.)
*/
public class ResourceAdapterImpl implements ResourceAdapter
{
   public void start( BootstrapContext bsCtx )
   {   
      System.out.println( "ResourceAdapterImpl started" );
   }
   public void stop()
   {
      System.out.println( "ResourceAdapterImpl stopped" );
   }
   public void endpointActivation(MessageEndpointFactory messageendpointfactory, ActivationSpec activationspec)
      throws ResourceException
   {
      throw new NotSupportedException();
   }
   public void endpointDeactivation(MessageEndpointFactory messageendpointfactory, ActivationSpec activationspec)
   {
   }
   public XAResource[] getXAResources(ActivationSpec aactivationspec[])
      throws ResourceException
   {
      throw new NotSupportedException();
   }
}

The following is an example of a resource adapter that submits work instances to the Work Manager. The resource adapter starts some work in the start() method, thus serving as a Java EE-compliant startup class.

Example 4-2 Resource Adapter Using the Work Manager and Submitting Work Instances

import javax.resource.NotSupportedException;
import javax.resource.ResourceException;
import javax.resource.spi.ActivationSpec;
import javax.resource.spi.BootstrapContext;
import javax.resource.spi.ResourceAdapter;
import javax.resource.spi.endpoint.MessageEndpointFactory;
import javax.resource.spi.work.Work;
import javax.resource.spi.work.WorkException;
import javax.resource.spi.work.WorkManager;
import javax.transaction.xa.XAResource;
/**
* This Resource Adapter starts some work in the start() method, 
* thus serving as a J2EE compliant "startup class" 
*/
public class ResourceAdapterWorker implements ResourceAdapter
{
   private WorkManager wm;
   private MyWork someWork;
   public void start( BootstrapContext bsCtx )
   {
      System.out.println( "ResourceAdapterWorker started" );
      wm = bsCtx.getWorkManager();
      try
      {
         someWork = new MyWork();
         wm.startWork( someWork );
      }
      catch (WorkException ex)
      {
         System.err.println( "Unable to start work: " + ex );
      }
   }
   public void stop()
   {
   // stop work that was started in the start() method
   someWork.release();
      System.out.println( "ResourceAdapterImpl stopped" );
   }
   public void endpointActivation(MessageEndpointFactory messageendpointfactory,
             ActivationSpec activationspec)
      throws ResourceException
   {
      throw new NotSupportedException();
   }
   public void endpointDeactivation(MessageEndpointFactory
             messageendpointfactory, ActivationSpec activationspec)
   {
   }
   public XAResource[] getXAResources(ActivationSpec activationspec[]) 
      throws ResourceException
   {
      throw new NotSupportedException();
   }
   // Work class
   private class MyWork implements Work
   {
      private boolean isRunning;
      public void run()
      {
         isRunning = true;
         while (isRunning)
         {
         // do a unit of work (e.g. listen on a socket, wait for an inbound msg, 
         // check the status of something)
         System.out.println( "Doing some work" );
         // perhaps wait some amount of time or for some event
         try
         {
            Thread.sleep( 60000 ); // wait a minute
         }
         catch (InterruptedException ex)
         {}
      }
   }
   public void release()
   {
         // signal the run() loop to stop
         isRunning = false;
      }
   }
}

Suspending and Resuming Resource Adapter Activity

You can program your resource adapter to use the suspend() method, which provides custom behavior for suspending activity. For example, using the suspend() method, you can queue up all incoming messages while allowing in-flight transactions to complete, or you can notify the Enterprise Information System (EIS) that reception of messages is temporarily blocked.

You then invoke the resume() method to signal that the inbound queue be drained and messages be delivered, or notify the EIS that message receipt was re-enabled. Basically, the resume() method allows the resource adapter to continue normal operations.

You initiate the suspend() and resume() methods by making a call on the resource adapter runtime MBeans programmatically, using WebLogic Scripting Tool, or from the WebLogic Server Administration Console. See "Start and stop a resource adapter" in the Oracle Fusion Middleware Oracle WebLogic Server Administration Console Help for more information.

The Suspendable.supportsSuspend() method determines whether a resource adapter supports a particular type of suspension. The Suspendable.isSuspended() method determines whether or not a resource adapter is presently suspended.

A resource adapter that supports suspend(), resume(), or production redeployment must implement the Suspendable interface to inform WebLogic Server that these operations are supported. These operations are invoked by WebLogic Server when the following occurs:

  • Suspend is called by the suspend() method on the connector component MBean.

  • The production redeployment sequence of calls is invoked (when a new version of the application is deployed that contains the resource adapter). See Suspendable Interface and Production Redeployment.

Example 4-3 contains the Suspendable interface for resource adapters:

Example 4-3 Suspendable Interface

package weblogic.connector.extensions;
import java.util.Properties;
import javax.resource.ResourceException;
import javax.resource.spi.ResourceAdapter;
/**
* Suspendable may be implemented by a ResourceAdapter JavaBean if it
* supports suspend, resume or side-by-side versioning
* @author Copyright (c) 2002 by BEA Systems, Inc. All Rights Reserved.
* @since November 14, 2003
*/
public interface Suspendable
{
/**
* Used to indicate that inbound communication is to be suspended/resumed
*/
int INBOUND = 1;
/**
* Used to indicate that outbound communication is to be suspended/resumed
*/
int OUTBOUND = 2;
/**
* Used to indicate that submission of Work is to be suspended/resumed
*/
int WORK = 4;
/**
* Used to indicate that INBOUND, OUTBOUND & WORK are to be suspended/resumed
*/
int ALL = 7;
/**
* May be used to indicate a suspend() operation
*/
int SUSPEND = 1;
/**
* May be used to indicate a resume() operation
*/
int RESUME = 2;
/**
* Request to suspend the activity specified. The properties may be null or
* specified according to RA-specific needs 
* @param type An int from 1 to 7 specifying the type of suspension being 
* requested (i.e. Suspendable.INBOUND, .OUTBOUND, .WORK or the sum of one
* or more of these, or the value Suspendable.ALL )
* @param props Optional Properties (or null) to be used for ResourceAdapter
* specific purposes
* @exception ResourceException If the resource adapter can't complete the
* request
*/
void suspend( int type, Properties props ) throws ResourceException;
/**
* Request to resume the activity specified. The Properties may be null or
* specified according to RA-specific needs
*
* @param type An int from 1 to 7 specifying the type of resume being
* requested (i.e. Suspendable.INBOUND, .OUTBOUND, .WORK or the sum of
* one or more of these, or the value Suspendable.ALL )
* @param props Optional Properties (or null) to be used for ResourceAdapter
* specific purposes
* @exception ResourceException If the resource adapter can't complete the
* request
*/
void resume( int type, Properties props ) throws ResourceException;
/**
*
* @param type An int from 1 to 7 specifying the type of suspend this inquiry
* is about (i.e. Suspendable.INBOUND, .OUTBOUND, .WORK or the sum of
* one or more of these, or the value Suspendable.ALL )
* @return true iff the specified type of suspend is supported
*/
boolean supportsSuspend( int type );
/**
* 
* Used to determine whether the specified type of activity is 
* currently suspended.
*
* @param type An int from 1 to 7 specifying the type of activity
* requested (i.e. Suspendable.INBOUND, .OUTBOUND, .WORK or the sum of
* one or more of these, or the value Suspendable.ALL )
* @return true iff the specified type of activity is suspened by this 
* resource adapter
*/
boolean isSuspended( int type );
/**
* Used to determine if this resource adapter supports the init() method used for
* resource adapter versioning (side-by-side deployment)
*
* @return true iff this resource adapter supports the init() method
*/
boolean supportsInit();
/**
* Used to determine if this resource adapter supports the startVersioning()
* method used for
* resource adapter versioning (side-by-side deployment)
*
* @return true iff this resource adapter supports the startVersioning() method
*/
boolean supportsVersioning();
/**
* Used by WLS to indicate to the current version of this resource adapter that 
* a new version of the resource adapter is being deployed. This method can
* be used by the old RA to communicate with the new RA and migrate services 
* from the old to the new.
* After being called, the ResourceAdapter is responsible for notifying the 
* Connector container via the ExtendedBootstrapContext.complete() method, that 
* it is safe to be undeployed.
*
* @param ra The new ResourceAdapter JavaBean
* @param props Properties associated with the versioning
* when it can be undeployed
* @exception ResourceException If something goes wrong
*/
void startVersioning( ResourceAdapter ra, 
Properties props ) throws ResourceException;
/**
* Used by WLS to inform a ResourceAdapter that it is a new version of an already
* deployed resource adapter. This method is called prior to start() so that
* the new resource adapter may coordinate its startup with the resource adapter
* it is replacing.
* @param ra The old version of the resource adapter that is currently running
* @param props Properties associated with the versioning operation
* @exception ResourceException If the init() fails.
*/
void init( ResourceAdapter ra, Properties props ) throws ResourceException;
}

Extended BootstrapContext

If, when a resource adapter is deployed, it has a resource adapter JavaBean specified in the <resource-adapter-class> element of its ra.xml descriptor, the WebLogic Server connector container calls the start() method on the resource adapter bean as required by the J2CA 1.5 Specification (http://java.sun.com/j2ee/connector/). The resource adapter code can use the BootstrapContext object that is passed in by the start() method to:

  • Obtain a WorkManager object for submitting Work instances

  • Create a Timer

  • Obtain an XATerminator for use in transaction inflow

These capabilities are all prescribed by the J2CA 1.5 Specification.

In addition to implementing the required javax.resource.spi.BootstrapContext, the BootstrapContext object passed to the resource adapter start() method also implements weblogic.connector.extensions.ExtendedBootstrapContext, which gives the resource adapter access to some additional WebLogic Server-specific extensions that enhance diagnostic capabilities. These extensions are described in the following sections.

Diagnostic Context ID

In the WebLogic Server diagnostic framework, a thread may have an associated diagnostic context. A request on the thread carries its diagnostic context throughout its lifetime, as it proceeds along its path of execution. The ExtendedBootstrapContext allows the resource adapter developer to set a diagnostic context payload consisting of a String that can be used, for example, to trace the execution of a request from an EIS all the way to a message endpoint.

This capability can serve a variety of diagnostic purposes. For example, you can set the String to the client ID or session ID on an inbound message from an EIS. During message dispatch, various diagnostics can be gathered to show the request flow through the system. As you develop your resource adapter classes, you can make use of the setDiagnosticContextID() and getDiagnosticContextID() methods for this purpose.

Note the following regarding the contents of the diagnostic context payload:

  • The payload can be viewed by other code in the same execution context, and it can also flow out of the process along with the Work instance. Therefore, you should ensure that the application does not include any sensitive data in the payload that, for example, could be returned by the getDiagnosticContextID() method.

  • The payload can be overwritten by other code in the same execution context. Therefore, the application must never have a dependency on a specific context ID being available in the payload. In addition, the application should also verify that the context ID in the payload matches what is expected before using it.

For more information about the diagnostic context, see Oracle Fusion Middleware Configuring and Using the Diagnostics Framework for Oracle WebLogic Server.

Dye Bits

The WebLogic Server diagnostic framework also provides the ability to dye a request. The ExtendedBootstrapContext allows you to set and retrieve four dye bits on the current thread for whatever diagnostic purpose the resource adapter developer chooses. For example, you might set priority of a request using the dye bits. For more information about request dyeing, see Oracle Fusion Middleware Configuring and Using the Diagnostics Framework for Oracle WebLogic Server

Callback Capabilities

You can use the ExtendedBootstrapContext.complete() method as a callback to the connector container. For detailed information on this feature, see "Redeploying Applications in a Production Environment" in Oracle Fusion Middleware Deploying Applications to Oracle WebLogic Server.