# hp Reliable Transaction Router
Application Design Guide

Previous | Contents | Index

## Authentication Using Callout Servers

RTR callout servers enable security checks to be carried out on all requests using a facility. Callout servers can run on backend or router nodes. They receive a copy of every transaction delivered to or passing through the node, and they vote on every transaction. To enable a callout server, use the /CALLOUT qualifier when issuing the RTR CREATE FACILITY command. Callout servers are facility based, not key-range or partition based.

An application enables a callout server with the CreateFacility method in the RTRFacilityManager class. For a router callout, the application sets the EnableRouterCallout boolean to true:

     RTRFacilityManager.CreateFacility(...
                                      bEnableRouterCallout = true
                                       ...);

For a backend callout server, the application sets the EnableBackendCallout boolean to true:

     RTRFacilityManager.CreateFacility(...
                                      bEnableBackendCallout = true);

# Chapter 5
Design with the C API

# RTR C Application Programming Interface

RTR provides a C application programming interface (API) that features transaction semantics and intelligent routing in the client/server environment. It provides software fault tolerance using shadow servers, standby servers, and concurrent server processing. It can provide authentication with callout servers. RTR makes single-point failures transparent to the application, guaranteeing that, within the limits of reliability of the basic infrastructure and the physical hardware used, a transaction will arrive at its destination.

The RTR C API contains 16 calls that address four groups of activity:

- Initialization/termination calls
- Messaging calls
- Transactional calls
- Informational calls

The initialization call signals RTR that a client or server application wants to use RTR services and the termination call releases the connection once the requested work is done.

Messaging calls enable client and server applications to send and receive messages and broadcasts.

Transactional calls collect groups of messages as transactions (txn).

Informational calls enable an application to set RTR options or interrogate RTR data structures.

Table 5-1 RTR C API Calls by Category
Initiation/termination Calls | Messaging Calls | Transactional Calls | Informational Calls | Manipulation
--- | --- | --- | --- | ---
rtr_open_channel | rtr_broadcast_event | rtr_start_tx | rtr_request_info | rtr_set_info
rtr_close_channel | rtr_reply_to_client | rtr_accept_tx | rtr_get_tid (tid is the transaction identifier) | rtr_set_user_ handle
| rtr_send_to_server | rtr_reject_tx | rtr_error_text | rtr_set_wakeup
| rtr_receive_message |  |  |
| rtr_ext_broadcast_event |  |  |

To execute these calls using the RTR CLI, precede each with the keyword CALL. For example,

    RTR> CALL RTR_OPEN_CHANNEL

Table 5-2 provides additional information on RTR API calls, which are listed in alphabetical order.

Table 5-2 RTR C API Calls
Routine Name | Description | Client and Server | Client Only | Server Only | Returns completion status as a message
--- | --- | --- | --- | --- | ---
rtr_accept_tx() | Votes on a transaction (server). |  |  | Yes | Yes
| Commits a transaction (client). |  | Yes |  |
rtr_broadcast_event() | Broadcasts an event message. | Yes |  |  |
rtr_close_channel() | Closes a previously opened channel. | Yes |  |  |
rtr_error_text() | Converts RTR message numbers to message text | Yes |  |  |
rtr_ext_broadcast_event() | Broadcasts an event message. | Yes |  |  |
rtr_get_tid() | Gets the current transaction ID. | Yes |  |  |
rtr_open_channel() | Opens a channel for sending and receiving messages. | Yes |  |  | Yes
rtr_receive_message() | Receives the next message (transaction message, event or completion status); returns a message and a message status block. | Yes |  |  |
rtr_reject_tx() | Rejects a transaction. | Yes |  |  |
rtr_reply_to_client() | Sends a response from a server to a client. |  |  | Yes |
rtr_request_info() | Requests information from RTR. | Yes |  |  | Yes
rtr_send_to_server() | Sends a message from a client to the server(s). |  | Yes |  |
rtr_set_info() | Sets an RTR parameter. | Yes |  |  | Yes
rtr_set_user_handle() | Associates a user value with a transaction. | Yes |  |  |
rtr_set_wakeup() | Sets a function to be called on message arrival. | Yes |  |  |
rtr_start_tx() | Explicitly starts a transaction and specifies its characteristics. |  | Yes |  |

## Using the rtr.h Header File

The `rtr.h` file included with the product defines all RTR data, status, and message types, including text that can be returned in error messages from an application. You must use it in application compilation.

To support the multi-operating system environment, error codes are processed by RTR using data values in `rtr.h` , and translated into text messages. Status codes are described in the Reliable Transaction Router C Application Programmer's Reference Manual.

# RTR Command Line Interface

