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

11. Writing Client Programs


Introduction

This chapter describes the ATMI routines that enable a client program to do the following:

The chapter ends with information about how to compile client programs.

Preliminaries

Before a client program is ready to join the application some preliminary processing may be called for to take advantage of BEA TUXEDO system capabilities.

Client Naming

An application can associate both a USRNAME and a CLTNAME with an execution of a client process. Values furnished for these names are combined by the BEA TUXEDO system with the logical machine identifier (LMID) of the machine where the process runs, in order to establish a unique identification for the process. It is left to the discretion of application developers and programmers to work out ways of acquiring the value for the fields. Once acquired they are passed to TPINITIALIZE in a TPINFDEF-REC record. Some possible ways are shown in later examples.

Note: If the process is running outside the administrative domain of the application, that is, if it is running on a workstation connected to the administrative domain, the LMID used is the one for the machine used by the workstation client to access the application.

Once a client process is uniquely identified client authentication can be implemented, out-of-band messages can be sent to a specific client or to groups of clients via TPNOTIFY and TPBROADCAST and detailed statistical information can be gathered via tmadmin(1).

Figure 11-1 shows an example of how names might be associated with clients accessing an application. In the example, the application uses the CLTNAME field to indicate a job routine.

Figure 11-1 Client Naming

Unsolicited Notification

Unsolicited notification refers to any communication with a client that is not an expected response to a service request (or an error code). The example that comes to mind is a broadcast message to announce that the world is coming to an end in five minutes. Within the client program there are three things you may want to do to handle such messages:

The setting values are described below in "The TPINFDEF-REC Record." TPSETUNSOL and TPCHKUNSOL are shown in examples later in this chapter and are described in Section 3cbl of the BEA TUXEDO Reference Manual.

Security Strategy

The BEA TUXEDO system provides five incremental levels of security.

Operating System
For platforms that have underlying security mechanisms, this is the first line of defense. The security level is configured to "NONE" (configuration is discussed below). This implies, not that there is no security, but that there are no additional mechanisms (for example, the BEA TUXEDO system application password) beyond what the platform provides.

The BEA TUXEDO system has the notion of an application administrator who configures the application, starts up the application (servers run with the permissions of this administrator), and monitors the running application, making dynamic changes as necessary. Note that this implies that server programs are "trusted" since they run with the administrator's permissions. This is supported using the underlying operating system login mechanism and read/write permissions on files, directories, and system resources.

Client programs are run directly by the users with their own permissions. However, they normally have access to the administrative configuration file and the interprocess communication mechanisms, such as the Bulletin Board in shared memory, as part of normal processing. This is true whether or not additional BEA TUXEDO system security is configured. For some applications running on platforms supporting such, a more secure approach is to have the files and IPC mechanisms accessible only to the application administrator and to have "trusted" client programs run with the permissions of the administrator (using a "setuid" mechanism). Combining this with BEA TUXEDO system security will allow the application to "know" who the user is that is making the request. For the most secure environment, only workstation clients should be allowed to access the application; client programs should not be allowed to run on the machines where application server and administrative programs run.

The BEA TUXEDO system security mechanisms can be used in addition to operating system security to prevent unauthorized access. The additional security can be used to avoid simple violations like someone accessing an unattended terminal. Or it can protect the boundaries of the administrative domain from inter-domain or workstation client access over the network by unauthorized users.

Application Password
This security level requires that every client provide an application password as part of joining the application. The security level is configured to APP_PW. The administrator must provide an application password when this level is configured and this password can also be changed administratively. It is the responsibility of the administrator to inform users of the application what the password is.

If this level of security is used, BEA TUXEDO system system-supplied client programs, ud(1) for example, prompt for the application password. Application-written client programs must include code to obtain the password from a user. The password should not be echoed to the user's terminal. The password is placed in clear text in the TPINFDEF-REC record and evaluated when the client calls TPINITIALIZE to join the application.

See "Writing Client Programs" in the BEA TUXEDO Programmer's Guide for examples of code for handling a password.

User Authentication
The third level of BEA TUXEDO system security is based on authenticating each individual user in addition to providing the application password. The security level is set to "USER_AUTH".

This level involves passing user-specific data to an authentication service. Often, the data is a per-user password. This data is automatically encrypted when passed over the network from workstation clients. The default authentication service, "AUTHSVC," is provided by a BEA TUXEDO system-supplied server, AUTHSVR. The operation of AUTHSVR is described in "Writing Service Routines" in the BEA TUXEDO Programmer's Guide. This server can be replaced with an application authentication server with logic specific to the application. (For example, it might access the widely-used Kerberos mechanism for authentication.)

With this level of security, authentication but not authorization is provided. That is, the user is checked when joining the application but then is free to execute any services, post events, and access application queues. It is possible for the servers to do application-specific authorization within the logic of the service routines, but there are no hooks for authorization checking for access to events or application queues. The alternative is to use the built-in access control checking.

Optional Access Control Lists
With the use of access control lists (ACLs), the user is not only authenticated when joining the application, but permissions are automatically checked when accessing application entities such as services. ACL security also includes the user-authentication security equivalent to USER_AUTH.

There are two levels of ACL checking. The first ACL security level is simply called ACL. If ACL is configured, the Access Control Lists are checked whenever a user attempts to access a service name, queue name, or event name within the application. If there is no ACL associated with the name, the assumption is that permission is granted. This is why this level is considered "optional" ACLs. It allows the administrator to configure access for those resources that need more security, but ACLs need not be configured for services, queues, or events that are accessible to everyone.

Some applications may find it necessary to use both system level and application authorization. An ACL can be used to control who can get to a service, and application logic can control data-dependent access (for example, who can handle transactions for more than a million dollars).

Mandatory Access Control Lists
The second ACL security level is "MANDATORY_ACL." This level is similar to ACL, but an access control list must be configured for every object for which users are to have access. If MANDATORY_ACL is specified and there is no ACL for the name, permission is denied.

A routine, TPCHKAUTH, is provided so the level of security can be checked before calling TPINITIALIZE. TPCHKAUTH returns a value corresponding to:

TPNOAUTH
normal UNIX login and file permission security

TPSYSAUTH
an application password is required. The client program should place it in the PASSWD field of the TPINFDEF-REC record.

TPAPPAUTH
the application password is required. In addition, the client is expected to provide a value to be passed to the application-specific authentication service in the DATALEN field of the TPINFDEF-REC record.

The TPINFDEF-REC Record

The TPINFDEF-REC record is a special BEA TUXEDO system typed record used by a client program to pass client identification and authentication information to the system as the client attempts to join the application. It is defined in the COBOL COPY file and contains the following fields:

05 USRNAME           PIC X(30).
05 CLTNAME PIC X(30).
05 PASSWD PIC X(30).
05 GRPNAME PIC X(30).
05 NOTIFICATION-FLAG PIC S9(9) COMP-5.
88 TPU-SIG VALUE 1.
88 TPU-DIP VALUE 2.
88 TPU-IGN VALUE 3.
05 ACCESS-FLAG PIC S9(9) COMP-5.
88 TPSA-FASTPATH VALUE 1.
88 TPSA-PROTECTED VALUE 2.
05 DATALEN PIC S9(9) COMP-5.

The USRNAME, CLTNAME and GRPNAME Members of TPINFDEF-REC

