Programming an Oracle Tuxedo Application Using COBOL

     Previous  Next    Open TOC in new window    View as PDF - New Window  Get Adobe Reader - New Window
Content starts here

Writing Servers

This topic includes the following sections:

 


Oracle Tuxedo System Controlling Program

To facilitate the development of ATMI servers, the Oracle Tuxedo system provides a predefined controlling program for server load modules. When you execute the buildserver -C command, the controlling program is automatically included as part of the server.

Note: The controlling program that the system provides is a closed abstraction; you cannot modify it.

In addition to joining and exiting from an application, the predefined controlling program accomplishes the following tasks on behalf of the server.

As indicated above, the main() routine handles all of the details associated with joining and exiting from an application, managing records and transactions, and handling communication.

Note: Because the system-supplied controlling program accomplishes the work of joining and leaving the application, you should not include calls to the TPINITIALIZE or TPTERM routine in your code. If you do, the routine encounters an error and returns TPEPROTO in TP-STATUS. For more information on the TPINITIALIZE or TPTERM routine, refer to “Writing Clients” in Programming Oracle Tuxedo ATMI Applications Using C.

 


System-supplied Server and Services

The controlling program provides one system-supplied ATMI server, AUTHSVR, and two subroutines, TPSVRINIT and TPSVRDONE. The default versions of all three, which are described in the following sections, can be modified to suit your application.

Notes: If you want to write your own versions of TPSVRINIT and TPSVRDONE, remember that the default versions of these two routines call tx_open() and tx_close(), respectively. If you write a new version of TPSVRINIT that calls tpopen() rather than tx_open(), you should also write a new version of TPSVRDONE that calls tpclose(). In other words, both routines in an open/close pair must belong to the same set.

System-supplied Server: AUTHSVR( )

You can use the AUTHSVR(5) server to provide individual client authentication for an application. The TPINITIALIZE routine calls this server when the level of security for the application is TPAPPAUTH, USER_AUTH, ACL, or MANDATORY_ACL.

The service in AUTHSVR looks in the USER-DATA-REC record for a user password (not to be confused with the application password specified in the PASSWD field of the TPINFDEF-REC record). By default, the system takes the string in data and searches for a matching string in the /etc/passwd file.

When called by a native-site client, TPINITIALIZE forwards the USER-DATA-REC record as it is received. This means that if the application requires the password to be encrypted, the client program must be coded accordingly.

When called by a Workstation client, TPINITIALIZE encrypts the data before sending it across the network.

System-supplied Services: TPSVRINIT Routine

When a server is booted, the Oracle Tuxedo system controlling program calls TPSVR INIT(3cbl) during its initialization phase, before handling any service requests.

If an application does not provide a custom version of this routine within the server, the system uses the default routine provided by the controlling program, which opens the resource manager and logs an entry in the central event log indicating that the server has successfully started. The central user log is an automatically generated file to which processes can write messages by calling the USERLOG( 3cbl) routine. Refer to “Managing Errors” in Programming Oracle Tuxedo ATMI Applications Using C for more information on the central event log.

You can use the TPSVRINIT routine for any initialization processes that might be required by an application, such as the following:

The following sections provide code samples showing how these initialization tasks are performed through calls to TPSVRINIT. Although it is not illustrated in the following examples, message exchanges can also be performed within this routine. However, TPSVRINIT fails if it returns with asynchronous replies pending. In this case, the replies are ignored by the Oracle Tuxedo system, and the server exits gracefully.

You can also use the TPSVRINIT routine to start and complete transactions, as described in “Managing Errors” in Programming Oracle Tuxedo ATMI Applications Using C.

Use the following signature to call the TPSVRINIT :routine

LINKAGE SECTION.
01 CMD-LINE.
05 ARGC PIC 9(4) COMP-5.
05 ARGV.
10 ARGS PIC X OCCURS 0 TO 9999 DEPENDING ON ARGC
.
01 TPSTATUS-REC.
COPY TPSTATUS.
PROCEDURE DIVISION USING CMD-LINE TPSTATUS-REC.
* User code
EXIT PROGRAM.

Receiving Command-line Options

When a server is booted, its first task is to read the server options specified in the configuration file. The options are passed through ARGC, which contains the number of arguments, and ARGV, which contains the arguments separated by a single SPACE character. The predefined controlling program then calls TPSVRINIT.

The following code example shows how the TPSVRINIT routine is used to receive command-line options.

Listing 5-1 Receiving Command-line Options in TPSVRINIT
  IDENTIFICATION DIVISION.
  PROGRAM-ID. TPSVRINIT.
  ENVIRONMENT DIVISION.
  CONFIGURATION SECTION.
  SOURCE-COMPUTER. USL-486.
  OBJECT-COMPUTER. USL-486.
*
  DATA DIVISION.
  WORKING-STORAGE SECTION.
*
  LINKAGE SECTION.
*
  01 CMD-LINE.
      05 ARGC PIC 9(4) COMP-5.
      05 ARGV.
           10 ARGS PIC X OCCURS 0 TO 9999 DEPENDING ON ARGC.
  01 SERVER-INIT-STATUS.
  COPY TPSTATUS.
*
 PROCEDURE DIVISION USING CMD-LINE SERVER-INIT-STATUS.
**********************************************************
* ARGC indicates the number of arguments and ARGV contains the
* arguments separated by a single SPACE.
**********************************************************
  A-START.
*
   . . . INSPECT the ARGV line and process arguments
   IF arguments are invalid
         SET TPEINVAL IN SERVER-INIT-STATUS TO TRUE.
   ELSE arguments are OK continue
         SET TPOK IN SERVER-INIT-STATUS TO TRUE.
*
   EXIT PROGRAM.

Opening a Resource Manager

