[Top] [Prev] [Next] [Bottom]

1. Introduction and Overview


The BEA TUXEDO System Development Environment

The purpose of this chapter is to describe the environment in which you will be writing code for a BEA TUXEDO system application.

In addition to the C code that expresses the logic of your application, you will be using the Application-Transaction Monitor Interface (ATMI), which refers to the interface between the BEA TUXEDO system transaction monitor and your application. The ATMI primitives are C language functions that resemble UNIX system calls, but they have the specific purpose of implementing the communication among application modules running under the control of the BEA TUXEDO system transaction monitor, including all the associated resources you need.

As you might remember from the BEA TUXEDO Product Overview, the BEA TUXEDO system uses an enhanced client-server architecture. Chapters 2 through 7 of this book describe how the ATMI primitives are used in writing and debugging clients and services. This chapter provides some of the context within which you will be doing that work.

Client Processes

A client process takes user input and sends it as a service request to a server process that offers the requested service.

Basic Client Operation

A client process uses one ATMI primitive to join an application, allocates a message buffer by using another ATMI primitive, and uses still others to send the buffer to a server and receive the reply.

The operation of a basic client process can be summarized by the pseudo-code shown in Listing 1-1.

Listing 1-1 Pseudo-code for a Client
main()
{
allocate a TPINIT buffer
place initial client identification in buffer
enroll as a client of the BEA TUXEDO application
allocate buffer
do while true {
place user input in buffer
send service request
receive reply
pass reply to the user }
leave application
}

Most of the statements in Listing 1-1 are implemented with ATMI primitives. Placing user input in a buffer and passing the reply to the user are implemented with C language functions.

When client programs are ready to test, you use the buildclient(1) command to compile and link edit them.

Client Sending Repeated Service Requests

A client may send and receive any number of service requests before leaving the application. These can be sent as a series of request/response calls or, if it is important to carry state information from one call to the next, a connection to a conversational server can be set up. The logic within the client program is about the same, but different ATMI primitives are used.

Server Processes and Service Subroutines

Servers are processes that provide one or more services. They continually check their message queue for service requests and dispatch them to the appropriate service subroutines.

Basic Server Operation

Applications combine their service subroutines with the main() that BEA TUXEDO provides in order to build server processes. This system supplied main() is a set of predefined functions. It performs server initialization and termination and allocates buffers to receive and dispatch incoming requests to service routines. All of this processing is transparent to the application.

Server and a service subroutine interaction can be summarized by the pseudo-code shown in Figure 1-1.

Figure 1-1 Pseudo-code for a Request/Response Server and a Service Subroutine

After some initialization a server allocates a buffer, waits until a request message is put on its message queue, dequeues the request, and dispatches it to a service subroutine for processing. If a reply is needed, the reply is considered part of request processing.

The conversational paradigm is somewhat different. Pseudo-code is shown in Figure 1-2.

Figure 1-2 Pseudo-code for a Conversational Service Subroutine

The BEA TUXEDO system-supplied main() contains the code needed to enroll as a server, advertise services, allocate buffers, and dequeue request messages. The ATMI primitives are used in service subroutines that process requests. When they are ready to compile and test, service subroutines are link edited with the server main() by means of the buildserver(1) command to form an executable server.

Servers as Requesters

The serially reusable architecture of servers is particularly significant if the operation requested by the user is logically divisible into several services, or several iterations of the same service. Such operations can be overlapped by having a server assume the role of a client and hand off part of the task to another server as part of fulfilling the original client's request. In such a capacity the server becomes a requester. Both clients and servers can be requesters. In fact, a client can only be a requester. The coding model for such a system is easily accomplished with the routines that are provided by ATMI.

A request/response server can also forward a request to another server. This is different from becoming a requester. In this case, the server does not assume the role of client since no reply is expected by the server that forwards a request. The reply is expected by the original client.

The ATMI Primitives

The Application-Transaction Monitor Interface is a reasonably compact set of primitives used to open and close resources, begin and end transactions, allocate and free buffers, and provide the communication between clients and servers. Table 1-1 summarizes them. Each routine is documented in Section 3C of the BEA TUXEDO Reference Manual.

Table 1-1 ATMI Primitives

Group Name Operation

Application Interface

tpinit()

join an application

tpterm()

leave an application

Buffer Management Interface

tpalloc()

allocate a buffer

tprealloc()

re-size a buffer

tpfree()

free a buffer

tptypes()

get buffer type

Request/Response Communication Interface

tpcall()