USRNAME, CLTNAME and GRPNAME are all strings of up to MAXTIDENT characters. MAXTIDENT is defined as 30. USRNAME is a name representing the caller; you might elect to use the number returned by getuid(2). CLTNAME is a client name whose semantics are application defined. GRPNAME allows a client to be associated with a resource manager group that is defined in the configuration file. This means that a client can access an XA-compliant resource manager as part of a global transaction. Currently, GRPNAME must be passed as SPACES, the client is not associated with a resource manager group and is in the default client group. The USRNAME and CLTNAME fields are associated with the client process when TPINITIALIZE is called and are used for both broadcast notification and the retrieval of administrative statistics.

The PASSWD Member of TPINFDEF-REC

PASSWD is a SPACES string of up to MAXTIDENT characters. It is an application password in unencrypted format that is used by TPINITIALIZE for validation against the application password stored in the TUXCONFIG file.

The Settings Members of TPINFDEF-REC

The settings members of TPINFDEF-REC are used to indicate the notification mechanism and system access mode to be used. Selections override values specified in the configuration file (with some exceptions explained below). Possible settings values are:

TPU-DIP
Select unsolicited notification by dip-in. This is the default method if nothing is specified in the configuration file. It has the advantage of giving the receiving program more control over when unsolicited messages are handled. The system will detect unsolicited messages for your client process only while you are within ATMI calls. You may want to check for unsolicited messages as part of your regular checking routine following returns from ATMI calls. If you specify this setting (or accept it as the default method), you should include a call to TPSETUNSOL early in your program. Until the handler for unsolicited messages is known no messages can be delivered.

TPU-SIG
Select unsolicited notification by signals. This method has the advantage of immediate notification, but has the limitations that you must have the same uid as the sending process, and is not available on all platforms (specifically, it is not available with the MS-DOS instantiation of the Workstation). If you specify this option but do not qualify for it, the system resets your choice to TPU-DIP and calls USERLOG to note the event.

TPU-IGN
Ignore unsolicited notification.

TPSA-FASTPATH
Specifies ATMI calls within application code can access BEA TUXEDO system internal tables via shared memory and that the shared memory is not protected against access by application code outside of BEA TUXEDO system libraries. Overrides the value in UBBCONFIG, except when NO_OVERRIDE is specified. This is the default if SYSTEM_ACCESS mode is unspecified.

TPSA-PROTECTED
Specifies ATMI calls within application code can access BEA TUXEDO system internal tables via shared memory but the shared memory is protected against access by application code outside of BEA TUXEDO system libraries. Overrides the value in UBBCONFIG, except when NO_OVERRIDE is specified.

The DATALEN Member of TPINFDEF-REC

DATALEN is the length of the application-specific data that will be sent to the authentication service. For native clients, it is not encoded by the system; it is passed to the authentication service as the client program provides it. For workstation clients, client authentication is handled by the system; it is passed over the network in encrypted form.

Joining and Leaving an Application

The two routines discussed in this section allow a client process to join and leave a BEA TUXEDO application. The syntax of these routines is:

01 TPINFDEF-REC.
COPY TPINFDEF.
01 USER-DATA-REC PIC X(any-length).
01 TPSTATUS-REC.
COPY TPSTATUS.
CALL "TPINITIALIZE" USING TPINFDEF-REC USER-DATA-REC TPSTATUS-REC.

and

01 TPSTATUS-REC.
COPY TPSTATUS.
CALL "TPTERM" USING TPSTATUS-REC.

Before a client can make any service request, it must join the application. If a service request (or any ATMI routine) is called before invoking TPINITIALIZE, then it is invoked automatically with a SPACES parameter. This implies that the features mentioned above cannot be used; the default values are used for client naming, unsolicited notification type, and system access mode, the client cannot be associated with a resource manager group, and an application password cannot be specified. To use these features, the application must explicitly invoke the TPINITIALIZE routine. Once invoked (either implicitly or explicitly), the calling process may initiate requests and receive replies. TPTERM removes the process from the application. When TPTERM returns successfully the process must again join the application before communicating with a BEA TUXEDO system server process. A typical client process might begin and end as illustrated in Listing 11-1.

Listing 11-1 Typical Client Process Paradigm
. . .
Check level of security
CALL TPSETUNSOL to name your handler routine for TPU-DIP
get USRNAME, CLTNAME
prompt for application PASSWD
SET TPU-DIP TO TRUE.
CALL "TPINITIALIZE" USING TPINFDEF-REC
USER-DATA-REC
TPSTATUS-REC.
IF NOT TPOK
error processing
. . .
make service call
receive the reply
check for unsolicited messages
. . .
CALL "TPTERM" USING TPSTATUS-REC.
IF NOT TPOK
error processing
. . .
EXIT PROGRAM.

The arguments to TPINITIALIZE are a structure, TPINFDEF-REC, that is defined in the COBOL COPY file, the user data and a status structure, TPSTATUS-REC, that is also defined in the COBOL COPY file.

TPTERM does not take an argument. Both routines return TP-STATUS IN TPSTATUS-REC set to [TPOK] upon success. On error, the command fails and sets TP-STATUS, to a value that indicates the nature of the error. TPSTATUS-REC is defined in the COBOL COPY file. There is a discussion of the values of TP-STATUS in Chapter 15, "Error Management." The complete list of error codes that can be returned for each of the ATMI routines can also be found on the manual pages that describe the routine and INTRO(3cbl) in the BEA TUXEDO Reference Manual.

An example of TPINITIALIZE and TPTERM is shown in Listing 11-2.

Listing 11-2 Joining and Leaving the Application
IDENTIFICATION DIVISION.
PROGRAM-ID. FIG1-3.
AUTHOR. TUXEDO DEVELOPMENT.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
*
WORKING-STORAGE SECTION.
*****************************************************
* Tuxedo definitions
*****************************************************
01 TPSTATUS-REC.
COPY TPSTATUS.
*
01 TPINFDEF-REC.
COPY TPINFDEF.
*****************************************************
* Log messages definitions
*****************************************************
01 LOGMSG.
05 FILLER PIC X(10) VALUE "FIG12-3 =>".
05 LOGMSG-TEXT PIC X(50).
01 LOGMSG-LEN PIC S9(9) COMP-5.
*
01 USER-DATA-REC PIC X(75).
******************************************************
PROCEDURE DIVISION.
START-HERE.
MOVE LENGTH OF LOGMSG TO LOGMSG-LEN.
*****************************************************
* Now register the client with the system.
*****************************************************
MOVE SPACES TO USRNAME.
MOVE SPACES TO CLTNAME.
MOVE SPACES TO PASSWD.
MOVE SPACES TO GRPNAME.
MOVE ZERO TO DATALEN.
SET TPU-DIP TO TRUE.
*
CALL "TPINITIALIZE" USING TPINFDEF-REC
USER-DATA-REC
TPSTATUS-REC.
IF NOT TPOK
MOVE "TPINITIALIZE FAILED" TO LOGMSG-TEXT
PERFORM DO-USERLOG
PERFORM EXIT-PROGRAM.
*****************************************************
* Application specific code
*****************************************************
. . .
*****************************************************
*Leave Application
*****************************************************
CALL "TPTERM" USING TPSTATUS-REC.
IF NOT TPOK
MOVE "TPTERM FAILED" TO LOGMSG-TEXT
PERFORM DO-USERLOG.
EXIT-PROGRAM.
STOP RUN.
*****************************************************
* Log messages to the userlog
*****************************************************
DO-USERLOG.
CALL "USERLOG" USING LOGMSG
LOGMSG-LEN
TPSTATUS-REC.

The previous example shows the client process attempting to join the application with a call to TPINITIALIZE. If an error is encountered, a message is written to the central event log via a call to USERLOG.

Record Management

Before messages can be sent between processes, a record must be defined for the message data. The following sections describe the record types supported by BEA TUXEDO and how records are tested for type using routines in the ATMI.