The following example illustrates another common use of TPSVRINIT: opening a resource manager. The Oracle Tuxedo system provides routines to open a resource manager, TPOPEN( 3cbl) and TX OPEN(3cbl). It also provides the complementary routines, TPCLOSE(3c bl) and TXCLOSE(3 cbl). Applications that use these routines to open and close their resource managers are portable in this respect. They work by accessing the resource manager instance-specific information that is available in the configuration file.

These routine calls are optional and can be used in place of the resource manager specific calls that are sometimes part of the Data Manipulation Language (DML) if the resource manager is a database. Note the use of the USERL OG(3cbl) routine to write to the central event log.

Note: To create an initialization function that both receives command-line options and opens a database, combine the following example with the previous example.
Listing 5-2 Opening a Resource Manager in TPSVRINIT
  IDENTIFICATION DIVISION.
  PROGRAM-ID. TPSVRINIT.
  ENVIRONMENT DIVISION.
  CONFIGURATION SECTION.
  SOURCE-COMPUTER. USL-486.
  OBJECT-COMPUTER. USL-486.
*
  DATA DIVISION.
  WORKING-STORAGE SECTION.
    01 TPSTATUS-REC.
      COPY TPSTATUS.
    01 LOGMSG         PIC X(50).
    01 LOGMSG-LEN    PIC S9(9) COMP-5.
*
  LINKAGE SECTION.
    01 CMD-LINE.
      05 ARGC PIC 9(4) COMP-5.
      05 ARGV.
           10 ARGS PIC X OCCURS 0 TO 9999 DEPENDING ON ARGC.
    01 SERVER-INIT-STATUS.
     COPY TPSTATUS.
*
  PROCEDURE DIVISION USING CMD-LINE SERVER-INIT-STATUS.
  A-START.
    . . . INSPECT the ARGV line and process arguments
    IF arguments are invalid
               MOVE "Invalid Arguments Passed" TO LOGMSG
               PERFORM EXIT-NOW.
    ELSE arguments are OK continue
 
    CALL "TPOPEN" USING TPSTATUS-REC.
    IF NOT TPOK
          MOVE "TPOPEN Failed" TO LOGMSG
    ELSE IF TPESYSTEM
          MOVE "System /T error has occurred" TO LOGMSG
    ELSE IF TPEOS
          MOVE "An Operating System error has occurred" TO LOGMSG
    ELSE IF TPEPROTO
          MOVE "TPOPEN was called in an improper Context" TO LOGMSG
    ELSE IF TPERMERR
          MOVE "Resource manager Failed to Open" TO LOGMSG
          PERFORM EXIT-NOW.
    SET TPOK IN SERVER-INIT-STATUS TO TRUE.
    EXIT PROGRAM.
 EXIT-NOW.
  SET TPEINVAL IN SERVER-INIT-STATUS TO TRUE
    MOVE 50 LOGMSG-LEN.
    CALL "USERLOG" USING LOGMSG
                  LOGMSG-LEN
                  TPSTATUS-REC.
  EXIT PROGRAM.

To guard against errors that may occur during initialization, TPSVRINIT can be coded to allow the server to exit gracefully before starting to process service requests.

System-supplied Services: TPSVRDONE Routine

The TPSVRDONE routine calls TPCLOSE to close the resource manager, similarly to the way TPSVRINIT calls TPOPEN to open it.

Use the following signature to call the TPSVRDONE routine:

  01 TPSTATUS-REC.
COPY TPSTATUS.
PROCEDURE DIVISION.
* User code
EXIT PROGRAM.

The following example illustrates how to use the TPSVRDONE routine to close a resource manager and exit gracefully.

Listing 5-3 Closing a Resource Manager with TPSVRDONE
  IDENTIFICATION DIVISION.
  PROGRAM-ID. TPSVRDONE.
  ENVIRONMENT DIVISION.
  CONFIGURATION SECTION.
  SOURCE-COMPUTER. USL-486.
  OBJECT-COMPUTER. USL-486.
*
  DATA DIVISION.
  WORKING-STORAGE SECTION.
   01 TPSTATUS-REC.
      COPY TPSTATUS.
   01 LOGMSG PIC X(50).
   01 LOGMSG-LEN PIC S9(9) COMP-5.
   01 SERVER-DONE-STATUS.
      COPY TPSTATUS.
  PROCEDURE DIVISION.
  A-START.
   CALL "TPCLOSE" USING TPSTATUS-REC.
   IF NOT TPOK
          MOVE "TPCLOSE Failed" TO LOGMSG
   ELSE IF TPESYSTEM
          MOVE "System /T error has occurred" TO LOGMSG
   ELSE IF TPEOS
          MOVE "An Operating System error has occurred" TO LOGMSG
   ELSE IF TPEPROTO
          MOVE "TPCLOSE was called in an improper Context" TO LOGMSG
   ELSE IF TPERMERR
          MOVE "Resource manager Failed to Open" TO LOGMSG
          PERFORM EXIT-NOW.
   SET TPOK IN SERVER-DONE-STATUS TO TRUE.
   EXIT PROGRAM.
  EXIT-NOW.
   SET TPEINVAL IN SERVER-DONE-STATUS TO TRUE
   MOVE 50 LOGMSG-LEN.
   CALL "USERLOG" USING LOGMSG
                  LOGMSG-LEN
                  TPSTATUS-REC.
   EXIT PROGRAM.

 


Guidelines for Writing Servers

Because the communication details are handled by the Oracle Tuxedo system controlling program, you can concentrate on the application service logic rather than communication implementation. For compatibility with the system-supplied controlling program, however, application services must adhere to certain conventions. These conventions are referred to, collectively, as the service template for coding service routines. They are summarized in the following list.

 


Defining a Service

When writing a service routine, you must call the TPSV CSTART(3cbl) routine before any others. This routine is used to retrieve the service’s parameters and data. Use the following signature to call the TPSVCSTART routine

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

The service information data structure is defined as TPSVCDEF in the COBOL COPY file. It includes the following members:

 05 COMM-HANDLE          PIC S9(9) COMP-5.