send a request, wait for answer

tpacall()

send request asynchronously

tpgetrply()

get reply after asynchronous call

tpcancel()

cancel communications handle for outstanding reply

tpgprio()

get priority of last request

tpsprio()

set priority of next request

Conversational Interface

tpconnect()

begin a conversation

tpdiscon

end a conversation

tpsend()

send data in conversation

tprecv()

receive data in conversation

Unsolicited Notification Interface

tpnotify()

notify by client id

tpbroadcast()

notify by name

tpsetunsol()

set unsolicited message handling routine

tpgetunsol()

get unsolicited message

tpchkunsol()

check for unsolicited messages

Transaction Management Interface

tpbegin()

begin a transaction

tpcommit()

commit the current transaction

tpabort()

abort the current transaction

tpgetlev()

check if in transaction mode

Service Routine Template

tpservice()

start a service

tpreturn()

end service routine

tpforward()

forward request and end service routine

Dynamic Advertisement Interface

tpadvertise()

advertise a service name

tpunadvertise()

unadvertise a service name

Resource Manager Interface

tpopen()

open a resource manager

tpclose()

close a resource manager

Event Broker/ Event Monitor Interface

tppost()

post an event

tpsubscribe()

subscribe to an event

tpunsubscribe()

unsubscribe to an event

An Overview of X/Open's TX Interface

In addition to ATMI's transaction management verbs, the BEA TUXEDO system also supports X/Open's TX Interface for defining and managing transactions. Because X/Open used ATMI's transaction demarcation verbs as the base for the TX Interface, the syntax and semantics of the TX Interface are quite similar to ATMI.

Table 1-2 introduces the routines in the TX Interface and highlights the main differences with their corresponding ATMI routines. For maximum portability, the TX routines can be used in place of the ATMI routines shown in Table 1-2.

Table 1-2 TX Verbs

TX Verbs Corresponding ATMI Verbs Main Differences

tx_begin

tpbegin

Timeout value not passed as argument to tx_begin. See tx_set_transaction_timeout.

tx_close

tpclose

None

tx_commit

tpcommit

tx_commit can optionally start a new transaction before it returns. This is known as a "chained" transaction.

tx_info

tpgetlev

tx_info returns the settings of transaction characteristics set via the three tx_set_* routines.

tx_open

tpopen

None

tx_rollback

tpabort

tx_rollback supports chained transactions.

tx_set_commit_return

tpscmt

None

tx_set_transaction_control

None

Defines whether the application is using chained or unchained transactions.

tx_set_transaction_timeout

tpbegin

Transaction timeout parameter separated from tx_begin.

The TX interface requires that tx_open() be called before using any other TX verbs. Thus, even if a client or a server is not accessing an XA-compliant resource manager, it must call tx_open() before it can use tx_begin(), tx_commit(), and tx_rollback() to define transactions.

Listing 1-2 contains an example of how the TX Interface can be used to support chained transactions. Note that tx_begin() must be used to start the first of a series of chained transactions. Also, note that before calling tx_close(), the application must switch to unchained transactions so that the last tx_commit() or tx_rollback() does not start a new transaction.

Listing 1-2 Chained Transactions Using TX Verbs
tx_open();
tx_set_transaction_control(TX_CHAINED);
tx_set_transaction_timeout(120);
tx_begin();
do_forever {
do work as part of transaction;
if (no more work exists)
tx_set_transaction_control(TX_UNCHAINED);
if (work done was successful)
tx_commit();
else
tx_rollback();
if (no more work exists)
break;
}
tx_close();

Typed Buffers

Messages are passed to servers in typed buffers. Why "typed?" Well, different types of data require different software to initialize the buffer, send and receive the data and perhaps encode and decode it, if the buffer is passed between heterogeneous machines. Buffers are designated as being of a specific type so the routines appropriate to the buffer and its contents can be invoked. These issues are typically not of concern to application developers, but more details can be found in buffer(3c), tuxtypes(5), and typesw(5).

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.

Using VIEW and FML Buffers

If you are using the VIEW or FML buffer types, some preliminary work is required to create view description files or field table files. In the case of VIEWs, a description file must exist and must be available to client and server processes that use a data structure described in the VIEW. For FML buffers, a field table file containing descriptions of all fields that may be in the buffer must be available.

Relationship Between Some VIEW Buffers and FML

There are two kinds of VIEW buffers. One is based on an FML buffer. The other VIEW buffer is independent; it is simply a C structure. Both types are described in view description files and compiled with viewc(1), the BEA TUXEDO system view compiler. We're going to talk first about the FML variety.