Typed Records for Messages

BEA TUXEDO is delivered with eight message record types defined:

STRING  CARRAY  VIEW  FML X_COMMON  X_OCTET  VIEW32 FML32

Note: A ninth type, X_C_TYPE, is defined but should not be used from COBOL.

The eight record types are defined in tmtypesw.c (which can be found in $TUXDIR/lib/tmtypesw.c, with documentation in tuxtypes(5)). When the BEA TUXEDO system software is built, tmtypesw.o is archived in the BEA TUXEDO system libraries that are automatically linked in when the buildclient and buildserver commands are invoked, so the eight defined types are available to your application programs.

The tmtypesw.c file can be edited to add or remove record types. Information about how to do this can be found in Administering the BEA TUXEDO System. Only record types defined in tmtypesw.c can be known to your client or server programs. The ubbconfig(5) BUFTYPE parameter can be used to specify the types and subtypes a given service can know about.

Record Types: STRING

The STRING record type is what is conventionally understood as a string in the C language. It is an arbitrary number of characters which may not contain LOW-VALUE characters anywhere within the record but may be at the end of the record. Data dependent routing is not provided for this record type. If routing routines are desired, they must be written as part of the application. Encoding and decoding is provided for this record type.

Record Types: CARRAY

The CARRAY record type (and equivalently X_OCTET) is an arbitrary number of characters which may contain LOW-VALUE characters. The application defines the semantics; it is not interpreted by BEA TUXEDO. Data dependent routing is not provided for this record type. If routing routines are desired, they must be written as part of the application. No encoding or decoding is provided for a CARRAY record when crossing machine boundaries since the bytes are not interpreted by the system.

Record Types: FML and FML32

Records of the FML type are very flexible buffers that hold field identifier/field value pairs. FML buffers offer the advantages of data independence and flexibility; fields may be present or absent, or may have multiple occurrences. Also, FML buffers interface well with both the BEA TUXEDO system DBMS and the DES. The BEA TUXEDO system DBMS supports fielded records in database files, and the mio client process of the BEA TUXEDO system DES uses fielded buffers for input and output data. In addition, this data type provides the functionality of data dependent routing. Automatic encoding and decoding is done if the buffer is passed between machines of different types.

In C, FML functions are used to manipulate FML typed buffers. These functions are not available in COBOL. However, functions are provided to initialize an FML buffer, to convert FML buffers to COBOL records, VIEWs, and back again.

The FML32 type is similar to the FML type but supports larger character fields, more fields, and larger overall records. It is also used on conversion to/from VIEW32 records. The FML32 buffer type uses environment variables suffixed with "32", that is, FIELDTBLS32 and FLDTBLDIR32. The primary use of FML32 in COBOL is simply to work with C programs that are using VIEW32 or FML32 typed buffers.

Record Types: VIEW, X_COMMON and VIEW32

Records of the VIEW type (and equivalently X_COMMON) are COBOL data structures that the application defines. The data structure is passed between processes in a VIEW typed record of a specific subtype. The process for defining a VIEW record was described in Chapter 10, "The BEA TUXEDO System Development Environment." A VIEW can be one derived from a fielded buffer (type FML) or one defined independently of a fielded buffer. The ATMI primitives all take both types of VIEW buffer, but there are differences in the way the two types of VIEWS themselves are defined and in how they are handled within your programs. These differences were described in Chapter 10, "The BEA TUXEDO System Development Environment." Both types of VIEW buffer support data dependent routing and automatic encoding and decoding when the buffer is passed between unlike machines.

The comparison of how to create and use the two VIEW types is summarized in Table 11-1.

Table 11-1 Comparison of Two VIEW Types

FML-dependent VIEW FML-independent VIEW

Creating

create the view description file with FML information in it

create the view description file without FML information in it

use the viewc -C compiler without the -n option to compile the description file

use the viewc -C compiler with the -n option to compile the description file

Using

set and export FIELDTBLS, FLDTBLDIR, VIEWFILES, VIEWDIR in the ENVFILE for the machine the client process is running on

set and export VIEWFILES and VIEWDIR in the ENVFILE for the machine the client process is running on

include the copy file FMLINFO, the copy file created from the view compiler in the programs that define FML and VIEW buffers

include the copy file created from the view compiler in the programs that define VIEW buffers

An X_COMMON record should contain only

PIC S9(4) COMP-5 (short) 
PIC S9(9) COMP-5
(long)
and
PIC (character)

fields, which are common to both the COBOL and C languages.

The VIEW32 record is similar to the VIEW type but supports larger character fields and bigger records. It is also used for conversion to/from FML32 records. The VIEW32 buffer type uses environment variables suffixed with "32", that is, FIELDTBLS32, FLDTBLDIR32, VIEWFILES32, and VIEWDIR32. The primary use of VIEW32 in COBOL is simply to work with C programs that are using VIEW32 or FML32 typed buffers.

Record Types: Summary

Although system configuration and defining record types are application design issues rather than programming issues, the above discussion has been included to explain how processes know about the various record types so you can correctly define records for the communication calls between processes.

ATMI Record Calls

It is important for the BEA TUXEDO programmer to know what record types are required and expected by the application. The ATMI routines take REC-TYPE and SUB-TYPE, both in TPTYPE-REC, as arguments. For the types provided by BEA TUXEDO, the REC-TYPE specifies the type of record that is to be sent. The SUB-TYPE argument has meaning only when REC-TYPE is VIEW, VIEW32, or X_COMMON. In this case, the SUB-TYPE is the name of the specific data structure defined as a VIEW, or X_COMMON. In the other record types, the SUB-TYPE argument is SPACES. LEN IN TPTYPE-REC specifies the amount of data to send and the amount received.

Service Calls

Once a client process has joined the application and placed the input data request in a record, it can then send the request message to a service subroutine for processing and receive a reply message. The next sections discuss the ATMI routines that allow processes that are acting as clients to send message requests to services and receive replies either synchronously or asynchronously.

The TPCALL routine sends a request to a service subroutine and synchronously waits for its reply.

The TPACALL routine sends a request to a service and immediately returns. The reply to the service call is asynchronously received by calling the TPGETRPLY routine.

Sending Synchronous Messages: TPCALL

TPCALL is used to send synchronous messages. The syntax of this routine is:

01 TPSVCDEF-REC.
COPY TPSVCDEF.
01 ITPTYPE-REC.
COPY TPTYPE.
01 IDATA-REC.
COPY User Data.
01 OTPYTPE-REC.
COPY TPTYPE.
01 ODATA-REC.
COPY User Data.
01 TPSTATUS-REC.
COPY TPSTATUS.
CALL "TPCALL" USING TPSVCDEF-REC
ITPTYPE-REC
IDATA-REC
OTPTYPE-REC
ODATA-REC
TPSTATUS-REC
.

TPCALL sends a request to the service that is specified in its first parameter, SERVICE-NAME IN TPSVCDEF-REC. The service named in SERVICE-NAME must be one offered in your application. TPCALL waits for the expected reply. It is logically the same as calling the TPACALL routine immediately followed by TPGETRPLY. The request carries the priority that is set by the system for the service specified in SERVICE-NAME unless a different priority has been explicitly set by a call to TPSPRIO.

The parameter of the routine, IDATA-REC, contains the data portion of the request and LEN IN ITPTYPE-REC specifies how much of IDATA-REC to send. Note that the REC-TYPE and SUB-TYPE, both in ITPTYPE-REC, must match the type (and subtype) expected by the service routine. If the types do not match, the system sets TP-STATUS to TPEITYPE and the routine call fails.

