PK
@zDoa, mimetypeapplication/epub+zipPK @zD iTunesMetadata.plistv
This chapter describes how Oracle WebLogic Tuxedo Connector uses the Field Manipulation Language (FML).
This chapter includes the following sections:
Note: For more information about using FML, see Programming a Tuxedo ATMI Application Using FML at |
FML is a set of java language functions for defining and manipulating storage structures called fielded buffers. Each fielded buffer contains attribute-value pairs in fields. For each field:
The attribute is the field's identifier.
The associated value represents the field's data content.
An occurrence number.
There are two types of FML:
FML16 based on 16-bit values for field lengths and identifiers. It is limited to 8191 unique fields, individual field lengths of 64K bytes, and a total fielded buffer size of 64K bytes.
FML32 based on 32-bit values for the field lengths and identifiers. It allows for about 30 million fields, and field and buffer lengths of about 2 billion bytes.
Note: The Oracle WebLogic Tuxedo Connector implements a subset of FML functionality. For more information regarding FML32, refer to FML32 Considerations. |
The FML application program interface (API) is documented in the weblogic.wtc.jatmi
package included in the Javadocs for WebLogic Server Classes.
Field tables are generated in a manner similar to Oracle Tuxedo field tables. The field tables are text files that provide the field name definitions, field types, and identification numbers that are common between the two systems. To interoperate with an Oracle Tuxedo system using FML, the following steps are required:
Copy the field tables from the Oracle Tuxedo system to Oracle WebLogic Tuxedo Connector environment.
For example: Your Oracle Tuxedo distribution contains a bank application example called bankapp
. It contains a file called bankflds
that has the following structure:
#Copyright (c) 1990 Unix System Laboratories, Inc. #All rights reserved #ident "@(#) apps/bankapp/bankflds $Revision: 1.3 $" # Fields for database bankdb # name number type flags comments ACCOUNT_ID 110 long - - ACCT_TYPE 112 char - - ADDRESS 109 string - - . . .
Converted the field table definition into Java source files. Use the mkfldclass
utility supplied in the weblogic.wtc.jatmi
package. This class is a utility function that reads a FML32 Field Table and produces a Java file which implements the FldTbl interface. There are two instances of this utility:
mkfldclass
mkfldclass32
Use the correct instance of the command to convert the bankflds
field table into FML32 java source. The following example uses mkfldclass.
java weblogic.wtc.jatmi.mkfldclass bankflds
The resulting file is called bankflds.java
and has the following structure:
import java.io.*; import java.lang.*; import java.util.*; import weblogic.wtc.jatmi.*; public final class bankflds implements weblogic.wtc.jatmi.FldTbl { /** number: 110 type: long */ public final static int ACCOUNT_ID = 33554542; /** number: 112 type: char */ public final static int ACCT_TYPE = 67108976; /** number: 109 type: string */ public final static int ADDRESS = 167772269; /** number: 117 type: float */ . . .
Compile the resulting bankflds.java
file using the following command:
javac bankflds.java
The result is a bankflds.class
file. When loaded, the Oracle WebLogic Tuxedo Connector uses the class file to add, retrieve and delete field entries from an FML32 field.
Add the field table class file to your application CLASSPATH.
Update your WTCServer
MBean.
Update the WTCResources
MBean to reflect the fully qualified location of the field table class file.
Use the keywords required to describe the FML buffer type: fml16 or fml32.
You can enter multiple field table classes in a comma separated list.
For example:
<wtc-resources> <name>BankappResources</name> <fld-tbl16-class>my.bankflds</fld-tbl16-class> <fld-tbl16-class>your.bankflds</fld-tbl16-class> <fld-tbl16-class>more.bankflds</fld-tbl16-class> </wtc-resources>
Restart your Oracle WebLogic Server to load the field table class definitions.
Oracle WebLogic Tuxedo Connector provides a property that provides an alternate method to compile FML tables. You may need to use the DynRdHdr
utility if:
You are using very large FML tables and the .java
method created by the mkfldclass32 class exceeds the internal Java Virtual Machine limit on the total complexity of a single class or interface.
You are using very large FML tables and are unable to load the class created when compiling the .java
method.
Use the following steps to use the DynRdHdr
property when compiling your FML tables:
Convert the field table definition into Java source files.
java -DDynRdHdr=Path_to_Your_FML_Table weblogic.wtc.jatmi.mkfldclass32 userTable
The arguments for this command are defined as follows:
Attribute | Description |
---|---|
-DDynRdHdr |
Oracle WebLogic Tuxedo Connector property used to compile an FML table. |
Path_to_Your_FML_Table
|
Path name of your FML table. This may be either a fully qualified path or a relative path that can be found as a resource file using the server's CLASSPATH. |
weblogic.wtc.jatmi.mkfldclass32 |
This class is a utility function that reads an FML32 Field Table and produces a Java file which implements the FldTbl interface. |
userTable |
Name of the |
Compile the userTable
file using the following command:
javac userTable.java
Add the userTable
.class
file to your application CLASSPATH.
Update the WTCResources
MBean to reflect the fully qualified location of the userTable
.class
file.
Target your WTC server. The userTable
.class
is loaded when the WTCServer service starts.
Once you have created the userTable
.class
file, you can modify the FML table and deploy the changes without having to manually create an updated userTable
.class
. When the WTC server is started, Oracle WebLogic Tuxedo Connector will load the updated FML table using the location specified in the Resources tab of your WTC server configuration. If the Path_to_Your_FML_Table
attribute changes, you will need to use the preceding procedure to update your userTable
.java
and userTable
.class
files.
Two new constructors for TypedFML32 are available to improve performance. The following topic provides explanation as to when to use these constructors.
The constructors are defined in the Javadocs for WebLogic Server Classes.
To gain TypedFML32 performance improvements, you can choose to give size hints to TypedFML32 constructors. There are two parameters that are available to those constructor:
A parameter that hints for maximum number of fields. This includes all the occurrences.
A parameter for the total number of field IDs used in the buffer.
For instance, a field table used by the buffer contains 20 field IDs, and each field can occur 20 times. In this case, the first parameter should be 400 for the maximum number of fields. The second parameter should be 20 for the total number of field IDs.
TypeFML32 mybuffer = new TypeFML32(400, 20);
Note: This usually works well with any size of buffer; however, it does not work well with extremely small buffers. |
If you have an extremely small buffer, use those constructor without hints. An example of an extremely small buffer is a buffer with less than 16 total occurrences. If the buffer is extremely large, for example contains more than 250000 total field occurrences, then the application should consider splitting it into several buffers smaller than 250000 total field occurrences.
Note: The data type specified must be FLAT or NO. If any other data type is specified, the redirection fails. |
The TranslateFML
element of the WTCtBridgeRedirect MBean is used to indicate if FML32 translation is performed on the message payload. There are two types of FML32 translation: FLAT and NO.
The message payload is translated using the Oracle WebLogic Tuxedo Connector internal FML32/XML translator. Fields are converted field-by-field values without knowledge of the message structure (hierarchy) and repeated grouping.
In order to convert an FML32 buffer to XML, the tBridge pulls each instance of each field in the FML32 buffer, converts it to a string, and places it within a tag consisting of the field name. All of these fields are placed within a tag consisting of the service name. For example, an FML32 buffer consisting of the following fields:
NAME JOE ADDRESS CENTRAL CITY PRODUCTNAME BOLT PRICE 1.95 PRODUCTNAME SCREW PRICE 2.50
The resulting XML buffer would be:
<FML32> <NAME>JOE</NAME> <ADDRESS>CENTRAL CITY</ADDRESS> <PRODUCTNAME>BOLT</PRODUCTNAME> <PRODUCTNAME>SCREW</PRODUCTNAME> <PRICE>1.95</PRICE> <PRICE>2.50</PRICE> </FML32>
No translation is used.
For JMS to Oracle Tuxedo, the tBridge maps a JMS TextMessage into an Oracle Tuxedo TypedBuffer (TypedString) and vice versa depending on the direction of the redirection. JMS BytesMessage are mapped into Oracle Tuxedo TypedBuffer (TypedCarray) and vice versa.
For Oracle Tuxedo to JMS, passing an FML/FML32 buffer behaves as if translateFML
is set to FLAT
. Therefore, in this case, setting translateFML
to NO
has no effect and if the Oracle Tuxedo buffer is of type FML/FML32, the translation takes place automatically.
Remember to consider the following information when working with FML32:
For XML input, the root element is required but ignored.
For XML output, the root element is always <FML32>.
The field table names must be loaded as described in FML Field Table Administration.
The tBridge translator is capable of only "flat" or linear grouping. This means that information describing FML32 ordering is not maintained, therefore buffers that contain a series of repeating data could be presented in an unexpected fashion. For example, consider a FML32 buffer that contains a list of parts and their associated price. The expectation would be PART A, PRICE A, PART B, PRICE B, etc. however since there is no structural group information contained within the tBridge, the resulting XML could be PART A, PART B, etc., PRICE A, PRICE B, etc.
When translating XML into FML32, the translator ignores STRING
values. For example, <STRING></STRING>
is skipped in the resulting FML32 buffer. All other types cause WTC to log an error resulting in translation failure.
Embedded FML is not supported in this release.
Embedded VIEW fields within FML32 buffers are supported in this release.
TypedCArray is supported for FML/FML32 to XML conversion. Select from the following list of supported field types:
SHORT
LONG
CHAR
FLOAT
DOUBLE
STRING
CARRAY
INT (FML32)
DECIMAL (FML32)
If you need to pass binary data, encode to a field type of your choice and decode the XML on the receiving side.
If you need to use CARRAY fields in an XML input buffer, you must first encode the content using base64. You must decode the base64 data after it is received and before it is processed by an application.
An alternative option to using the tBridge to automatically translate XML buffers to and from FML/FML32 is to use the XmlFmlCnv
class which supports ordering, grouping and beautifying functionality. The following code listing is an example that uses the XmlFmlCnv
class for conversion to and from XML buffer formats.
import weblogic.wtc.jatmi.TypedFML32; import weblogic.wtc.jatmi.FldTbl; import weblogic.wtc.gwt.XmlFmlCnv; public class xml2fml { public static void main(String[] args) { String xmlDoc = "<XML><MyString>hello</MyString></XML>"; TypedFML32 fmlBuffer = new TypedFML32(new MyFieldTable()); XmlFmlCnv c = new XmlFmlCnv(); fmlBuffer = c.XMLtoFML32(xmlDoc, fmlBuffer.getFieldTables()); String result = c.FML32toXML(fmlBuffer); System.out.println(result); } }
See Class XmlFmlCnv.
A TypedMBString
object can be used almost identically as a TypedString
object in a WTC application code. The only difference is that TypedMBString
has a codeset encoding name associated to the string data.
This section includes the following topics.
When an Oracle Tuxedo message that contains an MBSTRING data is sent to another Oracle Tuxedo domain, TypedMBString
uses the conversion function of java.lang.String
class to convert between Unicode and an external encoding. The TypedMBString
has a codeset encoding name associated to the string data.
When a TypedMBString
object is created by a WTC application code, the encoding name is set to null. The null value of the encoding name means that the default encoding name is used for Unicode string to byte array conversion while sending the MBSTRING data to a remote domain. By default, the Java's default encoding name for byte array string is used for the default encoding name.You can specify encoding or accept the default encoding. The following order defines the order of precedence for TypedMBString
.
Specify the encoding name by setMBEncoding()
method.
Specify the encoding name through the setDefaultMBEncoding()
method of weblogic.wtc.jatmi.MBEncoding
class.
Specify the encoding name through the RemoteMBEncoding
attribute of the WTCResourcesMBean
.
MBENCODINGPROPERTY
system property value.
Accept the Java default encoding name.
When an Oracle Tuxedo message that contains an MBSTRING data is received from a remote domain, the following actions take place.
WTC determines the encoding of the MBSTRING data by the codeset tcm
in the received message.
WTC creates a TypedMBString
object.
A TypedMBString
object can be used almost identically as a TyepdString
object in WTC application code. However, the TypedMBString has a codeset encoding name associated to the string data.
WTC passes the TypedMBString
object to the WTC application code. The application code knows the encoding of the received MBSTRING data by the instance method getMBEncoding()
.
FLD_MBSTRING is a field type added to TypedFML32
. In this case, a TypedMBString
object is passed to the TypedFML32
method as the associated object type of FLD_MBSTRING. You can specify the encoding name used for the MBSTRING conversion for a FLD_MBSTRING field.
The following order defines the order of precedence for TypedFML32.
Specify the encoding name by setMBEncoding()
method of the TypedMBString object for the field.
Specify the encoding name by setMBEncoding()
method of the TypedFML32 object.
Specify the encoding name through the setDefaultMBEncoding()
method of weblogic.wtc.jatmi.MBEncoding
class.
Specify the encoding name through the RemoteMBEncoding
attribute of the WTCResourcesMBean
.
MBENCODINGPROPERTY
system property value.
Accept the Java default encoding name.
Note: The following methods must be updated when using FLD_MBSTRING: The on-demand encoding methods and auto-conversion methods needed in Oracle Tuxedo, such as |
Developing Oracle WebLogic Tuxedo Connector Applications for Oracle WebLogic Server
12c (12.1.2)
E28118-01
June 2013
This document introduces the Oracle WebLogic Tuxedo Connector application development environment. It describes how to develop EJBs that allow Oracle WebLogic Server to interoperate with Oracle Tuxedo objects.
Oracle Fusion Middleware Developing Oracle WebLogic Tuxedo Connector Applications for Oracle WebLogic Server, 12c (12.1.2)
E28118-01
Copyright © 2007, 2013, Oracle and/or its affiliates. All rights reserved.
This software and related documentation are provided under a license agreement containing restrictions on use and disclosure and are protected by intellectual property laws. Except as expressly permitted in your license agreement or allowed by law, you may not use, copy, reproduce, translate, broadcast, modify, license, transmit, distribute, exhibit, perform, publish, or display any part, in any form, or by any means. Reverse engineering, disassembly, or decompilation of this software, unless required by law for interoperability, is prohibited.
The information contained herein is subject to change without notice and is not warranted to be error-free. If you find any errors, please report them to us in writing.
If this is software or related documentation that is delivered to the U.S. Government or anyone licensing it on behalf of the U.S. Government, the following notice is applicable:
U.S. GOVERNMENT END USERS: Oracle programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, delivered to U.S. Government end users are "commercial computer software" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations. As such, use, duplication, disclosure, modification, and adaptation of the programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, shall be subject to license terms and license restrictions applicable to the programs. No other rights are granted to the U.S. Government.
This software or hardware is developed for general use in a variety of information management applications. It is not developed or intended for use in any inherently dangerous applications, including applications that may create a risk of personal injury. If you use this software or hardware in dangerous applications, then you shall be responsible to take all appropriate failsafe, backup, redundancy, and other measures to ensure its safe use. Oracle Corporation and its affiliates disclaim any liability for any damages caused by use of this software or hardware in dangerous applications.
Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners.
Intel and Intel Xeon are trademarks or registered trademarks of Intel Corporation. All SPARC trademarks are used under license and are trademarks or registered trademarks of SPARC International, Inc. AMD, Opteron, the AMD logo, and the AMD Opteron logo are trademarks or registered trademarks of Advanced Micro Devices. UNIX is a registered trademark of The Open Group.
This software or hardware and documentation may provide access to or information on content, products, and services from third parties. Oracle Corporation and its affiliates are not responsible for and expressly disclaim all warranties of any kind with respect to third-party content, products, and services. Oracle Corporation and its affiliates will not be responsible for any loss, costs, or damages incurred due to your access to or use of third-party content, products, or services.
The following sections provide information about the development environment you will be using to write code for applications that interoperate between Oracle WebLogic Server and Oracle Tuxedo:
Note: For information on how to develop Oracle WebLogic Server Enterprise JavaBeans (EJBs), see Developing Enterprise JavaBeans, Version 2.1, for Oracle WebLogic Server. |
This document introduces the Oracle WebLogic Tuxedo Connector application development environment. It describes how to develop EJBs that allow Oracle WebLogic Server to interoperate with Oracle Tuxedo objects.
The document is organized as follows:
Chapter 1, "Introduction to Oracle WebLogic Tuxedo Connector Programming," provides information about the development environment you will be using to write code for applications that interoperate between Oracle WebLogic Server and Oracle Tuxedo.
Chapter 2, "Developing Oracle WebLogic Tuxedo Connector Client EJBs," provides information on how to create client EJBs.
Chapter 3, "Developing Oracle WebLogic Tuxedo Connector Service EJBs," provides information on how to create service EJBs.
Chapter 4, "Using Oracle WebLogic Tuxedo Connector for RMI/IIOP and CORBA Interoperability," provides information on how to develop CORBA applications for the Oracle WebLogic Tuxedo Connector.
Chapter 5, "Oracle WebLogic Tuxedo Connector JATMI Transactions," provides information on global transactions and how to define and manage them in your applications.
Chapter 6, "Oracle WebLogic Tuxedo Connector JATMI Conversations," provides information on conversations and how to define and manage them in your applications.
Chapter 7, "Using FML with Oracle WebLogic Tuxedo Connector," discusses the Field Manipulation Language (FML) and describes how the Oracle WebLogic Tuxedo Connector uses FML.
Chapter 8, "Oracle WebLogic Tuxedo Connector JATMI VIEWs," provides information on View buffers and how to define and manage them in your applications.
Chapter 9, "How to Create a Custom AppKey Plug-in," provides information on how to develop a Custom AppKey Plug-in.
Chapter 10, "Application Error Management," provide mechanisms to manage and interpret error conditions.
Note: For more information on the Oracle WebLogic Tuxedo Connector JATMI, view the Javadocs for WebLogic Classes. The Oracle WebLogic Tuxedo Connector classes are located in the weblogic.wtc.jatmi and weblogic.wtc.gwt packages. |
In addition to the Java code that expresses the logic of your application, you will be using the Java Application -to-Transaction Monitor Interface (JATMI) to provide the interface between Oracle WebLogic Server and Oracle Tuxedo.
Note: For more information, see Chapter 2, "Developing Oracle WebLogic Tuxedo Connector Client EJBs." |
A client process takes user input and sends a service request to a server process that offers the requested service. Oracle WebLogic Tuxedo Connector JATMI client classes are used to create clients that access services found in Oracle Tuxedo. These client classes are available to any service that is made available through a the Oracle WebLogic Tuxedo Connector WTCServer MBean.
Note: For more information, see Chapter 3, "Developing Oracle WebLogic Tuxedo Connector Service EJBs." |
Servers are processes that provide one or more services. They continually check their message queue for service requests and dispatch them to the appropriate service subroutines. Oracle WebLogic Tuxedo Connector uses EJBs to implement services which Oracle Tuxedo clients invoke.
Note: For more information, see Chapter 4, "Using Oracle WebLogic Tuxedo Connector for RMI/IIOP and CORBA Interoperability." |
The Oracle WebLogic Tuxedo Connector provides bi-directional interoperability between Oracle WebLogic Server and Oracle Tuxedo CORBA objects. The Oracle WebLogic Tuxedo Connector:
Enables Oracle Tuxedo CORBA objects to invoke upon EJBs deployed in Oracle WebLogic Server using the RMI/IIOP API (Inbound).
Enables objects (such as EJBs or RMI objects) to invoke upon CORBA objects deployed in Oracle Tuxedo using the RMI/IIOP API (Outbound).
Enables objects (such as EJBs or RMI objects) to invoke upon CORBA objects deployed in Oracle Tuxedo using a CORBA Java API (Outbound).
The JATMI is a set of primitives used to begin and end transactions, allocate and free buffers, and provide the communication between clients and servers.
Table 1-1 JATMI Primitives
Name | Operation |
---|---|
tpacall |
Use for asynchronous invocations of an Oracle Tuxedo service during request/response communication.
|
tpcall |
Use for synchronous invocation of an Oracle Tuxedo service during request/response communication. |
tpconnect |
Use to establish a connection to an Oracle Tuxedo conversational service. |
tpdiscon |
Use to abort a conversational connection and generate a TPEV_DISCONIMM event when executed by the process controlling the conversation. |
tpdequeue |
Use for receiving messages from an Oracle Tuxedo /Q during request/response communication. |
tpenqueue |
Use for placing a message on an Oracle Tuxedo /Q during request/response communication. |
tpgetrply |
Use for retrieving replies from an Oracle Tuxedo service during request/response communication. |
tprecv |
Use to receive data across an open connection from an Oracle Tuxedo application during conversational communication. |
tpsend |
Use to send data across a open connection to an Oracle Tuxedo application during conversational communication. |
tpterm |
Use to close a connection to an Oracle Tuxedo object. |
Oracle WebLogic Tuxedo Connector provides an interface called TypedBuffers that corresponds to Oracle Tuxedo typed buffers. Messages are passed to servers in typed buffers. The Oracle WebLogic Tuxedo Connector provides the following buffer types:
Table 1-2 TypedBuffers
Buffer Type | Description |
---|---|
TypedString |
Buffer type used when the data is an array of characters that terminates with the null character. Oracle Tuxedo equivalent: STRING. |
TypedCArray |
Buffer type used when the data is an undefined array of characters (byte array), any of which can be null. Oracle 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. Oracle Tuxedo equivalent: FML. |
TypedFML32 |
Buffer type similar to TypeFML but allows for larger character fields, more fields, and larger overall buffers. Oracle Tuxedo equivalent: FML32. |
TypedXML |
Buffer type used when data is an XML based message. Oracle 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. Oracle Tuxedo equivalent: VIEW |
TypedView32 |
Buffer type similar to View but allows for larger character fields, more fields, and larger overall buffers. Oracle Tuxedo equivalent: VIEW32. |
TypedMBString |
Buffer type used when the data is a wide array of characters to support multi-byte characters. Oracle Tuxedo equivalent: MBSTRING. |
This release includes the following new and changed features:
Support for readonly
transactions, see "Read-only, One-Phase Commit Optimizations" in Developing JTA Applications for Oracle WebLogic Server.
Support for tightly coupled transaction between WebLogic and Tuxedo, see "Transactions that Span Transaction Manager Systems" in Developing JTA Applications for Oracle WebLogic Server.
Nested view support, see Translating Nested Views.
For a comprehensive listing of the new WebLogic Server features introduced in this release, see What's New in Oracle WebLogic Server.
This chapter describes how to define and manage Oracle Tuxedo conversations in your applications. Tuxedo conversations are a supported method for message exchange between Oracle WebLogic Server and Oracle Tuxedo applications.
This chapter includes the following sections:
Overview of Oracle WebLogic Tuxedo Connector Conversational Communication
Oracle WebLogic Tuxedo Connector Conversation Characteristics
Oracle WebLogic Tuxedo Connector JATMI Conversation Primitives
Creating Oracle WebLogic Tuxedo Connector Conversational Clients and Servers
Note: For more information on conversational communications for Oracle Tuxedo, see "Writing Conversational Clients and Servers" in Programming a Tuxedo ATMI Application in C at |
Oracle WebLogic Tuxedo Connector supports Oracle Tuxedo conversations as a method to exchange messages between Oracle WebLogic Server and Oracle Tuxedo applications. In this form of communication, a virtual connection is maintained between the client and the server and each side maintains information about the state of the conversation. The process that opens a connection and starts a conversation is the originator of the conversation. The process with control of the connection is the initiator; the process without control is called the subordinate. The connection remains active until an event occurs to terminate it.
During conversational communication, a half-duplex connection is established between the initiator and the subordinate. Control of the connection is passed between the initiator and the subordinate. The process that has control can send messages (the initiator); the process that does not have control can only receive messages (the subordinate).
Oracle WebLogic Tuxedo Connector JATMI conversations have the following characteristics:
Data is passed using TypedBuffers. The type and sub-type of the data must match one of the types and sub-types recognized by the service.
The logical connection between the conversational client and the conversational server remains active until it is terminated.
Any number of messages can be transmitted across a connection between a conversational client and the conversational server.
A Oracle WebLogic Tuxedo Connector conversational client initiates a request for service using tpconnect rather than a tpcall or tpacall.
Oracle WebLogic Tuxedo Connector conversational clients and servers use the JATMI primitives tpsend to send data and tprecv to receive data.
A conversational client only sends service requests to a conversational server.
Conversational servers are prohibited from making calls to tpforward
.
Use the following Oracle WebLogic Tuxedo Connector primitives when creating conversational clients and servers that communicate between Oracle WebLogic Server and Oracle Tuxedo:
Table 6-1 Oracle WebLogic Tuxedo Connector Conversational Client Primitives
Name | Operation |
---|---|
tpconnect |
Use to establish a connection to an Oracle Tuxedo conversational service. |
tpdiscon |
Use to abort a connection and generate a TPEV_DISCONIMM event. |
tprecv |
Use to receive data across an open connection from an Oracle Tuxedo application. |
tpsend |
Use to send data across a open connection to an Oracle Tuxedo application. |
The following sections provide information on how to create conversational clients and servers.
Follow the steps outlined in Chapter 2, "Developing Oracle WebLogic Tuxedo Connector Client EJBs" to create Oracle WebLogic Tuxedo Connector conversational clients. The following section provide information on how to use tpconnect to open a connection and start a conversation.
A Oracle WebLogic Tuxedo Connector conversational client must establish a connection to the Oracle Tuxedo conversational service. Use the JATMI primitive tpconnect to open a connection and start a conversation. A successful call returns an object that can be used to send and receive data for a conversation.
The following table describes tpconnect
parameters:
Table 6-2 Oracle WebLogic Tuxedo Connector JATMI tpconnect Parameters
Parameter | Description |
---|---|
svc
|
Character pointer to a conversational service name. If you do not specify a |
data
|
Pointer to the data buffer. When establishing a connection, you can send data simultaneously by setting the |
flags
|
Use flags or combinations of flags as required by your application needs. Valid flag values are: TPSENDONLY: specifies that the control is being retained by the originator. The called service is subordinate and can only receive data. Do not use in combination with TPRECVONLY: specifies that control is being passed to the called service.The originator becomes subordinate and can only receive data. Do not use in combination with TPNOTRAN: specifies that when TPNOBLOCK: specifies that a request is not sent if a blocking condition exists. If TPNOTIME: specifies that the originator will block indefinitely and is immune to blocking timeouts. If the originator is in transaction mode, the call is subject to transaction timeouts. |
The following provides a code example to use tpconnect to start a conversation:
Example 6-1 Example Conversation Code
. . . Context ctx; Conversation myConv; TuxedoConnection myTux; TuxedoConnectionFactory tcf; . . . ctx = new InitialContext(); tcf = (TuxedoConnectionFactory) ctx.lookup ("tuxedo.services.TuxedoConnection"); myTux = tcf.getTuxedoConnection(); flags =ApplicationToMonitorInterface.TPSENDONLY; myConv = myTux.tpconnect("CONNECT_SVC",null,flags); . . .
Follow the steps outlined in Chapter 3, "Developing Oracle WebLogic Tuxedo Connector Service EJBs," to create Oracle WebLogic Tuxedo Connector conversational servers.
Once a conversational connection is established between a Oracle WebLogic Server application and an Oracle Tuxedo application, the communication between the initiator (sends message) and subordinate (receives message) is accomplished using send and receive calls. The following sections describe how Oracle WebLogic Tuxedo Connector applications use the JATMI primitives tpsend and tprecv:
Use the JATMI primitive tpsend to send a message to an Oracle Tuxedo application.
The following table describes tpsend
parameters:
Table 6-3 Oracle WebLogic Tuxedo Connector JATMI tpconnect Parameters
Parameter | Description |
---|---|
data
|
Pointer to the buffer containing the data sent with this conversation. |
flags |
The flag can be one of the following: TPRECVONLY: specifies that after the initiator's data is sent, the initiator gives up control of the connection. The initiator becomes subordinate and can only receive data. TPNOBLOCK: specifies that the request is not sent if a blocking condition exists. If TPNOTIME: specifies that an initiator is willing to block indefinitely and is immune from blocking timeouts. The call is subject to transaction timeouts. |
Use the JATMI primitive tprecv to receive messages from an Oracle Tuxedo application.
The following table describes tprecv
parameters:
Table 6-4 Oracle WebLogic Tuxedo Connector JATMI tpconnect Parameters
Parameter | Description |
---|---|
flags |
The flag can be one of the following: TPNOBLOCK: specifies that TPNOTIME: specifies that A flag value of 0 specifies that the initiator blocks until the condition subsides or a timeout occurs. |
A conversation between Oracle WebLogic Server and Oracle Tuxedo ends when the server process successfully completes its tasks. The following sections describe how a conversation ends:
An Oracle WebLogic Server conversational server ends a conversation by a successful call to return
. A TPEV_SVCSUCC event is sent to the Oracle Tuxedo client that originated connection to indicate that the service finished successfully. The connection is then disconnected in an orderly manner.
An Oracle Tuxedo conversational server ends a conversation by a successful call to tpreturn
. A TPEV_SVCSUCC event is sent to the Oracle WebLogic Tuxedo Connector client that originated connection to indicate that the service finished successfully. The connection is then disconnected in an orderly manner.
The order in which an conversation ends is important to gracefully end hierarchal conversations.
Assume there are two active connections: A-B and B-C. If B is a Oracle WebLogic Tuxedo Connector application in control of both connections, a call to return
has the following effect: the call fails and a TPEV_SVCERR event is posted on all open connections, and the connections are closed in a disorderly manner.
In order to terminate both connections in an orderly manner, the application must execute the following sequence:
B calls tpsend with TPRECVONLY to transfer control of the B-C connection to the Oracle Tuxedo application C.
C calls departure
with rval
set to TPSUCCESS
, TPFAIL
, or TPEXIT
.
B calls return
and posts an event (TPEV_SVCSUCC or TPEV_SVCFAIL) for A.
Conversational services can make request/response calls. Therefore, in the preceding example, the calls from B to C may be executed using tpacall() or tpcall() instead of tpconnect. Conversational services are not permitted to make calls to tpforward
.
Oracle WebLogic Server conversational clients or servers execute a disorderly disconnect is through a call to tpdiscon. This is the equivalent of "pulling the plug" on a connection.
A call to tpdiscon
:
Immediately tears down the connection and generates a TPEV_DISCONIMM at the other end of the connection. Any data that has not yet reached its destination may be lost. If the conversation is part of a transaction, the transaction must be rolled back.
Can only be called by the initiator of the conversation.
Oracle WebLogic Tuxedo Connector JATMI uses five events to manage conversational communication. The following table lists the events, the functions for which they are returned, and a detailed description of each.
Table 6-5 Oracle WebLogic Tuxedo Connector Conversational Communication Events
Event | Received by | Description |
---|---|---|
Tuxedo |
Control of the connection has passed; this Oracle Tuxedo process can now call | |
JATMI |
Control of the connection has passed; this JATMI process can now call | |
Tuxedo |
The connection has been torn down and no further communication is possible. The JATMI | |
JATMI |
The connection has been torn down and no further communication is possible. The Oracle Tuxedo | |
Tuxedo |
Received by the originator of the connection indicating that the subordinate program issued a | |
Tuxedo |
Received by the originator of the connection indicating that the subordinate program issued a successful | |
Tuxedo |
Received by the originator of the connection, indicating that the subordinate service finished successfully; that is, | |
JATMI |
Received by the originator of the connection, indicating that the subordinate service finished successfully; that is, | |
Tuxedo |
Received by the originator of the connection indicating that the subordinate program issued a | |
Tuxedo |
Received by the originator of the connection indicating that the subordinate program finished unsuccessfully. The service completed with status of TPFAIL or TPEXIT. |
Use the following guidelines while in conversation mode to insure successful completion of a conversation:
Use the JATMI conversational primitives as defined in the Oracle WebLogic Tuxedo Connector Conversation interface and ApplicationToMonitorInterface interface.
Always use a flag.
Only use flags defined in the Oracle WebLogic Tuxedo Connector JATMI.
Oracle WebLogic Tuxedo Connector does not have a parameter that can be used to limit the number of simultaneous conversations to prevent overloading the Oracle WebLogic Server network.
If Oracle Tuxedo exceeds the maximum number of possible conversations (defined by the MAXCONV
parameter), TPEV_DISCONIMM is the expected Oracle WebLogic Tuxedo Connector exception value.
A tprecv to an unauthorized Oracle Tuxedo service results in a TPEV_DISCONIMM exception value.
If a Oracle WebLogic Tuxedo Connector client is connected to an Oracle Tuxedo conversational service which does tpforward
to another conversational service, TPEV_DISCONIMM is the expected Oracle WebLogic Tuxedo Connector exception value.
Conversations may be initiated within a transaction. Start the conversation as part of the program statements in transaction mode. For more information on transactions, see Chapter 5, "Oracle WebLogic Tuxedo Connector JATMI Transactions."
If an Oracle WebLogic Tuxedo Connector remote domain experiences a TPENOENT, the remote domain will send back a disconnect event message and be caught on the Oracle WebLogic Tuxedo Connector application tprecv as a TPEV_DISCONIMM exception.
This preface describes the document accessibility features and conventions used in this guide—Developing Oracle WebLogic Tuxedo Connector Applications for Oracle WebLogic Server.
For information about Oracle's commitment to accessibility, visit the Oracle Accessibility Program website at http://www.oracle.com/pls/topic/lookup?ctx=acc&id=docacc
.
Access to Oracle Support
Oracle customers have access to electronic support through My Oracle Support. For information, visit http://www.oracle.com/pls/topic/lookup?ctx=acc&id=info
or visit http://www.oracle.com/pls/topic/lookup?ctx=acc&id=trs
if you are hearing impaired.
The following text conventions are used in this document:
Convention | Meaning |
---|---|
boldface |
Boldface type indicates graphical user interface elements associated with an action, or terms defined in text or the glossary. |
italic |
Italic type indicates book titles, emphasis, or placeholder variables for which you supply particular values. |
|
Monospace type indicates commands within a paragraph, URLs, code in examples, text that appears on the screen, or text that you enter. |
This chapter describes how to modify applications to use Oracle WebLogic Tuxedo Connector to support interoperability between Oracle WebLogic Server and Oracle Tuxedo CORBA objects.
This chapter includes the following sections:
How to Develop Oracle WebLogic Tuxedo Connector Client Beans using the CORBA Java API
How to Develop RMI/IIOP Applications for the Oracle WebLogic Tuxedo Connector
How to Manage Transactions for Oracle Tuxedo CORBA Applications
Note: You will need to perform some administration tasks to configure the Oracle WebLogic Tuxedo Connector for CORBA interoperability. For information on how to administer the Oracle WebLogic Tuxedo Connector for CORBA interoperability, see "Administration of Corba Applications" in Administering WebLogic Tuxedo Connector for Oracle WebLogic Server. For information on how to develop Oracle Tuxedo CORBA applications, see CORBA Programming at |
The Oracle WebLogic Tuxedo Connector enables objects (such as EJBs or RMI objects) to invoke upon CORBA objects deployed in Oracle Tuxedo using the CORBA Java API (Outbound). Oracle WebLogic Tuxedo Connector implements a WTC ORB which uses Oracle WebLogic Server RMI-IIOP runtime and CORBA support. This enhancement provides the following features:
Support of out and inout parameters
Support for a call a CORBA service from Oracle WebLogic Server using transactions and security.
Support for an ORB hosted in JNDI rather than an instance of the JDK ORB used in previous releases.
A wrapper is provided to allow users with legacy applications to use the new ORB without modifying their existing applications. Oracle recommends that users migrate to the new method of looking up the ORB in JNDI instead of doing:
ORB orb = ORB.init(args, Prop);
To use CORBA Java API, you must use the WTC ORB. Use one of the following methods to obtain an ORB in your Bean:
Properties Prop; Prop = new Properties(); Prop.put("org.omg.CORBA.ORBClass","weblogic.wtc.corba.ORB"); ORB orb = ORB.init(new String[0], Prop);
or
ORB orb = (ORB)(new InitialContext().lookup("java:comp/ORB"));
or
ORB orb = ORB.init();
You can use either of the following methods to reference objects deployed in Oracle Tuxedo:
The Oracle WebLogic Tuxedo Connector uses the CosNaming service to get a reference to an object in the remote Oracle Tuxedo CORBA domain. This is accomplished by using a corbaloc:tgiop
or corbaname:tgiop
object reference. The following statements use the CosNaming service to get a reference to an Oracle Tuxedo CORBA Object:
// Get the simple factory.
org.omg.CORBA.Object simple_fact_oref =
orb.string_to_object("corbaname:tgiop:simpapp#simple_factory");
Where:
simpapp
is the domain id of the Oracle Tuxedo domain specified in the Oracle Tuxedo UBB.
simple_factory
is the name that the object reference was bound to in the Oracle Tuxedo CORBA CosNaming server.
Note: For an example on how to develop client beans for outbound Oracle Tuxedo CORBA objects, see the The following |
Example 4-1 Example Service Application
. . . public String Toupper(String toConvert) throws RemoteException { log("toupper called, converting " + toConvert); try { // Initialize the ORB. String args[] = null; Properties Prop; Prop = new Properties(); Prop.put("org.omg.CORBA.ORBClass", "weblogic.wtc.corba.ORB"); ORB orb = (ORB) new InitialContext().lookup("java:comp/ORB"); // Get the simple factory. org.omg.CORBA.Object simple_fact_oref = orb.string_to_object("corbaname:tgiop:simpapp#simple_factory"); //Narrow the simple factory. SimpleFactory simple_factory_ref = SimpleFactoryHelper.narrow(simple_fact_oref); // Find the simple object. Simple simple = simple_factory_ref.find_simple(); // Convert the string to upper case. org.omg.CORBA.StringHolder buf = new org.omg.CORBA.StringHolder(toConvert); simple.to_upper(buf); return buf.value; } catch (Exception e) { throw new RemoteException("Can't call TUXEDO CORBA server: " +e); } } . . .
Oracle WebLogic Tuxedo Connector provides support for FactoryFinder objects using the find_one_factory_by_id method. This is accomplished by using a corbaloc:tgiop
or corbaname:tgiop
object reference. Use the following method to obtain the FactoryFinder object using the ORB:
// String to Object. org.omg.CORBA.Object fact_finder_oref = orb.string_to_object("corbaloc:tgiop:simpapp/FactoryFinder"); // Narrow the factory finder. FactoryFinder fact_finder_ref = FactoryFinderHelper.narrow(fact_finder_oref); // Use the factory finder to find the simple factory. org.omg.CORBA.Object simple_fact_oref = fact_finder_ref.find_one_factory_by_id(SimpleFactoryHelper.id());
Where:
simpapp
is the domain id of the Oracle Tuxedo domain specified in the Oracle Tuxedo UBB.
FactoryFinder
is the name that the object reference was bound to in the Oracle Tuxedo CORBA server.
WLEC is no longer available or supported in Oracle WebLogic Server. WLEC users should migrate their applications to Oracle WebLogic Tuxedo Connector. For more information, see WebLogic Tuxedo Connector Migration Guide for WLEC to Oracle WebLogic Server.
The following code provides an example of how to call the WTC ORB and get an object reference using FactoryFinder.
Example 4-2 Example FactoryFinder Code
. . . public ConverterResult convert (String changeCase, String mixed) throws ProcessingErrorException { String result; try { // Initialize the ORB. String args[] = null; Properties Prop; Prop = new Properties(); Prop.put("org.omg.CORBA.ORBClass","weblogic.wtc.corba.ORB"); ORB orb = (ORB)new InitialContext().lookup("java:comp/ORB"); org.omg.CORBA.Object fact_finder_oref = orb.string_to_object("corbaloc:tgiop:simpapp/FactoryFinder"); // Narrow the factory finder. FactoryFinder fact_finder_ref = FactoryFinderHelper.narrow(fact_finder_oref); // find_one_factory_by_id org.omg.CORBA.Object simple_fact_oref = fact_finder_ref.find_one_factory_by_id(FactoryFinderHelper.id()); // Narrow the simple factory. SimpleFactory simple_factory_ref = SimpleFactoryHelper.narrow(simple_fact_oref); // Find the simple object. Simple simple = simple_factory_ref.find_simple(); if (changeCase.equals("UPPER")) { // Invoke the to_upper opeation on M3 Simple object org.omg.CORBA.StringHolder buf = new org.omg.CORBA.StringHolder(mixed); simple.to_upper(buf); result = buf.value; } else { result = simple.to_lower(mixed); } } catch (org.omg.CORBA.SystemException e) {e.printStackTrace(); throw new ProcessingErrorException("Converter error: Corba system exception: " + e); } catch (Exception e) { e.printStackTrace(); throw new ProcessingErrorException("Converter error: " + e); } return new ConverterResult(result); } . . .
Note: For more information on how to develop RMI/IIOP applications, see Developing RMI Applications for Oracle WebLogic Server. |
RMI over IIOP (Internet Inter-ORB Protocol) extends RMI so that Java programs can interact with Common Object Request Broker Architecture (CORBA) clients and execute CORBA objects. The Oracle WebLogic Tuxedo Connector:
Enables Oracle Tuxedo CORBA objects to invoke upon EJBs deployed in Oracle WebLogic Server (Inbound).
Enables objects (such as EJBs or RMI objects) to invoke upon CORBA objects deployed in Oracle Tuxedo (Outbound).
The following sections provide information on how to modify RMI/IIOP applications to use the Oracle WebLogic Tuxedo Connector to interoperate with Oracle Tuxedo CORBA applications:
How to Modify Inbound RMI/IIOP Applications to use the Oracle WebLogic Tuxedo Connector
How to Develop Outbound RMI/IIOP Applications to use the Oracle WebLogic Tuxedo Connector
A client must pass the correct name to which the Oracle WebLogic Server's name service has been bound to the COSNaming Service.
The following code provides an example for obtaining a naming context. "WLS" is the bind name specified in the cnsbind
command detailed in "Administration of Corba Applications" in Administering WebLogic Tuxedo Connector for Oracle WebLogic Server.
Example 4-3 Example Code to Obtain a Naming Context
. . . // obtain a naming context TP::userlog("Narrowing to a naming context"); CosNaming::NamingContext_var context = CosNaming::NamingContext::_narrow(o); CosNaming::Name name; name.length(1); name[0].id = CORBA::string_dup("WLS"); name[0].kind = CORBA::string_dup(""); . . .
An EJB must use a FederationURL to obtain the initial context used to access a remote Oracle Tuxedo CORBA object. Use the following sections to modify outbound RMI/IIOP applications to use the Oracle WebLogic Tuxedo Connector:
The following code provides an example of how to configure an ejb-jar.xml
file to pass a FederationURL format to the EJB at run-time.
Example 4-4 Example ejb-jar.xml File Passing a FederationURL to an EJB
<?xml version="1.0"?> <!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN' 'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'> <ejb-jar> <small-icon>images/green-cube.gif</small-icon> <enterprise-beans> <session> <small-icon>images/orange-cube.gif</small-icon> <ejb-name>IIOPStatelessSession</ejb-name> <home>examples.iiop.ejb.stateless.TraderHome</home> <remote>examples.iiop.ejb.stateless.Trader</remote> <ejb-class>examples.iiop.ejb.stateless.TraderBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> <env-entry> <env-entry-name>foreignOrb</env-entry-name> <env-entry-type>java.lang.String </env-entry-type> <env-entry-value>corbaloc:tgiop:simpapp</env-entry-value> </env-entry> <env-entry> <env-entry-name>WEBL</env-entry-name> <env-entry-type>java.lang.Double </env-entry-type> <env-entry-value>10.0</env-entry-value> </env-entry> <env-entry> <env-entry-name>INTL</env-entry-name> <env-entry-type>java.lang.Double </env-entry-type> <env-entry-value>15.0</env-entry-value> </env-entry> <env-entry> <env-entry-name>tradeLimit</env-entry-name> <env-entry-type>java.lang.Integer </env-entry-type> <env-entry-value>500</env-entry-value> </env-entry> </session> </enterprise-beans> <assembly-descriptor> <container-transaction> <method> <ejb-name>IIOPStatelessSession</ejb-name> <method-intf>Remote</method-intf> <method-name>*</method-name> </method> <trans-attribute>NotSupported</trans-attribute> </container-transaction> </assembly-descriptor> </ejb-jar>
To pass the FederationURL to the EJB at run-time, add an env-entry
for the EJB in the ejb-jar.xml
file for your application. You must assign the following env-entry
sub-elements:
The env-entry-name
element is used to specify the name of the variable used to pass the value in the env-entry-value
element to the EJB. The example code shown in Example 4-4 specifies the env-entry-name
as foreignOrb
.
The env-entry-type
element is used to specify the data type (example String, Integer, Double) of the env-entry-value
element that is passed to the EJB. The example code shown in Example 4-4 specifies that the foreignOrb
variable passes String
data to the EJB.
The env-entry-value
element is used to specify the data that is passed to the EJB. The example code shown in Example 4-4 specifies that the foreignOrb
variable passes the following FederationURL format to the EJB:
corbaloc:tgiop:simpapp
Where simpapp
is the DOMAINID
of the Oracle Tuxedo remote service specified in the Oracle Tuxedo UBB.
This section provides information on how to use the FederationURL to obtain the InitialContext used to access a remote Oracle Tuxedo CORBA object.
The following code provides an example of how to use FederationURL to get an InitialContext.
Example 4-5 Example TraderBean.java Code to get InitialContext
. . . public void createRemote() throws CreateException { log("createRemote() called"); try { InitialContext ic = new InitialContext(); // Lookup a EJB-like CORBA server in a remote CORBA domain Hashtable env = new Hashtable(); env.put(Context.PROVIDER_URL, (String) ic.lookup("java:/comp/env/foreignOrb") + "/NameService"); InitialContext cos = new InitialContext(env); TraderHome thome = (TraderHome)PortableRemoteObject.narrow( cos.lookup("TraderHome_iiop"),TraderHome.class); remoteTrader = thome.create(); } catch (NamingException ne) { throw new CreateException("Failed to find value "+ne); } catch (RemoteException re) { throw new CreateException("Error creating remote ejb "+re); } } . . .
Use the following steps to use FederationURL to obtain an InitialContext for a remote Oracle Tuxedo CORBA object:
Retrieve the FederationURL format defined in the ejb-jar.xml
file.
Example:
"ic.lookup("java:/comp/env/foreignOrb")
The example code shown in Example 4-4 specifies that the foreignOrb
variable passes the following FederationURL format to the EJB:
corbaloc:tgiop:simpapp
Concatenate the FederationURL format with "/NameService
" to form the FederationURL.
Example:
"ic.lookup("java:/comp/env/foreignOrb") + "/NameService"
The resulting FederationURL is:
corbaloc:tgiop:simpapp/NameService
Get the InitialContext.
Example:
env.put(Context.PROVIDER_URL, (String) ic.lookup("java:/comp/env/foreignOrb") + "/NameService"); InitialContext cos = new InitialContext(env);
The result is the InitialContext of the Oracle Tuxedo CORBA object.
This section provides information on the syntax for the following FederationURL formats:
The CORBA URL
syntax is described in the CORBA specification. For more information, see the OMG Web Site at http://www.omg.org/
.
The corbaloc:tgiop
form is specific to the Oracle tgiop protocol.
This section provides the syntax for corbaloc URL format:
<corbaloc> = "corbaloc:tgiop":[<version>] <domain>["/"<key_string>] <version> = <major> "." <minor> "@" | empty_string <domain> = TUXEDO CORBA domain name <major> = number <minor> = number <key_string> = <string> | empty_string
This section provides examples on how to use corbaloc:tgiop
.
orb.string_to_object("corbaloc:tgiop:simpapp/NameService"); orb.string_to_object("corbaloc:tgiop:simpapp/FactoryFinder"); orb.string_to_object("corbaloc:tgiop:simpapp/InterfaceRepository"); orb.string_to_object("corbaloc:tgiop:simpapp/Tobj_SimpleEventsService"); orb.string_to_object("corbaloc:tgiop:simpapp/NotificationService"); orb.string_to_object("corbaloc:tgiop:1.1@simpapp/NotificationService);
You can also use the -ORBInitRef
option to orb.init
and resolve_initial_reference
.
Given the following -ORBInitRef
definitions:
-ORBInitRef FactoryFinder=corbaloc:tgiop:simp/FactoryFinder -ORBInitRef InterfaceRepository=corbaloc:tgiop:simp/InterfaceRepository -ORBInitRef Tobj_SimpleEventService=corbaloc:tgiop:simp/Tobj_SimpleEventsService -ORBInitRef NotificationService=corbaloc:tgiop:simp/NotificationService
then:
orb.resolve_initial_references("NameService"); orb.resolve_initial_references("FactoryFinder"); orb.resolve_initial_references("InterfaceRepository"); orb.resolve_initial_references("Tobj_SimpleEventService"); orb.resolve_initial_references("NotificationService");
You can also use the corbaname
format instead of the corbaloc
format.
Given the following -ORBInitRef
definition:
-ORBInitRef NameService=corbaloc:tgiop:simpapp/NameService
then:
orb.string_to_object("corbaname:rir:#simple_factory"); orb.string_to_object("corbaname:tgiop:simpapp#simple_factory"); orb.string_to_object("corbaname:tgiop:1.1@simpapp#simple_factory"); orb.string_to_object("corbaname:tgiop:simpapp#simple/simple_factory");
Note: For more information on managing transactions in Oracle Tuxedo CORBA applications, see "Overview of Transactions in Tuxedo CORBA Applications" in Using CORBA Transactions at |
The Oracle WebLogic Tuxedo Connector uses the Java Transaction API (JTA) to manage transactions with Oracle Tuxedo Corba Applications. For more detailed information, see:
"Transaction Design and Management Options" in Developing Enterprise JavaBeans, Version 2.1, for Oracle WebLogic Server
This chapter describes how to create custom AppKey generator plug-ins.
This chapter includes the following sections:
Note: You cannot customize Oracle Tuxedo AAA tokens. |
Create your custom Java plug-in using the AppKey and UserRec interfaces. You can provide any required initialization parameters or a property file using the param
parameter of the init
method.
Compile your plug-in. Example:
javac exampleAppKey.java
Update your CLASSPATH to include the path to your compiled plug-in. Example:
export CLASSPATH=$CLASSPATH:/home/mywork
Start your server.
Configure your WTC server to use the Custom Plug-in. For more information, see the "Custom Plug-in" in Administering WebLogic Tuxedo Connector for Oracle WebLogic Server.
The exampleAppKey.java
file is an example of a custom plug-in. It utilizes a tpusrfile
file as the database to store the AppKey.
Example 9-1 exampleAppKey.Java Custom Plug-In
import java.io.*; import java.lang.*; import java.util.*; import java.security.Principal; import weblogic.wtc.jatmi.AppKey; import weblogic.wtc.jatmi.UserRec; import weblogic.wtc.jatmi.DefaultUserRec; import weblogic.wtc.jatmi.TPException; import weblogic.security.acl.internal.AuthenticatedSubject; import weblogic.security.WLSPrincipals; /** * @author Copyright (c) 2002 by BEA Systems, Inc. All Rights Reserved. */ /** * @exclude * Sample AppKey plug-in using TPUSRFILE as the database for APPKEY. * It is installed through "Custom" option. * The syntax for option custom plug parameter input contains the full * pathname to the <tpusrfile> * * @author BEA Systems, Inc. */ public class exampleAppKey implements AppKey { private String anon_user = null; private String tpusrfile = null; private File myfile; private HashMap userMap; private long l_time; private int dfltAppkey; private boolean allowAnon; private final static int USRIDX = 0; private final static int PWDIDX = 1; private final static int UIDIDX = 2; private final static int GIDIDX = 3; private final static int CLTIDX = 4; private final static byte[] tpsysadm_string = { (byte)'t', (byte)'p', (byte)'s', (byte)'y', (byte)'s', (byte)'a', (byte)'d', (byte)'m' }; private final static byte[] tpsysop_string = { (byte)'t', (byte)'p', (byte)'s', (byte)'y', (byte)'s', (byte)'o', (byte)'p' }; public void init(String param, boolean anonAllowed, int dfltAppKey) throws TPException { if (param == null) { System.out.println("Error: tpusrAppKey.init@param == null"); throw new TPException(TPException.TPESYSTEM, "Invalid input parameter"); } // get the tpusrfile name parseParam(param); myfile = new File(tpusrfile); if (myfile.exists() != true) { System.out.println("Error: exampleAppKey.init@file \"" + param + "\" does not exist"); throw new TPException(TPException.TPESYSTEM, "Failed to find TPUSR file"); } if (myfile.isFile() != true) { System.out.println("Error: exampleAppKey.init@the specified name \"" + param + "\" is not a file"); throw new TPException(TPException.TPESYSTEM, "Invalid TPUSR file"); } if (myfile.canRead() != true) { System.out.println("Error: exampleAppKey.init@file \"" + param + "\" is not readable"); throw new TPException(TPException.TPESYSTEM, "Bad TPUSR file permission"); } userMap = new HashMap(); // create the cache if (createCache(tpusrfile) == -1) { System.out.println("Error: exampleAppkey.init@fail to create user cache"); throw new TPException(TPException.TPESYSTEM, "fail to create user cache"); } l_time = myfile.lastModified(); anon_user = weblogic.security.WLSPrincipals.getAnonymousUsername(); allowAnon = anonAllowed; dfltAppkey = dfltAppKey; System.out.println("exampleAppKey installed!"); return; } public void uninit() throws TPException { if (userMap != null) { userMap.clear(); } return; } public UserRec getTuxedoUserRecord(AuthenticatedSubject subj) { Object[] obj = subj.getPrincipals().toArray(); if (obj == null || obj.length == 0) { // a subject without principals is an anonymous user if (allowAnon) { return new DefaultUserRec(anon_user, dfltAppkey); } System.out.println("Error: exampleAppKey. getTuxedoUserRecord@return " + "anonymous user not allowed"); return null; } // looping through all Principal names if necessary to get first user // name defined in tpuser file Principal user; String username; int key; UserRec rec; for (int i = 0; i < obj.length; i++) { user = (Principal)obj[i]; username = user.getName(); if (username.equals(anon_user)) { return new DefaultUserRec(anon_user, dfltAppkey); } if ((rec = (UserRec)userMap.get(username)) != null) { return rec; } } System.out.println("WARN: exampleAppKey.getTuxedoUserRecord@return " + "null UserRec"); return null; } private int createCache(String fname) { FileInputStream fin; byte[] line; try { fin = new FileInputStream(fname); while ((line = readOneLine(fin)) != null) { DefaultUserRec newUser = parseOneLine(line); if (newUser != null) { userMap.put(newUser.getRemoteUserName(), newUser); } } fin.close(); } catch (FileNotFoundException fnfe) { System.out.println("Error: exampleAppKey.createCache@reason: " + fnfe); return -1; } catch (SecurityException se) { System.out.println("Error: exampleAppKey.createCache@reason: " + se); return -1; } catch (IOException ioe) { System.out.println("Error: exampleAppKey.createCache@reason: " + ioe); return -1; } catch (Exception e) { System.out.println("Error: exampleAppKey.createCache@reason: " + e); return -1; } return 0; } private byte[] readOneLine(FileInputStream fh) { int len = 80; byte[] line = new byte[len]; int inp = -1; int idx = 0; try { while ((inp = fh.read()) != -1) { if (idx == 0 && (inp == '\n' || inp == '\0')) { continue; } if (inp == '\n') { break; } if (idx == (len - 1)) { byte[] tmp = new byte[len + 80]; System.arraycopy(line, 0, tmp, 0, len); line = tmp; len += 80; } line[idx] = (byte)inp; idx++; } } catch (Exception e) { System.out.println("Error: exampleAppKey.readOneLine@reason: " + e); return null; } if (inp == -1 && idx == 0) { return null; } byte[] tmp = new byte[idx]; System.arraycopy(line, 0, tmp, 0, idx); return tmp; } private DefaultUserRec parseOneLine(byte[] line) { String name; int key = 0; DefaultUserRec usr; int firstCharacter; int i; int sidx; int fldlen; int fn; byte[] buid = null; byte[] bgid = null; byte[] clt = null; byte[] uname = null; firstCharacter = (int)line[0]; if (firstCharacter == '#' || firstCharacter == '\n' || firstCharacter == '!' || firstCharacter == '\0' || firstCharacter == '\r') { return null; } fldlen = 0; sidx = 0; for (i = 0, fn = 0; i < line.length && fn <= CLTIDX; i++) { if (line[i] == (byte)':') { switch (fn) { case USRIDX: uname = new byte[fldlen]; System.arraycopy(line, sidx, uname, 0, fldlen); break; case UIDIDX: buid = new byte[fldlen]; System.arraycopy(line, sidx, buid, 0, fldlen); break; case GIDIDX: bgid = new byte[fldlen]; System.arraycopy(line, sidx, bgid, 0, fldlen); break; case CLTIDX: if (line[sidx ] == (byte)'T' && line[sidx+1] == (byte)'P' && line[sidx+2] == (byte)'C' && line[sidx+3] == (byte)'L' && line[sidx+4] == (byte)'T' && line[sidx+5] == (byte)'N' && line[sidx+6] == (byte)'M' && line[sidx+7] == (byte)',') { sidx += 8; fldlen -= 8; } if (fldlen > 0) { clt = new byte[fldlen]; System.arraycopy(line, sidx, clt, 0, fldlen); } break; default: break; } // end of switch fn++; fldlen = 0; sidx = i + 1; } // end of if else { fldlen++; } } // try to tolerate incomplete line if (fn <= CLTIDX && fldlen > 0) { switch (fn) { case USRIDX: uname = new byte[fldlen]; System.arraycopy(line, sidx, uname, 0, fldlen); break; case UIDIDX: buid = new byte[fldlen]; System.arraycopy(line, sidx, buid, 0, fldlen); break; case GIDIDX: bgid = new byte[fldlen]; System.arraycopy(line, sidx, bgid, 0, fldlen); break; case CLTIDX: if (line[sidx ] == (byte)'T' && line[sidx+1] == (byte)'P' && line[sidx+2] == (byte)'C' && line[sidx+3] == (byte)'L' && line[sidx+4] == (byte)'T' && line[sidx+5] == (byte)'N' && line[sidx+6] == (byte)'M' && line[sidx+7] == (byte)',') { sidx += 8; fldlen -= 8; } clt = new byte[fldlen]; System.arraycopy(line, sidx, clt, 0, fldlen); break; } } if (uname == null || buid == null || bgid == null) { return null; } name = new String(uname); if (clt != null) { if (Arrays.equals(tpsysadm_string, clt) == true) { key = TPSYSADM_KEY; } else if (Arrays.equals(tpsysop_string, clt) == true) { key = TPSYSOP_KEY; } } if (key == 0) { Integer u_val; Integer g_val; int uid = 0; int gid = 0; try { u_val = new Integer(new String(buid)); g_val = new Integer(new String(bgid)); uid = u_val.intValue(); gid = g_val.intValue(); uid &= UIDMASK; gid &= GIDMASK; key = uid | (gid << GIDSHIFT); } catch (NumberFormatException nfe) { System.out.println("Error: exampleAppKey.readOneLine@reason: " + nfe); return null; } } return new DefaultUserRec(name, key); } private void parseParam(String param) { String str; // trim the input tpusrfile = param.trim(); return; } }
This chapter describes how to define and manage Oracle WebLogic Tuxedo Connector global transactions using the Java Transaction API (JTA).
This chapter includes the following sections:
A global transaction is a transaction that allows work involving more than one resource manager and spanning more than one physical site to be treated as one logical unit. A global transaction is always treated as a specific sequence of operations that is characterized by the following four properties:
Atomicity: All portions either succeed or have no effect.
Consistency: Operations are performed that correctly transform the resources from one consistent state to another.
Isolation: Intermediate results are not accessible to other transactions, although other processes in the same transaction may access the data.
Durability: All effects of a completed sequence cannot be altered by any kind of failure.
Note: For more detailed information, see the JTA API at |
The Oracle WebLogic Tuxedo Connector uses the Java Transaction API (JTA) to manage transactions.
JTA offers three types of transaction interfaces:
Transaction
TransactionManager
UserTransaction
The Transaction
interface allows operations to be performed against a transaction in the target Transaction object. A transaction object is created to correspond to each global transaction created. Use the Transaction
interface to enlist resources, synchronize registration, and perform transaction completion and status query operations.
The TransactionManager
interface allows the application server to communicate to the Transaction Manager for transaction boundaries demarcation on behalf of the application. Use the TransactionManager
interface to communicate to the transaction manager on behalf of container-managed EJB components.
The following table maps the functionality of Oracle Tuxedo transaction primitives to equivalent JTA transaction primitives.
Table 5-1 Mapping Oracle Tuxedo Transaction Primitives to JTA Equivalents
Oracle Tuxedo | Oracle Tuxedo Functionality | JTA Equivalent |
---|---|---|
tpabort |
Use to end a transaction. |
or rollback |
tpcommit |
Use to complete a transaction. |
commit |
tpgetlev |
Use to determine if a service routine is in transaction mode. |
getStatus |
tpbegin |
Use to begin a transaction. |
setTransactionTimeout begin |
Transactions can be defined in either client or server processes. A transaction has three parts: a starting point, the program statements that are in transaction mode, and a termination point.
To explicitly define a transaction, call the begin()
method. The same process that makes the call, the initiator, must also be the one that terminates it by invoking a commit()
, setRollbackOnly()
, or rollback()
. Any service subroutines that are called between the transaction delimiter become part of the current transaction.
Note: Setting |
A transaction is started by a call to begin()
. To specify a time-out value, precede the begin()
statement with a setTransactionTimeout(int seconds)
statement.
To propagate the transaction to Oracle Tuxedo, you must do the following:
Look up a TuxedoConnectionFactory object in the JNDI.
Get a TuxedoConnection object using getTuxedoConnection().
Service routines that are called within the transaction delimiter are part of the current transaction. However, if tpcall() or tpacall() have the flags parameter set to TPNOTRAN, the operations performed by the called service do not become part of that transaction. As a result, services performed by the called process are not affected by the outcome of the current transaction.
A transaction is terminated by a call to commit()
, rollback()
, or setRollbackOnly()
. When commit()
returns successfully, all changes to the resource as a result of the current transaction become permanent. In order for a commit()
to succeed, the following two conditions must be met:
The calling process must be the same one that initiated the transaction with a begin()
The calling process must have no transaction replies outstanding
If either condition is not true, the call fails and an exception is thrown.
setRollbackOnly()
and rollback()
are used to indicate an abnormal condition and to roll back any call descriptors to their original state.
Use setRollbackOnly()
if further processing or cleanup is needed before rolling back the transaction.
Use rollback()
if no further processing or cleanup is required before rolling back the transaction.
You must follow certain rules while in transaction mode to insure successful completion of a transaction. The basic rules of etiquette that must be observed while in a transaction mode follow:
You must propagate the transaction to Oracle Tuxedo using a TuxedoConnection object after you initiate a transaction with a begin()
.
tpterm() closes a connection to an object and prevents future operations on this object.
Processes that are participants in the same transaction must require replies for their requests.
Requests requiring no reply can be made only if the flags parameter of tpacall() is set to TPNOREPLY.
A service must retrieve all asynchronous transaction replies before calling commit()
.
The initiator must retrieve all asynchronous transaction replies before calling begin()
.
The asynchronous replies that must be retrieved include those that are expected from non-participants of the transaction, that is, replies expected for requests made with a tpacall() suppressing the transaction but not the reply.
If a transaction has not timed out but is marked abort-only, further communication should be performed with the TPNOTRAN flag set so that the work done as a result of the communication has lasting effect after the transaction is rolled back.
If a transaction has timed out:
the descriptor for the timed out call becomes stale and any further reference to it will return TPEBADDESC.
further calls to tpgetrply() or tprecv() for any outstanding descriptors will return the global state of transaction time-out by setting tperrono
to TPETIME.
asynchronous calls can be make with the flags parameter of tpacall() set to TPNOREPLY |
TPNOBLOCK |
TPNOTRAN.
Once a transaction has been marked abort-only for reasons other than time-out, a call to tpgetrply() will return whatever represents the local state of the call, that is, it can either return success or an error code that represents the local condition.
Once a descriptor is used with tpgetrply() to retrieve a reply, it becomes invalid and any further reference to it will return TPEBADDESC.
Once a descriptor is used with tpsend() or tprecv() to report an error condition, it becomes invalid and any further reference to it will return TPEV_DISCONIMM.
Once a transaction is aborted, all outstanding transaction call descriptions (made without the TPNOTRAN flag) become stale, and any further reference to them will return TPEBADDESC.
Oracle WebLogic Tuxedo Connector does not guarantee that all calls for a particular transaction Id are routed to a particular server instance when load balancing. Load balancing is performed on a per call basis.
The following provides a code example for a transaction:
Example 5-1 Example Transaction Code
public class TransactionSampleBean implements SessionBean { ..... public int transaction_sample () { int ret = 0; try { javax.naming.Context myContext = new InitialContext(); TransactionManager tm = (javax.transaction.TransactionManager) myContext.lookup("javax.transaction.TransactionManager"); // Begin Transaction tm.begin (); TuxedoConnectionFactory tuxConFactory = (TuxedoConnectionFactory) ctxt.lookup("tuxedo.services.TuxedoConnection"); // You could do a local JDBC/XA-database operation here // which will be part of this transaction. ..... // NOTE 1: Get the Tuxedo Connection only after // you begin the transaction if you want the // Tuxedo call to be part of the transaction! // NOTE 2: If you get the Tuxedo Connection before // the transaction was started, all calls made from // that Tuxedo Connection are out of scope of the // transaction. TuxedoConnection myTux = tuxConFactory.getTuxedoConnection(); // Do a tpcall. This tpcall is part of the transaction. TypedString depositData = new TypedString("somecharacters,5000.00"); Reply depositReply = myTux.tpcall("DEPOSIT", depositData, 0); // You could also do tpcalls which are not part of // transaction (For example, Logging all attempted // operations etc.) by setting the TPNOTRAN Flag! TypedString logData = new TypedString("DEPOSIT:somecharacters,5000.00"); Reply logReply = myTux.tpcall("LOGTRAN", logData, ApplicationToMonitorInterface.TPNOTRAN); // Done with the Tuxedo Connection. Do tpterm. myTux.tpterm (); // Commit Transaction... tm.commit (); // NOTE: The TuxedoConnection object which has been // used in this transaction, can be used after the // transaction only if TPNOTRAN flag is set. } catch (NamingException ne) { System.out.println ("ERROR: Naming Exception looking up JNDI: " + ne); ret = -1; } catch (RollbackException re) { System.out.println("ERROR: TRANSACTION ROLLED BACK: " + re); ret = 0; } catch (TPException te) { System.out.println("ERROR: tpcall failed: TpException: " + te); ret = -1; } catch (Exception e) { log ("ERROR: Exception: " + e); ret = -1; } return ret; }
This chapter describes how to create Oracle WebLogic Tuxedo Connector client EJBs. These client EJBs take user input and send service requests to a server process or outbound object that offers a requested service. Oracle WebLogic Tuxedo Connector JATMI client classes are used to create clients that access services found in Oracle Tuxedo.
This chapter includes the following sections:
Note: For more information on the Oracle WebLogic Tuxedo Connector JATMI, view the Javadocs for WebLogic Classes. The Oracle WebLogic Tuxedo Connector classes are located in the weblogic.wtc.jatmi and weblogic.wtc.gwt packages. |
Oracle Tuxedo and Oracle WebLogic Tuxedo Connector have different approaches to connect to services.
The following section compares how Oracle Tuxedo and Oracle WebLogic Tuxedo Connector join an application:
Oracle Tuxedo uses tpinit()
to join an application.
Oracle WebLogic Tuxedo Connector uses a WTCServer MBean to provide information required to create a path to the Oracle 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 Oracle WebLogic Server is started and a WTCServer MBean is present in the config.xml
file and assigned (targeted) to a server.
Oracle WebLogic Tuxedo Connector uses TuxedoConnectionFactory
to get a TuxedoConnection object and then uses getTuxedoConnection() to make a connection to the Oracle Tuxedo object. The following example shows how a Oracle WebLogic Server application joins an Oracle Tuxedo application using Oracle WebLogic Tuxedo Connector.
Example 2-1 Example Client Code to Join an Oracle 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(); . . .
The following section compares how Oracle Tuxedo and Oracle WebLogic Tuxedo Connector leave an application:
Oracle Tuxedo uses tpterm()
to leave an application.
Oracle WebLogic Tuxedo Connector uses the JATMI primitive tpterm() to close a connection to an Oracle Tuxedo object.
Oracle WebLogic Tuxedo Connector closes the pathway to an Oracle Tuxedo service when a WTCServer MBean is assigned a new target server or the server is shutdown.
A client process uses Java and JATMI primitives to provide the following basic application tasks:
Get an Oracle Tuxedo Object
Perform Message Buffering
Send and Receive Messages
Close a Connection to an Oracle Tuxedo Object
A client may send and receive any number of service requests before leaving the application.
Establish a connection to a remote domain by looking up tuxedo.services.TuxedoConnection
in the JNDI tree to get TuxedoConnectionFactory, and use it to get a TuxedoConnection
object.
Use the following TypedBuffers when sending and receiving messages between your application and Oracle 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. Oracle Tuxedo equivalent: STRING. |
TypedCArray |
Buffer type used when the data is an undefined array of characters (byte array), any of which can be null. Oracle 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. Oracle Tuxedo equivalent: FML. |
TypedFML32 |
Buffer type similar to TypeFML but allows for larger character fields, more fields, and larger overall buffers. Oracle Tuxedo equivalent: FML32. |
TypedXML |
Buffer type used when data is an XML based message. Oracle 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. Oracle Tuxedo equivalent: View |
TypedView32 |
Buffer type similar to View but allows for larger character fields, more fields, and larger overall buffers. Oracle Tuxedo equivalent: View32. |
TypedMBString |
Buffer type used when the data is a wide array of characters to support multi-byte characters. Oracle Tuxedo equivalent: MBSTRING. |
Oracle WebLogic Tuxedo Connector clients support three types of communications with Oracle Tuxedo service applications:
Request/Response Communication
Conversational Communication
Enqueuing and Dequeuing Messages
Note: Oracle WebLogic Tuxedo Connector does not provide a JATMI primitive to support setting the priority of a message request. All messages originating from a Oracle WebLogic Tuxedo Connector client have a message priority of 50. |
Use the following JATMI primitives to request and receive response messages between your Oracle WebLogic Tuxedo Connector client application and Oracle Tuxedo:
Table 2-2 JATMI Primitives
Name | Operation |
---|---|
tpacall |
Use for asynchronous invocations of an Oracle Tuxedo service.This JATMI primitive has two forms:
|
tpcall |
Use for synchronous invocation of an Oracle Tuxedo service. |
tpgetrply |
Use for retrieving replies from deferred synchronous calls to an Oracle Tuxedo service. |
tpcancel |
Use to cancel an outstanding message reply for a call descriptor returned by Note: You can not use |
Use tpcall
to send a request to a service and synchronously await for the reply. The service specified must be advertised by your Oracle Tuxedo application. Logically, tpcall()
has the same functionality as calling tpacall()
and immediately calling tpgetreply()
.
A deferred synchronous tpacall
allows you to send a request to an Oracle 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 an Oracle Tuxedo service and immediately returns from the call. The service specified must be advertised by your Oracle 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.
The asynchronous tpacall
allows you to send a request to an Oracle 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 an Oracle Tuxedo service. The service specified must be advertised by your Oracle 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 |
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.
Note: For more information on Conversational Communication, see Chapter 6, "Oracle WebLogic Tuxedo Connector JATMI Conversations." |
Use the following conversational primitives when creating conversational clients that communicate with Oracle Tuxedo services:
Table 2-3 Oracle WebLogic Tuxedo Connector Conversational Client Primitives
Name | Operation |
---|---|
tpconnect |
Use to establish a connection to an Oracle 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 an Oracle Tuxedo application. |
tpsend |
Use to send data across an open connection to an Oracle Tuxedo application. |
Use the following JATMI primitives to enqueue and dequeue messages between your Oracle WebLogic Tuxedo Connector client application and Oracle Tuxedo:
Use tpterm() to close a connection to an object and prevent future operations on this object.
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.
Example 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()); } . . .