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

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.

The data object interface:

  • Presents a unified representation of backend data types

  • Represents complex data

  • Supports most common primitive 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.

The types of data objects are


Primitive Objects

A primitive data-type object contains a single value of one of the following types

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.

list.addElemGString("abcd")

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:

  • operation

  • target

  • type

In the following example of the form <operation><target><type>:

getElemString()

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


Target

The targets 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

  • Field (structure) that uses name to address field

  • Current (itr) addresses object iterator is currently on


Type

The types of operations are

  • Int

  • Float

  • Double

  • String

  • FString

  • Binary

  • VBinary

  • DataObject

  • None


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. Code Example 2-1 Acquiring the UIF Runtime Object

private IBSPRuntime getRuntime()

{

   com.kivasoft.IContext _ctx =

   ((com.netscape.server.servlet.platformhttp.PlatformServletContext)

      getServletContext()).getContext();

   IBSPRuntime ibspruntime = access_cBSPRuntime.getcBSPRuntime
         (_ctx, null, null);

   return ibspruntime;   }

}




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


Service Provider

Definition

Value

tuxConnection

Virtual connection to a Tuxedo System for performing non transactional service invocations

tuxConnectionTx

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.

Code Example 2-2 Creating the Service Provider Object

private IBSPServiceProvider getServiceProvider(IBSPRuntime runtime)

{

   deb.println("Before createServiceProvider()");

   if (runtime != null)

      return runtime.createServiceProvider("Tuxedo-OnlineBank", "tuxConnection");

   else

      deb.println("runtime is null");

   return null;

}


Parameter

Definition

Tuxedo-OnlineBank

Data source name

tuxConnection

Service provider name



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

Table 2-1 Function Object Descriptions

Function Object Element

Description

Value

callService  

 

 

operations  

 

 

operations  

List of operations available in the function object template type  

 

callService  

Every tuxedo service maps to a function object with one operation in it called "callService"  

 

dataBlock  

The input and output data definition for the service  

 

INPUT      

The input definition for the service)  

 

inputBlock  

The input block of parameters for the tuxedo service (optional)  

Preset  

SAMOUNT, LAST_NAME, FIRST_NAME, MID_INIT, ACCT_TYPE, ADDRESS, PHONE, SSN, BRANCH_ID  

The input parameters for the service.

 

 

OUTPUT  

The output definition for the tuxedo service (results from the service invocation)  

 

outputBlock  

The output block of results from service invocation (optional)  

 

ACCOUNT_ID, SBALANCE  

The output result parameters for the tuxedo service  

 

propertySet  

The set of properties to be used for service invocation  

 

serviceName  

The name of the tuxedo service to be invoked (same as function object template name)  

 

isOneWay  

if set, the adapter just calls the service without expecting reply back from tuxedo (one way send)  

 

priority  

Sets the priority level of the service  

 

isPriorityRelative  

Indicates whether priority level is relative or absolute  

 


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");


Parameter

Definition

Tuxedo-OnlineBank

Data source name

OPEN_ACCT

Function name (same as Tuxedo service name)


Setting up and Executing the Function Object


To set up and execute the function object

  1. Specify and enable the service provider.

  2. Prepare the function object, set up the property set, and set up the input parameters in the function object's data block.

  3. Execute the function object.

  4. Retrieve the output parameters from the function block.

  5. Disable the service provider.

The following is an example of how to set up and execute a function object.

//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 STRING <--> string

primitive c_array, primitive X_OCTET <--> vbinary

FML/VIEW field types <--> UIF types

FML/VIEW Field Types

UIF Types

char, int, short

integer

long

integer

float

float

double

double

carray

vbinary

string

STRING

multiple occurrence field of any type

array "> Table 2-2 Mapping Tuxedo Data Types to UIF

FML/VIEW Field Types

UIF Types

char, int, short

integer

long

integer

float

float

double

double

carray

vbinary

string

STRING

multiple occurrence field of any type

array



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;

try {

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");

    sp.enable();

    fn.useServiceProvider(sp);

    fn.prepare("callService");

    IBSPDataObject data = fn.getDataBlock();

   // set the input string

    data.setAttrString("INPUT.inputBlock.INPUTSTRING", inputstr);

    fn.execute();

   // get the result string back

    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>");

} catch (BspException e) {

out.println("<font COLOR=red><b>Service Execution Error :<br>" +

e.getMessage() + "<br><hr><i>Service Execution Failed </i></b></font>");

} finally {

    if (sp != null && sp.isEnabled())

    sp.disable();

}



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

IBSPFunctionObject fn = null;

IBSPDataObject data = null, prop = null;

fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "CARRAYTEST");

hr = sp.enable();

hr = fn.useServiceProvider(sp);

hr = fn.prepare("callService");

data = fn.getDataBlock();

// set the input binary data

data.setAttrVBinary("INPUT.inputBlock.INPUTDATA", inputdata);

hr = fn.execute();

// get the result binary data

byte[] resultbytes =data.getAttrVBinary("OUTPUT.outputBlock.OUTPUTDATA");

} finally {

   if (sp != null)

    sp.disable();

}



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

IBSPFunctionObject fn = null;

IBSPDataObject data = null, prop = null;

fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "XOCTETTEST");

hr = sp.enable();

hr = fn.useServiceProvider(sp);

hr = fn.prepare("callService");

data = fn.getDataBlock();

data.setAttrVBinary("INPUT.inputBlock.INPUTDATA", inputdata);