If the record is a self-defining type, that is, a VIEW, VIEW32, FML, FML32, or X_COMMON record, LEN IN ITPTYPE-REC is ignored and can be set to zero. If REC-TYPE IN ITPTYPE-REC is STRING and LEN IN ITPTYPE-REC is 0, then the request is sent with no data portion. If the request requires no data, set REC-TYPE IN ITPTYPE-REC to SPACES. This causes the IDATA-REC and LEN IN ITPTYPE-REC parameters to be ignored.

The next two parameters indicate the record that is to receive the reply message, ODATA-REC, and the length of the reply data, LEN IN OTPTYPE-REC. If the reply message sent back contains no data portion, upon successful return from TPCALL, LEN IN OTPTYPE-REC will be set to zero, and the contents of the output record will remain unchanged. It is an error for LEN IN OTPTYPE-REC to be zero on input.

The same record can be used for both the request and reply message. If this is the case, then ODATA-REC must be REDEFINED to IDATA-REC.

Listing 11-3 shows a client program making a synchronous call using the same record for both the request and reply message. Using the same record is appropriate in this particular case, since the AUDV-REC message record has been set up to accommodate both request and reply information in the same record. The B-ID field is queried by the service but not overwritten and the BALANCE field has been initialized to zero in anticipation of the value to be returned by the service. The SERVICE-NAME variable represents the service name requested.

Listing 11-3 Using the Same Record for Request and Reply Messages
WORKING-STORAGE SECTION.
*****************************************************
* Tuxedo definitions
*****************************************************
01 TPTYPE-REC.
COPY TPTYPE.
*
01 TPSTATUS-REC.
COPY TPSTATUS.
*
01 TPSVCDEF-REC.
COPY TPSVCDEF.
*****************************************************
* Log messages definitions
*****************************************************
01 LOGMSG.
05 FILLER PIC X(6) VALUE "FIG =>".
05 LOGMSG-TEXT PIC X(50).
01 LOGMSG-LEN PIC S9(9) COMP-5.
*
01 USER-DATA-REC PIC X(75).
*****************************************************
* This VIEW record (audv) will be sent to the server
*****************************************************
01 AUDV-REC.
COPY AUDV.
*
******************************************************
PROCEDURE DIVISION.
START-FIG.
MOVE LENGTH OF LOGMSG TO LOGMSG-LEN.
*****************************************************
* Prepare the audv record
*****************************************************
MOVE "BRANCH" TO B-ID IN AUDV-REC.
MOVE 0 TO BALANCE IN AUDV-REC.
MOVE LENGTH OF AUDV-REC TO LEN.
MOVE "VIEW" TO REC-TYPE.
MOVE "audv" TO SUB-TYPE.
MOVE "SOMESERVICE" TO SERVICE-NAME.
SET TPBLOCK TO TRUE.
SET TPNOTRAN TO TRUE.
SET TPNOTIME TO TRUE.
SET TPSIGRSTRT TO TRUE.
SET TPNOCHANGE TO TRUE.
CALL "TPCALL" USING TPSVCDEF-REC
TPTYPE-REC
AUDV-REC
TPTYPE-REC
AUDV-REC
TPSTATUS-REC.
IF NOT TPOK
MOVE "Service Failed" TO LOGMSG-TEXT
PERFORM DO-USERLOG
PERFORM EXIT-PROGRAM.
DISPLAY BRANCH and BALANCE
. . .

Note: For an example in which different records are used for input and output see Listing 12-2 in Chapter 12, "Writing Service Routines."

If the reply is larger than ODATA-REC, then ODATA-REC will contain as much of the message as will fit in the record. The remainder is discarded and TPCALL sets TP-STATUS IN TPSTATUS-REC to TPTRUNCATE.

Values for the Settings: TPCALL

The last argument that TPCALL takes is TPSTATUS-REC. The settings in the TPSTATUS-REC argument can change the operation of the communication call in some way by allowing additional flexibility to the application. Valid settings are:

TPNOTRAN
If the client process is in transaction mode when it calls TPCALL, and the setting is TPNOTRAN, the service that is invoked by the call will not be part of the transaction; that is, the operations that the service performs are not part of the caller's transaction. There's more on this subject in Chapter 14, "Global Transactions in the BEA TUXEDO System." Either TPNOTRAN or TPTRAN must be set.

TPTRAN
If the client process is in transaction mode when it calls TPCALL, and the setting is TPTRAN, the service that is invoked by the call will be part of the transaction; that is, the operations that the service performs are part of the caller's transaction. Either TPNOTRAN or TPTRAN must be set.

TPNOCHANGE
By using this value, the calling program is indicating that it wants the message returned in the same type of record that was originally defined as the output record. In other words when this setting is set, the type of record returned to the caller must be the same as REC-TYPE IN OTPTYPE-REC and SUB-TYPE IN OTPTYPE-REC. This is known as strong record type checking. Either TPNOCHANGE or TPCHANGE must be set.

TPCHANGE
This setting allows a record type to be different than the original one so long as the caller recognizes the type. In this case, the record type, REC-TYPE IN OTPTYPE-REC, changes to the received record type. This is known as weak type checking. Either TPNOCHANGE or TPCHANGE must be set.

TPNOBLOCK
TPNOBLOCK concerns the action a routine call takes if a blocking condition exists. Callers of the communication routines typically block when waiting for a reply to arrive although they may also block when trying to send a request if all server queues or internal records are full. A default blocking time-out period is defined for the application in the configuration file. It specifies the amount of time a caller should wait for a blocking condition to subside when one exists. If the condition persists beyond this limit, the routine call fails and TP-STATUS is set to TPETIME. When the valid setting is TPNOBLOCK, if a blocking condition exists, the call fails immediately and the request message is not sent. In this case, TP-STATUS is set to TPEBLOCK. Note that TPCALL is a dual routine in that it both sends a request and receives a reply. When TPNOBLOCK is set, it affects only the send part of the routine; if all the server queues are filled or the internal records into which the message records are copied are full, the call will not block but immediately return. However, if it must wait for the reply (which is usually the case), this setting does not immunize the call from blocking while it waits. Either TPNOBLOCK or TPBLOCK must be set.

TPBLOCK
When the valid setting is TPBLOCK, if a blocking condition exists, the caller blocks until the condition changes or a timeout occurs, either transaction or blocking. Either TPNOBLOCK or TPBLOCK must be set.

TPNOTIME
By setting TPNOTIME, you are telling the system to ignore the blocking time-out limit because the caller is willing to wait indefinitely for the blocking condition to subside. However, if the caller is in transaction mode this setting has no effect; it is subject to the transaction time-out limit. The timing out of transactions will be discussed in Chapter 14, "Global Transactions in the BEA TUXEDO System." Either TPNOTIME or TPTIME must be set.

TPTIME
TPTIME indicates that you are telling the system to receive the blocking time-out if a blocking condition exists and the blocking time is reached. Either TPNOTIME or TPTIME must be set.

TPSIGRSTRT
Another valid setting is TPSIGRSTRT. This value concerns the action to take if there is a signal interrupt. When TPSIGRSTRT is set, the call is automatically made again. As a result, in the event that a signal interrupts the underlying system call, the routine call is reissued. When TPSIGRSTRT is not set and there is a signal interrupt, the routine call fails and TP-STATUS returns TPGOTSIG. Either TPSIGRSTRT or TPNOSIGRSTRT must be set.

TPNOSIGRSTRT
When TPNOSIGRSTRT is set and there is a signal interrupt, the call is not restarted and the routine call fails. Either TPSIGRSTRT or TPNOSIGRSTRT must be set.

