Skip navigation.
Downloads | Product Documentation | Support

WebLogic Tuxedo Connector Programmer's Guide

# Developing WebLogic Tuxedo Connector Client EJBs

Note: For more information on the WebLogic Tuxedo Connector JATMI, view the Javadocs for WebLogic Classes. The WebLogic Tuxedo Connector classes are located in the weblogic.wtc.jatmi and weblogic.wtc.gwt packages.

The following sections describe how to create client EJBs that take user input and send service requests to a server process or outbound object that offers a requested service.

- Joining and Leaving Applications
- Basic Client Operation
- Example Client EJB

WebLogic Tuxedo Connector JATMI`` client classes are used to create clients that access services found in Tuxedo.

# Joining and Leaving Applications

Tuxedo and WebLogic Tuxedo Connector have different approaches to connect to services.

## Joining an Application

The following section compares how Tuxedo and WebLogic Tuxedo Connector join an application:

- Tuxedo uses `tpinit()` to join an application.
- WebLogic Tuxedo Connector uses a WTCServer MBean to provide information required to create a path to the Tuxedo service. Security and client authentication is provided by configuring the Remote TDM and Imported Services MBean components of a WTCServer MBean. This pathway is created when the WebLogic Server is started and a WTCServer MBean is present in the `config.xml` file and assigned (targeted) to a server.
- WebLogic Tuxedo Connector uses TuxedoConnection to get a Tuxedo object and then uses getTuxedoConnection() to make a connection to the Tuxedo object. The following example shows how a WebLogic Server application joins a Tuxedo application using WebLogic Tuxedo Connector.

Listing 2-1 Example Client Code to Join a Tuxedo Application

>     .
>     .
>     .
>     try {
>          ctx = new InitialContext();
>          tcf =
>               (TuxedoConnectionFactory)
>               ctx.lookup("tuxedo.services.TuxedoConnection");
>          } catch (NamingException ne) {

>     // Could not get the tuxedo object, throw TPENOENT
>     throw new TPException(TPException.TPENOENT,
>          "Could not get TuxedoConnectionFactory : " + ne);
>          }

>     myTux = tcf.getTuxedoConnection();
>     .
>     .
>     .

## Leaving an Application

The following section compares how Tuxedo and WebLogic Tuxedo Connector leave an application:

- Tuxedo uses `tpterm()` to leave an application.
- WebLogic Tuxedo Connector uses the JATMI primitive tpterm() to close a connection to a Tuxedo object.
- WebLogic Tuxedo Connector closes the pathway to a Tuxedo service when a WTCserver MBean is assigned a new target server or the server is shutdown.

# Basic Client Operation

A client process uses Java and JATMI primitives to provide the following basic application tasks:

- Get a Tuxedo Object
- Perform Message Buffering
- Send and Receive Messages
- Close a Connection to a Tuxedo Object

A client may send and receive any number of service requests before leaving the application.

## Get a Tuxedo Object

Establish a connection to a remote domain by using the TuxedoConnectionFactory to lookup "`tuxedo.services.TuxedoConnection`" in the JNDI tree and get a `TuxedoConnection` object using getTuxedoConnection().

## Perform Message Buffering

Use the following TypedBuffers when sending and receiving messages between your application and Tuxedo:

Table 2-1 TypedBuffers

Buffer Type | Description
--- | ---
TypedString | Buffer type used when the data is an array of characters that terminates with the null character. Tuxedo equivalent: STRING.
TypedCArray | Buffer type used when the data is an undefined array of characters (byte array), any of which can be null. Tuxedo equivalent: CARRAY.
TypedFML | Buffer type used when the data is self-defined. Each data field carries its own identifier, an occurrence number, and possibly a length indicator. Tuxedo equivalent: FML.
TypedFML32 | Buffer type similar to TypeFML but allows for larger character fields, more fields, and larger overall buffers. Tuxedo equivalent: FML32.
TypedXML | Buffer type used when data is an XML based message. Tuxedo equivalent: XML for Tuxedo Release 7.1 and higher.
TypedView | Buffer type used when the application uses a Java structure to define the buffer structure using a view description file. Tuxedo equivalent: View
TypedView32 | Buffer type similar to View but allows for larger character fields, more fields, and larger overall buffers. Tuxedo equivalent: View32.
TypedXOctet | Buffer type used when the data is an undefined array of characters (byte array) any of which can be null. X_OCTET is identical in semantics to CARRAY. Tuxedo equivalent: X_OCTET.
TypedXCommon | Buffer type identical in semantics to View. Tuxedo equivalent: VIEW.
TypedXCType | Buffer type identical in semantics to View. Tuxedo equivalent: VIEW.