05 TPBLOCK-FLAG PIC S9(9) COMP-5.
88 TPBLOCK VALUE 0.
88 TPNOBLOCK VALUE 1.
05 TPTRAN-FLAG PIC S9(9) COMP-5.
88 TPTRAN VALUE 0.
88 TPNOTRAN VALUE 1.
05 TPREPLY-FLAG PIC S9(9) COMP-5.
88 TPREPLY VALUE 0.
88 TPNOREPLY VALUE 1.
05 TPACK-FLAG PIC S9(9) COMP-5 REDEFINES TPREPLY-FLAG.
88 TPNOACK VALUE 0.
88 TPACK VALUE 1.
05 TPTIME-FLAG PIC S9(9) COMP-5.
88 TPTIME VALUE 0.
88 TPNOTIME VALUE 1.
05 TPSIGRSTRT-FLAG PIC S9(9) COMP-5.
88 TPNOSIGRSTRT VALUE 0.
88 TPSIGRSTRT VALUE 1.
05 TPGETANY-FLAG PIC S9(9) COMP-5.
88 TPGETHANDLE VALUE 0.
88 TPGETANY VALUE 1.
05 TPSENDRECV-FLAG PIC S9(9) COMP-5.
88 TPSENDONLY VALUE 0.
88 TPRECVONLY VALUE 1.
05 TPNOCHANGE-FLAG PIC S9(9) COMP-5.
88 TPCHANGE VALUE 0.
88 TPNOCHANGE VALUE 1.
05 TPSERVICETYPE-FLAG PIC S9(9) COMP-5.
88 TPREQRSP VALUE 0.
88 TPCONV VALUE 1.
*
05 APPKEY PIC S9(9) COMP-5.
05 CLIENTID OCCURS 4 TIMES PIC S9(9) COMP-5.
05 SERVICE-NAME PIC X(127).

The following table describes the members of a TPSVCDEF data structure.

Table 5-1 TPSVCDEF Data Structure
Field
Description
COMM-HANDLE
Specifies, to the service routine, the communication handle used by the requesting process to invoke the service.
SETTINGS
(TPBLOCK-FLAG
TPTRAN-FLAG
, etc.)
Miscellaneous settings that control server characteristics. For more information on the settings, refer to the Oracle Tuxedo ATMI COBOL Function Reference.
APPKEY
Reserved for use by the application. If application-specific authentication is part of your design, the application-specific authentication server, which is called at the time a client joins the application, should return a client authentication key, as well as a success or failure indication. The Oracle Tuxedo system holds the APPKEY on behalf of the client and passes the information to subsequent service requests in this field. By the time the APPKEY is passed to the service, the client has already been authenticated. However, the APPKEY field can be used within the service to identify the user invoking the service or some other parameters associated with the user.
CLIENTID
Identifier of the client that originates a request.
SERVICE-NAME
Name of the service routine used by the requesting process to invoke the service.

For a description of the TPTYPE-REC data structure, refer to Defining Typed Records.

You must code the service in such a way that when it accesses the request data to be placed in DATA-REC, it expects the data to be in a record of the type defined for the service in the configuration file. Upon successful return, DATA-REC contains the data received and LEN contains the actual number of bytes moved.

The following sample listing shows a typical service definition.

Listing 5-4 Typical Service Definition
    IDENTIFICATION DIVISION.
    PROGRAM-ID. BUYSR.
    AUTHOR. TUXEDO DEVELOPMENT.
    ENVIRONMENT DIVISION.
    CONFIGURATION SECTION.
    SOURCE-COMPUTER. USL-486.
    OBJECT-COMPUTER. USL-486.
*
    INPUT-OUTPUT SECTION.
    . . .
******************************************************
* Tuxedo definitions
******************************************************
    01 TPSVCRET-REC.
    COPY TPSVCRET.
*
    01 TPTYPE-REC.
    COPY TPTYPE.
*
    01 TPSTATUS-REC.
    COPY TPSTATUS.
*
    01 TPSVCDEF-REC.
    COPY TPSVCDEF.
******************************************************
* Log message definitions
******************************************************
    01 LOGMSG.
            05 LOGMSG-TEXT PIC X(50).
*
    01 LOGMSG-LEN PIC S9(9) COMP-5.
******************************************************
* User defined data records
******************************************************
    01 CUST-REC.
    COPY CUST.
*
    LINKAGE SECTION.
*
    PROCEDURE DIVISION.
*
START-BUYSR.
    MOVE LENGTH OF LOGMSG TO LOGMSG-LEN.
    OPEN files or DATABASE
******************************************************
* Get the data that was sent by the client
******************************************************
    MOVE "Server Started" TO LOGMSG-TEXT.
    PERFORM DO-USERLOG.
    MOVE LENGTH OF CUST-REC TO LEN IN TPTYPE-REC.
    CALL "TPSVCSTART" USING TPSVCDEF-REC
                      TPTYPE-REC
                      CUST-REC
                      TPSTATUS-REC.
    IF TPTRUNCATE
        MOVE "Input data exceeded CUST-REC length" TO LOGMSG-TEXT
        PERFORM DO-USERLOG
        PERFORM A-999-EXIT.
    IF NOT TPOK
        MOVE "TPSVCSTART Failed" TO LOGMSG-TEXT
        PERFORM DO-USERLOG
        PERFORM A-999-EXIT.
    IF REC-TYPE NOT = "VIEW"
        MOVE "REC-TYPE in not VIEW" TO LOGMSG-TEXT
        PERFORM DO-USERLOG
        PERFORM A-999-EXIT.
    IF SUB-TYPE NOT = "cust"
        MOVE "SUB-TYPE in not cust" TO LOGMSG-TEXT
        PERFORM DO-USERLOG
        PERFORM A-999-EXIT.
     . . .
set consistency level of the transaction
     . . .