TPCALL sets TP-STATUS to TPOK upon success. On failure, the value of TP-STATUS is set to an appropriate value reflecting the type of error that occurred. Some of the causes for error have already been discussed, while others have transaction implications and will be introduced in Chapter 15, "Error Management." In general, communication calls may fail for a variety of errors. Many of the errors returned on communication calls can be fixed on an application level. They include application defined errors (TPESVCFAIL), errors in processing return arguments (TPESVCERR), typed record errors (TPEITYPE, TPEOTYPE), time-out (TPETIME), and protocol errors (TPEPROTO) among others. They are all discussed in Chapter 15, "Error Management," and are listed on the INTRO and TPCALL manual pages. The communication of these failures will also be explained in the discussion of the TPRETURN routine in Chapter 12, "Writing Service Routines."

Examples of the Use of Settings

The next three figures give examples of TPCALL using the communication settings in various scenarios.

The example shown in Listing 11-4 is based on a service which assumes the role of a client when it calls on the services of WITHDRAWAL and DEPOSIT. In the example, we have set the communication setting to TPSIGRSTRT in these service calls to give the transaction a better chance of committing.

Listing 11-4 Sending a Synchronous Message with TPSIGRSTRT Set
   WORKING-STORAGE SECTION.
*****************************************************
* Tuxedo definitions
*****************************************************
01 TPTYPE-REC.
COPY TPTYPE.
*
01 TPSTATUS-REC.
COPY TPSTATUS.
*
01 TPSVCDEF-REC.
COPY TPSVCDEF.
*****************************************************
* This VIEW record (audv) will be sent to the server
*****************************************************
01 AUDV-REC.
COPY AUDV.
*
******************************************************
PROCEDURE DIVISION.
START-FIG.
*****************************************************
* Prepare the audv record for withdrawal
*****************************************************
. . .
MOVE "WITHDRAWAL" TO SERVICE-NAME.
SET TPSIGRSTRT TO TRUE.
PERFORM DO-TPCALL.
IF NOT TPOK
MOVE "Cannot withdraw from debit account" TO LOGMSG-TEXT
PERFORM DO-USERLOG
PERFORM EXIT-PROGRAM.
MOVE "DEPOSIT" TO SERVICE-NAME.
SET TPSIGRSTRT TO TRUE.
PERFORM DO-TPCALL.
IF NOT TPOK
MOVE "Cannot deposit into credit account" TO LOGMSG-TEXT
PERFORM DO-USERLOG
PERFORM EXIT-PROGRAM.
. . .
*****************************************************
* Perform a TPCALL
*****************************************************
DO-TPCALL.
MOVE LENGTH OF AUDV-REC TO LEN.
MOVE "VIEW" TO REC-TYPE.
MOVE "audv" TO SUB-TYPE.
SET TPBLOCK TO TRUE.
SET TPNOTRAN TO TRUE.
SET TPNOTIME TO TRUE.
SET TPNOCHANGE TO TRUE.
CALL "TPCALL" USING TPSVCDEF-REC
TPTYPE-REC
AUDV-REC
TPTYPE-REC
AUDV-REC
TPSTATUS-REC.
. . .

Listing 11-5 illustrates a communication call that suppresses transaction mode. It is being made to a service that is not affiliated with a resource manager and it would be an error to allow it to participate in the transaction. Specifically in this example, an accounts receivable report, ACCRCV is to be printed against a database named ACCOUNTS. The service routine REPORT interprets the parameters and sends the byte stream for the completed report as a reply. The client, shown here, uses TPCALL to send the byte stream to a service called PRINTER that prints out the byte stream to the appropriate printer for this client. It receives a reply from the PRINTER service naming the printer that was chosen to print the report to make it convenient for the user to pick up the hard copy. Listing 11-6 shows a similar example using an asynchronous message call.

Listing 11-5 Sending a Synchronous Message with TPNOTRAN Set
    WORKING-STORAGE SECTION.
*****************************************************
* Tuxedo definitions
*****************************************************
01 ITPTYPE-REC.
COPY TPTYPE.
01 OTPTYPE-REC.
COPY TPTYPE.
*
01 TPSTATUS-REC.
COPY TPSTATUS.
*
01 TPSVCDEF-REC.
COPY TPSVCDEF.
*****************************************************
01 REPORT-REQUEST PIC X(100) VALUE SPACES.
01 REPORT-OUTPUT PIC X(50000) VALUE SPACES.
******************************************************
PROCEDURE DIVISION.
START-FIG.
. . .
join application
start transaction
. . .
********************************************************
* Send report request to REPORT service
* Receive results into REPORT-OUTPUT
********************************************************
MOVE "REPORT=accrcv DBNAME=accounts" TO REPORT-REQUEST.
MOVE "STRING" TO REC-TYPE IN ITYPE-REC.
MOVE 29 TO LEN IN ITYPE-REC.
MOVE "STRING" TO REC-TYPE IN OITYPE-REC.
MOVE 50000 TO LEN IN OTYPE-REC.
MOVE "REPORT" TO SERVICE-NAME.
SET TPTRAN TO TRUE.
SET TPBLOCK TO TRUE.
SET TPNOTIME TO TRUE.
SET TPSIGRSTRT TO TRUE.
SET TPNOCHANGE TO TRUE.
CALL "TPCALL" USING TPSVCDEF-REC
ITPTYPE-REC
REPORT-REQUEST
OTPTYPE-REC
REPORT-OUTPUT
TPSTATUS-REC.
IF NOT TPOK
error processing
IF TPETRUNCATE
The report was truncated
error processing
********************************************************
* Send REPORT-OUTPUT to PRINTER service
********************************************************
MOVE "PRINTER" TO SERVICE-NAME.
SET TPNOTRAN TO TRUE.
MOVE "STRING" TO REC-TYPE IN ITTYPE-REC.
MOVE LEN IN OTYPE-REC TO LEN IN ITYPE-REC.
CALL "TPCALL" USING TPSVCDEF-REC
ITPTYPE-REC
REPORT-OUTPUT
OTPTYPE-REC
REPORT-OUTPUT
TPSTATUS-REC.
IF NOT TPOK
error processing
. . .
terminate transaction
leave application

In Listing 11-5 where error processing has been indicated, it should include printing an error message, aborting the transaction, leaving the application, and exiting the program.

Listing 11-5 also illustrates the use of the TPNOCHANGE communication setting to enforce strong record type checking. The strong record type checking, TPNOCHANGE is used to force the reply to be returned in a record of type STRING. A possible reason for this check is to guard against errors that may occur in the REPORT service subroutine in processing the request that could result in a reply record of an incorrect type. Another, is to prevent changes that are not made consistently across all areas of dependency. For example, someone could have changed the REPORT service to standardize all replies in some other STRING format without modifying the client process to reflect the change.

Sending Asynchronous Messages: TPACALL

This section discusses the sending of asynchronous messages where the sender of the request does not wait for the reply. The first half of this communication is performed by TPACALL. The syntax of this routine is:

01 TPSVCDEF-REC.
COPY TPSVCDEF.
01 TPTYPE-REC.
COPY TPTYPE.
01 DATA-REC.
COPY User Data.
01 TPSTATUS-REC.
COPY TPSTATUS.
CALL "TPACALL" USING TPSVCDEF-REC TPTYPE-REC DATA-REC TPSTATUS-REC.