FML Views

BEA TUXEDO System FML is a family of functions, some of which convert an FML buffer into a C structure or vice versa. The C structure that is derived from the fielded buffer is referred to as an FML VIEW. The reason for converting FML buffers to C structures and back again is that while FML buffers provide data independence and convenience, they do involve processing overhead because they must be manipulated using FML function calls. C structures, while not providing flexibility, offer the performance required for lengthy manipulations on buffer data. If enough manipulation of the data is called for, you can improve the performance of your programs if you transfer fielded buffer data to C structures, operate on the data using normal C functions, and then put the data back into the FML buffer for storage or message transmission.

There are slight differences between a view description of an FML-based view and one that is independent of FML. Listing 1-3 shows a view description file with all of the available data types. The file is myview.v and the structure is based on an FML buffer. Note that the CARRAY1 field has a count of 2 occurrences and has the "C" count flag to indicate that an additional count element should be created in the structure so the application can indicate how many of the occurrences are actually being used. It also has the "L" length flag such that there is a length element (which occurs twice, once for each occurrence of the field) indicating how many of the characters the application has populated.

Listing 1-3 View Description File for FML View
VIEW MYVIEW
$ /* View structure */
#type cname fbname count flag size null
float float1 FLOAT1 1 - - 0.0
double double1 DOUBLE1 1 - - 0.0
long long1 LONG1 1 - - 0
short short1 SHORT1 1 - - 0
int int1 INT1 1 - - 0
dec_t dec1 DEC1 1 - 9,16 0
char char1 CHAR1 1 - - '\0'
string string1 STRING1 1 - 20 '\0'
carray carray1 CARRAY1 2 CL 20 '\0'
END

FML Field Table Files

Field table files are always required when using FML records, including the use of FML-dependent VIEWS. A field table file maps the logical name of a field in an FML buffer to a field identifier that uniquely identifies the field.

An example that could be used with the view shown in Listing 1-3 is shown in Listing 1-4.

Listing 1-4 The myview.flds Field Table File
# name       number    type     flags   comments
FLOAT1 110 float - -
DOUBLE1 111 double - -
LONG1 112 long - -
SHORT1 113 short - -
INT1 114 long - -
DEC1 115 string - -
CHAR1 116 char - -
STRING1 117 string - -
CARRAY1 118 carray - -

Independent VIEWs

Listing 1-5 shows the view description file, similar to the example in Listing 1-3, but for a VIEW independent from FML.

Listing 1-5 View Description File for Independent Views
$ /* View data structure */
VIEW MYVIEW
#type cname fbname count flag size null
float float1 - 1 - - -
double double1 - 1 - - -
long long1 - 1 - - -
short short1 - 1 - - -
int int1 - 1 - - -
dec_t dec1 - 1 - 9,16 -
char char1 - 1 - - -
string string1 - 1 - 20 -
carray carray1 - 2 CL 20 -
END

Note that in this view description, the format is similar to the FML-dependent view, except that the columns fbname and null in the file are ignored by the view compiler. These columns are not relevant when an FML buffer does not stand behind the view, but it is necessary to place some value (a dash, for example) in these columns to serve as a placeholder.

Corresponding Data Type Definitions

The C float and double fields correspond to COBOL COMP-1 and COMP-2, respectively.

The field types long and short correspond to S9(9) COMP-5 and S9(4) COMP-5 respectively in COBOL. (The use of COMP-5 is for use with MicroFocus COBOL so that the COBOL integer fields match the data format of the corresponding C fields; the data type for VS COBOL II would simply be COMP.)

The dec_t type maps to a COBOL COMP-3 packed decimal field. Packed decimals exist in the COBOL environment as two decimal digits packed into each byte with the low-order half byte used to store the sign. The length of a packed decimal may be 1 to 9 bytes with storage available for 1 to 17 digits and a sign. The dec_t field type is supported within the VIEW definition for the conversion of packed decimals between the C and the COBOL environments. The dec_t field is defined in a VIEW with a size of two numbers separated by a comma. The number to the left of the comma is the total number of bytes that the decimal occupies in COBOL. The number to the right is the number of digits to the right of the decimal point in COBOL. The formula for conversion to the COBOL declaration is:

dec_t(m, n) <=> S9(2*m-(n+1),n)COMP-3

