5.4 Defining a Service
You must define every service routine as a function that
receives one argument consisting of a pointer to a
TPSVCINFO
structure. The TPSVCINFO
structure is defined in the atmi.h
header file and
includes the following information:
char name[32];
long flags;
char *data;
long len;
int cd;
int appkey;
CLIENTID cltid;
The following table summarizes the TPSVCINFO
data
structure.
Table 5-1 TPSVCINFO Data Structure
Field | Description |
---|---|
name
|
Specifies, to the service routine, the name used by the requesting process to invoke the service. |
flags
|
Notifies the service if it is in transaction mode or if the caller is expecting a reply. The various ways in which a service can be placed in transaction mode are discussed in “Writing Global Transactions” on page 9-1.
The The flags member is set to |
data
|
Pointer to a buffer that was previously allocated by tpalloc() within the main() . This buffer is used to receive request messages. However, it is recommended that you also use this buffer to send back reply messages or forward request messages.
|
len
|
Contains the length of the request data that is in the buffer referenced by the data field.
|
cd
|
For conversational communication, specifies the connection descriptor. |
appkey
|
Reserved for use by the application. If application-specific authentication is part of your design, the application-specific authentication server, which is called when a client joins the application, should return a client authentication key as well as an indication of success or failure. 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 a service, the client has already been authenticated. However, the appkey field can be used within a service to identify the user invoking the service or some other parameters associated with the user.
If this field is not used, the system assigns it a default value of |
cltid
|
Structure of type CLIENTID used by the system to carry the identification of the client. You should not modify this structure.
|
When the
data
field in the
TPSVCINFO
structure is being accessed by a process,
the following buffer types must agree:
- Type of the request buffer passed by the calling process
- Type of the corresponding buffer code defined within the called service
- Type of the associated buffer type defined for the called service in the configuration file
The following listing illustrates a typical service definition.
This code is borrowed from the ABAL
(account balance)
service routine that is part of the banking application provided
with the Oracle Tuxedo software. ABAL
is part of the
BAL
server.
Listing Typical Service Definition
#include <stdio.h> /* UNIX */
#include <atmi.h> /* ORACLE Tuxedo System */
#include <sqlcode.h> /* ORACLE Tuxedo System */
#include "bank.flds.h" /* bankdb fields */
#include "aud.h" /* BANKING view defines */
EXEC SQL begin declare section;
static long branch_id; /* branch id */
static float bal; /* balance */
EXEC SQL end declare section;
/*
* Service to find sum of the account balances at a SITE
*/
void
#ifdef __STDC__
ABAL(TPSVCINFO *transb)
#else
ABAL(transb)
TPSVCINFO *transb;
#endif
{
struct aud *transv; /* view of decoded message */
/* Set pointer to TPSVCINFO data buffer */
transv = (struct aud *)transb->data;
set the consistency level of the transaction
/* Get branch id from message, do query */
EXEC SQL declare acur cursor for
select SUM(BALANCE) from ACCOUNT;
EXEC SQL open acur; /* open */
EXEC SQL fetch acur into :bal; /* fetch */
if (SQLCODE != SQL_OK) { /* nothing found */
(void)strcpy (transv->ermsg,"abal failed in sql aggregation");
EXEC SQL close acur;
tpreturn(TPFAIL, 0, transb->data, sizeof(struct aud), 0);
}
EXEC SQL close acur;
transv->balance = bal;
tpreturn (TPSUCCESS, 0, transb->data, sizeof(struct aud), 0);
}
In the preceding example, the application allocates a request
buffer on the client side by a call to tpalloc() with the
type
parameter set to VIEW
and the
subtype
set to aud
. The
ABAL
service is defined as supporting the
VIEW
typed buffer. The BUFTYPE
parameter
is not specified for ABAL
and defaults to
ALL
. The ABAL
service allocates a buffer
of the type VIEW
and assigns the data
member of the TPSVCINFO
structure that was passed to
the ABAL
subroutine to the buffer pointer. The
ABAL
server retrieves the appropriate data buffer by
accessing the corresponding
data
member, as
illustrated in the preceding example.
Note:
After the buffer is retrieved, but before the first attempt is made to access the database, the service must specify the consistency level of the transaction. Refer to Writing Global Transactions for more details on transaction consistency levels.