The TPACALL routine sends a request message to the service named in SERVICE-NAME IN TPSVCDEF-REC and immediately returns from the call. The three parameters, DATA-REC, LEN IN TPTYPE-REC, and the settings in TPSTATUS-REC, have the same semantics as IDATA-REC, LEN IN ITPTYPE-REC, and the settings in TPSTATUS-REC of the TPCALL routine. Upon successful completion of the call, TPACALL returns a value in COMM-HANDLE IN TPSVCDEF-REC which serves as a communications handle that can be used to get the correct reply for the sent request. While TPACALL is in transaction mode (the topic of Chapter 14, "Global Transactions in the BEA TUXEDO System,"), there may be no outstanding replies when the transaction commits; that is, within a given transaction, for each request sent expecting a reply a corresponding reply must eventually be received.

Values for the Settings: TPACALL

The communication settings that TPACALL takes as valid for TPSTATUS-REC pertain to the send part of the communication. As a result, the setting value TPNOCHANGE is removed since it concerns the output record which is not present in this call, and the values TPNOREPLY and TPREPLY are added since the receive part is not implicit to this communication call. When TPCALL is used the fact that a reply is expected is implicit. TPACALL represents only the sending part of TPCALL, and it is possible to indicate whether a reply is expected or not.

TPNOREPLY
If the value TPNOREPLY is set, it signals to TPACALL that a reply is not expected. Guidelines for using this setting correctly when a process is in transaction mode are discussed in Chapter 14, "Global Transactions in the BEA TUXEDO System." When TPNOREPLY is set, on success TPACALL returns the value of 0 in COMM-HANDLE, an invalid communications handle, where 0 cannot be used by TPGETRPLY. Either TPNOREPLY or TPREPLY must be set.

TPREPLY
If the value TPREPLY is set, it signals to TPACALL that a reply is expected. When TPREPLY is set, on success TPACALL returns a valid communications handle in COMM-HANDLE. Either TPNOREPLY or TPREPLY must be set.

An example of TPACALL using the TPNOREPLY|TPNOTRAN setting is shown in Listing 11-6. This example is similar to the one presented above in Listing 11-5. In this case, however, a reply is not expected from the PRINTER service. By setting both of these settings, the client is indicating that no reply is expected and the PRINTER service is not to be a participant in the current transaction. Chapter 15 fully discusses this situation. Refer to the "Transaction Rules" section.

Listing 11-6 Sending an Asynchronous Message with TPNOTRAN or TPNOREPLY
   WORKING-STORAGE SECTION.
*****************************************************
* Tuxedo definitions
*****************************************************
01 ITPTYPE-REC.
COPY TPTYPE.
01 OTPTYPE-REC.
COPY TPTYPE.
*
01 TPSTATUS-REC.
COPY TPSTATUS.
*
01 TPSVCDEF-REC.
COPY TPSVCDEF.
*****************************************************
01 REPORT-REQUEST PIC X(100) VALUE SPACES.
01 REPORT-OUTPUT PIC X(50000) VALUE SPACES.
******************************************************
PROCEDURE DIVISION.
START-FIG.
. . .
join application
start transaction
. . .
********************************************************
* Send report request to REPORT service
* Receive results into REPORT-OUTPUT
********************************************************
MOVE "REPORT=accrcv DBNAME=accounts" TO REPORT-REQUEST.
MOVE "STRING" TO REC-TYPE IN ITPTYPE-REC.
MOVE 29 TO LEN IN ITPTYPE-REC.
MOVE "STRING" TO REC-TYPE IN OITYPE-REC.
MOVE 50000 TO LEN IN OTPTYPE-REC.
MOVE "REPORT" TO SERVICE-NAME.
SET TPTRAN TO TRUE.
SET TPBLOCK TO TRUE.
SET TPNOTIME TO TRUE.
SET TPSIGRSTRT TO TRUE.
SET TPREPLY TO TRUE.
SET TPNOCHANGE TO TRUE.
CALL "TPCALL" USING TPSVCDEF-REC
ITPTYPE-REC
REPORT-REQUEST
OTPTYPE-REC
REPORT-OUTPUT
TPSTATUS-REC.
IF NOT TPOK
error processing
IF TPETRUNCATE
The report was truncated
error processing
********************************************************
* Send REPORT-OUTPUT to PRINTER service
********************************************************
MOVE "PRINTER" TO SERVICE-NAME.
SET TPNOTRAN TO TRUE.
SET TPNOREPLY TO TRUE.
MOVE "STRING" TO REC-TYPE IN ITPTYPE-REC.
MOVE LEN IN OTPTYPE-REC TO LEN IN ITPTYPE-REC.
CALL "TPACALL" USING TPSVCDEF-REC
ITPTYPE-REC
REPORT-OUTPUT
TPSTATUS-REC.
IF NOT TPOK
error processing
. . .
commit transaction
leave application

On error, TPACALL sets TP-STATUS to a value that reflects the nature of the error. TPACALL returns many of the same error codes as TPCALL. Again, the differences are based on the fact that one represents a synchronous call and the other an asynchronous call. These errors are discussed at length in Chapter 15, "Error Management."

Getting an Asynchronous Reply: TPGETRPLY

TPGETRPLY is the complementary routine to TPACALL. It receives a reply from a request previously sent by TPACALL. The syntax of this routine is:

01 TPSVCDEF-REC.
COPY TPSVCDEF.
01 TPTYPE-REC.
COPY TPTYPE.
01 DATA-REC.
COPY User Data.
01 TPSTATUS-REC.
COPY TPSTATUS.
CALL "TPGETRPLY" USING TPSVCDEF-REC TPTYPE-REC DATA-REC TPSTATUS-REC.

TPGETRPLY takes the value of the communication handle returned by TPACALL in COMM-HANDLE IN TPSVCDEF-REC. In the default case, the routine waits for the arrival of the reply that corresponds to the value contained in COMM-HANDLE. In waiting for this specific reply, a blocking time-out may occur. A time-out means that TPGETRPLY fails and TP-STATUS is set to TPETIME (unless TPNOTIME is set).

The second and third arguments to TPGETRPLY, DATA-REC and LEN IN TPTYPE-REC, have identical semantics to those of the ODATA-REC and LEN IN OTPTYPE-REC parameters of the TPCALL routine.

Getting and Setting Priority

ATMI provides two routines that allow you to determine and set the priority of the message request. The priority affects how the request is dequeued by the server. Servers dequeue requests with the highest priorities first. The syntax of these routines is:

01 TPPRIDEF-REC.
COPY TPPRIDEF.
01 TPSTATUS-REC.
COPY TPSTATUS.
CALL "TPGPRIO" USING TPPRIDEF-REC TPSTATUS-REC.

and

01 TPPRIDEF-REC.
COPY TPPRIDEF.
01 TPSTATUS-REC.
COPY TPSTATUS.
CALL "TPSPRIO" USING TPPRIDEF-REC TPSTATUS-REC.

The TPGPRIO routine can be called by a requester after invoking the TPCALL or TPACALL routine to retrieve the priority of the request message just sent. If it was called and no request was sent, the routine fails and sets TP-STATUS to TPENOENT. Upon success, TPGPRIO sets TP-STATUS to TPOK and returns an integer value in the range of 1 to 100, 100 being the highest priority value, in PRIORITY IN TPPRIDEF-REC. If the priority has not been explicitly set by using the TPSPRIO routine, the value of the priority will be that of the service routine that handles the request. The priority of the service is assigned the system default value of 50 unless it has been specifically defined to some other value by the administrator. See Listing 11-7 for an example of retrieving the priority of a message that was sent off in an asynchronous call.

Listing 11-7 Determining the Priority of the Sent Request
   WORKING-STORAGE SECTION.
