Previous Contents Index DocHome Next |
iPlanet Application Server Enterprise Connector for Tuxedo Developer's Guide |
Chapter 2 Programming for Tuxedo
The iPlanet Application Server Enterprise Connector for Tuxedo is a pre-built Java-based enterprise integration solution. The Tuxedo Enterprise Connector allows access to Tuxedo services from a J2EE compliant application.This chapter describes how to develop Java programs using the Tuxedo Enterprise Connector.
The following topics are covered:
About UIF Data Objects
Mapping Tuxedo Data Types to UIF Data Types
Developing Applications Using the Tuxedo Enterprise Connector
Using Tuxedo Buffers with the Tuxedo Enterprise Connector
Using the STRING Tuxedo Buffer Type
Using the CARRAY Tuxedo Buffer Type
Using the X_OCTET Tuxedo Buffer Type
Using the FML Tuxedo Buffer Type
Using the VIEW Tuxedo Buffer Type
Developing Client-side Transactions
Tuxedo Application Return Code
Developing International Applications
About UIF Data Objects
A UIF data object is a hierarchical data representation object and is somewhat like C/C++ structures. It can contain structures, arrays and lists, and is nested to arbitrary levels. Data objects are self describing and introspectable. Data objects are used to pass information and data across API boundaries between the application and UIF, and between UIF and the enterprise connector.The UIF supports two types of data objects:
Primitive Data Objects: wraps a single primitive value, such as an integer, a null terminated string, or a binary value.
A data object can also have a type object associated with it. This is known as a TypeInfo object and is used internally by UIF during object creation.Complex Data Objects: includes structure, list, and array data objects.
Primitive Data Objects
Figure 2-1 shows a primitive data object which contains a single value of one of the following types:
Figure 2-1    Primitive Data Object ![]()
Integer, float, and double
Integer, float, and double data type objects hold a value whose type corresponds to the Java data type.
Fixed length string and variable length string
Strings correspond to the Java String data type. A fixed length string has a maximum length. A variable length string has no length restriction.
Fixed size byte array and variable size byte array
A fixed size byte array has a maximum size. A variable size byte array has no size restriction.The maximum length of a fixed length string and the maximum size of a fixed size byte array are set when the initial value is specified.
Structure Objects
Figure 2-2 shows a structure object which contains other data objects or primitive values as fields. Each object within the structure object is referred to by a string that represents the field name. Field names have a maximum length of 64 characters. A structure's fields are heterogeneous.
Figure 2-2    Structure Object ![]()
List Objects
Figure 2-3 shows a list object which contains data objects or primitive values as list elements and can be heterogeneous. Each element within a list object is referred to by an integer that specifies its position in the list object.
Figure 2-3    List Object ![]()
Array Objects
Figure 2-4 shows an array object which contains data objects or primitive values as array elements. Array objects inherit from list objects. The difference between an array object and a list object is that array elements must be homogeneous. Each element within the array object is referred to by an integer that specifies its position in the array object.
Figure 2-4    Array Object ![]()
Refer to the iPlanet Unified Integration Framework Developer's Guide for details on data objects.
Mapping Tuxedo Data Types to UIF Data Types
The BEA Tuxedo system provides the following nine built-in buffer types:
STRING: a character array terminated by a null character.
Tuxedo also allows custom buffers which plug into your application. Currently custom built buffer types are not supported by the Tuxedo Enterprise Connector.CARRAY: an undefined character array, any of which can be a null character. The CARRAY is not self describing and the length must always be provided during transmission.
X_OCTET: is equivalent to a CARRAY.
FML: a proprietary BEA Tuxedo self defining buffer where each data field carries its own identifier, an occurrence number, and possibly a length indicator. It provides great flexibility but at the expense of processing overhead because all data manipulation is done via FML function calls rather than native C statements.
FML32: is similar to FML but allows for larger character fields, more fields, and larger overall buffers.
VIEW: a C structure that the application defines and requires a view description file. VIEW type buffers must have subtypes which designate individual data structures.
VIEW32: is similar to a VIEW buffer but allows for larger character fields, more fields, and larger overall buffers.
X_COMMON: is similar to a VIEW buffer but is used with both COBOL and C programs where field types are limited to short, long, and string.
Refer to BEA Tuxedo documentation for details about Tuxedo buffer types.
Tuxedo buffer types are mapped to UIF data types as follows:
Tuxedo Buffer Type
UIF Data Type
FML/VIEW Field Type
UIF Data Type
Developing Applications Using the Tuxedo Enterprise Connector
This section describes the basic steps involved in developing J2EE compliant applications which access the Tuxedo Service(s) using the Tuxedo Enterprise Connector.To invoke a Tuxedo Service from a Servlet, JavaServer Page (JSP), or Enterprise JavaBeans (EJB) you must do the following:
Acquire a Runtime Object
The runtime object is the entry point into the UIF. It is both the object factory and the access point for creating other objects. You must acquire a reference to a runtime object using the static method getcBSPRuntime() provided with netscape.bsp.runtime.access_cBSPRuntime class. This method takes three parameters; IContext object, ISession2 object, and AppLogic object. Currently the second and third parameters are not used and null must be passed.The following code fragment shows how to acquire a runtime object from a Servlet:
private IBSPRuntime getRuntime() ((com.netscape.server.servlet.platformhttp.PlatformServletContex t) getServletContext()).getContext();
netscape.bsp.runtime.IBSPRuntime rt =
Create a Service Provider Object
A service provider object is the logical representation of a connection to an EIS. Typically, the service provider is not bound to a physical connection until it is needed. It contains configuration information such as, host name, port number, application password, user name, client name, and data to create a connection. A service provider also needs the service provider type to manage the connection. A service provider must be enabled before being used.The createServiceProvider() method on IBSPRuntime interface is used to create the service provider and takes two parameters:
The Tuxedo Enterprise Connector supports the following two service provider templates, as shown in Figure 2-5:
tuxConnectionTx: is a virtual connection to Tuxedo to perform a transactional service invocation
tuxConnection: is a virtual connection to Tuxedo to perform a non transactional service invocation
Figure 2-5    Service Provider Types ![]()
The following code fragment illustrates how to create a service provider object:
private IBSPServiceProvider getServiceProvider(IBSPRuntime runtime)
{
if (runtime != null)
{
return runtime.createServiceProvider("Tuxedo-OnlineBank", "tuxConnection");
}
return null;
}Where: Tuxedo-OnlineBank is the datasource name.
tuxConnection is the service provider type.
Create a Function Object
A function object represents the logical business operations available on a datasource. The function object represents a Tuxedo Service definition in the BEA Tuxedo system. The function object needs to be set up and associated with a service provider before it can be executed. Figure 2-6 shows a function object.
Figure 2-6    Function Object ![]()
The following table shows the key components of a function object:
Component
Description
The Tuxedo service is mapped to a function object with one operation callService
The supported properties set used for service invocation, are as follows:
The createFunctionObject() method on IBSPRuntime interface is used to create the function object and takes two parameters: the datasource name and the function object name.
The following code fragment illustrates how to create a function object:
... IBSPServiceProvider sp = getServiceProvider(runtime);
IBSPFunctionObject fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "OPEN_ACCT");
Where: Tuxedo-OnlineBank is the datasource name.
OPEN_ACCT is the function object name.
Prepare and Execute a Function Object
Each function object needs a connection to an EIS before it can be executed. This connection is specified by associating a service provider with function object. The function object may have multiple operations, but must be prepared for a specific operation before it can be executed. Currently, function objects other than TransactionFO supports only one operation callService.To set up and execute a function object:
Enable the service provider and associate it with a function object.
The following code fragment illustrates how to prepare and execute the function object:Prepare the function object, set up the property set, and set up the input parameters in the function object's data block.
Retrieve the output parameters from the function object's data block.
Sample Code Walk-through
import java.io.*;// Import the following UIF Packages
import netscape.bsp.runtime.*;
import netscape.bsp.dataobject.*;
public class TuxSamples extends HttpServlet {
private IBSPRuntime rt = null;
private IBSPServiceProvider sp = null;
private IBSPFunctionObject fo = null;
private IBSPDataObject data = null;
private IBSPDataObject prop = null;
private IBSPDataObjectStructure config = null;
private com.kivasoft.IContext ctx = null;
private String strOperName = "callService";
private String strDataSource = "TEST";
private String strFOName = "";
public void init (ServletConfig config) throws ServletException {
ctx = ((com.netscape.server.servlet.platformhttp.PlatformServletContext) getServletContext()).getContext();
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
// add logic to call TOUPPER() method
rt = access_cBSPRuntime.getcBSPRuntime(ctx, null, null);
// Create the service provider and enable it
sp = rt.createServiceProvider("TEST", "tuxConnection");
// Create the function object and prepare
fo = rt.createFunctionObject("TEST", "TOUPPER");
data.setAttrString("INPUT.inputBlock.INPUTSTRING", inputStr);
// Execute the function object
outputStr = data.getAttrString("OUTPUT.outputBlock.OUTPUTSTRING");
if (!(inputStr.toUpperCase()).equals(outputStr)) {
System.out.println("ERROR : DATA MISMATCH");
System.out.println("ERROR : " + e);
Using Tuxedo Buffers with the Tuxedo Enterprise Connector
The Tuxedo Enterprise Connector supports the following built-in Tuxedo buffer types:Using the Tuxedo Enterprise Connector, you can develop J2EE applications which accesses Tuxedo services using any of the above buffer types. Please refer to BEA Tuxedo documentation for information about the Tuxedo buffer types.
The rest of the chapter provides sample code to illustrate the Tuxedo Enterprise Connector capabilities. The program examples are only code fragments used to illustrate a specific functionality. They are not intended to be compiled and run as provided, and additional code is required to be fully functional.
Using the STRING Tuxedo Buffer Type
The STRING buffer type is a character array terminated by a null character. This buffer type is useful for transmitting a character string.The following example for TOUPPER Tuxedo Service, illustrates how the Tuxedo Enterprise Connector works with a service whose buffer type is STRING. The TOUPPER Tuxedo Service is available in the Tuxedo simpapp example. The service converts the input string to uppercase and returns it to the client.
The service definition must be imported into the UIF repository using the Tuxedo Management Console. The service definition is:
interface SAMPLE {
void TOUPPER(
[in] STRING INPUTSTRING
[out] STRING OUTPUTSTRING
);
};Where: INPUTSTRING is the input parameter.
OUTPUTSTRING is the output parameter to the TOUPPER Tuxedo Service. The Tuxedo buffer type STRING is mapped to String data type in UIF.
Figure 2-7 shows how the service is mapped in the UIF repository:
Figure 2-7    TOUPPER Function Object ![]()
The following code fragment illustrates how the Tuxedo Enterprise Connector works with a service whose buffer type is STRING:
IBSPServiceProvider sp = null;
IContext ctx = ((com.netscape.server.servlet.platformhttp.PlatformServletContext) getServletContext()).getContext();
IBSPRuntime runtime = access_cBSPRuntime.getcBSPRuntime(ctx, null, null);
sp = runtime.createServiceProvider("TEST", "tuxConnection");
IBSPFunctionObject fn = runtime.createFunctionObject("TEST", "TOUPPER");
IBSPDataObject data = fn.getDataBlock();
data.setAttrString("INPUT.inputBlock.INPUTSTRING", inputstr);
resultstr = data.getAttrString("OUTPUT.outputBlock.OUTPUTSTRING");
Using the CARRAY Tuxedo Buffer Type
The CARRAY buffer type is an array of characters, any of which can be a null character. The application defines the array semantics; because the semantics are not interpreted by the BEA Tuxedo system. This buffer type is used to handle data opaquely. Unlike all other built-in buffer types, the CARRAY is not self describing.Consider a Tuxedo Service CARRAYSAMPLE whose input Tuxedo buffer type is CARRAY and output is also CARRAY. This service takes a buffer and passes it back to the client.
The service definition must be imported into the UIF repository using the Tuxedo Management Console. The service definition is:
interface SAMPLE {
void CARRAYSAMPLE(
[in] CARRAY INPUTDATA
[out] CARRAY OUTPUTDATA
);
};Where: INPUTDATA is the input parameter.
OUTPUTDATA is the output parameter to Tuxedo Service CARRAYSAMPLE. The CARRAY Tuxedo buffer type is mapped to VBinary in UIF.
Figure 2-8 shows how the service is mapped in the UIF repository:
Figure 2-8    CARRAYSAMPLE Function Object ![]()
The following code fragment illustrates how the Tuxedo Enterprise Connector works with a service whose buffer type is CARRAY:
byte[] inputdata = new byte[100];
// code to get service provider and runtime
fn = runtime.createFunctionObject("TEST", "CARRAYSAMPLE");
data.setAttrVBinary("INPUT.inputBlock.INPUTDATA", inputdata);
byte[] resultbytes = data.getAttrVBinary("OUTPUT.outputBlock.OUTPUTDATA");
Using the X_OCTET Tuxedo Buffer Type
The X_OCTET buffer type is defined as an alias for CARRAY to support XATMI.Consider a Tuxedo Service XOCTETSAMPLE whose input Tuxedo buffer type is X_OCTET and output is also X_OCTET. This service takes a buffer and passes it back to the client.
The service definition must be imported into the UIF repository using the Tuxedo Management Console. The service definition is:
interface SAMPLE {
void XOCTETSAMPLE (
[in] X_OCTET INPUTDATA
[out] X_OCTET OUTPUTDATA
);
};Where: INPUTDATA is the input parameter.
OUTPUTDATA is the output parameter to Tuxedo Service XOCTETSAMPLE. The X_OCTET Tuxedo buffer type is mapped to VBinary in UIF.
Figure 2-9 shows how the service is mapped in the UIF repository:
Figure 2-9    XOCTETSAMPLE Function Object ![]()
The following code fragment illustrates how the Tuxedo Enterprise Connector works with a service whose buffer type is X_OCTET:
byte[] inputdata = new byte[100];
// code to get service provider and runtime
fn = runtime.createFunctionObject("TEST", "XOCTETSAMPLE");
data.setAttrVBinary("INPUT.inputBlock.INPUTDATA", inputdata);
byte[] resultbytes = data.getAttrVBinary("OUTPUT.outputBlock.OUTPUTDATA");
Using the FML Tuxedo Buffer Type
The FML buffer type is a self describing buffer in which each data field carries its own identifier, an occurrence number, and possibly a length indicator. The FML32 buffer is similar to FML but allows for larger character fields and more fields and larger overall buffers. The individual fields in the FML buffer can be of data types float, double, long, short, char, string, and carray.If a field in FML buffer has multiple occurrences, then each occurrence is accessed by an index. Such a field is mapped to an array data type in UIF.
FML Sample 1
The following example for TRANSFER Tuxedo Service, illustrates how the Tuxedo Enterprise Connector works with a service whose buffer type is FML. The TRANSFER service is available in the Tuxedo bankapp example. This service uses FML as an input and output buffer. The input FML buffer has ACCOUNT_ID field of data type long with multiple occurrence and SAMOUNT field with string data type. The output FML buffer has a multiple occurrence string field SBALANCE.Before calling this service, FML Field Table and service definitions must be imported into the UIF repository using the Tuxedo Management Console.
The service definition is:
interface SAMPLE {
void TRANSFER(
[in,FML] LONG ACCOUNT_ID[]
[in,FML] STRING SAMOUNT
[out,FML] STRING SBALANCE[]
);
};This service uses the following FML field table definition file provided with Tuxedo bankapp application:
The input FML field ACCOUNT_ID has multiple occurrences and hence mapped to an array in UIF. This array contains elements of type integer, which holds the account ID. The single occurrence of input FML field SAMOUNT is mapped to string data type in UIF. The output FML field SBALANCE is of string data type with multiple occurrences and hence mapped to an array data type with string elements. Figure 2-10 illustrates the definition of the TRANSFER service in the UIF repository:
Figure 2-10    TRANSFER Function Object ![]()
The following code fragment illustrates how the Tuxedo Enterprise Connector works with a service whose buffer type is FML:
fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "TRANSFER");
data.setAttrString("INPUT.inputBlock.SAMOUNT", strAmount);
IBSPDataObjectArray arrayObj = (IBSPDataObjectArray) data.getAttrDataObject("INPUT.inputBlock.ACCOUNT_ID");
arrayObj.addElemInt(Integer.parseInt(frmAccountNumber));
arrayObj.addElemInt(Integer.parseInt(toAccountNumber));
arrayObj = (IBSPDataObjectArray) data.getAttrDataObject("OUTPUT.outputBlock.SBALANCE");
String frmBalanceStr = arrayObj.getElemString(0);
String toBalanceStr = arrayObj.getElemString(1);
FML Sample 2
Consider a more complex service FMLSAMPLE2. This service reads in an input FML buffer, creates a new FML buffer to store the data, and passes that buffer back to the client.Before calling this service, FML Field Table and service definitions must be imported into the UIF repository using the Tuxedo Management Console.
The service definition is as follows:
The above service uses the following FML field table definition file:
Figure 2-11 shows how the service is mapped in the UIF repository:
Figure 2-11    FMLSAMPLE2 Function Object ![]()
The following code fragment illustrates how the Tuxedo Enterprise Connector works with a service whose buffer type is FML:
fn = runtime.createFunctionObject("TEST", "FMLSAMPLE2");
data.setAttrInt("INPUT.inputBlock.char16", (int) 'a');
data.setAttrString("INPUT.inputBlock.string16", "Hello World");
data.setAttrInt("INPUT.inputBlock.long16", 9876);
data.setAttrInt("INPUT.inputBlock.short16", 8888);
data.setAttrFloat("INPUT.inputBlock.float16", 2123.1212f);
data.setAttrDouble("INPUT.inputBlock.double16", 234.234);
data.setAttrVBinary("INPUT.inputBlock.carray16", "Hello World".getBytes());
String outStr1 = data.getAttrString("OUTPUT.outputBlock.string16");
long outLong1 = data.getAttrInt("OUTPUT.outputBlock.long16");
short outShort1 = (short) data.getAttrInt("OUTPUT.outputBlock.short16");
float outFloat1 = data.getAttrFloat("OUTPUT.outputBlock.float16");
double outDouble1 = data.getAttrDouble("OUTPUT.outputBlock.double16" );
int outChar1 = data.getAttrInt("OUTPUT.outputBlock.char16");
FML Sample 3
Consider another service FMLSAMPLE3. This service reads in an input FML buffer, creates a new FML buffer to store the same data with multiple occurrences, and passes that buffer back to the client. The input FML buffer contains char16, string16, short16, long16, float16, double16, and carray16 fields with a single occurrence. The service returns FML buffer with multiple occurrences of the same input fields.Before calling this service, FML Field Table and service definitions must be imported into the UIF repository using the Tuxedo Management Console.
The service definition is as follows:
This service uses the same FML field table definition file, defined for FMLSAMPLE2 sample.
Figure 2-12    FMLSAMPLE3 Function Object ![]()
The following code fragment illustrates how the Tuxedo Enterprise Connector works with a service whose buffer type is FML:
IBSPDataObjectArray stringdo = (IBSDataObjectArray)
data.getAttrDataObject("OUTPUT.outputBlock.string16");
String outStr[] = new String[stringdo.getElemCount()];
for (int i = 0; i < outStr.length; i++)
outStr[i] = stringdo.getElemString(i);
IBSPDataObjectArray longdo = (IBSDataObjectArray)
data.getAttrDataObject("OUTPUT.outputBlock.long16");
long outLong[] = new long[longdo.getElemCount()];
for (int i = 0; i < outLong.length; i++)
outLong[i] = longdo.getElemInt(i);
IBSPDataObjectArray doubledo = (IBSDataObjectArray)
data.getAttrDataObject("OUTPUT.outputBlock.double16");
double outDouble[] = new double[doubledo.getElemCount()];
for (int i = 0; i < outDouble.length; i++)
outDouble[i] = doubledo.getElemDouble(i);
// similar code for the other output fields.
FML32 Sample
This sample illustrates how the Tuxedo Enterprise Connector works with a service whose buffer type is FML32. This service reads in an input FML32 buffer, creates a new FML32 buffer to store the data, and passes that buffer back to the client. The input FML32 buffer contains char32, string32, short32, long32, float32, double32, and carray32 fields with single occurrence. The service returns FML32 buffer with single occurrence of same fields.Before calling this service, FML32 Field Table and service definitions must be imported into the UIF repository using the Tuxedo Management Console.
The service definition is:
This service uses the following FML32 field table definition file:
Figure 2-13    FML32SAMPLE Function Object ![]()
The following code fragment illustrates how the Tuxedo Enterprise Connector works with a service whose buffer type is FML32:
fn = runtime.createFunctionObject("TEST", "FML32SAMPLE");
data.setAttrInt("INPUT.inputBlock.char32", (int) 'a');
data.setAttrString("INPUT.inputBlock.string32", "Hello World");
data.setAttrInt("INPUT.inputBlock.long32", 9876);
data.setAttrInt("INPUT.inputBlock.short32", 8888);
data.setAttrFloat("INPUT.inputBlock.float32", 2123.1212f);
data.setAttrDouble("INPUT.inputBlock.double32", 234.234);
data.setAttrVBinary("INPUT.inputBlock.carray32", "Hello World".getBytes());
String outStr1 = data.getAttrString("OUTPUT.outputBlock.string32");
long outLong1 = data.getAttrInt("OUTPUT.outputBlock.long32");
short outShort1 = (short) data.getAttrInt("OUTPUT.outputBlock.short32");
float outFloat1 = data.getAttrFloat("OUTPUT.outputBlock.float32");
double outDouble1 = data.getAttrDouble("OUTPUT.outputBlock.double32" );
int outChar1 = data.getAttrInt("OUTPUT.outputBlock.char32");
Using the VIEW Tuxedo Buffer Type
VIEW is a built-in Tuxedo typed buffer. The VIEW buffer provides a way to use C structures and COBOL records with the Tuxedo system. The VIEW buffer enables the Tuxedo runtime system to understand the format of C structures and COBOL records, that are based on the view description read at runtime. When allocating a VIEW buffer, your application specifies a VIEW buffer type and a subtype that matches the name of the view (the name that appears in the view description file). The individual fields in VIEW structure can be of data types char, string, carray, long, short, int, float, double, and dec_t.The VIEW32 buffer type is similar to VIEW but allows for larger character fields, more fields, and larger overall buffers. The X_COMMON buffer type is similar to VIEW but is used for both COBOL and C programs so field types should be limited to short, long, and string. The X_C_TYPE buffer type is equivalent to VIEW.
If a field in VIEW buffer is an array, it is mapped to an array data type in UIF and each element of the array is of corresponding UIF data type for the field type.
If your J2EE application calls any Tuxedo Service with VIEW, VIEW32, X_COMMON or X_C_TYPE buffer types. The Tuxedo environment variables VIEWFILES, VIEWDIR, VIEWFILES32, and VIEWDIR32 must be set before starting the iPlanet Application Server.
VIEW Sample
The following sample illustrates how the Tuxedo Enterprise Connector works with a service whose buffer type is VIEW. This sample uses a Tuxedo service VIEWSAMPLE with input and output VIEW buffer. This service accepts a VIEW buffer with subtype v16test1 as an input and outputs the same data as VIEW buffer with subtype v16test2.Before calling this service, VIEW and service definitions must be imported into the UIF repository using the Tuxedo Management Console.
The service definition is:
interface SAMPLE {
void VIEWSAMPLE(
[in, VIEW16 v16test1] VIEW16 inputBlock
[out,VIEW16 v16test2] VIEW16 outputBlock
);
};The definition of views v16test1 and v16test2 used in this service are as follows:
# type cname fbname count flag size null
# type cname fbname count flag size null
Figure 2-14 shows how the service is represented in the UIF repository.
Figure 2-14    VIEWSAMPLE Function Object ![]()
The following code fragment illustrates how the Tuxedo Enterprise Connector works with a service whose buffer type is VIEW:
fn = runtime.createFunctionObject("TEST", "VIEWTEST1");
hr = fn.prepare("callService");
data.setAttrInt("INPUT.inputBlock.char1", (int) 'a');
data.setAttrString("INPUT.inputBlock.str1", "Hello World");
data.setAttrInt("INPUT.inputBlock.long1", 9876);
data.setAttrInt("INPUT.inputBlock.short1", 8888);
data.setAttrInt("INPUT.inputBlock.int1", 9999);
data.setAttrFloat("INPUT.inputBlock.float1", 2123.1212f);
data.setAttrDouble("INPUT.inputBlock.double1", 234.234);
data.setAttrVBinary("INPUT.inputBlock.cary1", "Hello World".getBytes());
data.setAttrDouble("INPUT.inputBlock.dec1", 2123.12);
for (int i = 0; i < 5; i ++) {
data.getAttrString("OUTPUT.outputBlock.str1" + ".["+i+"]");
data.getAttrInt("OUTPUT.outputBlock.long1" + ".["+i+"]");
data.getAttrInt("OUTPUT.outputBlock.short1" + ".["+i+"]");
data.getAttrInt("OUTPUT.outputBlock.int1" + ".["+i+"]");
data.getAttrFloat("OUTPUT.outputBlock.float1" + ".["+i+"]");
data.getAttrDouble("OUTPUT.outputBlock.double1" + ".["+i+"]");
VIEW32 Sample
This sample illustrates how the Tuxedo Enterprise Connector works with a service whose buffer type is VIEW32. This sample uses a Tuxedo service VIEW32SAMPLE with input and output VIEW32 buffer. This service accepts a VIEW32 buffer with subtype v32test1 as an input and outputs the same data as VIEW32 buffer with subtype v32test2.Before calling this service, VIEW32 and service definitions must be imported into the UIF repository using the Tuxedo Management Console.
The service definition is as follows:
interface SAMPLE {
void VIEW32SAMPLE(
[in, VIEW32 v32test1] VIEW32 inputBlock
[out, VIEW32 v32test2] VIEW32 outputBlock
);
};The definition of views v32test1 and v32test2 are as follows:
# type cname fbname count flag size null
# type cname fbname count flag size null
Figure 2-15 shows how the service is represented in the UIF repository.
Figure 2-15    VIEW32SAMPLE Function Object ![]()
The following code fragment illustrates how the Tuxedo Enterprise Connector works with a service whose buffer type is VIEW32:
fn = runtime.createFunctionObject("TEST", "VIEW32TEST");
data.setAttrInt("INPUT.inputBlock.char1", (int) 'a');
data.setAttrString("INPUT.inputBlock.str1", "Hello World");
data.setAttrInt("INPUT.inputBlock.long1", 9876);
data.setAttrInt("INPUT.inputBlock.short1", 8888);
data.setAttrInt("INPUT.inputBlock.int1", 9999);
data.setAttrFloat("INPUT.inputBlock.float1", 2123.1212f);
data.setAttrDouble("INPUT.inputBlock.double1", 234.234);
data.setAttrVBinary("INPUT.inputBlock.cary1", "Hello World".getBytes());
data.setAttrDouble("INPUT.inputBlock.dec1", 2123.12);
for (int i = 0; i < 5; i ++) {
data.getAttrInt("OUTPUT.outputBlock.char1" + ".["+i+"]");
data.getAttrString("OUTPUT.outputBlock.str1" + ".["+i+"]");
data.getAttrInt("OUTPUT.outputBlock.long1" + ".["+i+"]");
data.getAttrInt("OUTPUT.outputBlock.short1" + ".["+i+"]");
data.getAttrInt("OUTPUT.outputBlock.int1" + ".["+i+"]");
data.getAttrFloat("OUTPUT.outputBlock.float1" + ".["+i+"]");
data.getAttrDouble("OUTPUT.outputBlock.double1" + ".["+i+"]");
data.getAttrDouble("OUTPUT.outputBlock.dec1" + ".["+i+"]");
X_COMMON Sample
This sample illustrates how the Tuxedo Enterprise Connector works with a service whose buffer type is X_COMMON. This sample uses a service XCOMMONSAMPLE with input and output X_COMMON buffer type. This service takes the data from the client X_COMMON buffer with subtype xcomtest1, creates a new X_COMMON buffer with subtype xcomtest2, populates the structure xcomtest2 and passes it back to the client.Before calling this service, VIEW and service definitions must be imported into the UIF repository using the Tuxedo Management Console.
The service definition is as follows:
interface SAMPLE {
void XCOMMONSAMPLE(
[in, X_COMMON xcomtest1] X_COMMON inputBlock
[out, X_COMMON xcomtest2] X_COMMON outputBlock
);
};The following listing shows the VIEW field definitions used in this service:
# view def for X_COMMON with count 1
# type cname fbname count flag size null
# view def for X_COMMON with count 10
# type cname fbname count flag size null
Figure 2-16 shows how the service is represented in the UIF repository.
Figure 2-16    XCOMMONSAMPLE Function Object ![]()
The code to populate the input structure xcomtest1 calls the service and gets the results from output xcomtest2 structure as shown below.
fn = runtime.createFunctionObject("TEST","XCOMMONSAMPLE");
data.setAttrInt("INPUT.inputBlock.char1", (int) 'a');
data.setAttrString("INPUT.inputBlock.str1", "Hello World");
data.setAttrInt("INPUT.inputBlock.long1", 9876);
data.setAttrInt("INPUT.inputBlock.short1", 8888);
for (int i = 0; i < 10; i ++) {
data.getAttrInt("OUTPUT.outputBlock.char1" + ".["+i+"]");
data.getAttrString("OUTPUT.outputBlock.str1" + ".["+i+"]");
data.getAttrInt("OUTPUT.outputBlock.long1" + ".["+i+"]");
data.getAttrInt("OUTPUT.outputBlock.short1" + ".["+i+"]");
X_C_TYPE Sample
This sample illustrates how the Tuxedo Enterprise Connector works with a service whose buffer type is X_C_TYPE. This sample uses a service XCTYPESAMPLE with input and output X_C_TYPE buffer type. This service takes the data from the client X_C_TYPE with subtype xctest1, creates a new X_C_TYPE buffer with subtype xctest2, populates the structure xctest2 and passes it back to the client.Before calling this service, VIEW and service definitions must be imported into the UIF repository using the Tuxedo Management Console.
The definition of the service is as follows:
interface SAMPLE{
void XCTYPESAMPLE(
[in, X_C_TYPE xctest1] X_C_TYPE inputBlock
[out, X_C_TYPE xctest2] X_C_TYPE outputBlock
);
};This service uses the following views:
# view def for X_C_TYPE with count 1
# type cname fbname count flag size null
# view def for X_C_TYPE with count 10
# type cname fbname count flag size null
Figure 2-17 shows how the service is represented in the UIF repository.
Figure 2-17    XCTYPESAMPLE Function Object ![]()
The code to populate the input structure xctest1 calls the service and gets the results from output xctest2 structure as shown below.
fn = runtime.createFunctionObject("TEST", "XCTYPESAMPLE");
data.setAttrInt("INPUT.inputBlock.char1", (int) 'a');
data.setAttrString("INPUT.inputBlock.str1", "Hello World");
data.setAttrInt("INPUT.inputBlock.long1", 9876);
data.setAttrInt("INPUT.inputBlock.short1", 8888);
for (int i = 0; i < 10; i ++) {
data.getAttrInt("OUTPUT.outputBlock.char1" + ".["+i+"]");
data.getAttrString("OUTPUT.outputBlock.str1" + ".["+i+"]");
data.getAttrInt("OUTPUT.outputBlock.long1" + ".["+i+"]");
data.getAttrInt("OUTPUT.outputBlock.short1" + ".["+i+"]");
TransactionFO Function Object
The TransactionFO is a special function object present with each Tuxedo datasource. It is created automatically when you create a new Tuxedo datasource. This special function object provides support to develop Java programs which calls ATMI functions tpbegin(), tpcommit(), and tpabort() from client process.The TransactionFO function object supports the following operations:
The above operations are mapped to tpbegin(), tpcommit(), and tpabort() of ATMI primitives. In the Tuxedo Enterprise Connector these operations are used to define client-side global transactions.
Figure 2-18 shows how the TransactionFO is represented in the UIF repository.
Figure 2-18    TransactionFO Function Object ![]()
The transaction is started by executing the BEGIN operation. Optionally, you can specify a timeout parameter. The timeout specifies the amount of time in seconds a transaction has before timing out. If the timeout parameter is not set the Tuxedo Enterprise Connector uses 60 seconds as the default value.
Developing Client-side Transactions
A transaction is bounded by a begin transaction and an end transaction. Between the begin transaction and end transaction, the application is said to be in transaction mode. This can be controlled either in Tuxedo clients or services. Client controlled transactions are known as client-side global transactions.The following sample illustrates how to use client-side transactions in Tuxedo Enterprise Connector.
This sample uses two user-defined Tuxedo services, WITHDRAWL and DEPOSIT to perform TRANSFER transaction. If WITHDRAWL operation fails, a rollback is performed. Otherwise, a DEPOSIT is performed and a commit completes the transaction.
The tuxConnectionTx service provider type must be used while creating the service provider object.
The following code fragment illustrates how to use the TransactionFO function object:
IBSPServiceProvider sp = null;
ctx = ((com.netscape.server.servlet.platformhttp.PlatformServletContext) getServletContext()).getContext();
rt = access_cBSPRuntime.getcBSPRuntime(ctx, null, null);
// create service provider using tuxConnectionTx type
sp = runtime.createServiceProvider("TEST", "tuxConnectionTx");
tx = new TuxTransaction(rt, sp, "TEST");
fn = rt.createFunctionObject("TEST", "WITHDRAWL");
fn = rt.createFunctionObject("TEST", "DEPOSIT");
TuxTransaction Class - Abstracts TransactionFO operations
import netscape.bsp.runtime.*;
import netscape.bsp.dataobject.*;
IBSPFunctionObject txfn = null;
public TuxTransaction(IBSPRuntime rt, IBSPServiceProvider sp, String ds) throws BspException
txfn = rt.createFunctionObject(ds, "TransactionFO");
public void begin() throws BspException
public void commit() throws BspException
public void rollback() throws BspException
Using propertySet Parameters
propertySet is used to describe the operational parameters associated with a function object. The following parameters are defined:
serviceName: The Tuxedo Service name to be invoked. This is same as the function object template name. It is a read-only parameter.
Figure 2-19 shows how the propertySet is represented in the UIF repository.isOneWay: If this flag is set, the enterprise connector calls the Tuxedo service without expecting a reply back from Tuxedo system. This is equivalent to setting TPNOREPLY parameter with function tpacall() in Tuxedo.
priority: Sets the priority of the Tuxedo request. The priority affects how the request is dequeued by the server. The interpretation of this value is dependent on the parameter, isPriorityRelative.
isPriorityRelative: Indicates whether priority level is relative or absolute. This parameter indicates how the priority value to be interpreted.
- If the flag is set to relative, the current priority value of the service, will be incremented or decremented based on sign of the priority value set.
- Using the absolute method, you can set a request's priority to an absolute value. The absolute value of priority must be in the range of 1 to 100, 100 being the highest priority value.
Figure 2-19    Function Object propertySet ![]()
The following code fragment illustrates how to set the priority:
sp = rt.createServiceProvider(inputs.strAdapterName, inputs.strSPTemplate);
fo = rt.createFunctionObject(inputs.strAdapterName, strFOName);
prop.setAttrInt("priority", 20);
prop.setAttrInt("isPriorityRelative", 1);
Using Tuxedo User Management
If your Tuxedo system is configured with security level TPAPPAUTH (USER_AUTH/ACL/MANDATORY_ACL), you must configure the Entities (Tuxedo authentication context) and WebUsers using the Tuxedo Management Console.The application programmer provides a WebUserId to the Tuxedo Enterprise Connector, which determines the Tuxedo authentication context to be used to process the request. The WebUserId must be set with the configuration structure of service provider before enabling by calling the enable() method.
The following code fragment illustrates how to set webuser-test as the WebUserId before enabling the Service Provider:
// Get Service Provider Config structure
config = (IBSPDataObjectStructure) sp.getConfig();
config.setAttrString("WebUserId", "webuser-test");
Tuxedo Application Return Code
The Tuxedo application return code is an application defined value. It can be returned from a Tuxedo service to the client along with the reply, regardless of whether or not the service completed successfully. The return code is defined as an integer and is used to carry a code that means something to the client. This code is passed using the second argument, rcode, in tpreturn() function. The Tuxedo clients can access via the global variable, tpurcode.The Tuxedo Enterprise Connector provides a facility to access this application return code within Java programs. This is stored with OUTPUT.urcode field.
The following code fragment illustrates how to get the Tuxedo application return code:
sp = rt.createServiceProvider(inputs.strAdapterName, inputs.strSPTemplate);
fo = rt.createFunctionObject(inputs.strAdapterName, strFOName);
int code = data.getAttrInt("OUTPUT.urcode");
Error and Exception Handling
The Tuxedo Enterprise Connector returns connector and Tuxedo system errors as exceptions using the netscape.bsp.BspException class. Always enclose the application logic within a try or catch block, and attempt to deal with an exception appropriately.The BspException class instance carries additional information if the exception is thrown due to a Tuxedo system error. Obtain the additional info object by calling getInfo() method on the exception object. This returns IBSPDataObjectStructure object with fields errno and errstr. These two fields are mapped to Tuxedo variables tperrno and tpstrerror, respectively. Then call getAttrInt("errno") and getAttrString("errstr") methods on the info object to get the Tuxedo system error number and the message associated with it.
The following code fragment demonstrates how to handle exceptions:
IBSPDataObjectStructure info = null;
errno = info.getAttrInt("errno");
strError = info.getAttrString("errstr");
The netscape.tux.TuxError class has constants which can be used to compare with the errno retuned from exception object.
The following constants are available:
Developing International Applications
The Enterprise Connector for Tuxedo supports developing J2EE compliant international applications using various character sets supported by the iPlanet Application Server. To use the Tuxedo connector in international mode, the iPlanet Application Server must operate in the INTERNATIONAL mode. Refer to the iPlanet Application Server documentation on how to run the iPlanet Application Server in INTERNATIONAL mode.All connector related error messages are formatted and logged in the operating system locale and character set in which the iPlanet Application Server is running. The character set used to pass the WebUserId to a Servlet, JSP, or EJB must be set correctly within your application. For details on how to specify character set and write J2EE compliant international applications, refer to iPlanet Application Server documentation.
The use of the CARRAY Tuxedo buffer type is recommended to transmit multi-byte data. Please contact BEA System for details on support of multi-byte and double byte character data in the BEA Tuxedo software.
Tuxedo SimpApp Sample Using Servlet
The simpapp sample demonstrates how a Servlet may connect to the Tuxedo system and call one of its services using the Tuxedo Enterprise Connector. In this sample the service is called TOUPPER, available in Tuxedo simpapp example. You may find the Tuxedo server simpapp application is created in the <tuxedo root dir>/apps/simpapp directory. The Java source code is available in <iAS root dir>/ias/APPS/TuxSimpApp directory.The TuxSimpApp sample directory contains:
File Name
Description
Tuxedo Online Bank Sample Using JSP & EJB
The bankapp sample application illustrates the Tuxedo connectivity of the Tuxedo Enterprise Connector to the bankapp application that comes with BEA Tuxedo system. The source code for the Tuxedo server bankapp application is located in the <tuxedo root dir>/apps/bankapp directory. The Tuxedo server bankapp application contains the services WITHDRAWAL, DEPOSIT, TRANSFER, INQUIRY, CLOSE_ACCT, and OPEN_ACCT.The bankapp sample application demonstrates techniques to use Servlet, EJB, and JSP J2EE components to develop a web-based application which accesses the Tuxedo services. The source code for this sample Java application is available in the <iAS root dir>/ias/APPS/TuxBank directory.
The TuxBank example directory contains:
XXXForm.jsp displays a form for input. When the user submits the form, it calls the Servlet BankServlet, which calls the EJB BankManager and forwards the request to the Tuxedo system using the UIF API. The response is taken and sent back to the Servlet which calls a JSP ShowXXX.jsp to display the results. In case of an error, ErrorPage.jsp is shown with the appropriate error message.
Previous Contents Index DocHome Next
Copyright © 2000 Sun Microsystems, Inc. Some preexisting portions Copyright © 2000 Netscape Communications Corp. All rights reserved.
Last Updated October 19, 2000