Examples
This chapter describes the usage and the entire flow of APIs by using a simple application example.
1. Message Transmission Program
The following figure is the flow of the program that sends and receives messages between a client and the server by using HMS APIs.
-
Client 1 copies the string data entered in the buffer to call a service.
-
A server’s service routine receives the string and converts it from the lowercase to uppercase to send it to HMS.
-
Client 2 receives a message from HMS after a specific time period.
1.1. HMS Configuration
The following is an example of an HMS configuration file.
*DOMAIN
hms SHMKEY = 74347,
TPORTNO = 8808
*NODE
Locke2 TMAXDIR ="/home/tmax5/tmax",
APPDIR ="/home/tmax5/tmax/appbin/",
MAXSESSION = 100
*SVRGROUP
hms01 NODENAME = "Locke2", CPC = 1, SVGTYPE = "HMS", RESTART = Y,
OPENINFO = "ORACLE_XA+Acc=P/scott/tiger+SesTm=60",
HMSINDEX = 2, HMSMSGLIVE = 1, HMSMAXTHR = 2, HMSMAXDBTHR = 5,
HMSNAME = hms_ora
svg1 NODENAME = "Locke2"
*HMS
queue01 SVGNAME = hms01, BOOT = "WARM", TYPE = "QUEUE"
topic01 SVGNAME = hms01, BOOT = "WARM", TYPE = "TOPIC"
*SERVER
svr SVGNAME = svg1
*SERVICE
SVC SVRNAME = svr
1.2. Client Program
The following is an example of a client program.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <usrinc/atmi.h>
#include <usrinc/hmsapi.h>
int main(int argc, char **argv)
{
char *sndbuf, *rcvbuf;
long rcvlen, sndlen;
HMS_SHND *sess;
HMS_CHND *cons;
hms_msg_t *msg;
if (argc != 2) {
printf("Usage : %s <message>\n\n", argv[0]);
exit(1);
}
if (tmaxreadenv("tmax.env", "TMAX") == -1) {
printf("error: tmaxreadenv() failed - %d\n", tperrno);
exit(1);
}
if (tpstart((TPSTART_T *) NULL) == -1) {
printf("error: tpstart() fail - %d\n", tperrno);
exit(1);
}
if ((sndbuf = (char *)tpalloc("STRING", NULL, 0)) == NULL) {
printf("error: sendbuf alloc failed !\n");
tpend();
exit(1);
}
if ((rcvbuf = (char *)tpalloc("STRING", NULL, 0)) == NULL) {
printf("error: recvbuf alloc failed !\n");
tpfree((char *)sndbuf);
tpend();
exit(1);
}
strcpy(sndbuf, argv[1]);
if(tpcall("SVC", sndbuf, 0, &rcvbuf, &rcvlen, 0)==-1){
printf("error: Can't send request to service SVC\n");
tpfree((char *)sndbuf);
tpfree((char *)rcvbuf);
tpend();
exit(1);
}
sleep(5);
/* RECV MESSAGE FROM HMS */
if ((sess = hms_create_session("hms01", 0, HMS_AUTO_ACK, 0)) == NULL) {
printf("error: hms_create_session() failed tperrno = %d\n", tperrno);
tpend();
exit(1);
}
if ((cons = hms_create_receiver(sess, "queue01", "cons01", NULL, NULL, 0))
== NULL) {
printf("error: hms_create_receiver() failed tperrno = %d\n", tperrno);
tpend();
exit(1);
}
/* ALLOCATION */
if ((msg = hms_alloc(sess, 1024)) == NULL) {
printf("error: hms_alloc() failed tperrno = %d\n", tperrno);
tpend();
exit(1);
}
/* RECV MESSAGE */
if (hms_recvex(cons, &msg, 5, 0) == -1) {
printf("error: hms_recvex() failed tperrno = %d\n", tperrno);
hms_free(msg);
tpend();
exit(1);
}
/* GET BODY */
rcvlen = 1024;
if (hms_get_body(msg, rcvbuf, &rcvlen) == -1) {
printf("error: hms_get_body() failed tperrno = %d\n", tperrno);
hms_free(msg);
tpend();
exit(1);
}
printf("HMS MESSAGE : %s\n", rcvbuf);
/* CLOSE RECEIVER */
if (hms_close_receiver(cons, 0) == -1) {
printf("error: hms_close_receiver() failed tperrno = %d\n", tperrno);
hms_free(msg);
tpend();
exit(1);
}
/* CLOSE SESSION */
if (hms_close_session(sess, 0) == -1) {
printf("error: hms_close_session() failed tperrno = %d\n", tperrno);
hms_free(msg);
tpend();
exit(1);
}
hms_free(msg);
tpend();
return 0;
}
1.3. Server Program
The following is an example of a server program.
<svr.c>
#include <stdio.h>
#include <stdlib.h>
#include <usrinc/atmi.h>
#include <usrinc/hmsapi.h>
HMS_SHND *sess = NULL;
HMS_CHND *prod = NULL;
int tpsvrinit(int argc, char **argv)
{
while(1) {
sess = hms_create_session("hms01", 0, HMS_AUTO_ACK, 0);
if (sess != NULL) {
break;
}
if (tperrno != TPENOREADY) {
printf("hms_create_session(hms01) : FAIL tperrno = %d\n", tperrno);
return -1;
}
}
prod = hms_create_sender(sess, "queue01", "prod_svc", 0);
if (prod == NULL) {
printf("hms_create_sender() : FAIL tperrno = %d\n", tperrno);
return -1;
}
return 1;
}
int tpsvrdone()
{
hms_close_sender(prod, 0);
hms_close_session(sess, 0);
return 1;
}
SVC(TPSVCINFO *msg)
{
int n, i;
hms_msg_t *hmsmsg = NULL;
char *data = msg->data;
int len = msg->len, asize;
printf("SVC STARTED!\n");
/* TOUPPER */
for (i = 0; i < len; i++)
data[i] = toupper(data[i]);
/* ALLOCATION */
asize = len +1024;
hmsmsg = hms_alloc(sess, asize);
if (hmsmsg == NULL) {
printf("hms_alloc : fail tperrno = %d\n", tperrno);
tpreturn(TPFAIL, 0, NULL, 0, 0);
}
/* SET BODY */
n = hms_set_body(hmsmsg, data, len);
if (n < 0) {
hms_free(hmsmsg);
printf("hms_set_body : fail tperrno = %d\n", tperrno);
tpreturn(TPFAIL, 0, NULL, 0, 0);
}
/* SEND : hms01, persistent */
n = hms_sendex(prod, hmsmsg, HMS_DLV_PERSISTENT, 0, 0, 0);
if (n < 0) {
hms_free(hmsmsg);
printf("hms_sendex(prod) : fail tperrno = %d\n", tperrno);
tpreturn(TPFAIL, 0, NULL, 0, 0);
}
/* FREE */
hms_free(hmsmsg);
printf("SVC SUCCESS!\n");
tpreturn(TPSUCCESS, 0, NULL, 0, 0);
}
1.4. Program Compilation
Client and server programs are compiled in the same manner as Tmax applications.
|
For more information about how to compile a program, refer to Tmax Application Development Guide. |
2. Message Storage Program
The following is the flow of the program that stores messages exchanged between the client and server into the database by using HMS APIs.
-
The client receives user input and transmits it to HMS as a queue-type message.
-
The server creates a consumer within an async session, and the ASYNC service receives the messages.
-
The ASYNC service inserts the received messages to the database.
2.1. HMS Configuration
The following is an example of HMS configuration.
*DOMAIN
hms SHMKEY = 74347,
TPORTNO = 8808
*NODE
Locke2 TMAXDIR ="/home/tmax5/tmax",
APPDIR ="/home/tmax5/tmax/appbin/",
MAXSESSION = 100
*SVRGROUP
hms01 NODENAME = "Locke2", CPC = 1, SVGTYPE = "HMS", RESTART = Y,
OPENINFO = "ORACLE_XA+Acc=P/scott/tiger+SesTm=60",
HMSINDEX = 2, HMSMSGLIVE = 1, HMSMAXTHR = 2, HMSMAXDBTHR = 5,
HMSNAME = hms_ora
svg1 NODENAME = "Locke2", RESTART = N,
OPENINFO = "ORACLE_XA+Acc=P/scott/tiger+SesTm=60",
DBNAME = "ORACLE", TMSNAME = tms_ora, MINTMS = 1
*HMS
queue01 SVGNAME = hms01, BOOT = "WARM", TYPE = "QUEUE"
topic01 SVGNAME = hms01, BOOT = "WARM", TYPE = "TOPIC"
*SERVER
async SVGNAME = svg1, CLOPT = "-- -i"
*SERVICE
ASYNCSVC SVRNAME = async
2.2. Client Program
The following is an example of a client program.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <usrinc/atmi.h>
#include <usrinc/hmsapi.h>
int main(int argc, char **argv)
{
long len;
HMS_SHND *sess;
HMS_PHND *prod;
hms_msg_t *msg;
char *data;
int no;
if (argc != 3) {
printf("Usage : %s <no> <message>\n\n", argv[0]);
exit(1);
}
if (tmaxreadenv("tmax.env", "TMAX") == -1) {
printf("error: tmaxreadenv() failed - %d\n", tperrno);
exit(1);
}
if (tpstart((TPSTART_T *) NULL) == -1) {
printf("error: tpstart() fail - %d\n", tperrno);
exit(1);
}
len = strlen(argv[2]);
data = argv[2];
no = atoi(argv[1]);
/* SEND MESSAGE TO HMS */
if ((sess = hms_create_session("hms01", 0, HMS_AUTO_ACK, 0)) == NULL) {
printf("error: hms_create_session() failed tperrno = %d\n", tperrno);
tpend();
exit(1);
}
if ((prod = hms_create_sender(sess, "queue01", "prod01", 0)) == NULL) {
printf("error: hms_create_sender() failed tperrno = %d\n", tperrno);
tpend();
exit(1);
}
/* ALLOCATION */
if ((msg = hms_alloc(sess, len + 1024)) == NULL) {
printf("error: hms_alloc() failed tperrno = %d\n", tperrno);
tpend();
exit(1);
}
/* SET BODY */
if (hms_set_body(msg, data, len) == -1) {
printf("error: hms_set_body() failed tperrno = %d\n", tperrno);
hms_free(msg);
tpend();
exit(1);
}
/* SET PROPERTY */
if (hms_set_property(msg, "NO", HMS_INT, (char *)&no, sizeof(int)) == -1) {
printf("error: hms_set_property() failed tperrno = %d\n", tperrno);
hms_free(msg);
tpend();
exit(1);
}
/* SEND MESSAGE */
if (hms_sendex(prod, msg, HMS_DLV_PERSISTENT, 0, 0, 0) == -1) {
printf("error: hms_sendex() failed tperrno = %d\n", tperrno);
hms_free(msg);
tpend();
exit(1);
}
if (hms_close_sender(prod, 0) == -1) {
printf("error: hms_close_sender() failed tperrno = %d\n", tperrno);
hms_free(msg);
tpend();
exit(1);
}
if (hms_close_session(sess, 0) == -1) {
printf("error: hms_close_session() failed tperrno = %d\n", tperrno);
hms_free(msg);
tpend();
exit(1);
}
hms_free(msg);
tpend();
return 0;
}
2.3. Server Program
The following is an example of a server program.
<async.pc>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <usrinc/atmi.h>
#include <usrinc/hmsapi.h>
HMS_SHND *sess;
HMS_CHND *cons;
int svrinit_start = 0;
void abend_callback(HMS_SHND *session)
{
printf("START ABEND_CALLBACK FUNCTION\n");
hms_close_session(session, 0);
printf("hms_close_session success\n");
while (1) {
sess = (HMS_SHND *) hms_create_async_session("hms01", abend_callback, 0);
if (sess == NULL) {
if (tperrno == TPENOREADY) {
usleep(500000);
continue;
}
printf("hms_create_session() : FAIL [%d]\n\n", tperrno);
return;
}
break;
}
cons = (HMS_CHND *) hms_create_receiver(sess, "queue01", "consasync", NULL,
"ASYNCSVC", 0);
if (cons == NULL) {
printf("hms_create_receiver() : FAIL tperrno = %d\n\n", tperrno);
return;
}
printf("END ABEND_CALLBACK FUNCTION\n");
}
int tpsvrinit(int argc, char **argv)
{
int c;
while ((c = getopt(argc, argv, "i")) != EOF) {
switch (c) {
case 'i':
svrinit_start = 1;
break;
}
}
if (svrinit_start == 1) {
printf("ASYNC SERVICE svrinit()\n");
while(1) {
sess = (HMS_SHND *) hms_create_async_session("hms01", abend_callback,
0);
if (sess == NULL) {
if (tperrno == TPENOREADY) {
usleep(500000);
continue;
}
printf("ASYNC SERVICE hms_create_async_session() failed,
tperrno[%d]\n", tperrno);
return;
}
break;
}
cons = (HMS_CHND *) hms_create_consumer(sess, "queue01", HMS_QUEUE,
"consasync", "", "ASYNCSVC", 0);
if (cons == NULL)
printf("ASYNC SERVICE hms_create_consumer() failed, tperrno[%d]\n",
tperrno);
return -1;
}
printf("ASYNC SERVICE svrinit() success\n");
}
return 1;
}
int tpsvrdone()
{
if (svrinit_start == 1) {
printf("ASYNC SERVICE svrdone()\n");
hms_close_consumer(cons, 0);
hms_close_session(sess, 0);
}
return 1;
}
/* DB INSERT */
EXEC SQL include sqlca.h;
EXEC SQL begin declare section;
int no;
char message[128];
EXEC SQL end declare section;
int DBInsert( int n, char *data )
{
printf("UPDATE START!!!\n");
memset( message, 0x00, sizeof(message) );
no = n;
strcpy(message, data);
EXEC SQL insert into hmstest(no, message) values(:no, :message);
if ( sqlca.sqlcode != 0 ){
printf( "insert failed sqlcode = %d\n",sqlca.sqlcode );
return -1;
}
return 1;
}
ASYNCSVC(TPSVCINFO *svc)
{
hms_msg_t *msg;
char *data;
long llen = 4096;
int prop = 0;
int type;
printf("ASYNC SERVICE CALLED\n");
msg = (hms_msg_t *)svc->data;
if ((data = (char *)tpalloc("CARRAY", NULL, 4096)) == NULL) {
printf("ASYNC SERVICE tpalloc return failed. tperrno[%d]\n",
tperrno);
tpreturn(TPFAIL, TPFAIL_ACK, svc->data, svc->len, 0);
}
if (hms_get_body(msg, data, &llen) < 0) {
printf("ASYNC SERVICE hms_get_body() return failed. tperrno[%d]\n",
tperrno);
tpreturn(TPFAIL, TPFAIL_ACK, svc->data, svc->len, 0);
}
data[llen] = '\0';
llen = sizeof(int);
if (hms_get_property(msg, "NO", &type, (char *)&prop, &llen) < 0) {
printf("ASYNC SERVICE hms_get_property() return failed. tperrno[%d]\n",
tperrno);
}
printf("ASYNC SERVICE RECV MESSAGE, BODY[%s], PROPERTY[NO:%d]\n", data, prop);
if (DBInsert(prop, data) == -1)
tpreturn(TPFAIL, TPFAIL_ACK, svc->data, svc->len, 0);
tpreturn(TPSUCCESS, 0, svc->data, svc->len, 0);
}
2.4. Database Script
Table Creation Script
The following is an Oracle table creation script.
sqlplus scott/tiger << EOF
create table hmstest (
no number(7),
message char(128)
);
EOF
Table and Data Output Script
The following is an example of a script to display Oracle tables and their data.
sqlplus scott/tiger << EOF desc hmstest; select * from hmstest; select count(*) from hmstest; EOF
2.5. Program Compilation
Server and client programs are compiled in the same manner as Tmax applications.
|
For more information about program compilation, refer to Tmax Application Development Guide. |