*****************************************************
* Tuxedo definitions
*****************************************************
01 TPTYPE-REC-1.
COPY TPTYPE.
01 TPTYPE-REC-2.
COPY TPTYPE.
*
01 TPSTATUS-REC.
COPY TPSTATUS.
*
01 TPSVCDEF-REC-1.
COPY TPSVCDEF.
01 TPSVCDEF-REC-2.
COPY TPSVCDEF.
*
01 TPPRIDEF-REC-1.
COPY TPPRIDEF.
01 TPPRIDEF-REC-2.
COPY TPPRIDEF.
*****************************************************
01 DATA-REC-1 PIC X(100) VALUE SPACES.
01 DATA-REC-2 PIC X(100) VALUE SPACES.
******************************************************
PROCEDURE DIVISION.
START-FIG.
. . .
join application
populate DATA-REC1 and DATA-REC2 with send request
. . .
MOVE "CARRAY" TO REC-TYPE IN TYPE-REC-1.
MOVE 100 TO LEN IN TYPE-REC-1.
MOVE "SERVICE1" TO SERVICE-NAME IN TPSVCDEV-REC-1.
SET TPTRAN TO TRUE IN TPSVCDEV-REC-1.
SET TPBLOCK TO TRUE IN TPSVCDEV-REC-1.
SET TPNOTIME TO TRUE IN TPSVCDEV-REC-1.
SET TPSIGRSTRT TO TRUE IN TPSVCDEV-REC-1.
SET TPREPLY TO TRUE IN TPSVCDEV-REC-1.
CALL "TPACALL" USING TPSVCDEF-REC-1
TPTYPE-REC-1
DATA-REC-1
TPSTATUS-REC.
IF NOT TPOK
error processing
CALL "TPGPRIO" USING TPPRIDEF-REC-1 TPSTATUS-REC
IF NOT TPOK
error processing
MOVE "CARRAY" TO REC-TYPE IN TYPE-REC-2.
MOVE 100 TO LEN IN TYPE-REC-2.
MOVE "SERVICE2" TO SERVICE-NAME IN TPSVCDEV-REC-2.
SET TPTRAN TO TRUE IN TPSVCDEV-REC-2.
SET TPBLOCK TO TRUE IN TPSVCDEV-REC-2.
SET TPNOTIME TO TRUE IN TPSVCDEV-REC-2.
SET TPSIGRSTRT TO TRUE IN TPSVCDEV-REC-2.
SET TPREPLY TO TRUE IN TPSVCDEV-REC-2.
CALL "TPACALL" USING TPSVCDEF-REC-2
TPTYPE-REC-2
DATA-REC-2
TPSTATUS-REC.
IF NOT TPOK
error processing
CALL "TPGPRIO" USING TPPRIDEF-REC-2 TPSTATUS-REC
IF NOT TPOK
error processing
IF PRIORITY IN TPSVCDEF-REC-1 >= PRIORITY IN TPSVCDEF-REC-2
PERFORM DO-GETREPLY1
PERFORM DO-GETREPLY2
ELSE
PERFORM DO-GETREPLY2
PERFORM DO-GETREPLY1
END-IF.
. . .
leave application
DO-GETRPLY1.
SET TPGETHANDLE TO TRUE IN TPSVCDEV-REC-1.
SET TPCHANGE TO TRUE IN TPSVCDEV-REC-1.
SET TPBLOCK TO TRUE IN TPSVCDEV-REC-1.
SET TPNOTIME TO TRUE IN TPSVCDEV-REC-1.
SET TPSIGRSTRT TO TRUE IN TPSVCDEV-REC-1.
CALL "TPGETRPLY" USING TPSVCDEF-REC-1
TPTYPE-REC-1
DATA-REC-1
TPSTATUS-REC.
IF NOT TPOK
error processing
DO-GETRPLY2
SET TPGETHANDLE TO TRUE IN TPSVCDEV-REC-2.
SET TPCHANGE TO TRUE IN TPSVCDEV-REC-2.
SET TPBLOCK TO TRUE IN TPSVCDEV-REC-2.
SET TPNOTIME TO TRUE IN TPSVCDEV-REC-2.
SET TPSIGRSTRT TO TRUE IN TPSVCDEV-REC-2.
CALL "TPGETRPLY" USING TPSVCDEF-REC-2
TPTYPE-REC-2
DATA-REC-2
TPSTATUS-REC.
IF NOT TPOK
error processing

It is also possible to use TPGPRIO to retrieve the priority of the request just received by the service. This is illustrated in Listing 12-3 in Chapter 12, "Writing Service Routines."

With the TPSPRIO routine, the programmer can override the priority level the request would normally inherit from the service to which it is dispatched. When TPSPRIO is called, it affects the priority level of the very next request only that is sent by TPCALL or TPACALL or forwarded by a service subroutine. Forwarding requests will be discussed later in Chapter 12, "Writing Service Routines." This routine takes two parameters, TPPRIDEF-REC and TPSTATUS-REC, and the second one indicates how the first one is to be interpreted. The first member, PRIORITY IN TPPRIDEF-REC, is an integer. In the default situation, its sign indicates whether the request's priority should be incremented or decremented in relation to the existing priority. For the first member to be treated as a relative value, the settings must be set to 0. If TPABSOLUTE is set, the priority value of the next request that is sent out will receive the absolute value of the integer contained in PRIORITY. The absolute value of PRIORITY must be in the range of 1 to 100. If the value is not in this range, the system uses the default value, 50. If TPRELATIVE is set, the priority value of the next request is sent out at the relative value of the integer contained in PRIORITY.

Listing 11-8 shows an excerpt from the TRANSFER service acting as a client process to call services of WITHDRAWAL. It invokes TPSPRIO to increase the priority of the request message it sends in its synchronous call to WITHDRAWAL. It does so to prevent the request from being queued for the WITHDRAWAL service (and later the DEPOSIT service) after already having waited on the TRANSFER queue.

Listing 11-8 Setting the Priority of a Request Message
    WORKING-STORAGE SECTION.
*****************************************************
* Tuxedo definitions
*****************************************************
01 TPTYPE-REC.
COPY TPTYPE.
*
01 TPSTATUS-REC.
COPY TPSTATUS.
*
01 TPSVCDEF-REC.
COPY TPSVCDEF.
*
01 TPPRIDEF-REC.
COPY TPPRIDEF.
*****************************************************
01 DATA-REC PIC X(100) VALUE SPACES.
******************************************************
PROCEDURE DIVISION.
START-FIG.
. . .
join application
. . .
MOVE 30 TO PRIORITY.
SET TPRELATIVE TO TRUE.
CALL "TPSPRIO" USING TPPRIDEF-REC TPSTATUS-REC
IF NOT TPOK
error processing
MOVE "CARRAY" TO REC-TYPE.
MOVE 100 TO LEN.
MOVE "WITHDRAWAL" TO SERVICE-NAME.
SET TPTRAN TO TRUE .
SET TPBLOCK TO TRUE .
SET TPNOTIME TO TRUE .
SET TPSIGRSTRT TO TRUE .
SET TPREPLY TO TRUE .
CALL "TPACALL" USING TPSVCDEF-REC
TPTYPE-REC
DATA-REC
TPSTATUS-REC.
IF NOT TPOK
error processing
. . .
leave application

Initiating a Conversational Connection

The discussion in this chapter has centered around how client programs initiate a request/response service request. Client programs can also connect to conversational servers by using TPCONNECT instead of TPCALL or TPACALL. Chapter 13, "Conversational Clients and Services," describes this topic in detail.

Sending a Broadcast Message

The TPBROADCAST routine is used to send an unsolicited message to registered clients within the application. It is mentioned in this chapter on client programs because it can be called by clients. A more complete discussion of its use can be found in Chapter 12, "Writing Service Routines."