******************************************************
* Exit
******************************************************
  A-999-EXIT.
     MOVE "Exiting" TO LOGMSG-TEXT.
     PERFORM DO-USERLOG.
     SET TPFAIL TO TRUE.
     COPY TPRETURN REPLACING TPSVCRET-REC BY TPSVCRET-REC
     TPTYPE-REC BY TPTYPE-REC
     DATA-REC BY CUST-REC
     TPSTATUS-REC BY TPSTATUS-REC.
******************************************************
* Write to userlog
******************************************************
  DO-USERLOG.
     CALL "USERLOG" USING LOGMSG
              LOGMSG-LEN
              TPSTATUS-REC.

In the preceding example, the request record on the client side was originally sent with REC-TYPE set to VIEW and the SUB-TYPE set to cust. The BUYSR service is defined in the configuration file as a service that knows about the VIEW typed record. BUYSR retrieves the data record by accessing the CUST-REC record. The consistency level of the transaction is specified after this record is retrieved but before the first database access is made. For more details on transaction consistency levels, refer to “Writing Global Transactions” in Programming Oracle Tuxedo ATMI Applications Using C.

Note: The TPGPRIO and TPSPRIO routines, used for getting and setting priorities, respectively, are described in detail in “Setting and Getting Message Priorities” in Programming Oracle Tuxedo ATMI Applications Using C.

The example code in this section shows how a service called PRINTER tests the priority level of the request just received using the TPGPRIO routine. Then, based on the priority level, the application routes the print job to the appropriate destination printer RNAME.

Next, the contents of INPUT-REC are sent to the printer. The application queries TPSVCDEF-REC to determine whether a reply is expected. If so, it returns the name of the destination printer to the client. For more information on the TPRETURN routine, refer to Terminating a Service Routine.

Listing 5-5 Checking the Priority of a Received Request
    IDENTIFICATION DIVISION.
    PROGRAM-ID. PRINTSR.
    AUTHOR. TUXEDO DEVELOPMENT.
    ENVIRONMENT DIVISION.
    CONFIGURATION SECTION.
    SOURCE-COMPUTER. USL-486.
    OBJECT-COMPUTER. USL-486.
*
    INPUT-OUTPUT SECTION.
    . . .
******************************************************
* Tuxedo definitions
******************************************************
    01 TPSVCRET-REC.
    COPY TPSVCRET.
*
    01 TPTYPE-REC.
    COPY TPTYPE.
*
    01 TPSTATUS-REC.
    COPY TPSTATUS.
*
    01 TPSVCDEF-REC.
    COPY TPSVCDEF.
*
    01 TPPRIDEF-REC.
    COPY TPPRIDEF.
******************************************************
* Log message definitions
******************************************************
    01 LOGMSG.
            05 FILLER PIC S9(9) VALUE
                    "TP-STATUS=".
            05 LOG-TP-STATUS PIC S9(9).
            05 LOGMSG-TEXT PIC X(50).
*
    01 LOGMSG-LEN PIC S9(9) COMP-5.
******************************************************
* User defined data records
******************************************************
    01 INPUT-REC PIC X(1000).
    01 PRNAME PIC X(20).
*
    LINKAGE SECTION.
*
    PROCEDURE DIVISION.
*
 START-PRINTSR.
    MOVE LENGTH OF LOGMSG TO LOGMSG-LEN.
    OPEN files or DATABASE
******************************************************
* Get the data that was sent by the client
******************************************************
    MOVE ZERO to TP-STATUS.
    MOVE "Server Started" TO LOGMSG-TEXT.
    PERFORM DO-USERLOG.
    MOVE LENGTH OF INPUT-REC TO LEN.
    CALL "TPSVCSTART" USING TPSVCDEF-REC
                      TPTYPE-REC
                      INPUT-REC
                      TPSTATUS-REC.
    IF NOT TPOK
             MOVE "TPSVCSTART Failed" TO LOGMSG-TEXT
             PERFORM DO-USERLOG
             SET TPFAIL TO TRUE.
             PERFORM A-999-EXIT.
    . . .
    Check other parameters
    CALL "TPGPRIO" USING TPPRIDEF-REC
                   TPSTATUS-REC.
    IF NOT TPOK
             MOVE "TPGPRIO Failed" TO LOGMSG-TEXT
             PERFORM DO-USERLOG
             SET TPFAIL TO TRUE.
             PERFORM A-999-EXIT.
    IF PRIORITY < 20
             MOVE "BIGJOBS" TO RNAME
    ELSE IF PRIORITY < 60
             MOVE "MEDJOBS" TO RNAME
    ELSE
             MOVE "HIGHSPEED" TO RNAME.
    . . .
    Print INPUT-REC on RNAME printer
    . . .
    IF TPNOREPLY
             MOVE SPACES TO REC-TYPE
             MOVE 0 TO LEN
             SET TPSUCCESS TO TRUE
             PERFORM A-999-EXIT
    IF TPREPLY
             MOVE "STRING" TO REC-TYPE
             MOVE LENGTH OF PRNAME TO LEN
             SET TPSUCCESS TO TRUE
             PERFORM A-999-EXIT.
******************************************************
* Exit
******************************************************
A-999-EXIT.
     MOVE "Exiting" TO LOGMSG-TEXT.
     PERFORM DO-USERLOG.
     SET TPSUCCESS TO TRUE.
     COPY TPRETURN REPLACING TPSVCRET-REC BY TPSVCRET-REC
              TPTYPE-REC buTPTYPE-REC
              DATA-REC BY PRNAME
              TPSTATUS-REC BY TPSTATUS-REC.
******************************************************
* Write to userlog
******************************************************
DO-USERLOG.
     MOVE TP-STATUS TO LOG-TP-STATUS.
     CALL "USERLOG" USING LOGMSG
               LOGMSG-LEN
               TPSTATUS-REC.

 


Terminating a Service Routine

The TPRET URN(3cbl), TPCANCEL(3 cbl), and TPFO RWAR(3cbl) routines specify that a service routine has completed with one of the following actions:

Sending Replies