## Send and Receive Messages

WebLogic Tuxedo Connector clients support three types of communications with Tuxedo service applications:

- Request/Response Communication
- Conversational Communication
- Enqueuing and Dequeuing Messages

### Request/Response Communication

Note: WebLogic Tuxedo Connector does not provide a JATMI primitive to support setting the priority of a message request. All messages originating from a WebLogic Tuxedo Connector client have a message priority of 50.

Use the following JATMI primitives to request and receive response messages between your WebLogic Tuxedo Connector client application and Tuxedo:

Table 2-2 JATMI Primitives

Name | Operation
--- | ---
`tpacall` | Use for asynchronous invocations of a Tuxedo service.This JATMI primitive has two forms: deferred synchronous asynchronous
`tpcall` | Use for synchronous invocation of a Tuxedo service.
`tpgetrply` | Use for retrieving replies from deferred synchronous calls to a Tuxedo service.
`tpcancel` | Use to cancel an outstanding message reply for a call descriptor returned by `tpacall`. Note: You can not use `tpcancel` to cancel a call descriptor associated with a transaction.

#### Using Synchronous Service Calls

Use `tpcall` to send a request to a service and synchronously await for the reply. The service specified must be advertised by your Tuxedo application. Logically, `tpcall()` has the same functionality as calling `tpacall()` and immediately calling `tpgetreply()`.

#### Using Deferred Synchronous Service Calls

A deferred synchronous `tpacall` allows you to send a request to a Tuxedo service and not immediately wait for the reply. This allows you to send a request, perform other work, and then retrieve the reply.

A deferred `tpacall()` service call sends a request to a Tuxedo service and immediately returns from the call. The service specified must be advertised by your Tuxedo application. Upon successful completion of the call, `tpacall()` returns an object that serves as a descriptor. The calling thread is now available to perform other tasks. You can use the call descriptor to:

- Get the correct reply for the sent request using `tpgetreply()`
- Cancel an outstanding message reply using `tpcancel()`.

When you are ready to retrieve the reply, use `tpgetreply()` to dequeue the reply using the call descriptor returned by `tpacall()`. If the reply is not immediately available, the calling thread polls for the reply.

If `tpacall()` is in a transaction, you must receive the reply using `tpgetreply()` before the transaction can commit. You can not use `tpcancel` to cancel a call descriptor associated with a transaction. For example: If you make three `tpacall()` requests in a transaction, you must make three `tpgetreply()` calls and successfully dequeue a reply for each of the three requests for the transaction to commit.

#### Using Asynchronous Calls

The asynchronous `tpacall` allows you to send a request to a Tuxedo service and release the thread resource that performed the call to the thread pool. This allows a very large number of outstanding requests to be serviced with a much smaller number of threads.

An asynchronous `tpacall()` service call sends a request to a Tuxedo service. The service specified must be advertised by your Tuxedo application. Upon successful completion of the call, asynchronous `tpacall()` returns an object that serves as a descriptor. The calling thread is now available to perform other tasks. You can use the call descriptor to identify the correct message reply from `TpacallAsynchReply` for a sent message request or cancel an outstanding message reply using `tpcancel()`.

Note: You can not use the call descriptor to invoke `tpgetreply()`.

When the service reply is ready, the `callback` object is invoked on a different thread. If the original request succeeded, the `TpacallAsynchReply.sucess` method returns the reply from the service. If the original request failed, the `TpacallAsynchReply.failure` method returns a failure code.