hr = fn.execute();

byte[] resultbytes =data.getAttrVBinary("OUTPUT.outputBlock.OUTPUTDATA");

} finally {

   if (sp != null)

    sp.disable();}



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.

FML/FML32 Field Types

UIF Types

char, int, short

integer

long

integer

float

float

double

double

carray

vbinary

string

STRING

multiple occurrence field of any type

array "> Table 2-3 Mapping FML Types to UIF Types

FML/FML32 Field Types

UIF Types

char, int, short

integer

long

integer

float

float

double

double

carray

vbinary

string

STRING

multiple occurrence field of any type

array

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 = sp.enable();

try {

   hr = fn.useServiceProvider(sp);

   hr = fn.prepare("callService");

   data = fn.getDataBlock();

   // populate the input data

   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));

   // call the service

   hr = fn.execute();

   // read the output results

   listObj = (IBSPDataObjectList) data.getAttrDataObject("OUTPUT.outputBlock.SBALANCE");

   String frmBalanceStr = listObj.getElemString(0);

   String toBalanceStr = listObj.getElemString(1);

   return new String[] { frmBalanceStr, toBalanceStr};

} catch (BspException e) {

   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

*base 1000

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 = sp.enable();

try {

   hr = fn.useServiceProvider(sp);

   hr = fn.prepare("callService");

   data = fn.getDataBlock();

   // populate the input data

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());

   // call the service

   hr = fn.execute();

   // read the output results

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" );

} catch (BspException e) {

   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 below

// ... populating input data

   hr = fn.execute();

   // read the output results

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 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

*base 1000

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 = sp.enable();

try {

   hr = fn.useServiceProvider(sp);

   hr = fn.prepare("callService");

   data = fn.getDataBlock();

   // populate the input data

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());

   // call the service

   hr = fn.execute();

   // read the output results

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" );

} catch (BspException e) {

   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

VIEW/VIEW32 Field Types  

UIF Types  

char, int, short <-->  

integer  

long <-->  

integer  

float <-->  

float  

double, dec_t<-->  

double  

carray<-->  

vbinary  

string <-->  

STRING  

multiple occurrence field of any type  

array  

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

#

VIEW v16test1

# type cname fbname count flag size null

char char1 - 1 - - -

string str1 - 1 - 100 -

carray cary1 - 1 - 100 -

long long1 - 1 - - -

short short1 - 1 - - -

int int1 - 1 - - -

float float1 - 1 - - -

double double1 - 1 - - -

dec_t dec1 - 1 - 9,2 -

END

#

# view def with all datatypes

#

VIEW v16test2

# type cname fbname count flag size null

char char1 - 5 - - -

string str1 - 5 - 100 -

carray cary1 - 5 - 100 -

long long1 - 5 - - -

short short1 - 5 - - -

int int1 - 5 - - -

float float1 - 5 - - -

double double1 - 5 - - -

dec_t dec1 - 5 - 9,2 -

END

The corresponding generated C Structures from viewc compiler is shown below.

struct v16test1 {

   char      char1;

   char      str1[100];

   char      cary1[100];

   long      long1;

   short      short1;

   int      int1;

   float      float1;

   double      double1;

   dec_t      dec1;

};

struct v16test2 {

   char      char1[5];

   char      str1[5][100];

   char      cary1[5][100];

   long      long1[5];

   short      short1[5];

   int      int1[5];

   float      float1[5];

   double      double1[5];

   dec_t      dec1[5];

};

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 = sp.enable();

try {

   hr = fn.useServiceProvider(sp);

   hr = fn.prepare("callService");

   data = fn.getDataBlock();

   // populate the input data

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);

// call the service

   hr = fn.execute();

// print the output results

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

#

VIEW v32test1

# type cname fbname count flag size null

char char1 - 1 - - -

string str1 - 1 - 100 -

carray cary1 - 1 - 100 -

long long1 - 1 - - -

short short1 - 1 - - -

int int1 - 1 - - -

float float1 - 1 - - -

double double1 - 1 - - -

dec_t dec1 - 1 - 9,2 -

END

#

# view def with all datatypes with count > 1

#

VIEW v32test2

# type cname fbname count flag size null

char char1 - 5 - - -

string str1 - 5 - 100 -

carray cary1 - 5 - 100 -

long long1 - 5 - - -

short short1 - 5 - - -

int int1 - 5 - - -

float float1 - 5 - - -

double double1 - 5 - - -

dec_t dec1 - 5 - 9,2 -

END

The corresponding generated C Structures from viewc32 compiler is shown below.

struct v32test1 {

   char   char1;

   char   str1[100];

   char   cary1[100];

   long   long1;

   short   short1;

   int   int1;

   float   float1;

   double   double1;

   dec_t   dec1;

};

struct v32test2 {

   char   char1[5];

   char   str1[5][100];

   char   cary1[5][100];

   long   long1[5];

   short   short1[5];

   int   int1[5];

   float   float1[5];

   double   double1[5];

   dec_t   dec1[5];

};

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 = sp.enable();

try {

   hr = fn.useServiceProvider(sp);

   hr = fn.prepare("callService");

   data = fn.getDataBlock();

   // populate the input data

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);

// call the service

   hr = fn.execute();

// print the output results

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

#

VIEW xcomtest1

# type cname fbname count flag size null

char char1 - 1 - - -

string str1 - 1 - 100 -

long long1 - 1 - - -

short short1 - 1 - - -

END

#

# view def for X_COMMON with count 10

#

VIEW xcomtest2

# type cname fbname count flag size null

char char1 - 10 - - -

string str1 - 10 - 100 -

long long1 - 10 - - -

short short1 - 10 - - -

END

The corresponding generated C Structures from viewc compiler is shown below.

struct xcomtest1 {

   char   char1;

   char   str1[100];

   long   long1;

   short   short1;

};

struct xcomtest2 {

   char   char1[10];

   char   str1[10][100];

   long   long1[10];

   short   short1[10];

};

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 = sp.enable();

try {

   hr = fn.useServiceProvider(sp);

   hr = fn.prepare("callService");

   data = fn.getDataBlock();

   // populate the input data

               

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);

// call the service

   hr = fn.execute();

// print the output results

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

#

VIEW xctest1

# type cname fbname count flag size null

char char1 - 1 - - -

string str1 - 1 - 100 -

long long1 - 1 - - -

short short1 - 1 - - -

END

#

# view def for x_c_type with count 10

#

VIEW xctest2

# type cname fbname count flag size null

char char1 - 10 - - -

string str1 - 10 - 100 -

long long1 - 10 - - -

short short1 - 10 - - -

END

The corresponding generated C Structures from viewc compiler is shown below.

struct xctest1 {

   char   char1;

   char   str1[100];

   long   long1;

   short   short1;

};

struct xctest2 {

   char   char1[10];

   char   str1[10][100];

   long   long1[10];

   short   short1[10];

};

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 = sp.enable();

try {

   hr = fn.useServiceProvider(sp);

   hr = fn.prepare("callService");

   data = fn.getDataBlock();

   // populate the input data

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);

// call the service

   hr = fn.execute();

// print the output results

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 Example

BEA 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.

  1. Make sure the bankapp Tuxedo server is up and running and is configured properly.

    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).

  2. Double check the datasource Tuxedo-OnlineBank configuration structure in bspbrowser for the configuration information settings like WSNADDR, WSDEVICE and TUXDIR.

  3. On Solaris system, make sure that the environment variables LD_LIBRARY_PATH includes the tuxedo workstation libraries directory (<TUXWSDIR>/lib).