The TPRETUR N(3cbl) and TPFORWA R(3cbl) calls are COBOL copy files that contain EXIT statements to mark the end of a service routine and send a message to the requester or forward the request to another service, respectively. Use the following signature to call the TPRETURN routine:

 01 TPSVCRET-REC.
COPY TPSVCRET.
01 TPTYPE-REC.
COPY TPTYPE.
01 DATA-REC.
COPY User Data.
01 TPSTATUS-REC.
COPY TPSTATUS.
COPY TPRETURN REPLACING TPSVCRET-REC BY TPSVCRET-REC
TPTYPE-REC BY TPTYPE-REC
DATA-REC BY DATA-REC
TPSTATUS-REC BY TPSTATUS-REC.
Note: You must use COPY here instead of CALL to ensure that the EXIT statement is called properly, and the COBOL service routine returns control to the Oracle Tuxedo system.

The following listing provides the TPSVCRET-REC record signature:

 05 TPRETURN-VAL    PIC S9(9) COMP-5.
88 TPSUCCESS VALUE 0.
88 TPFAIL VALUE 1.
88 TPFAIL VALUE 2.
05 APPL-CODE PIC S9(9) COMP-5.

Table 5-2 describes the members of a TPSVCRET-REC data structure.

Table 5-2 TPSVCRET-REC Data Structure Members
Member
Description
TP-RETURN-VAL
Indicates whether or not the service has completed successfully on an application-level. The value is an integer that is represented by a symbolic name. Valid settings include:
  • TPSUCCESS—the calling routine succeeded. The routine stores the reply message in the caller’s record. If there is a reply message, it is in the caller’s record.
  • TPFAIL (default)—the service terminated unsuccessfully. The routine reports an error message to the client process waiting for the reply. In this case, the client’s TPCALL or TPGETRPLY routine call fails and the system sets the TP-STATUS variable to TPESVCFAIL to indicate an application-defined failure. If a reply message was expected, it is available in the caller’s record.
  • TPEXIT—the service terminated unsuccessfully. The routine reports an error message to the client process waiting for the reply, and exits.
For a description of the effect that the value of this argument has on global transactions, refer to “Writing Global Transactions” in Programming Oracle Tuxedo ATMI Applications Using C.
APPLC-CODE
Returns an application-defined return code to the caller. The client can access the value returned in APPLC-CODE by querying APPL-RETURN-CODE IN TPSTATUS-REC. The routine returns this code regardless of success or failure.

Refer to Defining a Service for a description of the TPTYPE-REC record.

The primary function of a service routine is to process a request and return a reply to a client process. It is not necessary, however, for a single service to do all the work required to perform the requested function. A service can act as a requester and pass a request call to another service the same way a client issues the original request: through calls to TPCALL or TPACALL.

Note: The TPCALL and TPACALL routines are described in detail in “Writing Request/Response Clients and Servers” in Programming Oracle Tuxedo ATMI Applications Using C.

When TPRETURN is called, control always returns to the controlling program. If a service has sent requests with asynchronous replies, it must receive all expected replies or invalidate them with TPCANCEL before returning control to the controlling program. Otherwise, the outstanding replies are automatically dropped when they are received by the Oracle Tuxedo system controlling program, and an error is returned to the caller.

If the client invokes the service with TPCALL, after a successful call to TPRETURN, the reply message is available in the O-DATA-REC record. If TPACALL is used to send the request, and TPRETURN returns successfully, the reply message is available in the DATA-REC record of TPGETRPLY.

If a reply is expected and TPRETURN encounters errors while processing its arguments, it sends a failed message to the calling process. The caller detects the error by checking the value placed in TP-STATUS. In the case of failed messages, the system sets the TP-STATUS to TPESVCERR. This situation takes precedence over the value of APPL-RETURN-CODE IN TPSTATUS-REC. If this type of error occurs, no reply data is returned, and both the contents and length of the caller’s output record remain unchanged.

If TPRETURN returns a message in a record of an unknown type or a record that is not allowed by the caller (that is, if the call is made with TPNOCHANGE), the system returns TPEOTYPE in TP-STATUS. In this case, application success or failure cannot be determined, and the contents and length of the output record remain unchanged.

The value returned in APPL-RETURN-CODE IN TPSTATUS-REC is not relevant if the TPRETURN routine is invoked and a timeout occurs for the call waiting for the reply. This situation takes precedence over all others in determining the value that is returned in TP-STATUS. In this case, TP-STATUS is set to TPETIME and the reply data is not sent, leaving the contents and length of the caller’s reply record unchanged. There are two types of timeouts in the Oracle Tuxedo system: blocking and transaction timeouts (discussed in “Writing Global Transactions” in Programming Oracle Tuxedo ATMI Applications Using C).

The example code in this section shows the TRANSFER service that is part of the XFER server. Basically, the TRANSFER service makes synchronous calls to the WITHDRAWAL and DEPOSIT services. It allocates a separate record for the reply message since it must use the request record for the calls to both the WITHDRAWAL and the DEPOSIT services. If the call to WITHDRAWAL fails, the service writes the message cannot withdraw on the status line of the form and sets TP-RETURN-VAL IN TPSVCRET-REC of the TPRETURN routine to TPFAIL. If the call succeeds, the debit balance is retrieved from the reply record.

Note: In the following example, the application moves the identifier for the “destination account” (which is retrieved from the cr_id variable) to the zeroth occurrence of the ACCOUNT_ID field in the transf fielded record. This move is necessary because this occurrence of the field in an FML record is used for data-dependent routing. Refer to Setting Up an Oracle Tuxedo Application for more information.

A similar scenario is followed for the call to DEPOSIT. On success, the service sets the TP-RETURN-VAL IN TPSVCRET-REC to TPSUCCESS, returning the pertinent account information to the status line.

