Chapter 5. Examples

Table of Contents

5.1. Message Transmission Program
5.1.1. Configuring an HMS Environment
5.1.2. Client Program
5.1.3. Server Program
5.1.4. Compiling the Program
5.2. Message Saving Program
5.2.1. Configuring an HMS Environment
5.2.2. Client Program
5.2.3. Server Program
5.2.4. Database Script
5.2.5. Compiling the Program

This chapter describes the usage and the entire flow of APIs by using a simple application example.

5.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.

[Figure 5.1] Flow of a Message Transmission Program

Flow of a Message Transmission Program


  1. Client 1 copies the string data entered in the buffer to call a service.

  2. A server's service routine receives the string and converts it from the lowercase to uppercase to send it to HMS.

  3. Client 2 receives a message from HMS after a specific time period.

5.1.1. Configuring an HMS Environment

The following is an example of the HMS environment 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

5.1.2. Client Program

The following is an example of the 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;
}

5.1.3. Server Program

The following is an example of the 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);
}

5.1.4. Compiling the Program

The method for compiling client and server programs is the same as that for compiling Tmax applications.

Note

For more information about how to compile a program, refer to the "Tmax Application Development Guide".

5.2. Message Saving Program

The following is the flow of the program that saves the messages exchanged between a client and the server in a database by using HMS APIs.

[Figure 5.2] Flow of a Message Saving Program

Flow of a Message Saving Program

  1. Client 1 receives a user's input and then transmits the message of the queue type to HMS.

  2. The server creates a consumer within an async session and the ASYNC service receives the messages.

  3. The ASYNC service inserts the received messages to the database.

5.2.1. Configuring an HMS Environment

The following is an example of the HMS environment 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", 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

5.2.2. Client Program

The following is an example of the 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;
}

5.2.3. Server Program

The following is an example of the 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);
}

5.2.4. Database Script

Table Creation Script

The following is an example of a script to create an Oracle table.

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 output Oracle tables and their data.

sqlplus scott/tiger << EOF
desc hmstest;
select * from hmstest;
select count(*) from hmstest;
EOF

5.2.5. Compiling the Program

The method for compiling client and server programs is the same as that for compiling Tmax applications.

Note

For more information, refer to the "Tmax Application Development Guide".