Once these steps are done correctly, this sample application should run without any problem.

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

  • Highly scalable solution

  • 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:

File Name                            Description

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

  • 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

  • jsp/TransferAmountForm.jsp jsp/WithdrawAmountForm.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.   


tuxbank.ear

The J2EE packaged application. Register it with iPlanet Application Server 6.0 using command j2eeappreg tuxbank   

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.

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

  • HTML

  • Java language, Servlet API and EJB API, J2EE

  • BSP API



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:

  1. Packages

    To use iPlanet Application Server Enterprise Connector for Tuxedo, import the following into your servlet or EJBs:

    • import netscape.bsp.*;

    • import netscape.bsp.runtime.*;

    • import netscape.bsp.dataobject.*;

  2. Configuring data Source and services in repository

    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.

  3. Getting a runtime instance (refer to UIF API Developer's Guide)

    In a servlet/EJB using,

    com.kivasoft.IContext ctx = com.kivasoft.util.GX.GetContext();

    IBSPRuntime ibspruntime = access_cBSPRuntime.getcBSPRuntime(ctx, null, null);

  4. Getting the service provider (refer to BSP API Reference)

    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.

  5. Calling a tuxedo service

    1. Setting the security attributes (if a service expects any)

      IBSPDataObject config = sp.getConfig();

      if (config != null) {

      config.setAttrString("WebUserName", "webuser-smith");

      }

    2. Creating a function object

      fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "BalanceInquiry");

    3. Enabling the service provider

      hr = sp.enable();

    4. Preparing the service provider and setting up

      hr = fn.useServiceProvider(sp);

      hr = fn.prepare("callService");

    5. Populating the input data

      data = fn.getDataBlock();

      data.setAttrInt("INPUT.inputBlock.ACCOUNT_ID", Integer.parseInt(accountNumber));

    6. Calling the service

      hr = fn.execute();

    7. Getting the output results from the service

      String outputBalance = data.getAttrString("OUTPUT.outputBlock.SBALANCE");

  6. Disabling the data source

    sp.disable();


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 STRING <--> string

  • primitive c_array, primitive X_OCTET <--> vbinary

  • FML/VIEW field types  <--> BSP types

  • char  int short <--> integer

  • long <--> integer

  • float <-->  float

  • double <--> double

  • carray<--> vbinary

  • string <--> STRING

  • multiple occurrence field of any of above type<--> array


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