Handling Unsolicited Notification

The three routines in this section allow a client to handle unsolicited messages. They are TPGETUNSOL, TPSETUNSOL and TPCHKUNSOL. The syntax for TPSETUNSOL is:

01 CURR-ROUTINE   PIC S9(9) COMP-5.
01 PREV-ROUTINE PIC S9(9) COMP-5.
01 TPSTATUS-REC.
COPY TPSTATUS.
CALL "TPSETUNSOL" USING CURR-ROUTINE PREV-ROUTINE TPSTATUS-REC.

TPSETUNSOL allows a client to identify the routine that should be invoked when an unsolicited message is received by the BEA TUXEDO libraries. Prior to the first call to TPSETUNSOL, any unsolicited messages received by the BEA TUXEDO libraries on behalf of the client are logged and ignored. A call to TPSETUNSOL with a function number, CURR-ROUTINE, set to 0 has the same effect. The method used by the system for notification and detection is determined by the application default, which can be overridden on a per-client basis (see TPINITIALIZE).

The routine number passed, in CURR-ROUTINE, on the call to TPSETUNSOL selects one of 16 predefined routines. The routine names must be _tm_dispatch1 through _tm_dispatch8 for C routines that provide unsolicited message handling and TMDISPATCH9 through TMDISPATCH16 for COBOL routines that provide the same message handling. The routine _tm_dispatch1 through _tm_dispatch8 must conform to the parameter definition described in tpsetunsol(3c). Routines TMDISPATCH9 through TMDISPATCH16 must use TPGETUNSOL to receive the data.

Listing 11-9 is an example of a client setting a COBOL unsolicited function.

Listing 11-9 Setting an Unsolicited Function
*
* Call TPSETUNSOL - Set a COBOL unsolicited message handler
* Routine TMDISPATCH9 will be called
*
MOVE 9 to CURR-ROUTINE.
CALL "TPSETUNSOL" USING
CURR-ROUTINE
PREV-ROUTINE
TPSTATUS-REC.
IF NOT TPOK
Routine TMDISPATCH9 will receive unsolicited messages
ELSE
Process error condition

The syntax of TPGETUNSOL is:

01 TPTYPE-REC.
COPY TPTYPE.
01 DATA-REC.
COPY User data.
01 TPSTATUS-REC.
COPY TPSTATUS.
CALL "TPGETUNSOL" USING TPTYPE-REC DATA-REC TPSTATUS-REC.

TPGETUNSOL gets unsolicited messages that were sent via TPBROADCAST or TPNOTIFY. This routine may be called only from an unsolicited message handler.

Upon successful return, LEN IN TPTYPE-REC contains the actual number of bytes moved into DATA-REC. REC-TYPE and SUB-TYPE, both in TPTYPE-REC, contain the data's type and sub-type, respectively. If the message is larger than DATA-REC, then DATA-REC will contain only as many bytes as will fit in the record. The remainder of the message is discarded and sets TPTRUNCATE. If LEN is 0, upon successful completion, then the message has no data portion and DATA-REC was not modified.

Listing 11-10 is an example of a COBOL program receiving an unsolicited message.

Listing 11-10 Receiving an Unsolicited Message
 IDENTIFICATION DIVISION.
PROGRAM-ID. TMDISPATCH9.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. USL-486.
OBJECT-COMPUTER. USL-486.
*
DATA DIVISION.
WORKING-STORAGE SECTION.
*
01 TPTYPE-REC.
COPY TPTYPE.
*
01 TPSTATUS-REC.
COPY TPSTATUS.
*
01 DATA-REC PIC X(1000).
*
PROCEDURE DIVISION.
*
A-000.
*
MOVE "CARRAY" TO REC-TYPE.
MOVE 1000 TO LEN.
CALL "TPGETUNSOL" USING TPTYPE-REC
DATA-REC
TPSTATUS-REC.
IF NOT TPOK
error processing
*
Process message
DISPLAY "TPGETUNSOL IS TPOK".
DISPLAY "MESSAGE IS" DATA-REC.
DISPLAY "LENGTH IS" LEN.
EXIT PROGRAM.
*

The syntax of TPCHKUNSOL is:

01 MSG-NUM          PIC S9(9)  COMP-5.
01 TPSTATUS-REC.
COPY TPSTATUS.
CALL "TPCHKUNSOL" USING MSG-NUM TPSTATUS-REC.

TPCHKUNSOL is used by a client to trigger checking for unsolicited messages. Calls to this routine in a client using signal-based notification do nothing and return immediately. Calls to this routine can result in calls to an application-defined unsolicited message handling routine by the BEA TUXEDO system libraries.

Upon successful completion, TPCHKUNSOL sets TP-STATUS to [TPOK] and returns the number of unsolicited messages dispatched in MSG-NUM.

Listing 11-11 is an example of a COBOL program checking for the arrival of an unsolicited message.

Listing 11-11 Arrival of an Unsolicited Message
*
* Check for unsolicited messages
*
CALL "TPCHKUNSOL" USING MESS-NUM
TPSTATUS-REC.
*
IF TPOK
IF MESS-NUM IS = 0
No messages were processed by the
unsolicited function
ELSE
MESS-NUM number of messages were
processed by the unsolicited function
END-IF
ELSE
process error
END-IF

Compiling Client Programs

To compile your client programs you have several methods to choose from. You can use regular COBOL Compilation System utilities to make object files. The object files can be kept as individual files or collected into an archive file. If you prefer, you can retain your programs as source (.cbl) files. In any event, when you invoke buildclient to produce an executable client, you specify your input files on the command line with the -f option.

The buildclient Command

buildclient(1) is used to put together an executable client program. Options identify the name of the output file, input files provided by the application, and various libraries. When compiling a COBOL client, the -C option must be used to indicate that the language is COBOL. This ensures that the correct language libraries are included in linking the program.

buildclient with the -C option invokes the cobcc command. The environment variables ALTCC and ALTCFLAGS can be set to name an alternative compile command and to set flags for the compile and link edit phases. The default value for ALTCC is cobcc.

The buildclient -o Option

The -o option is used to assign a name to the executable output file. If no name is provided, the file is named a.out.

The buildclient -f and -l Options

The -f and -l options are used to specify files to be used in the link edit phase. The files specified in the -f (first) option are brought in before the BEA TUXEDO libraries, whereas the files specified in the -l (last) option are brought in after these libraries. There is a significance to the order of the options. The order is dependent on routine references and in what libraries the references are resolved. Input files should be listed ahead of libraries that might be used to resolve their references. If input files are .cbl and .c files, they are first compiled. Object files can be either separate.o files or groups of files in archive (.a) files. If more than a single file name is given as an argument to a -f or -l option, the syntax calls for a list enclosed in double quotes. You can use as many -f and -l options as you need.

The following represents the command line that was used to create the BUY executable program. The environment variable ALTCC is set to cobcc. The environment variable ALTCFLAGS is set to -I $TUXDIR/include.

buildclient -C -o BUY -f BUY.cbl

The buildclient -r Option

The -r option is used to specify which resource manager access libraries should be link edited with the executable client. The choice is specified with a string from the $TUXDIR/udataobj/RM file. Only one string can be specified. The database routines in your service are the same regardless of which library is used.

All valid strings that name resource managers are contained in the $TUXDIR/udataobj/RM file. When integrating a new resource manager into the BEA TUXEDO system, this file must be updated to include the information about the resource manager. For more information, refer to buildtms(1) in the BEA TUXEDO Reference Manual and Administering the BEA TUXEDO System.



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