The command line interface (CLI) to the RTR API enables the programmer to write short RTR applications from the RTR command line. This can be useful for testing short program segments and exploring how RTR works. For an example of a sequence of commands that starts RTR and exchanges messages between a client and a server, see RTR Getting Started.

# Designing an RTR Client/Server Application

The design of an RTR client/server application should capitalize on the RTR multi-layer model, separating client activity in the application from server and database activity. The RTR client software layer passes messages transparently to the router layer, and the router layer sends messages and transactions reliably and transparently, based on message content, to appropriate server processes. Server application software typically interacts with database software to update and query the database, and respond back to the client.

All RTR calls complete synchronously. Subsequent completion events are returned as messages to the application (see Table 5-2).

The client/server environment has both plusses and minuses. Performing processing on the client that does not need to be handled by the server is a plus, as it enables the client to perform tasks that the server need have no knowledge of, and need expend no resources to support. With RTR as the medium for moving transactions from client to server, the application need not be concerned in detail about how the transactions are sent, or what to do in the event of node or site failures. RTR handles all required journaling and recovery without direct intervention by the application. The application needs no code to deal with server and link failures. However, the application must deal with transactions that get aborted, such as business-logic cases (for example, insufficient funds in a bank account) where rules dictate the abort. Table 5-3 lists the types of transaction aborts.

Table 5-3 How RTR Reports Aborted Transactions
Transaction Aborted | Action
--- | ---
Business logic cases. For example, insufficient funds in a bank account. | Application reports error to user. Server or client aborts transactions.
RTR generated abort, `RTR_STS_NODSTFND` . RTR has exhausted all redundancy paths. | Application reports system unavailable, perhaps temporarily.
Timeout abort. | Task dependent. Try again or inform user.
Deadlock aborts. | None. RTR reschedules.

In a client/server environment, application design becomes more complex because the designer must consider what tasks the clients are to perform, and what the servers must do. Typically the client application will capture information entered by the user, while the server interacts with the database to update the database with transactions passed to it by the router.

## The RTR Journal

The RTR journal is always in use, recording transaction activity to persistent storage. The journal thus provides the capability of recovery from any single hardware or process failure. When a server application no longer provides service, for example, when it goes off line, goes down, or is taken out of service temporarily, RTR aborts all transactions for that service with `RTR_STS_NODSTFND` . When doing transactional shadowing, the journal at the active site is used to record transactions, for the out-of- service site. Journaling on frontends is required to support nested transactions to record the final state of a transaction.

If transactions do not update the database, specify them as read-only by using the `RTR_F_SEN_READONLY` flag on the `rtr_send_to_server` call. Read-only transactions are not recovered as uncertain transactions. Also, in a shadowed environment, these transactions would not be remembered and would therefore save on journal space.

# Data Content Routing with Partitions or Key Ranges

Client applications use data content routing to route each transactional request to the appropriate server servicing the correct database segment. The key value supplied by the client application in the key fields (as defined in the definition of the partition) is used by RTR to achieve data content or data partition routing.

## Partitions or Key Ranges

RTR enables an application to route transactions by partition or key range , rather than sending all transaction requests to a single server application.

When RTR has chosen a specific server for a request within a given transaction, RTR ensures that all requests within that transaction are routed to the same server application channel.

Key ranges, or data partitions, are a major concept in RTR. An application is said to service a partition. Failovers and other availability attributes are applied to all applications, which service a given partition. All server applications able to service a specific data partition on a given node are called concurrents of one another. Concurrent servers may be either multiple channels within a given process, or separate processes.

Partitions can be given names. This lets the system manager manipulate the attributes for a partition at runtime. For example, the operator can temporarily suspend the presentation of online transactions to the partition. This provides time to initiate a database backup operation.

Partitions, in RTR, are the essence of routing. The server application declares its intention to service a certain partition or key range by associating itself with a name, or explicitly defining the key format and range of values.

A partition has many attributes, some of which are specified by the programmer or operator. Some key attributes include:

- Name
- Facility (domain or name space)
- Key format (location in the message where the key value can be found, size, and type)
- Range of values
- Redundancy attributes (concurrency, either/or, parallel processing)
- Resource manager bindings (XA, DTC, DDTM)
- Failover preferences
- Node priority

To plan for future expansion, consider using compound keys rather than single field keys. For example, using a bank example, with a bank that has multiple branches, an application that routes data to each bank can use a BankID key field or partition. Over time, the application may also need to further subdivide transactions not only by bank but also by customer ID. If the application is initially written with a compound key providing both a BankID and a CustomerID key, it can be simpler to make such a change in future.

### Multithreading

