JATMI Client Programming
Client applications can access an Oracle Tuxedo service using the Java Application To Monitor Interface (JATMI). JATMI is a straight Java implementation of the Oracle Tuxedo ATMI interface.
To develop a JATMI-based Tuxedo JCA Adapter client application, you must do the following steps:
Create a new interaction instance
Create and input a new JATMI Typed Buffer data record instance.
Call Oracle Tuxedo service
Retrieve output data record reply
Release resources
The code examples in this section perform service calls to an Oracle Tuxedo service. The service name is TOUPPER and requires configuration. For more information, see Configuration File Examples. The Tuxedo TOUPPER service requires a STRING Typed Buffer for input and output.
To create new interaction instance, the client application must place a call to the Connection. When you use the JATMI interaction extension (com.oracle.tuxedo.adapter.cci.TuxedoInteractionSpec), an interaction specification is not required to customize the interaction between client applications and Oracle Tuxedo services.The JATMI service invocation interface already includes these interaction specifications as shown in Listing 22.
Listing 22 New JATMI Interaction Instance
Interaction ix;
...
ix = c.reateInteraction()
The input data must be transported using an Oracle Tuxedo Typed Buffer. Listing 23 shows the "TOUPPER" service using a STRING Typed Buffer for input and output.
Listing 23 TOUPPER" Service Using a STRING Buffer Type
TypedString inData;
...
inData = new TypedString(string_to_convert);
Listing 24 shows the actual "TOUPPER" service request and data retrieval reply.
Listing 24 JATMI Client Application TOUPPER Service Request and Output Data Retrieval
Reply myRtn;
TypedString outData;
myRtn = ix.tpcall("TOUPPER", inData, 0);
outData= (TypedString)myRtn.getReplyBuffer();
String returned_data = outData.toString()
Listing 25 shows how the resources are released.
Listing 25 JATMI Client Application Resource Release
ix.tpterm();
c.close();
To compile the Java code, the client application must import the following packages.
- javax.resource.cci
- weblogic.wtc.jatmi
- com.oracle.tuxedo.adapter.cci
- com.oracle.tuxedo
Listing 26 shows a JATMI client application program example.
Listing 26 JATMI Client Application Program Example
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.ejb.CreateException;
import javax.resource.cci.ConnectionFactory;
import javax.resource.cci.Connection;
import javax.resource.cci.Interaction;
import javax.resource.cci.Interactionspec;
import javax.resource.ResourceException;
import weblogic.wtc.jatmi.TPException;
import weblogic.wtc.jatmi.TPReplyException;
import weblogic.wtc.jatmi.Reply;
import weblogic.wtc.jatmi.TypedString;
import com.oracle.tuxedo.adapter.TuxedoReplyException;
import com.oracle.tuxedo.adapter.cci.TuxedoInteraction;
...
public String Toupper(String string_to_convert) throws TPException, TPReplyException
{
Context ctx;
ConnectionFactory cf;
Connection c;
Interaction ix;
TypedString inData;
TypedString outData;
Reply myRtn;
try {
ctx = new InitialContext();
cf = ctx.lookup("eis/TuxedoConnectionFactory");
c = cf.getConnection();
ix = c.createInteraction();
inData = new TypedString(string_to_convert);
myRtn = ix.tpcall("TOUPPER", inData, 0);
outData= (TypedString)myRtn.getReplyBuffer();
String returned_data = outData.toString();
ix.tpterm();
c.close()
return returned_data;
}
catch (NamingException ne) {
throw new TPException(TPException.TPESYSTEM,
"Could not get TuxedoConnectionFactory");
}
catch (ResourceException re) {
throw new TPException(TPException.TPESYSTEM,
"ResourceException occurred, reason: " + re);
}
}
Inbound EJB Service Programming
You can use the Oracle Tuxedo JCA Adapter to access EJB-based Tuxedo client services. In order for the Oracle Tuxedo JCA Adapter to invoke an EJB, the EJB must use theweblogic.wtc.jatmi.TuxedoService interface. This interface defines a single method called service as shown in Listing 27.
Listing 27 EJB Service Single Method
public Reply service(TPServiceInformation svcinfo)
throws TPException, TPReplyException, RemoteException;
To develop an EJB-based service application using the TuxedoService.service() interface, you must do the following steps:
Retrieve input data and perform task.
Create Typed Buffer for output data.
Setup the output data to be returned to caller.
Configure the EJB deployment descriptor.
The code examples in this section show how to:
- use the TuxedoService interface.
- configure the EJB in the Oracle Tuxedo JCA Adapter configuration file to expose the service.
- configure the Oracle Tuxedo GWTDOMAIN gateway to import the service.
The service name is TOLOWER and requires configuration. For more information, see Configuration File Examples. The EJB service uses a STRING Typed Buffer for input and output.
Listing 28 shows an example of how input data is retrieved using TPServiceInformation (shown in Listing 27).
Listing 28 EJB Input Data Retrieved from TPServiceInformation
TypedString data;
...
data = (TypedString)mydata.getServiceData();
The input data is converted to lower case as shown in Listing 29
Listing 29 EJB Input Data Converted to Lower Case
String lowered;
...
lowered = data.toString().toLowerCase();
When the output data is available, it must be wrapped in an Oracle Tuxedo Typed Buffer. Listing 30 shows the how the output data is wrapped using the TypedString Typed Buffer.
Listing 30 EJB Output Data Wrapped in TypedString Typed Buffer
TypedString return_data;
...
return_data = new TypedString(lowered);
The output Typed Buffer is then transported back to the caller (using the TPServiceInformation object) as shown in Listing 31.
Listing 31 EJB Output Typed Buffer Transported to Caller
mydata.setReplyBuffer(return_data);
In order for Tuxedo JCA Adapter to successfully invoke the EJB service, the EJB deployment descriptor must be configured using the following information:
- home interface: weblogic.wtc.jatmi.TuxedoServiceHome
- remote interface: weblogic.wtc.jatmi.TuxedoService
- jndi name: tuxedo.services.TolowerHome
The required prefix (tuxedo.services) and the EJB name (TolowerHome) are configured in the <EXPORT><SOURCE> element of the Oracle Tuxedo JCA Adapter configuration file as shown in Listing 32.
Listing 32 EJB “TOLOWER”Configuration
<Export name="TOLOWER">
<RemoteName>TOLOWER</RemoteName>
<SessionName>session_1</SessionName>
<Type>EJB</Type>
<Source>tuxedo.services.TolowerHome</Source>
</Export>
To successfully compile the Java code, the client application must import the following packages:
- weblogic.wtc.jatmi
- com.oracle.tuxedo.adapter.tdom
Listing 33 shows an EJB client application program example.
Listing 33 EJB Client Application Program Example
package test.tuxedo.simpserv;
import javax.ejb.CreateException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import weblogic.wtc.jatmi.TPException;
import weblogic.wtc.jatmi.TypedString;
import weblogic.wtc.jatmi.Reply;
import com.oracle.tuxedo.adapter.tdom.TPServiceInformation;
...
public Reply service(TPServiceInformation mydata) throws TPException
{
TypedString data;
String lowered;
TypedString returned_data;
data = (TypedString)mydata.getServiceData();
lowered = data.toString().toLowerCase();
returned_data = new TypedString(lowered);
mydata.setReplyBuffer(return_data);
return mydata;
}
...
Inbound POJO Service Programming
You can use the Oracle Tuxedo JCA Adapter to access Plain Old Java Object (POJO)-based Tuxedo client services.
In order for the Oracle Tuxedo JCA Adapter to invoke a POJO service, the POJO service must provide a method with same name as the exported name. This method must take two fixed arguments: TPServiceInformation and TPRequestAsyncReply.
To develop an POJO-based service application using the TuxedoService.service() interface, you must do the following steps:
Retrieve input data and perform a task.
Create Typed Buffer for output data.
Setup the output data to be returned to caller.
Inform Tuxedo JCA Adapter POJO handler of success or failure
Configure the POJO deployment descriptor.
The code examples in this section show how to:
- use an ordinary Java class to provide a service to an Oracle Tuxedo C/C++ client.
- configure the POJO in the Oracle Tuxedo JCA Adapter configuration file to expose the service
- configure an Oracle Tuxedo GWTDOMAIN gateway to import the service
The service name is MYTOLOWER and requires configuration. For more information, see Configuration File Examples. The POJO service requires a STRING Typed Buffer for input and output.
Listing 34 shows an example of how input data is retrieved using TPServiceInformation (shown in Listing 27).
Listing 34 POJO Input Data Retrieved from Input TPServiceInformation
TypedString typedstr;
...
data = (TypedString)svcinfo.getServiceData();
The input data is converted to lower case as shown in Listing 35
Listing 35 POJO Input Data Converted into Lower Case
String lower;
...
lower = typedstr.toString().toLowerCase();
When the output data is available, it must be wrapped in an Oracle Tuxedo Typed Buffer. Listing 36 shows the how the output data is wrapped using the TypedString Typed Buffer.
Listing 36 POJO Output Data Wrapped in TypedString Buffer
TypedString return_data;
...
return_data = new TypedString(lower);
The output Typed Buffer is then transported back to the caller (using the TPServiceInformation object) as shown in Listing 31.
Listing 37 POJO Output Typed Buffer Transported to Caller
mydata.setReplyBuffer(return_data);
areply.success(svcinfo);
In order for the Oracle Tuxedo JCA Adapter to successfully invoke a POJO service, the POJO deployment descriptor must be configured. The POJO method name must be configured in the <EXPORT> section of the Oracle Tuxedo JCA Adapter configuration file as shown in Listing 38.
The <SOURCE> element contains the fully qualified class name, and the <SourceLocation> element contains the full path name to the .JAR file that contains the class. The .JAR file must be configured in the CLASSPATH.
Listing 38 POJO "TOLOWER_POJO" Configuration
<Export name="TOLOWER_POJO">
<RemoteName>TOLOWER_POJO</RemoteName>
<SessionName>session_1</SessionName>
<Type>POJO</Type>
<Source>com.oracle.tuxedo.test.MyTolower</Source>
<SourceLocation>c:\tuxedo\jca\test\myapp.jar</SourceLocation>
</Export>
To successfully compile the Java code, the client application must import the following packages.
- weblogic.wtc.jatmi
- com.oracle.tuxedo.adapter.tdom
Listing 39 shows a POJO client application program example.
Listing 39 POJO Client Application Program Example
package com.oracle.tuxedo.test;
import javax.ejb.CreateException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import weblogic.wtc.jatmi.TPException;
import weblogic.wtc.jatmi.TypedString;
import weblogic.wtc.jatmi.Reply;
import weblogic.wtc.jatmi.TPRequestAsyncReply;
import com.oracle.tuxedo.adapter.tdom.TPServiceInformation;
...
public void TOLOWER_POJO(TPServiceInformation svcinfo, TPRequestAsyncReply areply) throws TPException
{
TypedString typedstr;
String lower;
TypedString returned_data;
typedstr = (TypedString)svcinfo.getServiceData();
lower = typedstr.toString().toLowerCase();
returned_data = new TypedString(lower);
svcinfo.setReplyBuffer(return_data);
areply.success(svcinfo);
}
...
AUTOTRAN Programming
The Oracle Tuxedo JCA Adapter supports adapter managed AUTOTRAN transaction. For AUTOTRAN transaction the Tuxedo JCA Adapter will start a transaction if the service request is not already part of an existing transaction. The Tuxedo JCA Adapter will commit or rollback the transaction before returning the reply or exception to client program. Whether Tuxedo JCA Adapter will commit or rollback transaction depends on the reply and session connection status. If the reply indicates a failure or the session connection error then it will rollback the transaction, otherwise it will commit the transaction.
To develop a synchronous CCI-based Tuxedo JCA Adapter AUTOTRAN client program the procedure and program is exactly the same as developing an ordinary synchronous CCI-based cleint without transaction as described in section with title 'CCI Client Programming' in this book. The only differences is configuration.
Listing 40 shows an example that enables AUTOTRAN on imported resource TOUPPER with tranaction timeout set to 15 seconds.
Listing 40 AUTOTRAN Configuration Using DMCONFIG File
....
<Import name="TOUPPER" autotran=true trantime=15>
<RemoteName>TOUPPER</RemoteName>
<SessionName>session_1</SessionName>
<LoadBalancing>RoundRobin</LoadBalancing>
</Import>
....
Beside using Tuxedo JCA Adapter Configuration file to configure the AUTOTRAN for individual imported resource, user can also enable the adapter-wise AUTOTRAN using property in the Resource Adapter Deployment Descriptor.
Listing 41 shows an example that enables AUTOTRAN on every imported resource with transaction timeout set to 15 seconds.
Listing 41 Enable AUTOTRAN Using Property in ra.xml
...
<config-property>
<config-property-name>appManagedLocalTxTimeout</config-property-name>
<config-property-type>java.lang.Integer</config-property-type>
<config-property-value>15</config-property-value>
</config-property>
<config-property>
<config-property-name>autoTran</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
<config-property-value>true</config-property-value>
</config-property>
...
Configuration File Examples
To run the Oracle Tuxedo JCA Adapter, you must configure the following files:
- Oracle Tuxedo JCA Adapter configuration file
- Oracle Tuxedo UBBCONFIG and DMBCONFIG files
Oracle Tuxedo JCA Adapter Configuration Examples
The Oracle Tuxedo JCA Adapter configuration file is a formal syntax XML file. The location of this file is configured in the ra.xml file in the resource adapter configuration property. For more information, see the Oracle JCA Users Guide and the Oracle Tuxedo JCA Adapter Reference Guide.
Listing 42 shows an example ra.xml file snippet that links the configuration file with the Oracle Tuxedo JCA Adapter.
Listing 42 ra.xml File Example
<config-property>
<config-property-name>dmconfig</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>c:/myJcaApp/adapter/bdmconfig.xml</config-property-value>
</config-property>
Listing 43 shows an Oracle Tuxedo JCA Adapter DMCONFIG file example that accesses:
- A single Oracle Tuxedo application domain
- Oracle Tuxedo TOUPPER_V32 and TOUPPER services
Note:TOUPPER_V32 is a VIEW32 Typed Buffer service. TOUPPER is a STRING Typed Buffer service.
The Local Access Point defines the Oracle Tuxedo JCA Adapter listening end point. The Remote Access Point defines the Oracle Tuxedo GWTDOMAIN gateway listening end point.
Listing 43 Oracle Tuxedo JCA Adapter Configuration File
<?xml version="1.0" encoding="UTF-8"?><TuxedoConnector>
<Resources>
<ViewFile32Classes>tuxedo.test.simpapp.View32</ViewFile32Classes>
</Resources>
<LocalAccessPoint name="JDOM">
<AccessPointId>JDOM_ID</AccessPointId>
<NetworkAddress>//localhost:10801</NetworkAddress>
</LocalAccessPoint>
<RemoteAccessPoint name="TDOM1">
<AccessPointId>TDOM1_ID</AccessPointId>
<NetworkAddress>//localhost:12478</NetworkAddress>
</RemoteAccessPoint>
<SessionProfile name="profile_1">
<Security>NONE</Security>
<BlockTime>30000</BlockTime>
<Interoperate>false</Interoperate>
<ConnectionPolicy>ON_STARTUP</ConnectionPolicy>
<ACLPolicy>local</ACLPolicy>
<CredentialPolicy>local</CredentialPolicy>
<RetryInterval>60</RetryInterval>
<MaxRetries>1000</MaxRetries>
<CompressionLimit>1000000</CompressionLimit>
</SessionProfile>
<Session name="session_1">
<LocalAccessPointName>JDOM</LocalAccessPointName>
<RemoteAccessPointName>TDOM1</RemoteAccessPointName>
<ProfileName>profile_1</ProfileName>
</Session>
<Import name="TOUPPER">
<RemoteName>TOUPPER</RemoteName>
<SessionName>session_1</SessionName>
<LoadBalancing>RoundRobin</LoadBalancing>
</Import>
<Import name="TOUPPER_V32">
<RemoteName>TOUPPER_V32</RemoteName>
<SessionName>session_1</SessionName>
<LoadBalancing>RoundRobin</LoadBalancing>
</Import>
<Export name="TOLOWER">
<RemoteName>TOLOWER</RemoteName>
<SessionName>session_1</SessionName>
<Type>EJB</Type>
<Source>tuxedo.services.TolowerHome</Source>
</Export>
<Export name="TOLOWER_POJO">
<RemoteName>TOLOWER_POJO</RemoteName>
<SessionName>session_1</SessionName>
<Type>POJO</Type>
<Source>com.oracle.tuxedo.test.MyTolower</Source>
<SourceLocation>c:\tuxedo\jca\test\MyApp.jar</SourceLocation>
</Export>
</TuxedoConnector>
JCA Adapter AUTOTRAN Configuration
Listing 44 provides an AUTOTRAN configuration example.
Listing 44 AUTOTRAN Configuration Example
<?xml version="1.0" encoding="UTF-8"?>
<connector xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/connector_1_5.xsd"
version="1.5">
<display-name>Tuxedo JCA Adapter</display-name>
<vendor-name>Oracle</vendor-name>
<eis-type>Tuxedo</eis-type>
<resourceadapter-version>11gr1(11.1.1.2.0)</resourceadapter-version>
<license>
<description>Tuxedo SALT license</description>
<license-required>false</license-required>
</license>
<resourceadapter>
<resourceadapter-class>com.oracle.tuxedo.adapter.
TuxedoClientSideResourceAdapter</resourceadapter-class>
<config-property>
<config-property-name>xaAffinity</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>true</config-property-value>
</config-property>
<config-property>
<config-property-name>appManagedLocalTxTimeout
</config-property-name>
<config-property-type>java.lang.Integer</config-property-type>
<config-property-value>30</config-property-value>
</config-property>
<config-property>
<config-property-name>autoTran</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
<config-property-value>true</config-property-value>
</config-property>
<!--
Uncomment this if you are running Tuxedo version before 11.1.1.2.0
<config-property>
<config-property-name>localAccessPointSpec</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>//localhost:10801/domainId=JDOM_ID
</config-property-value>
</config-property>
}
Build
Right click project EchoMDB in the Project Explorer, and then select Deploy as shown in Figure 13. This compiles it into class in the build directory.
Figure 5 Compile
Create EJB JAR File
Right click the project EchoMDB in the Project Explorer and select Export. The Export menu popup appears as shown in Figure 14.
Figure 6 Export Popup Window
In the Export popup window select EJB JAR file. Click Next. The EJB Jar Export popup window appears as shown in Figure 15. Select EchoMDB from the drop down menu, and enter the complete path of the jar file name in the Destination: text field. Click Finish.
Figure 7 EJB Jar Export Popup Window
The Save Resources popup window appears as shown in Figure 16 click “OK”.
Figure 8 Save Resources Popup Window
For Oracle Tuxedo JCA Adapter dispatching-based MDB, you must add activation-config-property to its ejb-jar.xml file using one of two ways.
The first method is to unzip the jar file. After the jar file is unzipped, modify the META-INF/ejb-jar.xml, and then re-jar the bean jar file. Listing 1 shows an example ejb-jar.xml file suitable to this type of MDB.
Listing 1 ejb-jar.xml File Example
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar id="ejb-jar_ID" version="2.1" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=”http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd">
<display-name>EchoMDB</display-name>
<enterprise-beans>
<!-- message driven descriptor -->
<message-driven id="EchoMDB">
<ejb-name>EchoMDB</ejb-name>
<ejb-class>ejbs.EchoMDBBean</ejb-class>
<!-- message listener interface -->
<messaging-type>com.oracle.tuxedo.adapter.intf.TuxedoMDBService</messag
ing-type>
<transaction-type>Container</transaction-type>
<!-- the values for the Activation Spec JavaBean -->
<activation-config>
<activation-config-property>
<activation-config-property-name>source</activation-config-property-name>
<activation-config-property-value>eis/echo</activation-config-property-value>
</activation-config-property>
</activation-config>
</message-driven>
</enterprise-beans>
</ejb-jar>
Where eis/echo is the JNDI name of EchoMDB.
Similarly, the second method is to modify ejb-jar.xml file directly to add activation-config-property using ASTK before the MDB is being deployed and exported.
Oracle Tuxedo Conversational Server Programming Tips
When a Java conversational client initiates a tpconnect() call, the Oracle Tuxedo "C" language conversational server service routine is invoked; however, before the service routine is invoked the Oracle Tuxedo system implements a RECEIVE command implicitly and puts all the data and events into the input argument of the service routine.
If the Java client initiates tpconnect(TPSENDONLY), the Oracle Tuxedo server will have data in TPSVCINFO->data, and TPSVCINFO->len. The TPSENDONLY flag is translated to TPRECVONLY and conveyed in the TPSVCINFO->flags field. In this case, the TPRECVONLY flag can be ignored by the server service routine, and the server should continue initiating tprecv() until it receives a TPEV_SENDONLY event.
If the Java client initiates tpconnect(TPRECVONLY), the Oracle Tuxedo server will have both event and data in TPSVCINFO. The event is in the TPSVCINFO->flags field, and user data is in TPSCVINFO->data, the data length is in TPSVCINFO->len. The server should start initiating tpsend() until it either finishes the conversation with tpreturn(), or returns control to the client with tpsend(TPRECVONLY).
WARNING: You can also choose not to send data, in this case TPSVCINFO->data will be NULL .
The following is a typical Oracle Tuxedo conversational server code example that handles tpconnect().
Listing 2
void