For example, say a size of 6,4 is specified in the VIEW. There are 4 digits to the right of the decimal point, 7 digits to the left, and the last half byte stores the sign. The COBOL application programmer would represent this as 9(7)V9(4), with the V representing the decimal point between the number of digits to each side. Note that there is no dec_t type supported in FML; if FML-dependent VIEWs are used, then the field must be mapped to a C type in the VIEW file (for instance, the packed decimal can be mapped to an FML string field and the mapping functions do the conversion between the formats).

A decimal field can be initialized and accessed in C using the functions described on the decimal(3c) reference page.

Creating Header Files from View Descriptions

View description files are source files. To use the view in a program, you need a header file that defines the structures in the view. You can create a header file from the myview.v view description file by invoking the view compiler, viewc(1). viewc creates two files. One is the header file and the other is the binary version of the source description file, myview.V. This binary file must be in the environment when a VIEW buffer is allocated. For an FML-dependent VIEW, the compiler is invoked as follows.

viewc myview.v

The header file it creates from the myview.v description file is shown in Listing 1-6.

Listing 1-6 Header File Created for FML View
struct MYVIEW {
float float1;
double double1;
long long1;
short short1;
int int1;
dec_t dec1;
char char1;
char string1[20];
unsigned short L_carray1[2]; /* length array of carray1 */
short C_carray1; /* count of carray1 */
char carray1[2][20];
};

To compile a view description of an independent view, use the -n option on the command line, as follows.

viewc -n myview.v

The header file created is the same with or without the -n option. Header files for views must be brought into client programs and service subroutines with #include statements.

For use with VIEW32, the viewc32 command should be used.

Header Files from Field Tables

To create a field header file from the field table file, use the mkfldhdr(1) command. For example:

mkfldhdr myview.flds

creates a file called myview.flds.h that can be #include'd in a service routine or client program so you can refer to fields by their symbolic names. The myview.flds.h header file produced by mkfldhdr from this field table file is shown in Listing 1-7.

Listing 1-7 The myview.flds.h Header File
/*       fname    fldid            */
/* ----- ----- */

#define FLOAT1 ((FLDID)24686) /* number: 110 type: float */
#define DOUBLE1 ((FLDID)32879) /* number: 111 type: double */
#define LONG1 ((FLDID)8304) /* number: 112 type: long */
#define SHORT1 ((FLDID)113) /* number: 113 type: short */
#define INT1 ((FLDID)8306) /* number: 114 type: long */
#define DEC1 ((FLDID)41075) /* number: 115 type: string */
#define CHAR1 ((FLDID)16500) /* number: 116 type: char */
#define STRING1 ((FLDID)41077) /* number: 117 type: string */
#defineCARRAY1 ((FLDID)49270) /* number: 118 type: carray */

For use with FML32, the mkfldhdr32 command should be used.

Other Header Files

If you are using FML or VIEW typed buffers, #include the header files generated from their field table files or view description files as described above.

In addition, all BEA TUXEDO system application programs must #include the atmi.h header file.

If you are using FML buffers, #include the fml.h header file in your programs.

Environment Variables

Environment variables needed either for clients or service routines associated with a server can be set in ENVFILEs that are specified in the configuration file. The environment variables that might have to be set for field tables and view descriptions, for example, are summarized in Table 1-3.

Table 1-3 BEA TUXEDO System Environment Variables

Variable Contains Used By

FIELDTBLS

comma-separated list of field table file names

client and server processes using FML buffers

FLDTBLDIR

colon-separated list of directories to be used to find field table files with relative file names

client and server processes using FML buffers

VIEWFILES

comma-separated list of binary view description files

client and server processes using VIEW buffers

VIEWDIR

colon-separated list of directories to be used to find binary view description files

client and server processes using VIEW buffers

For the FML32 and VIEW32 record types, the environment variables are suffixed with 32, that is, FLDTBLDIR32, FIELDTBLS32, VIEWFILES32, and VIEWDIR32.

The CC and CFLAGS environment variables are used by the buildclient(1) and buildserver(1) commands. You may want to set them in your environment to make compilation of clients and servers more convenient. Set CC to the command that invokes the C compiler. It defaults to cc. Set CFLAGS to the link edit flags you may want to use on the compile command line. Setting this variable is optional.

The location of the BEA TUXEDO system binary files must be known to your application. It is the convention to install the BEA TUXEDO system software under a root directory whose location is specified in the TUXDIR environment variable. $TUXDIR/bin must be included in your PATH in order for your application to locate the executables for BEA TUXEDO system commands.

Configuration File

