Previous Contents Index DocHome Next |
iPlanet Application Server Enterprise Connector for Tuxedo Developer's Guide |
Chapter 2 Programming for Tuxedo
You use the iPlanet Application Server Enterprise Connector for Tuxedo to execute Tuxedo services from J2EE compliant applications. Tuxedo services mined using the data mining procedure provided in the iPlanet Application Server Enterprise Connector for Tuxedo Administrator's Guide can be invoked from EJBs, Java Servlets or Java Server Pages using the UIF API. You should have a thorough understanding of the Unified Integration Framework and Tuxedo as a prerequisite for reading this chapter.This chapter contains the following sections:
Data Objects
Acquiring the UIF Runtime Object and Mapping it
Creating the Service Provider Object
Mapping Tuxedo Data Types to UIF
Using the STRING Tuxedo buffer
Using the CARRAY Tuxedo Buffer
Using the X_OCTET Tuxedo Buffer
Data Objects
Data objects represent data in a hierarchical fashion. UIF uses data objects to store data and metadata.The iPlanet Application Server Enterprise Connector for Tuxedo allows you to provide inputs for a Tuxedo service invocation or get outputs from Tuxedo service access data object interface.
Presents a unified representation of backend data types
Data objects are built from primitive types. A primitive data object contains a primitive value. For example, a primitive data type might be an integer or a string. Arrays and structures are complex data objects.
Primitive Objects
Primitive Objects
A primitive data-type object contains a single value of one of the following types
Integer, float, double
Figure 2-1    Primitive Object
Integer, float, double
Integer, float, and double-data type objects hold a value whose type corresponds to the Java data type.When a primitive data object is assigned to a list, array, or structure, the data object is unwrapped and its value is copied into the list, array or structure. The data object itself is not used. When a primitive value is obtained by using an untyped get method, such as getField(), getElem(), getAttr(), or getCurrent(), the returned value is wrapped in a primitive data object. When this happens, the value is copied, so that modifying the returned primitive data object does not change the source object.
Fixed length string, variable length string
Strings correspond to the Java string data type. A fixed length string has a maximum length, whereas a variable length string has no restrictions on its length.
Fixed-size byte array, variable-size byte array
A fixed-size byte array has a maximum size, whereas a variable-size byte array has no restriction on its size.When a new value replaces an old value, the old value is released. Thus, when a new value is assigned to a variable-length string or a variable-sized byte array, the old value is released. When a new value is assigned to a fixed-length string or a fixed-size byte array, the new value is copied over the old one. In the case of a fixed-length string, the copied string is truncated to fit, if necessary. In the case of a fixed-size byte array, a shorted array is zero filled on the right and a longer array is truncated to fit.
The maximum length of a fixed-length string and the maximum size of a fixed-size byte array are set when the string's initial value is specified. For instance, the maximum length of the array in the following example is four characters.
If a five character value is used, the value is truncated to four characters by dropping the fifth character.
Structure Objects
Structure objects contain 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 32 characters. A structure's fields are heterogeneous.
Figure 2-2    Structure Object
Array Objects
An array object contains data objects or primitive values as elements in the object. array objects inherit from list objects. The difference between an array object and a list object is that the array's 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-3    Array Object
API Naming Conventions
Methods in the API conform to a naming convention that specifies:In the following example of the form <operation><target><type>:
get is the operation, Elem is the target, and String is the type.
Operation
There are many types of operations but the two most commonly used are
None (primitive)
Attr (complex DataObject such as a list, array, or structure) that uses path to address attribute.
Elem (list/array) uses index to address element
Type
The types of operations are
Attributes and Paths
In the API, methods of the IBSPDataObject interface do not distinguish between an element in an array and a field in a structure. In this case the element or field is referred to as an attribute.The path to an element is its element number, beginning from zero. The path to a field is its field name.You may combine element numbers and field names to create paths to attributes in complex data objects, such as a field of a structure that contains a list of elements. In this case, you specify the path as the individual attributes separated by periods (.); i.e. use "field1.[01]" to identify the first element of a list at field1 in the structure.
Changing Data Types
If an attribute's type is primitive, it can not change. For example, the following code will cause an error because it tries to change the type of a primitive from an integer to a float:list.addElemInt (100) ; // assume 100 is added to element 1
list.setElemFloat (1, 3.14) ; // fails because the type of element is int
You can change the data type of non-primitive, as in the following example:
list.addElemDataObject (aStruct) ; // add a structure to element 1
list.setElemDataObject (1, array) ; // change to array succeeds
Acquiring the UIF Runtime Object and Mapping it
The runtime object is the entry point into UIF. It is both the object factory and the access point for creating other objects.The following is an example of how to acquire a runtime object from a servlet. The procedure is similar for EJB except that the IContext object is obtained using the com.kivasoft.util.GX.GetContext() API rather than the getServletContext() API.
Creating the Service Provider Object
The service provider is the logical representation of a connection to a backend system. Typically, the service provider is not bound to a physical connection until it is absolutely necessary. You must enable a service provider before it can be used.
Detailed Description of a Service Provider
A service provider represents a virtual connection to a backend Tuxedo system. It contains configuration information like: the kinds of data required to create a connection; host, port, username, and password.A service provider may also specify additional information required to manage a connection. The following diagram shows the parts of a service provider type.
Figure 2-4    Service Provider Types
Virtual connection to a Tuxedo System for performing non transactional service invocations
Virtual connection to a tuxedo System for performing a transactional service invocation
The following is an example of how to create a service provider object.
Creating the Function Object
A function object is a group of related operations that share a common state. In the iPlanet Application Server Enterprise Connector for Tuxedo, you must set up a function object and associate it with a service provider before the function object is executed.
Detailed Description of a Function Object
A function object represents the logical business functions available on a data source. The function object represents a Tuxedo service definition in BEA Tuxedo system. A function object specifies the service provider it requires for execution. In the case of Tuxedo, one function object exists for each service provider.The following diagram shows the parts of a function object.
Figure 2-5    Function Object Type
The following is an example of how to create a function object.
Code Example 2-3 Creating the Function Object ... IBSPServiceProvider sp = getServiceProvider(runtime); IBSPFunctionObject fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "OPEN_ACCT");
Setting up and Executing the Function Object
To set up and execute the function object
Specify and enable the service provider.
The following is an example of how to set up and execute a function object.Prepare the function object, set up the property set, and set up the input parameters in the function object's data block.
//creating a function object
fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "INQUIRY");
// Enabling the service provider
hr = sp.enable();
// preparing the service provider and setting up
hr = fn.useServiceProvider(sp);
hr = fn.prepare("callService");
// Populating the input data
data = fn.getDataBlock();
data.setAttrInt("INPUT.inputBlock.ACCOUNT_ID", acctnum);
// Calling the service
hr = fn.execute();
// Getting the output results from the service
String outputBalance = data.getAttrString("OUTPUT.outputBlock.SBALANCE");// disabling the data source
sp.disable();
Mapping Tuxedo Data Types to UIF
The BEA Tuxedo system provides nine buffer types for messages: STRING, CARRAY, VIEW, VIEW32, FML, FML32, X_OCTET, X_COMMON, and X_C_TYPE. Applications can define additional types as needed. Consult the manual pages referred to above and Administering the BEA Tuxedo System.The STRING buffer type is used when the data is an array of characters that terminates with the null character.
The data in a CARRAY buffer is an undefined array of characters, any of which can be null. The CARRAY is not self-describing and the length must always be provided when transmitting this buffer type. The X_OCTET buffer type is equivalent to CARRAY.
The VIEW type is a C structure that the application defines and for which there has to be a view description file. Buffers of the VIEW type must have subtypes, which designate individual data structures. The X_C_TYPE buffer type is equivalent to VIEW. 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 VIEW32 buffer type is similar to VIEW but allows for larger character fields, more fields, and larger overall buffers.
An FML buffer is a proprietary BEA Tuxedo system type of self-defining buffer where each data field carries its own identifier, an occurrence number, and possibly a length indicator. This type provides great flexibility at the expense of some processing overhead in that all data manipulation is done via FML function calls rather than native C statements.
The FML32 data type is similar to FML but allows for larger character fields, more fields, and larger overall buffers.
The following table is a mapping between Java types and Tuxedo parameter types required by a Tuxedo service. Use the appropriate data object types for the value to the data object.
FML, FML32, VIEW, VIEW32, X_COMMON, X_C_TYPE <---> struct
primitive c_array, primitive X_OCTET <--> vbinary
FML/VIEW field types <--> UIF types
"> Table 2-2 Mapping Tuxedo Data Types to UIF
Using the STRING Tuxedo buffer
Consider a Tuxedo service TOUPPER whose input Tuxedo buffer type is STRING and output is also STRING. You should mine the service using the data mining tool into the repository (by using either the Jolt bulk loader format file or IDL format file). During the mining process, the input STRING parameter name is specified as some INPUTSTRING and the output STRING parameter name is specified as some OUTPUTSTRING. The Tuxedo buffer type STRING maps to the UIF data type String directly. The user needs to set appropriately the input string, execute the service and read the output string. You can use the following code snippet to access this Tuxedo service from a servlet or EJB.IBSPServiceProvider sp = null;
IContext ctx = ((com.netscape.server.servlet.platformhttp.PlatformServletContext)
getServletContext()).getContext();
IBSPRuntime runtime = access_cBSPRuntime.getcBSPRuntime(ctx, null, null);
sp = runtime.createServiceProvider("Tuxedo-SimpApp", "tuxConnection");
IBSPFunctionObject fn = runtime.createFunctionObject("Tuxedo-SimpApp", "TOUPPER");
IBSPDataObject data = fn.getDataBlock();
data.setAttrString("INPUT.inputBlock.INPUTSTRING", inputstr);
resultstr = data.getAttrString("OUTPUT.outputBlock.OUTPUTSTRING");
out.println("Result text from service : <b><font color=blue>" + resultstr + "</font><br><hr><i>Service Executed Successfully </i></b><br>");
out.println("<font COLOR=red><b>Service Execution Error :<br>" +
e.getMessage() + "<br><hr><i>Service Execution Failed </i></b></font>");
if (sp != null && sp.isEnabled())
Using the CARRAY Tuxedo Buffer
Consider a Tuxedo service CARRAYTEST whose input Tuxedo buffer type is CARRAY and output is also CARRAY (could be different, if required). You should mine the service using the data mining tool into the repository. The CARRAY data type of Tuxedo maps to the VBINARY as a UIF data type for its data object. During the mining process, specify the input CARRAY parameter name to some INPUTDATA and the output CARRAY parameter name to some OUTPUTDATA. You can use the following code snippet to access this Tuxedo service from a servlet or EJB.byte[] inputdata = new byte[100];
.... // code to fill inputdata
// .. code to get service provider and runtime
IBSPDataObject data = null, prop = null;
fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "CARRAYTEST");
hr = fn.useServiceProvider(sp);
hr = fn.prepare("callService");
data.setAttrVBinary("INPUT.inputBlock.INPUTDATA", inputdata);
byte[] resultbytes =data.getAttrVBinary("OUTPUT.outputBlock.OUTPUTDATA");
Using the X_OCTET Tuxedo Buffer
Using an X_OCTET data type is very similar to using the CARRAY data type. Consider a Tuxedo service XOCTETTEST whose input and output Tuxedo buffer type is X_OCTET (can be different too if required).Mine the service into the repository using the data mining tool. The Tuxedo X_OCTET data type maps to the UIF VBINARY datatype for its data object. During the mining process, specify the input X_OCTET parameter as some INPUTDATA and the X_OCTET output parameter name as some OUTPUTDATA. You can use the following code snippet to access this Tuxedo service from a servlet or EJB.
byte[] inputdata = new byte[100];
.... // code to fill inputdata
// .. code to get service provider and runtime
IBSPDataObject data = null, prop = null;
fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "XOCTETTEST");
hr = fn.useServiceProvider(sp);
hr = fn.prepare("callService");
data.setAttrVBinary("INPUT.inputBlock.INPUTDATA", inputdata);
byte[] resultbytes =data.getAttrVBinary("OUTPUT.outputBlock.OUTPUTDATA");
Using the FML/FML32 Tuxedo Buffer
An FML Tuxedo buffer is a self-defining 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 FML buffer is can contain a set of fields. For the FML buffers, the data types of the individual fields can be float, double, long, short, char, STRING, CARRAY. UIF doesn't support all these data types. Thus a mapping need to be done to the nearest data type in UIF for each of these data type. The mapping is shown in the below table.
"> Table 2-3 Mapping FML Types to UIF Types If a field in an FML buffer has multiple or repeated occurrences, then each occurrence is accessed by an index. Such a field is mapped in UIF to an ARRAY object each element of the array is of corresponding UIF type for the field type.
Consider the example of the TRANSFER service that is a part of the OnlineBank sample application. The TRANSFER Tuxedo service accepts FML as input and output buffers. The input FML buffer has a multiple occurrence integer field ACCOUNT_ID with count 2 and a STRING field SAMOUNT. The output FML buffer has a multiple occurrence STRING filed SBALANCE.
The Tuxedo FML field definitions table present in bankflds file used by bankapp application is shown below.
# name number type flags comments
ACCOUNT_ID 110 long - -
ACCT_TYPE 112 char - -
ADDRESS 109 string - -
AMOUNT 117 float - -
BALANCE 105 float - -
BRANCH_ID 104 long - -
FIRST_NAME 114 string - -
LAST_ACCT 106 long - -
LAST_TELLER 107 long - -
MID_INIT 115 char - -
PHONE 108 string - -
SSN 111 string - -
TELLER_ID 116 long - -
SBALANCE 201 string - used for dollar format
SAMOUNT 202 string - used for dollar format
XA_TYPE 203 short - choice in MENU mask
CURS 204 string - place holder in masks
SVCHG 205 string - -
VIEWNAME 206 string - view name
OPEN_CR 207 char - open a credit card?
TYPE_CR 208 char - type of a credit card
STATLIN 209 string - -This service maps to a function object in UIF with name TRANSFER. The input FML field ACCOUNT_ID has two occurrences and hence maps to a UIF array element inside the INPUT.inputBlock with name ACCOUNT_ID and the elements of the array map to integer elements of UIF. Input FML field SAMOUNT maps to an string field SAMOUNT in the UIF data object INPUT.inputBlock. Output FML field SBALANCE is of string type and has multiple occurrences. It maps to a UIF array element inside the INPUT.inputBlock with name SBALANCE and the elements in the array map to string elements of UIF.
TRANSFER Service Example
fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "TRANSFER");hr = fn.useServiceProvider(sp);
hr = fn.prepare("callService");
data.setAttrString("INPUT.inputBlock.SAMOUNT", ""+amount);
IBSPDataObjectList listObj = (IBSPDataObjectList) data.getAttrDataObject("INPUT.inputBlock.ACCOUNT_ID");
listObj.addElemInt(Integer.parseInt(frmAccountNumber));
listObj.addElemInt(Integer.parseInt(toAccountNumber));
listObj = (IBSPDataObjectList) data.getAttrDataObject("OUTPUT.outputBlock.SBALANCE");
String frmBalanceStr = listObj.getElemString(0);
String toBalanceStr = listObj.getElemString(1);
return new String[] { frmBalanceStr, toBalanceStr};
throw new ApplicationException(e);
} finally { if (sp != null && sp.isEnabled()) sp.disable(); }
FMLTEST1 Example
Next, let us consider a more complex fictitious service FMLTEST1 which takes as input FML buffer and returns as output another FML buffer. Let the fields table used by this service be given below.# name number type flags comments
char16 1 char - this is a char field
string16 2 string - this is a string field
short16 3 short - this is a short field
long16 4 long - this is a long field
float16 5 float - this is a float field
double16 6 double - this is a double field
carray16 7 carray - this is a carray field
Let the input FML fields that the service expects in the input FML buffer be char16, string16, short16, long16, float16, double16 and carray16. Let all of them are having single occurrence only. Let the server output FML buffer contain the same single valued fields.
Before calling this service, the FML fields should be mined by using the tools. Then the service should be defined in a Jolt bulk loader or IDL format, and imported into the UIF repository under the datasource (say Tuxedo-OnlineBank for example).
Before going into the actual code, the data types mapping is explained next for input and output blocks.
In the servlet or EJB, the input char field char16 maps to an UIF integer field INPUT.inputBlock.char16, the input string field string16 maps to an UIF string field INPUT.inputBlock.string16, the input string field short16 maps to an UIF string field INPUT.inputBlock.short16, the input string field long16 maps to an UIF string field INPUT.inputBlock.long16, the input string field float16 maps to an UIF float field INPUT.inputBlock.float16, the input string field double16 maps to an UIF double field INPUT.inputBlock.double16, the input carray field carray16 maps to an UIF vbinary field INPUT.inputBlock.carray16.
In the servlet or EJB, the output char field char16 maps to an UIF integer field OUTPUT.outputBlock.char16, the output string field string16 maps to an UIF string field OUTPUT.outputBlock.string16, the output string field short16 maps to an UIF string field OUTPUT.outputBlock.short16, the output string field long16 maps to an UIF string field OUTPUT.outputBlock.long16, the output string field float16 maps to an UIF float field OUTPUT.outputBlock.float16, the output string field double16 maps to an UIF double field OUTPUT.outputBlock.double16, the output carray field carray16 maps to an UIF vbinary field OUTPUT.outputBlock.carray16.
The code snippet which populates the input data, calls this service and the results are shown below.
fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "FMLTEST1");
hr = fn.useServiceProvider(sp);
hr = fn.prepare("callService");
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.cary16", "Hello World".getBytes());
String outStr1 = data.getAttrString("OUTPUT.outputBlock.string16" );
long outLong1 = data.getAttrInt("OUTPUT.outputBlock.long16" );
int outInt1 = data.getAttrInt("OUTPUT.outputBlock.int16" );
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" );
throw new ApplicationException(e);
} finally { if (sp != null && sp.isEnabled()) sp.disable(); }
FMLTEST 2 Example
Consider another service FMLTEST2 which returns a FML buffer with all the fields in it having multiple occurrences. The output fields in the buffer be string16, long16, int16, short16, float16, double16, char16. Since the output FML buffer has fields which have multiple occurrence, in the service definition time, these should be defined as arrays. The UIF data object returned after calling this service will then have the fields string16, long16, int16, short16, float16, double16, char16 as arrays fields in INPUT.inputBlock. You can use the UIF data object API getElemCount on the array element to get the number of elements for each field and then allocate sufficient arrays and retrieve the data back. The code to retrieve this is given belowIBSPDataObjectArray 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 intdo = (IBSDataObjectArray)
data.getAttrDataObject("OUTPUT.outputBlock.int16");
int outInt[] = new int[intdo.getElemCount()];
for (int i = 0; i < outInt.length; i++)
outInt[i] = intdo.getElemInt(i);
// similar code for the other output fields.
FML32 Buffers Example
The next example explains how to call Tuxedo services which use FML32 buffers. The procedure is exactly the same as that of FML buffers. Let us consider a more complex fictitious service FML32TEST1 which takes as input FML buffer and returns as output another FML buffer. The fields table this service uses are given below.# name number type flags comments
char32 1 char - this is a char field
string32 2 string - this is a string field
short32 3 short - this is a short field
long32 4 long - this is a long field
float32 5 float - this is a float field
double32 6 double - this is a double field
carray32 7 carray - this is a carray field
The input FML fields that the service expects in the input FML buffer be char32, string32, short32, long32, float32, double32 and carray32. Each is having a single occurrence only. The server output FML buffer contains the same fields, which are also single valued.
Before calling this service, the FML fields are mined by using the data mining tools. Then you should define the service in Jolt bulk loader or IDL format and imported into the repository under data source for instance, Tuxedo-OnlineBank for example. For the Jolt bulk loader syntax see:
http://edocs.beasys.com/tuxwle/jolt12/devgd/dvbulkld.htm#1019784
Data type mapping for input and output blocks
In the servlet/EJB, the input char field char32 maps to an UIF integer field INPUT.inputBlock.char32, the input string field string32 maps to an UIF string field INPUT.inputBlock.string32, the input string field short32 maps to an UIF string field INPUT.inputBlock.short32, the input string field long32 maps to an UIF string field INPUT.inputBlock.long32, the input string field float32 maps to an UIF float field INPUT.inputBlock.float32, the input string field double32 maps to an UIF double field INPUT.inputBlock.double32, the input carray field carray32 maps to an UIF vbinary field INPUT.inputBlock.carray32.In the servlet/EJB, the output char field char32 maps to an UIF integer field OUTPUT.outputBlock.char32, the output string field string32 maps to an UIF string field OUTPUT.outputBlock.string32, the output string field short32 maps to an UIF string field OUTPUT.outputBlock.short32, the output string field long32 maps to an UIF string field OUTPUT.outputBlock.long32, the output string field float32 maps to an UIF float field OUTPUT.outputBlock.float32, the output string field double32 maps to an UIF double field OUTPUT.outputBlock.double32, the output carray field carray32 maps to an UIF vbinary field OUTPUT.outputBlock.carray32.
The code snippet to populate the input data, to call this service and get the results back is shown below
fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "FML32TEST1");
hr = fn.useServiceProvider(sp);
hr = fn.prepare("callService");
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.cary32", "Hello World".getBytes());
String outStr1 = data.getAttrString("OUTPUT.outputBlock.str32" );
long outLong1 = data.getAttrInt("OUTPUT.outputBlock.long32" );
int outInt1 = data.getAttrInt("OUTPUT.outputBlock.int32" );
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" );
throw new ApplicationException(e);
} finally { if (sp != null && sp.isEnabled()) sp.disable(); }
Using VIEW Tuxedo Data Types
VIEW is a built-in Tuxedo type 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, which are based on the view description that is read at run time.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 parameter name must match the field name in that view. Since the Tuxedo runtime system can determine the space needed, based on the structure size, your application need not provide a buffer length. The runtime system can also automatically handle such things as computing how much data to send in a request or response, and handle encoding and decoding when the message transfers between different machine types. The VIEW32 type is like the FML32 type in that it allows for larger character fields and larger overall buffers.
The VIEW buffer maps to a C Structure and hence contains a set of fields. For the VIEW buffers, the data types of the individual fields can be float, double, long, short, int, dec_t, char, string and carray. UIF does not support all these data types. Thus a mapping need to be done to the nearest data type in UIF for each data type. The mapping is shown in the following table.
Table 2-4 Tuxedo VIEW Data Types
If a field in VIEW buffer is an array, it is mapped in UIF to an ARRAY object each element of the array is of corresponding UIF type for the field type.
Note: If any J2EE application on iPlanet Application Server Enterprise Connector for Tuxedo uses VIEW/VIEW32, before running the iPlanet Application Server, make sure that you set the VIEWDIR, VIEWDIR32, VIEWFILES, VIEWFILES32 environment variables appropriately. Otherwise, these services are not called and iPlanet Application Server returns an error. Information regarding how to set up these variables is present in Chapter 3, Setup of FML Programmers Guide that ships with the Tuxedo system.
Example 1
Let us consider a service VIEWTEST1 which uses an input Tuxedo VIEW buffer with name v16test1 and output buffer view v16test2. The view description file containing descriptions of v16test1 and v16test2 views has contents as shown below.# view def with all datatypes with count 1
# type cname fbname count flag size null
# type cname fbname count flag size null
The corresponding generated C Structures from viewc compiler is shown below.
Before calling the service, these VIEW files should be imported into the UIF repository using the tuxedo management console or command line tool viewminer and the service should be defined using jolt bulk loader format or the IDL format and imported into the UIF repository.
The code to populate the input view v16test1, call the service and get the results from output view v16test2 is shown below.
fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "VIEWTEST1");
hr = fn.useServiceProvider(sp);
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.1212);
for (int i = 0; i < 5; i ++) {
out.println("char1:"+ (char)data.getAttrInt("OUTPUT.outputBlock.char1" + ".["+i+"]") + "<br>");
out.println("str1:"+ data.getAttrString("OUTPUT.outputBlock.str1" + ".["+i+"]") + "<br>");
out.println("long1:"+ data.getAttrInt("OUTPUT.outputBlock.long1" + ".["+i+"]") + "<br>");
out.println("short1:"+ data.getAttrInt("OUTPUT.outputBlock.short1" + ".["+i+"]") + "<br>");
out.println("int1:"+ data.getAttrInt("OUTPUT.outputBlock.int1" + ".["+i+"]") + "<br>");
out.println("float1:"+ data.getAttrFloat("OUTPUT.outputBlock.float1" + ".["+i+"]") + "<br>");
out.println("double1:"+ data.getAttrDouble("OUTPUT.outputBlock.double1" + ".["+i+"]") + "<br>");
out.println("cary1:"+ (new String(data.getAttrVBinary("OUTPUT.outputBlock.cary1" + ".["+i+"]"))) + "<br>");
out.println("dec1:"+ data.getAttrDouble("OUTPUT.outputBlock.dec1" + ".["+i+"]") + "<br>");
Example 2
Let us consider a service VIEW32TEST which uses an input Tuxedo VIEW buffer with name v32test1 and output buffer view v32test2. The view description file containing descriptions of v32test1 and v32test2 views has contents as shown below.# view def with all datatypes with count 1
# type cname fbname count flag size null
# view def with all datatypes with count > 1
# type cname fbname count flag size null
The corresponding generated C Structures from viewc32 compiler is shown below.
Before calling the service, these VIEW32 files should be imported into the repository using the tuxedo management console or command line tool viewminer and the service should be defined using jolt bulk loader format or the IDL format and imported into the UIF repository.
The code to populate the input view v32test1, call the service and get the results from output view v32test2 is shown below.
fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "VIEW32TEST");
hr = fn.useServiceProvider(sp);
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.1212);
for (int i = 0; i < 5; i ++) {
out.println("char1:"+ (char)data.getAttrInt("OUTPUT.outputBlock.char1" + ".["+i+"]") + "<br>");
out.println("str1:"+ data.getAttrString("OUTPUT.outputBlock.str1" + ".["+i+"]") + "<br>");
out.println("long1:"+ data.getAttrInt("OUTPUT.outputBlock.long1" + ".["+i+"]") + "<br>");
out.println("short1:"+ data.getAttrInt("OUTPUT.outputBlock.short1" + ".["+i+"]") + "<br>");
out.println("int1:"+ data.getAttrInt("OUTPUT.outputBlock.int1" + ".["+i+"]") + "<br>");
out.println("float1:"+ data.getAttrFloat("OUTPUT.outputBlock.float1" + ".["+i+"]") + "<br>");
out.println("double1:"+ data.getAttrDouble("OUTPUT.outputBlock.double1" + ".["+i+"]") + "<br>");
out.println("cary1:"+ (new String(data.getAttrVBinary("OUTPUT.outputBlock.cary1" + ".["+i+"]"))) + "<br>");
out.println("dec1:"+ data.getAttrDouble("OUTPUT.outputBlock.dec1" + ".["+i+"]") + "<br>");
Example 3
Using X_Common data type, let us consider a service x_commonTEST which uses an input tuxedo x_common buffer with name xcomtest1 and output buffer x_common xcomtest2. The x_common description file containing descriptions of xcomtest1 and xcomtest2 x_commons has contents as shown below.# 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
The corresponding generated C Structures from viewc compiler is shown below.
Before calling the service, these x_common files should be imported into the UIF repository using the Tuxedo Management Console or command line tool x_commonminer and the service should be defined using Jolt bulk loader format or the IDL format and imported into the UIF repository.
The code to populate the input x_common xcomtest1, call the service and get the results from output x_common xcomtest2 is shown below.
fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "x_commonTEST");
hr = fn.useServiceProvider(sp);
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);
for (int i = 0; i < 10; i ++) {
out.println("char1:"+ (char)data.getAttrInt("OUTPUT.outputBlock.char1" + ".["+i+"]") + "<br>");
out.println("str1:"+ data.getAttrString("OUTPUT.outputBlock.str1" + ".["+i+"]") + "<br>");
out.println("long1:"+ data.getAttrInt("OUTPUT.outputBlock.long1" + ".["+i+"]") + "<br>");
out.println("short1:"+ data.getAttrInt("OUTPUT.outputBlock.short1" + ".["+i+"]") + "<br>");
Example 4
Using x_c_type data type, let us consider a service x_c_typeTEST which uses an input tuxedo x_c_type buffer with name xctest1 and output buffer x_c_type xctest2. The x_c_type description file containing descriptions of xctest1 and xctest2 x_c_types has contents as shown below.# 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
The corresponding generated C Structures from viewc compiler is shown below.
Before calling the service, these x_c_type files should be imported into the repository using the tuxedo management console or command line tool x_c_typeminer and the service should be defined using jolt bulk loader format or the IDL format and imported into the repository.
The code to populate the input x_c_type xctest1, call the service and get the results from output x_c_type xctest2 is shown below.
fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "x_c_typeTEST");
hr = fn.useServiceProvider(sp);
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);
for (int i = 0; i < 10; i ++) {
out.println("char1:"+ (char)data.getAttrInt("OUTPUT.outputBlock.char1" + ".["+i+"]") + "<br>");
out.println("str1:"+ data.getAttrString("OUTPUT.outputBlock.str1" + ".["+i+"]") + "<br>");
out.println("long1:"+ data.getAttrInt("OUTPUT.outputBlock.long1" + ".["+i+"]") + "<br>");
out.println("short1:"+ data.getAttrInt("OUTPUT.outputBlock.short1" + ".["+i+"]") + "<br>");
Tuxedo Online Bank Sample
Instructions for running Tuxedo Online Bank ExampleBEA Tuxedo comes with a sample application called bankapp. This is in <Tuxedo>/APPS/bankapp directory. On the Tuxedo server side, make sure that this application is built, configured and running properly. Refer to BEA's Tuxedo Application Development Guide for instructions on configuring this application. Also, The workstation client of Tuxedo comes with a client version of the same application which is a GUI based workstation client.
Make sure the bankapp Tuxedo server is up and running and is configured properly.
Once these steps are done correctly, this sample application should run without any problem.
Double check the datasource Tuxedo-OnlineBank configuration structure in bspbrowser for the configuration information settings like WSNADDR, WSDEVICE and TUXDIR.
- To double check this, on the machine where iPlanet Application Server Enterprise Connector for Tuxedo is installed, compile and run the Workstation client application that ships with BEA Tuxedo and is in directory <TuxedoWS Directory>/APPS/ws. (Note that Tuxedo/WS software should be present in the machine where iAS for Tuxedo is installed).
On Solaris system, make sure that the environment variables LD_LIBRARY_PATH includes the tuxedo workstation libraries directory (<TUXWSDIR>/lib).
Use account numbers for testing in the range of 100001 - 100007 etc. (See bankapp server source for more information of valid account numbers).
OnlineBank Tuxedo Sample Additional Information
iPlanet Application Server Enterprise Connector for Tuxedo is an highly scalable web connectivity solution to BEA Tuxedo system which allows HTTP servlets/EJBs running in iPlanet Application Server 6.0 J2EE App call the services of BEA Tuxedo system. iPlanet Application Server Enterprise Connector for Tuxedo allows Tuxedo applications to be web-enabled, using the iPlanet Application Server 6.0 as an HTTP and application server.
Key Features
Key features of this architecture include:
Enables use of Java HTTP servlets/EJBs to provide a dynamic HTML front-end for Tuxedo applications
Provides session pooling to use Tuxedo resources efficiently
Provides extensive failover capabilities
Supports client side transactions
Integrates session pool management into the iPlanet Application Server Enterprise Connector for Tuxedo Management Console
About Tuxedo OnlineBank Example
This section provides step-by-step information on understanding/running the iPlanet Application Server Enterprise Connector for Tuxedo OnlineBank example, a J2EE application to access a Tuxedo service that calls various services for banking.There are two parts to the OnlineBank example: the J2EE application that is shipped with the iPlanet Application Server Enterprise Connector for Tuxedo examples, and the Tuxedo service application (bankapp) that is shipped with the Tuxedo examples. The Tuxedo bankapp server contains the services WITHDRAWAL, DEPOSIT, TRANSFER, INQUIRY, CLOSE_ACCT, OPEN_ACCT. The INQUIRY service accepts an integer input FML field ACCOUNT_ID and returns a string result FML field SBALANCE.
You can find the source code for the TuxBank example in the <iASinstallation>/ias/APPS/TuxBank directory.
Here is what you'll find in the TuxBank example directory:
BankServlet.java Sample Servlet that calls the BankManagerBean EJB which in turn calls Tuxedo
IBankManager.java IBankManagerHome.java BankManagerBean.java
The stateless EJB which calls the Tuxedo service:
jsp/AccountCloseForm.jsp jsp/AccountOpenForm.jsp
JSPs for the J2EE application. XXXForm.jsp displays a form for input and when the user submits the form, calls the Servlet BankServlet.java which in turn does trivial validation and calls the EJB BankManager which in turn forwards the request to the Tuxedo System using BSP API. The response is taken and sent back to the servlet which in turn calls a JSP ShowXXX.jsp to display the results back to the user. In case of Error, ErrorPage.jsp is shown with appropriate error message.jsp/BalanceQueryForm.jsp jsp/Copyright.jsp jsp/DepositAmountForm.jsp
jsp/ErrorPage.jsp jsp/Footer.jsp jsp/Header.jsp jsp/MainMenu.jsp
jsp/ShowAccountClose.jsp jsp/ShowAccountOpen.jsp jsp/ShowBalance.jsp
jsp/ShowDeposit.jsp jsp/ShowTransfer.jsp jsp/ShowWithdrawl.jsp
tuxbank.ear
The J2EE packaged application. Register it with iPlanet Application Server 6.0 using command j2eeappreg tuxbankJSPs for the J2EE application. XXXForm.jsp displays a form for input and when the user submits the form, calls the Servlet BankServlet.java which in turn does trivial validation and calls the EJB BankManager which in turn forwards the request to the Tuxedo System using BSP API. The response is taken and sent back to the servlet which in turn calls a JSP ShowXXX.jsp to display the results back to the user. In case of Error, ErrorPage.jsp is shown with appropriate error message.
The iPlanet Application Builder 6.0 can be used to Rapidly develop applications like these in a short period of time. The entire Tuxedo OnlineBank Example is developed and tested using iAB 6.0.
A complete listing of the Tuxedo server-side source code of the bankapp application service is located in the Tuxedo distribution in the >$TUXDIR/apps/bankapp where $TUXDIR is the Tuxedo home directory.
To run this example, you should be familiar with:
The Tuxedo architecture and the sample application, simpapp
iPlanet Application Server Enterprise Connector for Tuxedo
Overview
The TuxBank example is easy to follow. Just launch the http://<hostname>/GXApp/TuxBank page from the web Server and select the MainMenu link in there. Rest of it is very self explanatory.Select one of the options in the menu say Deposit. The deposit form is displayed. Enter the account number and the deposit amount and click the SUBMIT button to submit the request.
The BankServlet calls the EJB BankManager which in turn uses BSP API to populate the input data for the tuxedo service, calls the service, gets back the results which are passed back to servlet which in turn forwards it into jsp which displays the results.
Getting Started Checklist
Verify that you have a supported browser (Netscape or IE, later than 3.2) installed on your client machine. The client machine must have a network connection to the iPlanet Application Server Enterprise Connector for Tuxedo that is used to connect to the Tuxedo environment.Configure and boot Tuxedo and the bankapp example.
Follow the directions in the Tuxedo user documentation to bring up the server side bankapp application. Make sure the WITHDRAWAL, DEPOSIT, TRANSFER, INQUIRY, CLOSE_ACCT, OPEN_ACCT services are available.
Set up the data source for iPlanet Application Server Enterprise Connector for Tuxedo. Refer to the iPlanet Application Server Enterprise Connector for Tuxedo Administrator's Guide for details.
Ensure that the WITHDRAWAL, DEPOSIT, TRANSFER, INQUIRY, CLOSE_ACCT, OPEN_ACCT services are defined in the iAS for Tuxedo 6.0 data source Repository.
The bankapp repository definition is present in <iasinstallation>/ias/APPS/adapters/tux/samples/metadata/BankDataSource.xml. Import this XML file into the repository after required modifications.
Writing applications for iPlanet Application Server Enterprise Connector for Tuxedo.
Calling a configured and imported service from a servlet or EJB:
Packages
Configuring data Source and services in repository
- To use iPlanet Application Server Enterprise Connector for Tuxedo, import the following into your servlet or EJBs:
Getting a runtime instance (refer to UIF API Developer's Guide)
- Use the tuxedo management console to create/edit data source (tuxconsole.bat or tuxconsole.sh).
- Use fmlminer command line utility to mine the fml/fml32 tables into the repository.
- Use viewminer command line utility to mine the view/view32/xcommon/xctype tables into the repository.
- Define the services in Jolt Bulk Loader format and import them inside the repository using the joltmigrator tool. The OnlineBank application services are defined in Jolt Bulk Loader format and are present in the <ias installation>/ias/APPS/TuxBank/joltbankfo.txt file.
Getting the service provider (refer to BSP API Reference)
- In a servlet/EJB using,
- com.kivasoft.IContext ctx = com.kivasoft.util.GX.GetContext();
- IBSPRuntime ibspruntime = access_cBSPRuntime.getcBSPRuntime(ctx, null, null);
Calling a tuxedo service
- IBSPServiceProvider sp = runtime.createServiceProvider("Tuxedo-OnlineBank", "tuxConnection");
- where "Tuxedo-OnlineBank" is the data source name and "tuxConnection" is the type of the service provider requested (in this case it is a non transactional service provider. If you give tuxConnectionTx, we get a transactional tuxedo service provider on which we can call tuxedo services under client side transaction.
Setting the security attributes (if a service expects any)
Disabling the data source
Creating a function object
- IBSPDataObject config = sp.getConfig();
- if (config != null) {
- config.setAttrString("WebUserName", "webuser-smith");
- }
Enabling the service provider
Preparing the service provider and setting up
Populating the input data
Calling the service
- data = fn.getDataBlock();
- data.setAttrInt("INPUT.inputBlock.ACCOUNT_ID", Integer.parseInt(accountNumber));
Getting the output results from the service
Converting DataObject Data Types to Tuxedo Data Types
The following is a mapping between Java types and Tuxedo parameter types required by a Tuxedo service. Use the appropriate DO types for the value to the DataObject.
FML, FML32, VIEW, VIEW32, X_COMMON, X_C_TYPE <---> struct
primitive c_array, primitive X_OCTET <--> vbinary
Handling Exceptions
Errors or failures that may occur when iAS for Tuxedo initiates a Tuxedo service call are reported to your application via Java exceptions. You should always enclose the execute() method within a try / catch block and attempt to deal with any exceptions appropriately. See the BankManagerBean.java EJB implementation source code for example. The execute() method can throw a runtime exception netscape.bsp.BSPException and the application program can catch and handle that exception appropriately.The BSPException class instance that is thrown as exception has methods to get more information regarding the actual exception. If the exception is due to a tuxedo system error, one can get more information about the error by getting the info object on the exception by calling its getInfo() method and getting attributes errno and errstr in that. Here is the code snippet of how to do it
IBSPDataObjectStructure info = null;
errorMessage = "Error in service Execution : <br>" +
"Error message from adapter : " + e.getMessage() + "<br>";
errorMessage += (info.attrExists("errno") ? " Tuxedo System Error code : " + info.getAttrInt("errno") + "<br>" : "") +
(info.attrExists("errstr") ? " Tuxedo System Error string : " + info.getAttrString("errstr") + "<br>" : "");
Code Snippet for BankServlet.java
The netscape.tux.TuxError has constants which can be compared with the errno attribute return value for Tuxedo specific errors.Code Snippet for BankServlet.javawhich handles requests for the users and forwards it to EJB and displays results by invoking the JSP.
** BankServlet is a blank servlet to which you add your own code.
public class BankServlet extends HttpServlet
public void init(ServletConfig config) throws ServletException
public void doBalanceQuery(HttpServletRequest req, HttpServletResponse res)
String accountNumber = req.getParameter("AccountNumber");
if (accountNumber == null || accountNumber.length() == 0)
throw new Exception("Account Number missing in the request !!");
IBankManager bankManager = getBankManager();
String balance = bankManager.balanceQuery(accountNumber, req.getParameter("txn") != null);
// format the results and invoke results page
req.setAttribute("AccountBalance", balance);
req.setAttribute("AccountNumber", accountNumber);
RequestDispatcher dispatcher = getServletContext().
getRequestDispatcher("/jsp/ShowBalance.jsp");
public void doDepositAmount(HttpServletRequest req, HttpServletResponse res)
String accountNumber = req.getParameter("AccountNumber");
if (accountNumber == null || accountNumber.length() == 0)
throw new Exception("Account Number missing in the request !!");
String depositAmountStr = req.getParameter("DepositAmount");
if (depositAmountStr == null || depositAmountStr.length() == 0)
throw new Exception("Deposit Amount missing in the request !!");
depositAmount = java.text.NumberFormat.getNumberInstance().parse(depositAmountStr). doubleValue();
throw new Exception ("Deposit Amount entered is invalid !!");
throw new Exception ("Deposit Amount entered is invalid !!");
IBankManager bankManager = getBankManager();
String balance = bankManager.depositAmount(accountNumber, depositAmount, req.getParameter("txn") != null);
// format the results and invoke results page
req.setAttribute("OldBalance",
java.text.NumberFormat.getCurrencyInstance(Locale.US).format(
Double.parseDouble(balance.replace('$',' ')) - depositAmount
req.setAttribute("NewBalance", balance);
req.setAttribute("DepositAmount", java.text.NumberFormat.getCurrencyInstance(Locale.US).format(deposi tAmount));
req.setAttribute("AccountNumber", accountNumber);
RequestDispatcher dispatcher = getServletContext().
getRequestDispatcher("/jsp/ShowDeposit.jsp");
public void doOpenAccount(HttpServletRequest req, HttpServletResponse res)
AccountData acctData = new AccountData();
String branch = req.getParameter("Branch");
throw new Exception("Invalid/NO branch id selected !!");
String ssn = req.getParameter("SSN");
if (ssn == null || ssn.length() != 11)
throw new Exception("SSN Invalid <br> Use Browser Back Button and Enter SSN in format NNN-NN-NNNN!!");
String depositAmountStr = req.getParameter("INITIALBALANCE");
if (depositAmountStr == null || depositAmountStr.length() == 0)
throw new Exception("Initial Balance missing in the request <br> Use Browser Back Button and Enter SSN in format NNN-NN-NNNN!!!!");
depositAmount = java.text.NumberFormat.getNumberInstance().parse(depositAmountStr). doubleValue();
throw new Exception ("Initial Deposit Amount entered is invalid !!<br> Use Browser Back Button and reenter it");
throw new Exception ("Initial Deposit Amount entered is invalid !!<br> Use Browser Back Button and reenter it!!");
acctData.setBalance(depositAmount);
String fname = req.getParameter("FIRSTNAME");
if (fname == null || fname.length() <= 0)
throw new Exception("First Name Not entered <br> Use Browser Back Button and reenter it!!");
String mname = req.getParameter("MIDDLENAME");
if (mname == null || mname.length() <= 0)
acctData.setMiddleName(mname);
String lname = req.getParameter("LASTNAME");
if (lname == null || lname.length() <= 0)
throw new Exception("Last Name Not entered <br> Use Browser Back Button and reenter it!!");
String address = req.getParameter("ADDRESS");
if (address == null || address.length() <= 0)
throw new Exception("Address not entered <br> Use Browser Back Button and reenter it!!");
String address2 = req.getParameter("ADDRESS2");
if (address2 == null || address2.length() <= 0)
acctData.setAddress2(address2);
String city = req.getParameter("CITY");
if (city == null || city.length() <= 0)
throw new Exception("City not entered <br> Use Browser Back Button and reenter it!!");
String state = req.getParameter("STATE");
if (state == null || state.length() <= 0)
throw new Exception("State not entered <br> Use Browser Back Button and reenter it!!");
String zip = req.getParameter("ZIP");
if (zip == null || zip.length() <= 0)
throw new Exception("Zipcode not entered <br> Use Browser Back Button and reenter it!!");
String homePhone = req.getParameter("HOMEPHONE");
if (homePhone == null || homePhone.length() <= 0)
throw new Exception("HomePhone not entered <br> Use Browser Back Button and reenter it!!");
acctData.setHomePhone(homePhone);
String workPhone = req.getParameter("WORKPHONE");
if (workPhone == null || workPhone.length() <= 0)
throw new Exception(" Work Phone not entered <br> Use Browser Back Button and reenter it!!");
acctData.setWorkPhone(workPhone);
IBankManager bankManager = getBankManager();
String acctNum = bankManager.openAccount(acctData, req.getParameter("txn") != null);
acctData.setAccountNumber(acctNum);
req.setAttribute("accountdata", acctData);
RequestDispatcher dispatcher = getServletContext().
getRequestDispatcher("/jsp/ShowAccountOpen.jsp");
public void doCloseAccount(HttpServletRequest req, HttpServletResponse res)
String accountNumber = req.getParameter("AccountNumber");
if (accountNumber == null || accountNumber.length() == 0)
throw new Exception("Account Number missing in the request !!");
// TODO: perform other validations for account number if necessary
IBankManager bankManager = getBankManager();
String balance = bankManager.closeAccount(accountNumber, req.getParameter("txn") != null);
// format the results and invoke results page
req.setAttribute("ClosingBalance", balance);
req.setAttribute("AccountNumber", accountNumber);
RequestDispatcher dispatcher = getServletContext().
getRequestDispatcher("/jsp/ShowAccountClose.jsp");
public void doTransferAmount(HttpServletRequest req, HttpServletResponse res)
String fromAccountNumber = req.getParameter("FromAccountNumber");
if (fromAccountNumber == null || fromAccountNumber.length() == 0)
throw new Exception("From Account Number missing in the request !!");
String toAccountNumber = req.getParameter("ToAccountNumber");
if (toAccountNumber == null || toAccountNumber.length() == 0)
throw new Exception("To Account Number missing in the request !!");
String transferAmountStr = req.getParameter("Amount");
if (transferAmountStr == null || transferAmountStr.length() == 0)
throw new Exception("Transfer Amount missing in the request !!");
// TODO: perform other validations for account number and transfer if necessary
transferAmount = java.text.NumberFormat.getNumberInstance().parse(transferAmountStr) .doubleValue();
throw new Exception ("Transfer Amount entered is invalid !!");
throw new Exception ("Transfer Amount entered is invalid !!");
IBankManager bankManager = getBankManager();
String balance[] = bankManager.transferAmount(fromAccountNumber, toAccountNumber, transferAmount, req.getParameter("txn") != null);
// format the results and invoke results page
req.setAttribute("FromAccountNumber", fromAccountNumber);
req.setAttribute("ToAccountNumber", toAccountNumber);
req.setAttribute("TransferAmount", java.text.NumberFormat.getCurrencyInstance(Locale.US).format(transf erAmount));
req.setAttribute("FromBalance", balance[0]);
req.setAttribute("ToBalance", balance[1]);
RequestDispatcher dispatcher = getServletContext().
getRequestDispatcher("/jsp/ShowTransfer.jsp");
public void doWithdrawAmount(HttpServletRequest req, HttpServletResponse res)
String accountNumber = req.getParameter("AccountNumber");
if (accountNumber == null || accountNumber.length() == 0)
throw new Exception("Account Number missing in the request !!");
String withdrawlAmountStr = req.getParameter("WithdrawlAmount");
if (withdrawlAmountStr == null || withdrawlAmountStr.length() == 0)
throw new Exception("Withdrawl Amount missing in the request !!");
withdrawlAmount = java.text.NumberFormat.getNumberInstance().parse(withdrawlAmountStr ).doubleValue();
throw new Exception ("Withdrawl Amount entered is invalid !!");
throw new Exception ("Withdrawl Amount entered is invalid !!");
IBankManager bankManager = getBankManager();
String balance = bankManager.withdrawAmount(accountNumber, withdrawlAmount, req.getParameter("txn") != null);
baldouble = Double.parseDouble(balance.replace('$',' '));
} catch (Exception e) { throw new ApplicationException("Invalid balance " + balance + " returned from service call. Error: " + e.getMessage()); }
// format the results and invoke results page
req.setAttribute("OldBalance", java.text.NumberFormat.getCurrencyInstance(Locale.US).format(baldou ble + withdrawlAmount));
req.setAttribute("NewBalance", balance);
req.setAttribute("WithdrawlAmount", java.text.NumberFormat.getCurrencyInstance(Locale.US).format(withdr awlAmount));
req.setAttribute("AccountNumber", accountNumber);
RequestDispatcher dispatcher = getServletContext().
getRequestDispatcher("/jsp/ShowWithdrawl.jsp");
public void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
res.setContentType("text/html");
// decide what this servlet has been invoked for ....
String action = req.getParameter("Action");
if (action == null || action.trim().equals(""))
new ErrorHandler(this, req, res).displayError("Invalid Action parameter " + action + " !");
else if (action.equalsIgnoreCase("BalanceQuery") )
else if (action.equalsIgnoreCase("DepositAmount") )
else if (action.equalsIgnoreCase("OpenAccount") )
else if (action.equalsIgnoreCase("CloseAccount") )
else if (action.equalsIgnoreCase("TransferAmount") )
else if (action.equalsIgnoreCase("WithdrawAmount") )
new ErrorHandler(this, req, res).displayError("Invalid Action parameter " + action + " !");
new ErrorHandler(this, req, res).displayError(e.getMessage());
* Utility function that Returns the BankManager stateless session EJBean .
private IBankManager getBankManager() throws Exception
IBankManagerHome bankManagerHome = BankManagerUtil.getBankManagerHome();
throw new Exception ("BankManager Home is null");
((com.netscape.server.servlet.platformhttp.PlatformServletContext)
getServletContext()).getContext();
IBankManager bankManager = bankManagerHome.create();
bankManager.setSessionContext(_ctx);
* Returns a string that contains information about the servlet.
public String getServletInfo()
return "This servlet handles bankManager requests";
IBankManager.java - Interface for the Stateless EJB
package TuxBank;import java.rmi.RemoteException;
public interface IBankManager extends EJBObject
public void setSessionContext(com.kivasoft.IContext ctx)
throws java.rmi.RemoteException;
public String balanceQuery(String accountNumber, boolean bTxn)
throws java.rmi.RemoteException, ApplicationException;
// returns balance after deposit
public String depositAmount(String accountNumber, double amount, boolean bTxn)
throws java.rmi.RemoteException, ApplicationException;
// returns balance after withdraw
public String withdrawAmount(String accountNumber, double amount, boolean bTxn)
throws java.rmi.RemoteException, ApplicationException;
// returns balances in from and to account numbers
public String[] transferAmount(String frmAccountNumber, String toAccountNumber, double amount, boolean bTxn)
throws java.rmi.RemoteException, ApplicationException;
// return final closing balance
public String closeAccount(String accountNumber, boolean bTxn)
throws java.rmi.RemoteException, ApplicationException;
// returns AccountNumber if successfull
public String openAccount(AccountData acctData, boolean bTxn)
throws java.rmi.RemoteException, ApplicationException;
The EJB That Calls the Tuxedo Services
package TuxBank;import netscape.bsp.runtime.*;
import netscape.bsp.dataobject.*;
* The enterprise-bean class for a Session Enterprise Java Bean.
* After generation, this class contains the required methods for bean compilation and
* deployment, but no business logic.
* The bean developer may add create and business methods here, matching the
* corresponding methods in the remote and home interfaces.
* A create method with no arguments is required for all session EJBs.
public class BankManagerBean implements javax.ejb.SessionBean
private SessionContext _sessionContext;
private com.kivasoft.IContext m_ctx;
* Called by the container after creating this instance, and before transferring it to the pool of
* available instances. This is a good place to allocate resources which are scoped to the lifetime
* @param ctx SessionContext the link between this bean and its container
* @exception RemoteException if there are problems with RMI
public void setSessionContext(SessionContext ctx)
public void setSessionContext(com.kivasoft.IContext ctx)
* Called by the container after the instance has its session context, to "customize" the
* bean with information from a specific session. This is the only create method allowed for
* @exception CreateException if there are problems during creation
* @exception RemoteException if there are problems with RMI
public void ejbCreate() throws java.rmi.RemoteException, javax.ejb.CreateException
* Called by the container when this instance is being destroyed due to a user remove()
* operation, or after expiration of a timeout.
* @exception RemoteException if there are problems with RMI
public void ejbRemove() throws java.rmi.RemoteException
* Called when the instance is activated from its "passive" state. The instance should
* acquire any resource that it has released earlier in the ejbPassivate() method.
* @exception RemoteException if there are problems with RMI
* @exception RemoveException to disallow removing the instance
public void ejbActivate() throws java.rmi.RemoteException
* Called before the instance enters the "passive" state. The instance should release
* any resources that it can re-acquire later in the ejbActivate() method.
* @exception RemoteException if there are problems with RMI
* @exception RemoveException to disallow removing the instance
public void ejbPassivate() throws java.rmi.RemoteException
* Null constructor, mandatory for serialization/activation/passivation.
public String balanceQuery(String accountNumber, boolean bTxn)
throws java.rmi.RemoteException, ApplicationException
debugPrintln(" Before getRuntime()");
IBSPRuntime runtime = getRuntime();
debugPrintln("After getRuntime()");
debugPrintln("Before getServiceProvider()");
IBSPServiceProvider sp = null;
tx = new TuxTransaction(runtime, "Tuxedo-OnlineBank");
} catch (BspException e) { throw new ApplicationException(e); }
sp =getServiceProvider(runtime);
debugPrintln("After getServiceProvider()");
IBSPDataObject data = null, prop = null;
debugPrintln("Before createFunctionObject()");
fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "INQUIRY");
debugPrintln("After createFunctionObject()");
debugPrintln("After enable(), hr = "+hr);
hr = fn.useServiceProvider(sp);
debugPrintln("After useServiceProvider(), hr = "+hr);
hr = fn.prepare("callService");
debugPrintln("After prepare(), hr = "+hr);
debugPrintln("After getDataBlock()");
data.setAttrInt("INPUT.inputBlock.ACCOUNT_ID", Integer.parseInt(accountNumber));
debugPrintln("Before execute()");
try { if (tx != null) tx.rollback(); } catch (Exception exxxx) {}
throw new ApplicationException(e);
String outputBalance = data.getAttrString("OUTPUT.outputBlock.SBALANCE");
throw new ApplicationException(e);
} finally { if (sp != null && sp.isEnabled()) sp.disable(); }
public String depositAmount(String accountNumber, double amount, boolean bTxn)
throws java.rmi.RemoteException, ApplicationException
debugPrintln(" Before getRuntime()");
IBSPRuntime runtime = getRuntime();
debugPrintln("After getRuntime()");
debugPrintln("Before getServiceProvider()");
IBSPServiceProvider sp = null;
tx = new TuxTransaction(runtime, "Tuxedo-OnlineBank");
} catch (BspException e) { throw new ApplicationException(e); }
sp =getServiceProvider(runtime);
debugPrintln("After getServiceProvider()");
IBSPDataObject data = null, prop = null;
debugPrintln("Before createFunctionObject()");
fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "DEPOSIT");
debugPrintln("After createFunctionObject()");
debugPrintln("After enable(), hr = "+hr);
hr = fn.useServiceProvider(sp);
debugPrintln("After useServiceProvider(), hr = "+hr);
hr = fn.prepare("callService");
debugPrintln("After prepare(), hr = "+hr);
debugPrintln("After getDataBlock()");
data.setAttrInt("INPUT.inputBlock.ACCOUNT_ID", Integer.parseInt(accountNumber));
data.setAttrString("INPUT.inputBlock.SAMOUNT", ""+amount);
debugPrintln("Before execute()");
try { if (tx != null) tx.rollback(); } catch (Exception exxxx) {}
throw new ApplicationException(e);
String outputBalance = data.getAttrString("OUTPUT.outputBlock.SBALANCE");
throw new ApplicationException(e);
} finally { if (sp != null && sp.isEnabled()) sp.disable(); }
public String withdrawAmount(String accountNumber, double amount, boolean bTxn)
throws java.rmi.RemoteException, ApplicationException
debugPrintln(" Before getRuntime()");
IBSPRuntime runtime = getRuntime();
debugPrintln("After getRuntime()");
debugPrintln("Before getServiceProvider()");
IBSPServiceProvider sp = null;
tx = new TuxTransaction(runtime, "Tuxedo-OnlineBank");
} catch (BspException e) { throw new ApplicationException(e); }
sp =getServiceProvider(runtime);
debugPrintln("After getServiceProvider()");
IBSPDataObject data = null, prop = null;
debugPrintln("Before createFunctionObject()");
fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "WITHDRAWAL");
debugPrintln("After createFunctionObject()");
debugPrintln("After enable(), hr = "+hr);
hr = fn.useServiceProvider(sp);
debugPrintln("After useServiceProvider(), hr = "+hr);
hr = fn.prepare("callService");
debugPrintln("After prepare(), hr = "+hr);
debugPrintln("After getDataBlock()");
data.setAttrInt("INPUT.inputBlock.ACCOUNT_ID", Integer.parseInt(accountNumber));
data.setAttrString("INPUT.inputBlock.SAMOUNT", ""+amount);
debugPrintln("Before execute()");
try { if (tx != null) tx.rollback(); } catch (Exception exx) {}
throw new ApplicationException(e);
String outputBalance = data.getAttrString("OUTPUT.outputBlock.SBALANCE");
throw new ApplicationException(e);
} finally { if (sp != null && sp.isEnabled()) sp.disable(); }
public String[] transferAmount(String frmAccountNumber, String toAccountNumber, double amount, boolean bTxn)
throws java.rmi.RemoteException, ApplicationException
debugPrintln(" Before getRuntime()");
IBSPRuntime runtime = getRuntime();
debugPrintln("After getRuntime()");
debugPrintln("Before getServiceProvider()");
IBSPServiceProvider sp = null;
tx = new TuxTransaction(runtime, "Tuxedo-OnlineBank");
} catch (BspException e) { throw new ApplicationException(e); }
sp =getServiceProvider(runtime);
debugPrintln("After getServiceProvider()");
IBSPDataObject data = null, prop = null;
debugPrintln("Before createFunctionObject()");
IBSPDataObject config = sp.getConfig();
fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "TRANSFER");
debugPrintln("After createFunctionObject()");
debugPrintln("After enable(), hr = "+hr);
hr = fn.useServiceProvider(sp);
debugPrintln("After useServiceProvider(), hr = "+hr);
hr = fn.prepare("callService");
debugPrintln("After prepare(), hr = "+hr);
debugPrintln("After getDataBlock()");
data.setAttrString("INPUT.inputBlock.SAMOUNT", ""+amount);
IBSPDataObjectList listObj = (IBSPDataObjectList) data.getAttrDataObject("INPUT.inputBlock.ACCOUNT_ID");
listObj.addElemInt(Integer.parseInt(frmAccountNumber));
listObj.addElemInt(Integer.parseInt(toAccountNumber));
debugPrintln("Before execute()");
try { if (tx != null) tx.rollback(); } catch (Exception exx) {}
throw new ApplicationException(e);
listObj = (IBSPDataObjectList) data.getAttrDataObject("OUTPUT.outputBlock.SBALANCE");
String frmBalanceStr = listObj.getElemString(0);
String toBalanceStr = listObj.getElemString(1);
return new String[] { frmBalanceStr, toBalanceStr};
throw new ApplicationException(e);
} finally { if (sp != null && sp.isEnabled()) sp.disable(); }
public String closeAccount(String accountNumber, boolean bTxn)
throws java.rmi.RemoteException, ApplicationException
debugPrintln(" Before getRuntime()");
IBSPRuntime runtime = getRuntime();
debugPrintln("After getRuntime()");
debugPrintln("Before getServiceProvider()");
IBSPServiceProvider sp = null;
tx = new TuxTransaction(runtime, "Tuxedo-OnlineBank");
} catch (BspException e) { throw new ApplicationException(e); }
sp =getServiceProvider(runtime);
debugPrintln("After getServiceProvider()");
IBSPDataObject data = null, prop = null;
debugPrintln("Before createFunctionObject()");
fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "CLOSE_ACCT");
debugPrintln("After createFunctionObject()");
debugPrintln("After enable(), hr = "+hr);
hr = fn.useServiceProvider(sp);
debugPrintln("After useServiceProvider(), hr = "+hr);
hr = fn.prepare("callService");
debugPrintln("After prepare(), hr = "+hr);
debugPrintln("After getDataBlock()");
data.setAttrInt("INPUT.inputBlock.ACCOUNT_ID", Integer.parseInt(accountNumber));
debugPrintln("Before execute()");
try { if (tx != null) tx.rollback(); } catch (Exception exx) {}
throw new ApplicationException(e);
String outputBalance = data.getAttrString("OUTPUT.outputBlock.SBALANCE");
throw new ApplicationException(e);
} finally { if (sp != null && sp.isEnabled()) sp.disable(); }
public String openAccount(AccountData acctData, boolean bTxn)
throws java.rmi.RemoteException, ApplicationException
debugPrintln(" Before getRuntime()");
IBSPRuntime runtime = getRuntime();
debugPrintln("After getRuntime()");
debugPrintln("Before getServiceProvider()");
IBSPServiceProvider sp = null;
tx = new TuxTransaction(runtime, "Tuxedo-OnlineBank");
} catch (BspException e) { throw new ApplicationException(e); }
sp =getServiceProvider(runtime);
debugPrintln("After getServiceProvider()");
IBSPDataObject data = null, prop = null;
debugPrintln("Before createFunctionObject()");
fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "OPEN_ACCT");
debugPrintln("After createFunctionObject()");
debugPrintln("After enable(), hr = "+hr);
hr = fn.useServiceProvider(sp);
debugPrintln("After useServiceProvider(), hr = "+hr);
hr = fn.prepare("callService");
debugPrintln("After prepare(), hr = "+hr);
debugPrintln("After getDataBlock()");
data.setAttrString("INPUT.inputBlock.SSN", acctData.getSSN());
data.setAttrString("INPUT.inputBlock.LAST_NAME", acctData.getLastName());
data.setAttrString("INPUT.inputBlock.FIRST_NAME", acctData.getFirstName());
data.setAttrString("INPUT.inputBlock.SAMOUNT", ""+acctData.getBalance());
String str = acctData.getMiddleName();
if (str != null && str.length() > 0)
data.setAttrInt("INPUT.inputBlock.MID_INIT", (int) midinit);
str = acctData.getAccountType();
if (str != null && str.length() > 0)
data.setAttrInt("INPUT.inputBlock.ACCT_TYPE", accttype);
data.setAttrString("INPUT.inputBlock.ADDRESS", ""+acctData.getAddress() + ", " +
acctData.getAddress2() + ", " +
data.setAttrInt("INPUT.inputBlock.BRANCH_ID", Integer.parseInt(acctData.getBranch()));
data.setAttrString("INPUT.inputBlock.PHONE", ""+acctData.getWorkPhone());
debugPrintln("Before execute()");
try { if (tx != null) tx.rollback(); } catch (Exception exx) {}
throw new ApplicationException(e);
String outputBalance = data.getAttrString("OUTPUT.outputBlock.SBALANCE");
int accountNumber = data.getAttrInt("OUTPUT.outputBlock.ACCOUNT_ID");
throw new ApplicationException(e);
} finally { if (sp != null && sp.isEnabled()) sp.disable(); }
private IBSPRuntime getRuntime() throws ApplicationException
debugPrintln(" before access_cBSPRuntime.getcBSPRuntime ");
IBSPRuntime ibspruntime = access_cBSPRuntime.getcBSPRuntime(m_ctx, null, null);
debugPrintln(" after access_cBSPRuntime.getcBSPRuntime ");
throw new Exception("access method returned null !");
throw new ApplicationException("Unable to get Runtime object. Error : " + e.getMessage());
private IBSPServiceProvider getServiceProvider(IBSPRuntime runtime) throws ApplicationException
debugPrintln("Before createServiceProvider()");
return runtime.createServiceProvider("Tuxedo-OnlineBank", "tuxConnection");
throw new Exception("createServiceProvider() returned null!!");
throw new ApplicationException("Unable to get Service provider for data source Tuxedo-OnlineBank connection:tuxConnection\n" +
public void debugPrintln(String str)
// comment this line if you dont want debugging statments to be printed
TuxTransaction.java Class Abstracts Client Side Transaction
package TuxBank;import netscape.bsp.runtime.*;
import netscape.bsp.dataobject.*;
IBSPServiceProvider sp = null;
IBSPFunctionObject txfn = null;
public TuxTransaction(IBSPRuntime runtime, String datasource) throws BspException
sp = runtime.createServiceProvider(datasource, "tuxConnectionTx");
txfn = runtime.createFunctionObject(datasource, "TransactionFO");
public IBSPServiceProvider getServiceProvider()
public void begin() throws BspException
public void commit() throws BspException
public void rollback() throws BspException
ApplicationException Class Encapsulates Information in the Exceptions
package TuxBank;import netscape.bsp.dataobject.IBSPDataObjectStructure;
** <code>ApplicationException</code> is a user-defined class.
public class ApplicationException extends Exception
errorMessage = "Unknown Error";
public ApplicationException(String str)
public ApplicationException(netscape.bsp.BspException e)
IBSPDataObjectStructure info = null;
errorMessage = "Error in service Execution : <br>" +
"Error message from adapter : " + e.getMessage() + "<br>";
errorMessage += (info.attrExists("errno") ? " Tuxedo System Error code : " + info.getAttrInt("errno") + "<br>" : "") +
(info.attrExists("errstr") ? " Tuxedo System Error string : " + info.getAttrString("errstr") + "<br>" : "");
AccountOpenForm.JSP to Accept Details for Opening a New Account
<HEAD><%@ include file="Header.jsp" %>
<TABLE BORDER="1" CELLPADDING="4" WIDTH="500">
<td WIDTH="85%" ALIGN="left"><font size="+1" face="PrimaSans BT, Verdana, sans-serif"
color="black">Open Account</font> </td>
<th WIDTH="15%" ALIGN="right"></th>
<td WIDTH="35%" ALIGN="left"></td>
<form METHOD="Get" ACTION="/NASApp/TuxBank/BankServlet" NAME="ADD_CUSTOMER">
<INPUT TYPE=HIDDEN NAME="Action" Value="OpenAccount">
<div align="center"><center><table CELLSPACING="10" WIDTH="1057">
<!---- Dump the Customer info here -->
<td WIDTH="85" ALIGN="right" width="146">SSN :</td>
<td WIDTH="267" ALIGN="left" width="210" colspan="2"> <input TYPE="text" NAME="SSN"
size="20" value="121-11-2111"></td>
<td WIDTH="85" ALIGN="right" width="146">First :</td>
<td WIDTH="267" ALIGN="left" width="210" colspan="2"><input TYPE="text" NAME="FIRSTNAME"
size="20" value="Nirav Shah"> </td>
<td width="125" ALIGN="right" width="150">Middle :</td>
<td ALIGN="left" width="33"><input TYPE="text" NAME="MIDDLENAME" MAXLENGth="3" SIZE="2" value="k"> </td>
<td ALIGN="left" width="55">Last :</td>
<td ALIGN="left" width="190"><input TYPE="text" NAME="LASTNAME" size="20" value="nShah"></td>
<td WIDTH="218" ALIGN="left" width="209"></td>
<td WIDTH="85" ALIGN="right" width="146">Address :</td>
<td WIDTH="267" ALIGN="left" width="210" colspan="2"><input TYPE="text" NAME="ADDRESS" value="Oak Pointe Apartments"
<td WIDTH="125" ALIGN="right" width="150">Street Addr :</td>
<td WIDTH="302" ALIGN="left" width="200" colspan="3"><input TYPE="text" NAME="ADDRESS2" value="450, N.Mathilda Ave"
<td WIDTH="85" ALIGN="right" width="146">City :</td>
<td WIDTH="267" ALIGN="left" width="210" colspan="2"><input TYPE="text" NAME="CITY" value="Sunnyvale"
<td WIDTH="125" ALIGN="right" width="150">State :</td>
<td WIDTH="302" ALIGN="left" width="200" colspan="3"><input TYPE="text" NAME="STATE" value="CA"
<td WIDTH="85" ALIGN="right" width="146">Zip :</td>
<td WIDTH="267" ALIGN="left" width="210" colspan="2"><input TYPE="text" NAME="ZIP" value="94086"
<td WIDTH="125" ALIGN="right" width="150">Home Phone :</td>
<td WIDTH="302" ALIGN="left" width="200" colspan="3"><input TYPE="text" NAME="HOMEPHONE" value="566-787-9998"
<td WIDTH="85" ALIGN="right" width="146">Work Phone :</td>
<td WIDTH="267" ALIGN="left" width="210" colspan="2"><input TYPE="text" NAME="WORKPHONE" value="789-898-5558"
<td WIDTH="125" ALIGN="right" width="150">Initial Balance:</td>
<td WIDTH="302" ALIGN="left" width="200" colspan="3"><input TYPE="text" value="25000.00"
NAME="INITIALBALANCE" size="20"> </td>
<td WIDTH="85" ALIGN="right" width="146">Account Type:</td>
<td ALIGN="left" width="149"><input type="radio" value="C" checked name="AccountType">Checkings</td>
<td WIDTH="106" ALIGN="left" width="210"><input type="radio" name="AccountType" value="S">Savings</td>
<td WIDTH="125" ALIGN="right" width="150"></td>
<td WIDTH="302" ALIGN="left" width="200" colspan="3"></td>
<td WIDTH="85" ALIGN="right" width="146">Branch:</td>
<td ALIGN="left" colspan="6"><table border="0" width="100%" cellspacing="1"
<td><input type="radio" value="1" checked name="Branch">San Francisco</td>
<td><input type="radio" name="2" value="Branch">Chicago</td>
<td><input type="radio" name="3" value="Branch">Atlanta</td>
<td><input type="radio" name="4" value="Branch">Philadelphia</td>
<td><input type="radio" name="5" value="Branch">Los Angeles</td>
<td><input type="radio" name="6" value="Branch">St. Louis</td>
<td><input type="radio" name="7" value="Branch">Boston</td>
<td><input type="radio" name="8" value="Branch">Dallas</td>
<td><input type="radio" name="9" value="Branch">New York</td>
<td><input type="radio" name="10" value="Branch">Miami</td>
<input type=CHECKBOX name="txn" value="true">Run service in Client Side Transaction
<td WIDTH="85" ALIGN="right" width="146"></td>
<td WIDTH="267" ALIGN="left" width="210" colspan="2"><input TYPE="submit" NAME="BUTTON"
<table BGCOLOR="#999999" CELLPADDING="4" CELLSPACING="2">
<td WIDTH="150" ALIGN="CENTER"><a HREF="/NASApp/TuxBank/jsp/MainMenu.jsp"
NAME="Link138"><font COLOR="blue">Main Menu</font></a></td>
<%@ include file="Footer.jsp" %>
ShowAccountOpen.jsp Displays the Results of Account Opening Transaction
<HEAD><%@ include file="Header.jsp" %>
<jsp:useBean id="accountdata" class="TuxBank.AccountData" scope="request">
<TABLE BORDER="1" CELLPADDING="4" WIDTH="500">
<font size="+1" face="PrimaSans BT, Verdana, sans-serif" color="black">New Account Transaction</FONT>
Details of the new Account created :<br>
<b>Account Number : <jsp:getProperty name="accountdata" property="accountNumber"/> </B>
SSN : <jsp:getProperty name="accountdata" property="sSN"/>
Name : <jsp:getProperty name="accountdata" property="firstName"/>
<jsp:getProperty name="accountdata" property="middleName"/> <jsp:getProperty name="accountdata" property="lastName"/> <p>
Address :<TABLE CELLPADDING="0" CELLSPACING="1" BORDER="0" COLS="1"><TR>
<TD> <jsp:getProperty name="accountdata" property="address"/> <jsp:getProperty name="accountdata" property="address2"/> <br>
<jsp:getProperty name="accountdata" property="city"/> <jsp:getProperty name="accountdata" property="state"/> <jsp:getProperty name="accountdata" property="zip"/> </TD>
Home Phone :<jsp:getProperty name="accountdata" property="homePhone"/>
Work Phone :<jsp:getProperty name="accountdata" property="workPhone"/>
Initial Balance : <jsp:getProperty name="accountdata" property="displayBalance"/> <br>
<TABLE BGCOLOR="#999999" CELLPADDING="4" CELLSPACING="2">
<td WIDTH=600 ALIGN=CENTER><A HREF="/NASApp/TuxBank/jsp/MainMenu.jsp" NAME="Link5"><FONT COLOR="blue">Main Menu</FONT></A></TD>
<%@ include file="Footer.jsp" %
Jolt Migration Procedure
The Tuxedo Enterprise Connector provides a painless migration strategy for migrating existing Jolt Applications and comes with a Jolt migration tool joltmigrator. It accepts the Jolt bulk loader format files and converts them to UIF XML format and exports them into the repository. This chapter gives step by step procedure for doing this migration.
Create a data source for your application using Tuxedo Management Console Tools
The report printed gives any services which are rejected due to absence of any views or FML fields that the services uses.Copy the fml/fml32 field tables and view/view32 object files from the tuxedo server system and import them into the repository either using the Tuxedo Management Console or handily command line tools. All the FML/FML32 and view/view32 object files that the application uses should be imported.
Take the jolt bulk loader format service definitions file and pass it onto the joltmigrator command line tool using the command
joltmigrator -f <joltsvc file> -s <datasourcename> ( ON UNIX it is joltmigrator.sh)
Modify the servlets using Jolt to use the UIF API and call the tuxedo services.
Command Line Tools
The command line tools that ship with the Tuxedo Enterprise Connector, are as follows:
FML Miner
Mines FML/FML32 tables into the UIF repository.Usage:fmlminer -f <fmlfiles> -s <datasource> [-d <fmldirs>] [-o <outputxml file
-f <fmlfiles> : List of files seperated by commas
-s <datasource> : name of the datasource to import to
-d <fmldirs> : list of directories (seperated by , or path
seperator) for searching fml files [optional]
-o <outputxml file> : name of the xml file for storing imported XML
-3 : Option to indicate that <fmlfiles>
are having FML32 ids [optional]
Example : fmlminer -f "%FIELDTBLS%" -d "%FLDTBLDIR%" -s Tuxedo-OnlineBank
Extracts all FML files listed in FIELDTBLS environment var from FLD TBLDIR directory into Tuxedo-OnlineBank datasource. In case of Solaris the command is fmlminer.sh.
VIEWMiner
Mines the VIEW/VIEW32/X_COMMON/X_C_TYPE tables into the UIF repository.Usage:viewminer -f <viewfiles> -s <datasource> -t <viewtype> -p <TUXDIR> [-d <viewdirs>] [-o <outputxml file>]
-f <viewfiles> : List of view object files seperated by commas
-s <datasource> : name of the datasource to import to
-t <viewtype> : one of VIEW|VIEW32|X_C_TYPE|X_COMMON
-p <TUXDIR> : Location of tuxedo workstation client dir
-d <viewdirs> : list of directories (seperated by , or path seperator)
for searching view files[optional]
-o <outputxml file>: name of the xml file for storing imported xml [optional]
Example : viewminer -f "%VIEWFILES%" -d "%VIEWDIR%" -s Tuxedo-OnlineBank -p d:\tuxedo -t VIEW
Extracts all FML files listed in VIEWFILESenvironment var from VIEWDIR directory into Tuxedo-OnlineBank datasource. In case of Solaris, it is viewminer.sh.
JOLT Migrator
Converts Jolt Bulk Loader formatted files into UIF XML and imports them into the UIF repository.Usage:joltmigrator -f <filename> -s <datasourcename> [-o outxmlfile]]
filename is the jolt services file, datasourcename is the name of datasource where to import and outxmlfile is the output XML file (optional).
Previous Contents Index DocHome Next
Copyright © 2000 Sun Microsystems, Inc. Some preexisting portions Copyright © 2000 Netscape Communications Corp. All rights reserved.
Last Updated June 09, 2000