You should implement the `callback` object using the following guidelines:

- The reply thread is obtained from the threadpool. The thread making the asynchronous `tpacall()` does not wait for the reply message.
- The user context of the reply thread will be restored to that of the original caller of asynchronous `tpacall()`.
- It is up to the callback object to restore any additional context and resume whatever processing was interrupted when the original asynchronous `tpacall()` was made.
- It is up to you to synchronize work within the multi threaded environment. For example: If an asynchronous `tpacall()` request is made and the reply is returned immediately, it is possible for the call back object to be modified by the reply thread before the calling thread has finished.
- The reply thread will not retain the transaction context of the calling thread.
- If asynchronous `tpacall()` is in a transaction, you must receive the reply using `TpacallAsynchReply` before the transaction can commit. You can not use `tpcancel` to cancel a call descriptor associated with a transaction.

### Conversational Communication

Note: For more information on Conversational Communication, see WebLogic Tuxedo Connector JATMI Conversations.

Use the following conversational primitives when creating conversational clients that communicate with Tuxedo services:

Table 2-3 WebLogic Tuxedo Connector Conversational Client Primitives

Name | Operation
--- | ---
`tpconnect` | Use to establish a connection to a Tuxedo conversational service.
`tpdiscon` | Use to abort a connection and generate a TPEV_DISCONIMM event when executed by the process controlling the conversation.
`tprecv` | Use to receive data across an open connection from a Tuxedo application.
`tpsend` | Use to send data across a open connection to a Tuxedo application.

### Enqueuing and Dequeuing Messages

Use the following JATMI primitives to enqueue and dequeue messages between your WebLogic Tuxedo Connector client application and Tuxedo /Q:

Table 2-4 JATMI Primitives

Name | Operation
--- | ---
`tpdequeue` | Use for receiving messages from a Tuxedo /Q.
`tpenqueue` | Use for placing a message on a Tuxedo /Q.

## Close a Connection to a Tuxedo Object

Use tpterm() to close a connection to an object and prevent future operations on this object.

# Example Client EJB

The following Java code provides an example of the `ToupperBean.java` client EJB which sends a string argument to a server and receives a reply string from the server.

Listing 2-2 Example Client Application

>     .
>     .
>     .
>     public String Toupper(String toConvert)
>        throws TPException, TPReplyException
>     {
>     	     Context ctx;
>     	     TuxedoConnectionFactory tcf;
>     	     TuxedoConnection myTux;
>     	     TypedString myData;
>          	Reply myRtn;
>     	     int status;

>     	     log("toupper called, converting " + toConvert);

>     	     try {
>               		ctx = new InitialContext();
>     		          tcf = (TuxedoConnectionFactory) ctx.lookup(
>                     			"tuxedo.services.TuxedoConnection");
>     	     }
>     	     catch (NamingException ne) {
>     		          // Could not get the tuxedo object, throw TPENOENT
>                		throw new TPException(TPException.TPENOENT, "Could not get TuxedoConnectionFactory : " + ne);
>          	}

>     	     myTux = tcf.getTuxedoConnection();

>     	     myData = new TypedString(toConvert);

>     	     log("About to call tpcall");
>          	try {
>     		          myRtn = myTux.tpcall("TOUPPER", myData, 0);
>     	}
>     	     catch (TPReplyException tre) {
>     		          log("tpcall threw TPReplyExcption " + tre);
>               		throw tre;
>     	     }
>          	catch (TPException te) {
>               		log("tpcall threw TPException " + te);
>               		throw te;
>          	}
>          	catch (Exception ee) {
>               		log("tpcall threw exception: " + ee);
>               		throw new TPException(TPException.TPESYSTEM, "Exception: " + ee);
>          	}
>          log("tpcall successfull!");

>          	myData = (TypedString) myRtn.getReplyBuffer();

>          	myTux.tpterm();	// Closing the association with Tuxedo

>          	return (myData.toString());
>     }
>     .
>     .
>     .