An application can be multithreaded. There are several ways to use multithreading in the application architecture. Check the Reliable Transaction Router Release Notes and SPD for the current extent of support for multithreaded programming for a given platform.

The two common ways of using multithreading are:

- Dedicating a thread for every RTR channel. This way, any channel can decide to wait to receive from RTR without affecting the ability of the other channels to continue processing.
- Having a dedicated channel for receiving messages from RTR. Other channels send messages to RTR, or perform other activity such as reading from a different device.

One word of caution for application developers who intend to deploy on OpenVMS: AST programming and threading do not mix well, and may cause intermittent deadlocks. It is therefore prudent not to use ASTs when using threads on OpenVMS with RTR.

### RTR Call Sequence

For a client, an application typically uses the following calls in this order:

C API Client Call | Instantiation
--- | ---
rtr_open_channel() rtr_receive_message() | one per channel
rtr_start_tx() rtr_send_to_server() [one or more] rtr_accept_tx() rtr_receive_message()[zero or more receive messages for the expected number of replies] | each per transaction

For a server, an application typically uses the following calls in this order:

C API Server Call | Instantiation
--- | ---
rtr_open_channel() rtr_receive_message() | one per channel
rtr_receive_message() [one or more] rtr_reply_to_client() [zero or more] rtr_accept_tx() rtr_receive_message() | each per transaction

The `rtr_receive_message` call returns a message and a message status block ( `MsgStatusBlock` ). For example,

     ... status = rtr_receive_message(&Channel,
                                              RTR_NO_FLAGS,
                                              RTR_ANYCHAN,
                                              MsgBuffer,
                                              DataLen,
                                              RTR_NO_TIMOUTMS,
                                              &MsgStatusBlock);

The message status block contains the message type, the user handle, if any, the message length, the TID, and the event number, if the message type is `rtr_mt_rtr_event` or `rtr_mt_user_event` . For more information on the message status block, refer to the descriptions of `rtr_receive_message` and `rtr_set_user_handle` in the Reliable Transaction Router C Application Programmer's Reference Manual.

### RTR Message Types

RTR calls and responses to them contain RTR message types (mt) such as `rtr_mt_reply` or `rtr_mt_rejected` . The four groups of message types, listed in Table 5-4, are:

- Transactional
- Transactional status
- Event-related
- Informational

Table 5-4 RTR Message Types
Transactional | Status | Event-related | Informational
--- | --- | --- | ---
rtr_mt_msg1 | rtr_mt_accepted | rtr_mt_user_event | rtr_mt_opened
rtr_mt_msg1_uncertain | rtr_mt_rejected | rtr_mt_rtr_event | rtr_mt_closed
rtr_mt_msgn | rtr_mt_prepare |  | rtr_mt_request_info
rtr_mt_reply | rtr_mt_prepared |  | rtr_mt_rettosend

Applications should include code for all RTR expected return message types. Message types are returned to the application in the message status block. For more detail on message types see the Reliable Transaction Router C Application Programmer's Reference Manual. Figure 5-1 shows the RTR C API calls you use to achieve transactional messaging in your application.

Figure 5-1 RTR C API Calls for Transactional Messaging

### Message Format Definitions

To work in a mixed-operating system environment, an application can specify a message format definition on the following calls:

- `rtr_send_to_server`
- `rtr_reply_to_client`
- `rtr_broadcast_event`
- `rtr_ext_broadcast_event`

RTR performs data marshaling, evaluating and converting data appropriately as directed by the message format descriptions provided in the application.

The following example shows an RTR application using a message format declaration; first the RTR call specifying that `TXN_MSG_FMT` contains the actual format declaration, then the definition used by the call.

RTR application call:

    status = rtr_send_to_server(p_channel,
                                RTR_NOFLAGS,
                                &txn_msg,
                                msg_size,
                                TXN_MSG_FMT );

Data definition: `#define TXN_MSG_FMT "%1C%UL%7UL%31C"`

This data structure accommodates an 8-bit signed character field ( C ) for the key, a 32-bit unsigned field (UL) for the server number, a 224-bit (7x32) field (7UL) for the transaction ID, and a 31-bit byte (248-bit) field (31C) for character text. For details of defining message format for a mixed-endian environment, refer to the Reliable Transaction Router C Application Programmer's Reference Manual.

# Using the XA Protocol

You use the XA protocol supported by RTR to communicate with an X/Open Distributed Transaction Processing (DTP) conformant resource manager. This eliminates the need for an application program to process `rtr_mt_uncertain` messages. For examples of system setup, refer to the Reliable Transaction Router System Manager's Manual, Appendix C.

Previous | Next | Contents | Index