Listing 5-6 TPRETURN Routine
   IDENTIFICATION DIVISION.
   PROGRAM-ID. TRANSFER.
   AUTHOR. TUXEDO DEVELOPMENT.
   ENVIRONMENT DIVISION.
   CONFIGURATION SECTION.
   SOURCE-COMPUTER. USL-486.
   OBJECT-COMPUTER. USL-486.
*
   INPUT-OUTPUT SECTION.
   . . .
******************************************************
* Tuxedo definitions
******************************************************
   01 TPSVCRET-REC.
   COPY TPSVCRET.
*
   01 TPTYPE-REC.
   COPY TPTYPE.
*
   01 TPSTATUS-REC.
   COPY TPSTATUS.
*
   01 TPSVCDEF-REC.
   COPY TPSVCDEF.
******************************************************
* User defined data records
******************************************************
   01 TRANS-REC.
      COPY TRANS-AMOUNT.
*
   LINKAGE SECTION.
*
   PROCEDURE DIVISION.
*
   START-TRANSFER.
******************************************************
* Get the data that was sent by the client
******************************************************
    MOVE LENGTH OF TRANS-REC TO LEN.
    CALL "TPSVCSTART" USING TPSVCDEF-REC
                      TPTYPE-REC
                      TRANS-REC
                      TPSTATUS-REC.
    IF NOT TPOK
             MOVE "Transaction Encountered An Error" TO STATUS-LINE
             SET TPFAIL TO TRUE.
             COPY TPRETURN REPLACING TPSVCRET-REC BY TPSVCRET-REC
                      TPTYPE-REC BY TPTYPE-REC
                      DATA-REC BY TRANS-REC
                      TPSTATUS-REC BY TPSTATUS-REC.
    ELSE
             . . . Check other parameters
******************************************************
* must have a valid debit and credit account number
******************************************************
    CALL "FIND-ACCOUNT-FUNCTION" USING TRANS-DEBIT-ACCOUNT IN TRANS-REC.

    IF TRANS-DEBIT-ACCOUNT is not valid
             MOVE "Invalid Debit Account Number"
                      TO STATUS-LINE IN TRANS-REC
             SET TPFAIL TO TRUE
             COPY TPRETURN REPLACING
                      DATA-REC BY TRANS-REC.

    CALL "FIND-ACCOUNT-FUNCTION" USING TRANS-CREDIT-ACCOUNT IN TRANS-REC.
  
    IF TRANS-CREDIT-ACCOUNT is not valid
             MOVE "Invalid Credit Account Number"
             TO STATUS-LINE IN TRANS-REC
             SET TPFAIL TO TRUE
             COPY TPRETURN REPLACING
                      DATA-REC BY TRANS-REC.
******************************************************
* Check amount to transfer
******************************************************
    IF TRANS-AMOUNT IN TRANS-REC < 0
             MOVE "Invalid Transfer Amount Requested"
                      TO STATUS-LINE IN TRANS-REC
             SET TPFAIL TO TRUE
             COPY TPRETURN REPLACING
                      DATA-REC BY TRANS-REC.
******************************************************
* Make Withdrawal using another service
******************************************************
    MOVE "WITHDRAWAL" TO SERVICE-NAME.
    . . . set other TPCALL parameters
    CALL "TPCALL" USING . . .
    IF NOT TPOK
             MOVE "Cannot withdraw from debit account"
                   TO STATUS-LINE IN TRANS-REC
             SET TPFAIL TO TRUE
             COPY TPRETURN REPLACING
                   DATA-REC BY TRANS-REC.
******************************************************
* Make Deposit using another service
******************************************************
    MOVE "DEPOSIT" TO SERVICE-NAME.
    . . . set other TPCALL parameters
    CALL "TPCALL" USING . . .
    IF NOT TPOK
            MOVE "Cannot Deposit into credit account"
                   TO STATUS-LINE IN TRANS-REC
            SET TPFAIL TO TRUE
            COPY TPRETURN REPLACING
                   DATA-REC BY TRANS-REC.
    . . .
    MOVE "Transfer completed" TO STATUS-LINE IN TRANS-REC
    . . . MOVE all the data into TRANS-REC needed by the client
    SET TPSUCCESS TO TRUE
    COPY TPRETURN REPLACING
                   DATA-REC BY TRANS-REC.

Invalidating Descriptors

If a service calling TPGETRPLY (described in detail in “Writing Request/Response Clients and Servers” in Programming Oracle Tuxedo ATMI Applications Using C) fails with TPETIME and decides to cancel the request, it can invalidate the descriptor with a call to TPCANC EL(3cbl). If a reply subsequently arrives, it is silently discarded.

TPCANCEL cannot be used for transaction replies (that is, for replies to requests made without the TPNOTRAN flag set). Within a transaction, TPABO RT(3cbl) does the same job of invalidating the transaction call descriptor.

Listing 5-7 shows how to invalidate a reply after timing out.

Listing 5-7 Invalidating a Reply After Timing Out
. . .  Set up parameters to TPACALL
SET TPNOTRAN TO TRUE.
CALL "TPACALL" USING TPSVCDEF-REC
                   TPTYPE-REC
                   DEBIT-REC
                   TPSTATUS-REC.
IF NOT TPOK
       error processing
. . .
CALL "TPGETRPLY" USING TPSVCDEF-REC
                   TPTYPE-REC
                   DEBIT-REC
                   TPSTATUS-REC.
IF NOT TPOK
       error processing
IF TPETIME
       CALL "TPCANCEL" TPSVCDEF-REC
                   TPSTATUS-REC.
    . . .
    SET TPSUCCESS TO TRUE.
    COPY TPRETURN REPLACING TPSVCRET-REC BY TPSVCRET-REC
                   TPTYPE-REC BY TPTYPE-REC
                   DATA-REC BY DEBIT-REC
                   TPSTATUS-REC BY TPSTATUS-REC.

Forwarding Requests

The TPFORWA R(3cbl) routine allows a service to forward a request to another service for further processing.

Use the following signature to call the TPFORWAR routine:

01 TPSVCDEF-REC.
COPY TPSVCDEF.
01 TPTYPE-REC.
COPY TPTYPE.
01 DATA-REC.
COPY User Data.
01 TPSTATUS-REC.
COPY TPSTATUS.
COPY TPFORWAR REPLACING TPSVCDEF-REC BY TPSVCDEF-REC
TPTYPE-REC BY TPTYPE-REC
DATA-REC BY DATA-REC
TPSTATUS-REC BY TPSTATUS-REC.

For descriptions of the TPSVCDEF-REC and TPTYPE-REC records, refer to Defining a Service.

The functionality of TPFORWAR differs from a service call: a service that forwards a request does not expect a reply. The responsibility for providing the reply is passed to the service to which the request has been forwarded. The latter service sends the reply to the process that originated the request. It becomes the responsibility of the last server in the forward chain to send the reply to the originating client by invoking TPRETURN.

Figure 5-1 shows one possible sequence of events when a request is forwarded from one service to another. Here a client initiates a request using the TPCALL routine and the last service in the chain (SVC_C) provides a reply using the TPRETURN routine.

Figure 5-1 Forwarding a Request

Forwarding a Request

Service routines can forward requests at specified priorities in the same manner that client processes send requests, by using the TPSPRIO routine.

When a process calls TPFORWAR, the system that supplied the controlling program regains control, and the server process is free to do more work.

Note: If a server process is acting as a client and a reply is expected, the server is not allowed to request services from itself. If the only available instance of the desired service is offered by the server process making the request, the call fails, indicating that a recursive call cannot be made. However, if a service routine sends a request (to itself) with the TPNOREPLY communication flag set, or if it forwards the request, the call does not fail because the service is not waiting for itself.

Calling TPFORWAR can be used to indicate success up to that point in processing the request. If no application errors have been detected, you can invoke TPFORWAR, otherwise, you can call TPRETURN with TP-RETURN-VAL IN TPSVCRET-REC set to TPFAIL.

The following example illustrates how the service sends its data record to the DEPOSIT service by calling TPFORWAR. If the new account is added successfully, the branch record is updated to reflect the new account, and the data record is forwarded to the DEPOSIT service. On failure, TPRETURN is called with TP-RETURN-VAL IN TPSVCRET-REC set to TPFAIL and the failure is reported on the status line of the form.

Listing 5-8 How to Use TPFORWAR
    . . .
******************************************************
* Get the data that was sent by the client
******************************************************
    MOVE LENGTH OF TRANS-REC TO LEN.
    CALL "TPSVCSTART" USING TPSVCDEF-REC
                      TPTYPE-REC
                      TRANS-REC
                      TPSTATUS-REC.
    IF NOT TPOK
             MOVE "Transaction Encountered An Error" TO STATUS-LINE
             SET TPFAIL TO TRUE.
             COPY TPRETURN REPLACING
DATA-REC BY TRANS-REC.
    ELSE
. . . Check other parameters
******************************************************
* Insert new account record
******************************************************
    CALL "ADD-NEW-ACCOUNT-FUNCTION" USING TRANS-ACCOUNT IN TRANS-REC.
    IF Adding New Account Failed
             MOVE "Account not added" TO STATUS-LINE IN TRANS-REC
             SET TPFAIL TO TRUE
             COPY TPRETURN REPLACING
                       DATA-REC BY TRANS-REC.
******************************************************
* Forward record to the DEPOSIT service to add initial
* balance into account
******************************************************
    MOVE "DEPOSIT" TO SERVICE-NAME.
    . . . set other TPFORWAR parameters
    COPY TPFORWAR REPLACING
                       DATA-REC BY TRANS-REC.

 


Advertising and Unadvertising Services

When a server is booted, it advertises the services it offers based on the values specified for the CLOPT parameter in the configuration file.

Note: The services that a server may advertise are initially defined when the buildserver command is executed. The -s option allows a comma-separated list of services to be specified. It also allows you to specify a routine with a name that differs from that of the advertised service that is to be called to process the service request. Refer to the buildserver(1) in the Oracle Tuxedo Command Reference for more information.

The default specification calls for the server to advertise all services with which it was built. Refer to the UBBCONFIG(5) or servopts(5) reference page in the File Formats, Data Descriptions, MIBs, and System Processes Reference for more information.

Because an advertised service uses a service table entry in the bulletin board, and can therefore be resource-expensive, an application may boot its servers in such a way that only a subset of the services offered are available. To limit the services available in an application, define the CLOPT parameter, within the appropriate entry in the SERVERS section of the configuration file, to include the desired services in a comma-separated list following the -s option. The -s option also allows you to specify a routine with a name other than that of the advertised service to be called to process the request. Refer to the servopts(5) reference page in the File Formats, Data Descriptions, MIBs, and System Processes Reference for more information.

An Oracle Tuxedo application administrator can use the advertise and unadvertise commands of tmadmin(1) to control the services offered by servers. The TPADVERTISE and TPUNADVERTISE routines enable you to dynamically control the advertisement of a service in a request/response or conversational server. The service to be advertised (or unadvertised) must be available within the same server as the service making the request.

Advertising Services

Use the following signature to call the TPADVERT ISE(3cbl) routine:

01 SERVICE-NAME           PIC X(127).
01 PROGRAM-NAME PIC X(32).
01 TPSTATUS-REC.
COPY TPSTATUS.
CALL "TPADVERTISE" USING SERVICE-NAME PROGRAM-NAME TPSTATUS-REC.

Table 5-3 describes the members of a TPADVERTISE data structure.

Table 5-3 TPADVERTISE Data Structure Members
Member
Description
SERVICE-NAME
Name of the service to be advertised. The service name must be a character string of up to 127 characters. Names longer than 127 characters are truncated. The SPACES string is not a valid value. If it is specified, an error (TPEINVAL) results.
PROGRAM-NAME
Oracle Tuxedo system routine that is called to perform a service. Frequently, this name is the same as the name of the service. The SPACES string is not a valid value. If it is specified, an error results.