The configuration file specifies the configuration of an application to the BEA TUXEDO system. For a BEA TUXEDO system application in production, it is the responsibility of the BEA TUXEDO system administrator to set up a configuration file that defines the application. In the development environment, the responsibility may be delegated to application programmers to create their own.

If you are faced with the task of creating a configuration file, here are some suggestions:

Making the Configuration Usable

The configuration file is an ASCII file. To make it usable, you have to run tmloadcf(1) to convert it to a binary file. The TUXCONFIG environment variable must be set to the pathname for the binary file, and exported.

The Bulletin Board

The bulletin board is the BEA TUXEDO system name for a group of data structures in a segment of shared memory that is allocated from information stored in TUXCONFIG when the application is booted. Both client and server processes attach to the bulletin board. Part of the bulletin board associates service names with the queue address of servers that advertise that service. Clients send their requests to the name of the service they want to invoke, rather than to a specific address.

All processes that are part of a BEA TUXEDO application share this IPC resource.

Starting and Stopping an Application

Execute the tmboot(1) command to bring up an application. The command gets the IPC resources needed by the application, and starts administrative processes and the application servers.

When it is time to bring the application down, execute the tmshutdown(1) command. tmshutdown stops the servers and releases the IPC resources used by the application, except any that might be used by the database resource manager.

Service Gateway

GWTUX2TE and GWTE2TUX are BEA TUXEDO system servers that provide connectivity between BEA TUXEDO and BEA TOP END systems. GWTUX2TE provides connectivity between BEA TUXEDO clients and BEA TOP END servers. GWTE2TUX provides connectivity between BEA TOP END clients and BEA TUXEDO servers. One or both of these gateway servers may be configured.

Programming Paradigms

Gateway servers support request/response messages only. The following BEA TUXEDO client API calls for sending and receiving are allowed:

BEA TOP END servers cannot set the APPL_CONTEXT flag. If this flag is set, the gateway server dissolves the BEA TOP END dialog and returns an error (TPESVCFAIL) to the BEA TUXEDO client.

The following BEA TOP END client API calls are allowed:

Buffer Types

The gateway servers support BEA TUXEDO CARRAY (X_OCTET) buffers only. Attempts to send other types of buffers from a BEA TUXEDO application generate an error (TPESVCFAIL) which is logged by the gateway server.

Configuration

The GWTUX2TE and GWTE2TUX gateway servers use the BEA TOP END remote client and remote server services. GWTUX2TE assumes the role of a BEA TOP END client and makes use of the remote client services. GWTE2TUX assumes the role of a BEA TOP END server and makes use of the remote server services. Therefore, you must provide a BEA TOP END remote client/server configuration file on any BEA TUXEDO node running these gateway processes.

Examples

The following example shows how gateway servers are defined in the BEA TUXEDO UBBCONFIG file and in the BEA TOP END service definition file.

In this example, a BEA TUXEDO client issues tpcall to the RSERVICE service. The request is forwarded (via the GWTUX2TE gateway) to a BEA TOP END system (pluto) and invokes a BEA TOP END service (RPRODUCT:RFUNC).

Similarly, a BEA TOP END client issues tp_client_send, specifying LPRODUCT as the PRODUCT and LFUNC as the FUNCTION. The request is forwarded (via the GWTE2TUX gateway) to the BEA TUXEDO system and invokes a BEA TUXEDO service (LSERVICE).

Listing 1-8 BEA TUXEDO UBBCONFIG File
##############
#UBBCONFIG
*GROUPS
TOPENDGRP GRPNO=1

#
*SERVERS
GWTE2TUX SRVGRP="TOPENDGRP" SRVID=1001 RESTART=Y MAXGEN=3 GRACE=10
CLOPT="-- -f servicedefs -R 30"
GWTUX2TE SRVGRP="TOPENDGRP" SRVID=1002 RESTART=Y MAXGEN=3 GRACE=10
MIN=5 MAX=5
CLOPT="-- -f servicedefs"

Listing 1-9 BEA TOP END Service Definition File
############
#service definition file
*TE_LOCAL_SERVICES
DEFAULT: PRODUCT=LPRODUCT
LSERVICE FUNCTION=LFUNC

*TE_REMOTE_SERVICES
RSERVICE PRODUCT=RPRODUCT FUNCTION=RFUNC

Listing 1-10 BEA TOP END Remote Configuration File
# TOP END remote configuration file
[top end configuration file]
[component type] remote server
[system] pluto
[primary node] //topendmach 5000


[Top] [Prev] [Next] [Bottom]