catch (BSPException e) {

   IBSPDataObjectStructure info = null;

   errorMessage = "Error in service Execution : <br>" +

   "Error message from adapter : " +  e.getMessage() + "<br>";

   info=e.getInfo();

   if (info != null) {

      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.

package TuxBank;

import java.util.*;

import java.lang.reflect.*;

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

/**

** BankServlet is a blank servlet to which you add your own code.

*/

public class BankServlet extends HttpServlet

{

public void init(ServletConfig config) throws ServletException

{

super.init(config);

}

public void doBalanceQuery(HttpServletRequest req, HttpServletResponse res)

throws Exception

{

String accountNumber = req.getParameter("AccountNumber");

if (accountNumber == null || accountNumber.length() == 0)

throw new Exception("Account Number missing in the request !!");

// invoke the business method

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");

   dispatcher.include(req, res);

}

public void doDepositAmount(HttpServletRequest req, HttpServletResponse res)

throws Exception

{

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 !!");

// validate deposit

double depositAmount = 0.0;

try {

depositAmount = java.text.NumberFormat.getNumberInstance().parse(depositAmountStr). doubleValue();

} catch (Exception e) {

throw new Exception ("Deposit Amount entered is invalid !!");

}

if (depositAmount <= 0.0)

throw new Exception ("Deposit Amount entered is invalid !!");

// invoke the business method

IBankManager bankManager = getBankManager();

String balance = bankManager.depositAmount(accountNumber, depositAmount, req.getParameter("txn") != null);

      

// format the results and invoke results page

      try {

    req.setAttribute("OldBalance",

          java.text.NumberFormat.getCurrencyInstance(Locale.US).format(

            Double.parseDouble(balance.replace('$',' ')) - depositAmount

          )

         );

            

      } catch (Exception e) {}

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");

   dispatcher.include(req, res);

}

public void doOpenAccount(HttpServletRequest req, HttpServletResponse res)

throws Exception

{

AccountData acctData = new AccountData();

   String branch = req.getParameter("Branch");

   if (branch == null)

throw new Exception("Invalid/NO branch id selected !!");

   acctData.setBranch(branch);

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!!");

acctData.setSSN(ssn);

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!!!!");

// validate deposit

double depositAmount = 0.0;

try {

depositAmount = java.text.NumberFormat.getNumberInstance().parse(depositAmountStr). doubleValue();

} catch (Exception e) {

throw new Exception ("Initial Deposit Amount entered is invalid !!<br> Use Browser Back Button and reenter it");

}

if (depositAmount <= 0.0)

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!!");

acctData.setFirstName(fname);

String mname = req.getParameter("MIDDLENAME");

if (mname == null || mname.length() <= 0)

mname = "";

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!!");

acctData.setLastName(lname);

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!!");

acctData.setAddress(address);

String address2 = req.getParameter("ADDRESS2");

if (address2 == null || address2.length() <= 0)

address2 = "";

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!!");

acctData.setCity(city);

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!!");

acctData.setState(state);

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!!");

acctData.setZip(zip);

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);

// invoke the business method

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");

   dispatcher.include(req, res);

}

public void doCloseAccount(HttpServletRequest req, HttpServletResponse res)

throws Exception

{

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

// invoke the business method

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");

   dispatcher.include(req, res);

}

public void doTransferAmount(HttpServletRequest req, HttpServletResponse res)

throws Exception

{

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

// validate transfer

double transferAmount = 0.0;

try {

transferAmount = java.text.NumberFormat.getNumberInstance().parse(transferAmountStr) .doubleValue();

} catch (Exception e) {

throw new Exception ("Transfer Amount entered is invalid !!");

}

if (transferAmount <= 0.0)

throw new Exception ("Transfer Amount entered is invalid !!");

// invoke the business method

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");

   dispatcher.include(req, res);

}

public void doWithdrawAmount(HttpServletRequest req, HttpServletResponse res)

throws Exception

{

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 !!");

// validate withdrawl

double withdrawlAmount = 0.0;

try {

withdrawlAmount = java.text.NumberFormat.getNumberInstance().parse(withdrawlAmountStr ).doubleValue();

} catch (Exception e) {

throw new Exception ("Withdrawl Amount entered is invalid !!");

}

if (withdrawlAmount <= 0.0)

throw new Exception ("Withdrawl Amount entered is invalid !!");

// invoke the business method

IBankManager bankManager = getBankManager();

String balance = bankManager.withdrawAmount(accountNumber, withdrawlAmount, req.getParameter("txn") != null);

double baldouble = 0.0;

      try {

         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");

   dispatcher.include(req, res);

}

   /**

    * Main Dispatcher

    */

   public void service(HttpServletRequest req, HttpServletResponse res)

      throws ServletException, IOException

   {

    res.setContentType("text/html");

      

      try {

// 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") )

doBalanceQuery(req, res);

       else if (action.equalsIgnoreCase("DepositAmount") )

doDepositAmount(req, res);

       else if (action.equalsIgnoreCase("OpenAccount") )

doOpenAccount(req, res);

       else if (action.equalsIgnoreCase("CloseAccount") )

doCloseAccount(req, res);

       else if (action.equalsIgnoreCase("TransferAmount") )

doTransferAmount(req, res);

       else if (action.equalsIgnoreCase("WithdrawAmount") )

doWithdrawAmount(req, res);

       else      

       new ErrorHandler(this, req, res).displayError("Invalid Action parameter " + action + " !");

      } catch (Exception e) {

       e.printStackTrace();

       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();

      if (bankManagerHome == null)

         throw new Exception ("BankManager Home is null");

      com.kivasoft.IContext _ctx =

          ((com.netscape.server.servlet.platformhttp.PlatformServletContext)

          getServletContext()).getContext();

      IBankManager bankManager = bankManagerHome.create();

      if (bankManager != null)

         bankManager.setSessionContext(_ctx);

      return bankManager;

   }

   /**

    * Returns a string that contains information about the servlet.

    */

   public String getServletInfo()

   {

      return "This servlet handles bankManager requests";

   }//end getServletInfo

}


IBankManager.java - Interface for the Stateless EJB

package TuxBank;

import javax.ejb.*;

import java.rmi.RemoteException;

import java.util.*;

import java.io.*;

public interface IBankManager extends EJBObject

{

public void setSessionContext(com.kivasoft.IContext ctx)

             throws java.rmi.RemoteException;

// returns balance

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 java.util.*;

import java.io.*;

import java.rmi.*;

import javax.ejb.*;

import netscape.bsp.*;

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

* of the instance.

* @param ctx SessionContext the link between this bean and its container

* @exception RemoteException if there are problems with RMI

*/

   public void setSessionContext(SessionContext ctx)

      throws RemoteException

   {

      _sessionContext = ctx;

   }

   

   public void setSessionContext(com.kivasoft.IContext ctx)

      throws RemoteException

   {

      m_ctx = 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

* a stateless bean.

* @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 BankManagerBean()

{

}

public String balanceQuery(String accountNumber, boolean bTxn)

      throws java.rmi.RemoteException, ApplicationException

   {

      int hr=1;

      debugPrintln(" Before getRuntime()");

      IBSPRuntime runtime = getRuntime();

      debugPrintln("After getRuntime()");

      debugPrintln("Before getServiceProvider()");

      IBSPServiceProvider sp = null;

      TuxTransaction tx = null;

      if (bTxn) {

         try {

            tx = new TuxTransaction(runtime, "Tuxedo-OnlineBank");

         } catch (BspException e) { throw new ApplicationException(e); }

         sp = tx.getServiceProvider();

      } else

         sp =getServiceProvider(runtime);

      debugPrintln("After getServiceProvider()");

      IBSPFunctionObject fn = null;

      IBSPDataObject data = null, prop = null;

      debugPrintln("Before createFunctionObject()");

      fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "INQUIRY");

      debugPrintln("After createFunctionObject()");

      try {

         debugPrintln("After enable(), hr = "+hr);

         hr = sp.enable();

         hr = fn.useServiceProvider(sp);

         debugPrintln("After useServiceProvider(), hr = "+hr);

         hr = fn.prepare("callService");

         debugPrintln("After prepare(), hr = "+hr);

         data = fn.getDataBlock();

         debugPrintln("After getDataBlock()");

         data.setAttrInt("INPUT.inputBlock.ACCOUNT_ID", Integer.parseInt(accountNumber));

         debugPrintln("Before execute()");

         if (tx != null)

            tx.begin();

         try {

            hr = fn.execute();

         } catch (BspException e) {

                  try { if (tx != null) tx.rollback(); } catch (Exception exxxx) {}

                  throw new ApplicationException(e);

         }

         if (tx != null)

            tx.commit();

         String outputBalance = data.getAttrString("OUTPUT.outputBlock.SBALANCE");

         return outputBalance;

      } catch (BspException e) {

         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

   {

      int hr=1;

      debugPrintln(" Before getRuntime()");

      IBSPRuntime runtime = getRuntime();

      debugPrintln("After getRuntime()");

      debugPrintln("Before getServiceProvider()");

      IBSPServiceProvider sp = null;

      TuxTransaction tx = null;

      if (bTxn) {

         try {

            tx = new TuxTransaction(runtime, "Tuxedo-OnlineBank");

         } catch (BspException e) { throw new ApplicationException(e); }

         sp = tx.getServiceProvider();

      } else

         sp =getServiceProvider(runtime);

      debugPrintln("After getServiceProvider()");

      IBSPFunctionObject fn = null;

      IBSPDataObject data = null, prop = null;

      debugPrintln("Before createFunctionObject()");

      fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "DEPOSIT");

      debugPrintln("After createFunctionObject()");

      hr = sp.enable();

      debugPrintln("After enable(), hr = "+hr);

      try {

         hr = fn.useServiceProvider(sp);

         debugPrintln("After useServiceProvider(), hr = "+hr);

         hr = fn.prepare("callService");

         debugPrintln("After prepare(), hr = "+hr);

         data = fn.getDataBlock();

         debugPrintln("After getDataBlock()");

         data.setAttrInt("INPUT.inputBlock.ACCOUNT_ID", Integer.parseInt(accountNumber));

         data.setAttrString("INPUT.inputBlock.SAMOUNT", ""+amount);

         debugPrintln("Before execute()");

         if (tx != null)

            tx.begin();

         try {

            hr = fn.execute();

         } catch (BspException e) {

                  try { if (tx != null) tx.rollback(); } catch (Exception exxxx) {}

                  throw new ApplicationException(e);

         }

         if (tx != null)

            tx.commit();

         String outputBalance = data.getAttrString("OUTPUT.outputBlock.SBALANCE");

         return outputBalance;

      } catch (BspException e) {

         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

   {

      int hr=1;

      debugPrintln(" Before getRuntime()");

      IBSPRuntime runtime = getRuntime();

      debugPrintln("After getRuntime()");

      debugPrintln("Before getServiceProvider()");

      IBSPServiceProvider sp = null;

      TuxTransaction tx = null;

      if (bTxn) {

         try {

            tx = new TuxTransaction(runtime, "Tuxedo-OnlineBank");

         } catch (BspException e) { throw new ApplicationException(e); }

         sp = tx.getServiceProvider();

      } else

         sp =getServiceProvider(runtime);

      debugPrintln("After getServiceProvider()");

      IBSPFunctionObject fn = null;

      IBSPDataObject data = null, prop = null;

      debugPrintln("Before createFunctionObject()");

      fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "WITHDRAWAL");

      debugPrintln("After createFunctionObject()");

      hr = sp.enable();

      debugPrintln("After enable(), hr = "+hr);

      try {

         hr = fn.useServiceProvider(sp);

         debugPrintln("After useServiceProvider(), hr = "+hr);

         hr = fn.prepare("callService");

         debugPrintln("After prepare(), hr = "+hr);

         data = fn.getDataBlock();

         debugPrintln("After getDataBlock()");

         data.setAttrInt("INPUT.inputBlock.ACCOUNT_ID", Integer.parseInt(accountNumber));

         data.setAttrString("INPUT.inputBlock.SAMOUNT", ""+amount);

         debugPrintln("Before execute()");

         if (tx != null)

            tx.begin();

         try {

            hr = fn.execute();

         } catch (BspException e) {

                  try { if (tx != null) tx.rollback(); } catch (Exception exx) {}

                  throw new ApplicationException(e);

         }

         if (tx != null)

            tx.commit();

         String outputBalance = data.getAttrString("OUTPUT.outputBlock.SBALANCE");

         return outputBalance;

      } catch (BspException e) {

         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

   {

      int hr=1;

      debugPrintln(" Before getRuntime()");

      IBSPRuntime runtime = getRuntime();

      debugPrintln("After getRuntime()");

      debugPrintln("Before getServiceProvider()");

      IBSPServiceProvider sp = null;

      TuxTransaction tx = null;

      if (bTxn) {

         try {

            tx = new TuxTransaction(runtime, "Tuxedo-OnlineBank");

         } catch (BspException e) { throw new ApplicationException(e); }

         sp = tx.getServiceProvider();

      } else

         sp =getServiceProvider(runtime);

      debugPrintln("After getServiceProvider()");

      IBSPFunctionObject fn = null;

      IBSPDataObject data = null, prop = null;

      debugPrintln("Before createFunctionObject()");

      IBSPDataObject config = sp.getConfig();

      fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "TRANSFER");

      debugPrintln("After createFunctionObject()");

      hr = sp.enable();

      debugPrintln("After enable(), hr = "+hr);

      try {

         hr = fn.useServiceProvider(sp);

         debugPrintln("After useServiceProvider(), hr = "+hr);

         hr = fn.prepare("callService");

         debugPrintln("After prepare(), hr = "+hr);

         data = fn.getDataBlock();

         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()");

         if (tx != null)

            tx.begin();

         try {

            hr = fn.execute();

         } catch (BspException e) {

                  try { if (tx != null) tx.rollback(); } catch (Exception exx) {}

                  throw new ApplicationException(e);

         }

         if (tx != null)

            tx.commit();

         listObj = (IBSPDataObjectList) data.getAttrDataObject("OUTPUT.outputBlock.SBALANCE");

         String frmBalanceStr = listObj.getElemString(0);

         String toBalanceStr = listObj.getElemString(1);

         return new String[] { frmBalanceStr, toBalanceStr};

      } catch (BspException e) {

         throw new ApplicationException(e);

      } finally { if (sp != null && sp.isEnabled()) sp.disable(); }

   }

   public String closeAccount(String accountNumber, boolean bTxn)

      throws java.rmi.RemoteException, ApplicationException

   {

      int hr=1;

      debugPrintln(" Before getRuntime()");

      IBSPRuntime runtime = getRuntime();

      debugPrintln("After getRuntime()");

      debugPrintln("Before getServiceProvider()");

      IBSPServiceProvider sp = null;

      TuxTransaction tx = null;

      if (bTxn) {

         try {

            tx = new TuxTransaction(runtime, "Tuxedo-OnlineBank");

         } catch (BspException e) { throw new ApplicationException(e); }

         sp = tx.getServiceProvider();

      } else

         sp =getServiceProvider(runtime);

      debugPrintln("After getServiceProvider()");

      IBSPFunctionObject fn = null;

      IBSPDataObject data = null, prop = null;

      debugPrintln("Before createFunctionObject()");

      fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "CLOSE_ACCT");

      debugPrintln("After createFunctionObject()");

      hr = sp.enable();

      debugPrintln("After enable(), hr = "+hr);

      try {

         hr = fn.useServiceProvider(sp);

         debugPrintln("After useServiceProvider(), hr = "+hr);

         hr = fn.prepare("callService");

         debugPrintln("After prepare(), hr = "+hr);

         data = fn.getDataBlock();

         debugPrintln("After getDataBlock()");

         data.setAttrInt("INPUT.inputBlock.ACCOUNT_ID", Integer.parseInt(accountNumber));

         debugPrintln("Before execute()");

         if (tx != null)

            tx.begin();

         try {

            hr = fn.execute();

         } catch (BspException e) {

                  try { if (tx != null) tx.rollback(); } catch (Exception exx) {}

                  throw new ApplicationException(e);

         }

         if (tx != null)

            tx.commit();

         String outputBalance = data.getAttrString("OUTPUT.outputBlock.SBALANCE");

         return outputBalance;

      } catch (BspException e) {

         throw new ApplicationException(e);

      } finally { if (sp != null && sp.isEnabled()) sp.disable(); }

   }

public String openAccount(AccountData acctData, boolean bTxn)

throws java.rmi.RemoteException, ApplicationException

{

      int hr=1;

      debugPrintln(" Before getRuntime()");

      IBSPRuntime runtime = getRuntime();

      debugPrintln("After getRuntime()");

      debugPrintln("Before getServiceProvider()");

      IBSPServiceProvider sp = null;

      TuxTransaction tx = null;

      if (bTxn) {

         try {

            tx = new TuxTransaction(runtime, "Tuxedo-OnlineBank");

         } catch (BspException e) { throw new ApplicationException(e); }

         sp = tx.getServiceProvider();

      } else

         sp =getServiceProvider(runtime);

      debugPrintln("After getServiceProvider()");

      IBSPFunctionObject fn = null;

      IBSPDataObject data = null, prop = null;

      debugPrintln("Before createFunctionObject()");

      fn = runtime.createFunctionObject("Tuxedo-OnlineBank", "OPEN_ACCT");

      debugPrintln("After createFunctionObject()");

      hr = sp.enable();

      try {

         debugPrintln("After enable(), hr = "+hr);

         hr = fn.useServiceProvider(sp);

         debugPrintln("After useServiceProvider(), hr = "+hr);

         hr = fn.prepare("callService");

         debugPrintln("After prepare(), hr = "+hr);

         data = fn.getDataBlock();

         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());

         char midinit = '\0';

         String str = acctData.getMiddleName();

         if (str != null && str.length() > 0)

            midinit = str.charAt(0);

         data.setAttrInt("INPUT.inputBlock.MID_INIT", (int) midinit);

         char accttype = '\0';

         str = acctData.getAccountType();

         if (str != null && str.length() > 0)

            accttype = str.charAt(0);

         data.setAttrInt("INPUT.inputBlock.ACCT_TYPE", accttype);

         data.setAttrString("INPUT.inputBlock.ADDRESS", ""+acctData.getAddress() + ", " +

                           acctData.getAddress2() + ", " +

                           acctData.getCity () + ", " +

                           acctData.getState() + "-" +

                           acctData.getZip());

         data.setAttrInt("INPUT.inputBlock.BRANCH_ID", Integer.parseInt(acctData.getBranch()));

         data.setAttrString("INPUT.inputBlock.PHONE", ""+acctData.getWorkPhone());

         debugPrintln("Before execute()");

         if (tx != null)

            tx.begin();

         try {

            hr = fn.execute();

         } catch (BspException e) {

                  try { if (tx != null) tx.rollback(); } catch (Exception exx) {}

                  throw new ApplicationException(e);

         }

         if (tx != null)

            tx.commit();

         String outputBalance = data.getAttrString("OUTPUT.outputBlock.SBALANCE");

         int accountNumber = data.getAttrInt("OUTPUT.outputBlock.ACCOUNT_ID");

         return ""+accountNumber;

      } catch (BspException e) {

         throw new ApplicationException(e);

      } finally { if (sp != null && sp.isEnabled()) sp.disable(); }

}

   private IBSPRuntime getRuntime() throws ApplicationException

   {

      try {

         debugPrintln(" before access_cBSPRuntime.getcBSPRuntime ");

         IBSPRuntime ibspruntime = access_cBSPRuntime.getcBSPRuntime(m_ctx, null, null);

         debugPrintln(" after access_cBSPRuntime.getcBSPRuntime ");

         if (ibspruntime == null)

            throw new Exception("access method returned null !");

         return ibspruntime;

      } catch (Exception e) {

         throw new ApplicationException("Unable to get Runtime object. Error : " + e.getMessage());

      }

   }

   

   private IBSPServiceProvider getServiceProvider(IBSPRuntime runtime) throws ApplicationException

   {

      try {

      debugPrintln("Before createServiceProvider()");

      if (runtime != null)

         return runtime.createServiceProvider("Tuxedo-OnlineBank", "tuxConnection");

      else

         throw new Exception("createServiceProvider() returned null!!");

      } catch (Exception e) {

         throw new ApplicationException("Unable to get Service provider for data source Tuxedo-OnlineBank connection:tuxConnection\n" +

               "Reason : " +e.getMessage());

      }

   }

   public void debugPrintln(String str)

   {

      // comment this line if you dont want debugging statments to be printed

      System.out.println(str);

   }

}


TuxTransaction.java Class Abstracts Client Side Transaction

package TuxBank;

import java.util.*;

import java.io.*;

import java.rmi.*;

import javax.ejb.*;

import netscape.bsp.*;

import netscape.bsp.runtime.*;

import netscape.bsp.dataobject.*;

public class TuxTransaction {

   IBSPServiceProvider sp = null;

   IBSPFunctionObject txfn = null;

   public TuxTransaction(IBSPRuntime runtime, String datasource) throws BspException

   {

      sp = runtime.createServiceProvider(datasource, "tuxConnectionTx");

      sp.enable();

      txfn = runtime.createFunctionObject(datasource, "TransactionFO");

      txfn.useServiceProvider(sp);

   }

   public IBSPServiceProvider getServiceProvider()

   {

      return sp;

   }

   public void begin() throws BspException

   {

      txfn.prepare("BEGIN");

      txfn.execute();

   }

   public void commit() throws BspException

   {

      txfn.prepare("COMMIT");

      txfn.execute();

   }

   public void rollback() throws BspException

   {

      txfn.prepare("ROLLBACK");

      txfn.execute();

   }

}


ApplicationException Class Encapsulates Information in the Exceptions

package TuxBank;

import java.util.*;

import java.lang.reflect.*;

import java.io.*;

import netscape.bsp.dataobject.IBSPDataObjectStructure;

/**

** <code>ApplicationException</code> is a user-defined class.

*/

public class ApplicationException extends Exception

{

   private String errorMessage;

   public ApplicationException()

   {

      errorMessage = "Unknown Error";

   }

   public ApplicationException(String str)

   {

      errorMessage = str;

   }

   public ApplicationException(netscape.bsp.BspException e)

   {

      IBSPDataObjectStructure info = null;

      errorMessage = "Error in service Execution : <br>" +

         "Error message from adapter : " + e.getMessage() + "<br>";

    info=e.getInfo();

      if (info != null) {

         errorMessage += (info.attrExists("errno") ? " Tuxedo System Error code : " + info.getAttrInt("errno") + "<br>" : "") +

            (info.attrExists("errstr") ? " Tuxedo System Error string : " + info.getAttrString("errstr") + "<br>" : "");

      }

   }

   public String getMessage()

   {

      return errorMessage;

   }

}


AccountOpenForm.JSP to Accept Details for Opening a New Account

<HEAD>

</HEAD><BODY>

<%@ include file="Header.jsp" %>

<center>

<TABLE BORDER="1" CELLPADDING="4" WIDTH="500">

<TR>

<TD>

<table WIDTH="800">

<tr>

<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>

</tr>

</table>

</center></div>

<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 -->

<tr>

<td WIDTH="85" ALIGN="right" width="146">SSN :</td>

<td WIDTH="267" ALIGN="left" width="210" colspan="2">&nbsp;<input TYPE="text" NAME="SSN"

size="20" value="121-11-2111"></td>

</tr>

<tr>

<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&nbsp; :</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>

</tr>

<tr>

<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"

size="20"> </td>

<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"

size="20"> </td>

</tr>

<tr>

<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"

size="20"> </td>

<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"

size="20"> </td>

</tr>

<tr>

<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"

size="20"> </td>

<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"

size="20"> </td>

</tr>

<tr>

<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"

size="20"> </td>

<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>

</tr>

<tr>

<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>

</tr>

<tr>

<td WIDTH="85" ALIGN="right" width="146">Branch:</td>

<td ALIGN="left" colspan="6"><table border="0" width="100%" cellspacing="1"

cellpadding="0">

<tr>

<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></td>

</tr>

<tr>

<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>

</tr>

</table>

</td>

</tr>

<tr>

   <td width="267">

<input type=CHECKBOX name="txn" value="true">Run service in Client Side Transaction

   </td>

</tr>

   <tr>

<td WIDTH="85" ALIGN="right" width="146"></td>

<td WIDTH="267" ALIGN="left" width="210" colspan="2"><input TYPE="submit" NAME="BUTTON"

VALUE="Open Account"> </td>

</tr>

</table>

</center></div>

</form>

<p align="center"><br>

</p>

<div align="center"><center>

<table BGCOLOR="#999999" CELLPADDING="4" CELLSPACING="2">

<tr>

<td WIDTH="150" ALIGN="CENTER"><a HREF="/NASApp/TuxBank/jsp/MainMenu.jsp"

NAME="Link138"><font COLOR="blue">Main Menu</font></a></td>

</tr>

</table>

</td>

</tr>

</table>

</center>

<br>

<%@ include file="Footer.jsp" %>

</P>

</BODY>


ShowAccountOpen.jsp Displays the Results of Account Opening Transaction

<HEAD>

</HEAD><BODY>

<%@ include file="Header.jsp" %>

<jsp:useBean id="accountdata" class="TuxBank.AccountData" scope="request">

</jsp:useBean>

<P><br>

</P>

<center>

<TABLE BORDER="1" CELLPADDING="4" WIDTH="500">

<TR>

<TD>

<font size="+1" face="PrimaSans BT, Verdana, sans-serif" color="black">New Account Transaction</FONT>

<br>

<hr>

Details of the new Account created :<br>

<b>Account Number : <jsp:getProperty name="accountdata" property="accountNumber"/> </B>

&nbsp;<br>

<hr width=20%>

SSN : <jsp:getProperty name="accountdata" property="sSN"/>

<br>

Name : <jsp:getProperty name="accountdata" property="firstName"/>

&nbsp; <jsp:getProperty name="accountdata" property="middleName"/> &nbsp;<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"/> &nbsp; <jsp:getProperty name="accountdata" property="address2"/> <br>

<jsp:getProperty name="accountdata" property="city"/> &nbsp;<jsp:getProperty name="accountdata" property="state"/> &nbsp; <jsp:getProperty name="accountdata" property="zip"/>&nbsp;</TD>

</TR>

</TABLE>

</p>

Home Phone :<jsp:getProperty name="accountdata" property="homePhone"/>

<br>

Work Phone :<jsp:getProperty name="accountdata" property="workPhone"/>

<br>

Initial Balance : <jsp:getProperty name="accountdata" property="displayBalance"/> <br>

</TD>

</TR>

</TABLE></P>

<br>

<center>

<TABLE BGCOLOR="#999999" CELLPADDING="4" CELLSPACING="2">

<tr>

<td WIDTH=600 ALIGN=CENTER><A HREF="/NASApp/TuxBank/jsp/MainMenu.jsp" NAME="Link5"><FONT COLOR="blue">Main Menu</FONT></A></TD>

</TR>

</TABLE>

</CENTER>

<br>

</TD>

</TR>

</TABLE>

</center>

<%@ include file="Footer.jsp" %

</P>

</BODY>



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.

  1. Create a data source for your application using Tuxedo Management Console Tools

  2. 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.

  3. 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)

The report printed gives any services which are rejected due to absence of any views or FML fields that the services uses.

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

>] [ -3 (for fml32) ]

Options details:

-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

                [optional]

-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>]

Options details ...

-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