Unadvertising Services

The TPUNA DVERTISE(3cbl) routine removes the name of a service from the service table of the bulletin board so that the service is no longer advertised.

Use the following signature for the TPUNADVERTISE routine:

01 SERVICE-NAME           PIC X(127).
01 TPSTATUS-REC.
COPY TPSTATUS.
CALL "TPUNADVERTISE" USING SERVICE-NAME TPSTATUS-REC.

The TPUNADVERTISE data structure contains one member, which is described in Table 5-4.

Table 5-4 TPUNADVERTISE Data Structure Member
Member
Description
SERVICE-NAME
Name of the service to be advertised. The service name must be a character string of up to 127 characters. Names longer than 127 characters are truncated. The SPACES string is not a valid value. If it is specified, an error (TPEINVAL) results.

Example: Dynamic Advertising and Unadvertising of a Service

The following example shows how to use the TPADVERTISE routine. In this example, a server called TLR is programmed to offer only the service called TLRINIT when booted. After some initialization, TLRINIT advertises two services called DEPOSIT and WITHDRAW. Both are performed by the TLRFUNCS routine, and both are built into the TLR server.

After advertising DEPOSIT and WITHDRAW, TLRINIT unadvertises itself.

Listing 5-9 Dynamic Advertising and Unadvertising
    . . .
**************************************************
* Advertise DEPOSIT service to be processed by
* routine TLRFUNCS
**************************************************
    MOVE "DEPOSIT" TO SERVICE-NAME.
    MOVE "TLRFUNCS" TO PROGRAM-NAME.
    CALL "TPADVERTISE" USING SERVICE-NAME
                       PROGRAM-REC
                       TPSTATUS-REC.
    IF NOT TPOK
           error processing
**************************************************
* Advertise WITHDRAW service to be processed by
* the same routine TLRFUNCS
**************************************************
    MOVE "WITHDRAW" TO SERVICE-NAME.
    MOVE "TLRFUNCS" TO PROGRAM-NAME.
    CALL "TPADVERTISE" USING SERVICE-NAME
                       PROGRAM-REC
                       TPSTATUS-REC.
    IF NOT TPOK
           error processing
**************************************************
* Unadvertise TLRINIT service (yourself)
**************************************************
    MOVE "TLRINIT" TO SERVICE-NAME.
    CALL "TPUNADVERTISE" USING SERVICE-NAME
                       TPSTATUS-REC.
    IF NOT TPOK
            error processing

 


Building Servers

To build an executable ATMI server, compile your application service subroutines with the Oracle Tuxedo system server adaptor and all other referenced files using the buildserver(1) command with the -C option.

Note: The Oracle Tuxedo server adaptor accepts messages, dispatches work, and manages transactions (if transactions are enabled).

Use the following syntax for the buildserver command:

buildserver -C -o filename -f filenames -l filenames -s -v

Table 5-5 describes the buildserver command-line options:

Table 5-5 buildserver Command-line Options
This Option . . .
Allows You to Specify the . . .
-o filename
Name of the executable output file. The default is SERVER.
-f filenames
List of files that are link edited before the Oracle Tuxedo system libraries. You can specify the -f option more than once, and multiple filenames for each occurrence of -f. If you specify a COBOL program file (file.cbl), it is compiled before it is linked. You can specify other object files (file.o) separately, or in groups in an archive file (file.a).
-l filenames
List of files that are link edited after the Oracle Tuxedo system libraries. You can specify the -l option more than once, and multiple filenames for each occurrence of -l. If you specify a COBOL program file (file.cbl), it is compiled before it is linked. You can specify other object files (file.o) separately, or in groups in an archive file (file.a).
-r filenames
List of resource manager access libraries that are link edited with the executable server. The application administrator is responsible for predefining all valid resource manager information in the $TUXDIR/updataobj/RM file using the buildtms(1) command. You can specify only one resource manager. Refer to Setting Up an Oracle Tuxedo Application for more information.
-s [service:]routine
Name of service or services offered by the server and the name of the routine that performs each service. You can specify the -s option more than once, and multiple services for each occurrence of -s. The server uses the specified service names to advertise its services to clients.
Typically, you should assign the same name to both the service and the routine that performs that service. Alternatively, you can specify any names. To assign names, use the following syntax: service:routine.

Notes: The Oracle Tuxedo libraries are linked in automatically. You do not need to specify the Oracle Tuxedo library names on the command line.
Note: Link editing must be done by running the buildclient command.

The order in which you specify the library files to be link edited is significant: it depends on the order in which routines are called and which libraries contain references to those functions.

By default, the buildserver command invokes the UNIX cobcc command, which uses the MicroFocus Net Express compiler. To use Fujitsu’s NetCOBOL ALTCC must be set, even on a Windows system. You must set ALTCC=cobcc85 for NetCOBOL. You can specify an alternative compile command and set your own flags for the compile and link-edit phases, however, by setting the ALTCC and ALTCFLAGS environment variables, respectively. For more information, refer to “Setting Environment Variables” in Programming Oracle Tuxedo ATMI Applications Using C.

Note: 1. On a Windows system, the ALTCC and ALTCFLAGS environment variables are not applicable and setting them will produce unexpected results. You must compile your application first using a COBOL compiler and then pass the resulting object file to the buildserver command.
Note: 2. ALTCFLAGS only works for the MicroFocus COBOL compiler. For other supported COBOL compilers (i.e., IBMCOBOL or AccuCOBOL), CFLAGS is supported and is sufficient.

The following command processes the acct.o application file and creates a server called ACCT that contains two services: NEW_ACCT, which calls the OPEN_ACCT routine, and CLOSE_ACCT, which calls a routine of the same name:

buildserver -C – o ACCT – f acct.o – s NEW_ACCT:OPEN_ACCT – s CLOSE_ACCT

See Also


  Back to Top       Previous  Next