Sample COBOL Program for VIEW Buffer

Introduction

This article provides a sample COBOL Client program and C server program to use the VIEW buffer type which exchanges VIEW message with C program in Tuxedo.  This post may be useful to you as it contains additional sample code.

Tuxedo Buffer type

Tuxedo (Transactions for Unix, Extended for Distributed Operations) is a middleware platform used to manage distributed transaction processing in distributed computing environments. Tuxedo is a transaction processing system, or transaction-oriented middleware, also known as an Enterprise Application Server for a variety of systems and programming languages: C/C++, COBOL and PYTHON.  Since Tuxedo version 12c, JAVA is also a supported programming language (with some limitations).

In Tuxedo, FML (Field Manipulation Language) is the standard way to define application message format and guarantee the transparency between different hardware and platforms.  FML message is a self describing, dynamical message, which each Tuxedo runtime can translate by its standard library into the right format for the application.  FML is first choice when we develop a Tuxedo based distributed application.

The programming languages C/C++ and COBOL widely uses static structures to define a complex structure (struct for C, COPY BOOK for COBOL).  For this reason, Tuxedo provides another way to define application data structure: VIEW/VIEW32. VIEW and VIEW32 are same concept, VIEW is defined for 16- bit machines and VIEW32 is for 32bit machine.

A VIEW description is a text file to describe a complex data structure with elementary field definition, field element including all basic data types of programming language like CHAR, INT, STRING, DOUBLE, etc.

There are two kinds of VIEW definitions

–           One is linking with FML description, it means each field of VIEW is mapped to a FML filed name

–          Other one is no relation with FML description, which means each field of VIEW is not mapping to a FML filed name.

For the detail about FML and VIEW concept, description, API, programming practices, please reference:

http://docs.oracle.com/cd/E35855_01/tuxedo/docs12c/fml/fml02.html

Recently, I have completed a Proof Of Concept with Web service integration with COBOL program. In this POC, we exchange VIEW structure between C and COBOL and manipulate the FML buffer and VIEW structure between C and COBOL.

I think it is worthy to share this sample code for other similar user case. This blog post will show only the COBOL program and the C program which exchanges the data with VIEW structure.

Sample COBOL program manipulate VIEW w/o FML

View Description file for input data

VIEW CardInfoGrp (file name: CardInfoGrp.v)
$ /* View structure  */
#type    cname          fbname        count      flag          size          null
long     MessageID       –                1         –           –               1
string   MsgPostTime     –                1         –           200            “”
string   CardNbr         –                1         –           200            “”
END

View Description file for input data

VIEW Response (file name: Response.v)
$ /* View structure  */
#type    cname          fbname        count      flag          size          null
string    RespCd         –                1         –           200            “”
string    ApplId         –                1         –           200            “”
string    MktCd          –                1         –           200            “”
END

Sample setenv

export TUXDIR=/u01/app/oracle/product/tuxedo12.1.1.0
export COBDIR=/u01/app/cobol-it-64-bdb
export COBCPY=${TUXDIR}/cobinclude
export LD_LIBRARY_PATH=$TUXDIR/lib:$COBDIR/lib:$LD_LIBRARY_PATH
export SHLIB_PATH=$TUXDIR/lib:$SHLIB_PATH
export LIBPATH=$TUXDIR/lib:$LIBPATH
#   You must set the C/C++ compiler path in PATH.
export PATH=$TUXDIR/bin:$COBDIR/bin:$APPDIR :$PATH
export LANG=C
export APPDIR=/home/oracle/AMEX_WS/cobol_view_sample
export TUXCONFIG=$APPDIR/tuxconfig
export VIEWDIR32=$APPDIR
export VIEWFILES32=CardInfoGrp_view.V,Response_view.V

Sample UBBCONFIG

File name: UBBSIMPLE
*RESOURCES
IPCKEY           123456
DOMAINID         simpapp
MASTER           simple
MAXACCESSERS     10
MAXSERVERS       5
MAXSERVICES      10
MODEL            SHM
LDBAL            N
*MACHINES
DEFAULT:
    APPDIR=”/home/oracle/AMEX_WS/cobol_view_sample”
    TUXCONFIG=”/home/oracle/AMEX_WS/cobol_view_sample/tuxconfig”
    TUXDIR=”/u01/app/oracle/product/tuxedo12.1.1.0″
“oow.localdomain”                 LMID=simple
*GROUPS
GROUP1
    LMID=simple GRPNO=1        OPENINFO=NONE
*SERVERS
DEFAULT:
    CLOPT=”-A”
TESTVIEW       SRVGRP=GROUP1 SRVID=1
*SERVICES
TESTVIEW

Sample C Server program (File Name: TESTVIEW.c)

#include <stdio.h>
#include <ctype.h>
#include <userlog.h>
#include <fml32.h>
#include <fml1632.h>            /* TUXEDO */
#include <atmi.h>
#include <Uunix.h>                /* TUXEDO */
#include "CardInfoGrp_view.h" /* simple view defines */
#include "Response_view.h"      /* simple view defines */

#ifdef __cplusplus
extern "C"
#endif
void
#if defined(__STDC__) || defined(__cplusplus)
TESTVIEW(TPSVCINFO *msg)
#else
TESTVIEW(msg)
TPSVCINFO *msg;
#endif
{
int i,len;
struct CardInfoGrp *CardInfoGrpv;    /* pointer to CardInfoGrp buf struct */
// struct CardInfoGrp *CardInfoGrpv2;
struct Response *Responsev;             /* pointer to Response buf struct */
/* Create buffer and set data pointer */
if ((CardInfoGrpv = (struct CardInfoGrp *)tpalloc(VIEWTYPE, "CardInfoGrp", sizeof(struct CardInfoGrp))) == (struct CardInfoGrp *)NULL) {
(void)userlog("Unable to allocate space for VIEW, %s", tpstrerror(tperrno));
tpreturn(TPFAIL, tperrno, NULL, 0L, 0);
}
if ((Responsev = (struct Response *)tpalloc(VIEWTYPE, "Response", sizeof(struct Response))) == (struct Response *)NULL) {
(void)userlog("Unable to allocate space for VIEW, %s", tpstrerror(tperrno));
tpreturn(TPFAIL, tperrno, NULL, 0L, 0);
}

memcpy (CardInfoGrpv,msg->data,msg->len);
userlog("Input Message for CardInfoGrpv %d", CardInfoGrpv->MessageID);
userlog("Input Message for MsgPostTime  [%s]", CardInfoGrpv->MsgPostTime);
userlog("Input Message for CardNbr [%s]", CardInfoGrpv->CardNbr);

memset(Responsev->RespCd,' ',sizeof(Responsev->RespCd));
(void)strcpy(Responsev->RespCd,"Response Code");
memset(Responsev->ApplId,' ',sizeof(Responsev->ApplId));
(void)strcpy(Responsev->ApplId,"APP ID");
memset(Responsev->MktCd,' ',sizeof(Responsev->MktCd));
(void)strcpy(Responsev->MktCd,"Market code");
tpreturn(TPSUCCESS, 0, (char *)Responsev, 0L, 0);
}

Sample COBOL Client Program (File Name: COBOLCLI.cbl)

IDENTIFICATION DIVISION.
PROGRAM-ID. COBOLCLI.
AUTHOR. TUXEDO DEVELOPMENT.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SPECIAL-NAMES.
SYSERR IS STANDARD-ERROR.
DATA DIVISION.
WORKING-STORAGE SECTION.
*****************************************************
* Tuxedo definitions
*****************************************************
01  TPINTYPE-REC.
COPY TPTYPE
01  TPOUTTYPE-REC.
COPY TPTYPE.
01  TPSTATUS-REC.
COPY TPSTATUS.
01  TPSVCDEF-REC.
COPY TPSVCDEF.
*
01  TPINFDEF-REC VALUE LOW-VALUES.
COPY TPINFDEF.
01  STAT-STRING                 PIC X(100).
* APPLICATION VIEW RECORD
01 CARDINFOGRP-REC.
COPY CARDINFOGRP.
01 RESPONSE-REC.
COPY RESPONSE.
01  USER-DATA-REC  PIC X(75).
******************************************************
PROCEDURE DIVISION.
START-CSIMPCL.
DISPLAY "COBOL Client Started".
*********** ASSIGN INPUT TEST DATA *******************
MOVE 24042013 TO MESSAGEID IN CARDINFOGRP-REC.
MOVE "06:12:16 PTC" TO MSGPOSTTIME IN CARDINFOGRP-REC.
MOVE LOW-VALUE TO MSGPOSTTIME(13:187).
MOVE "379739073661008" TO CARDNBR IN CARDINFOGRP-REC.
MOVE LOW-VALUE TO CARDNBR (16:184).
********** MAIN LOGIC ********************************
PERFORM DO-TPINIT.
PERFORM DO-TPCALL.
PERFORM DO-TPTERM.
PERFORM EXIT-PROGRAM.
*****************************************************
* Now register the client with the system.
*****************************************************
DO-TPINIT.
MOVE SPACES TO USRNAME.
MOVE SPACES TO CLTNAME.
MOVE SPACES TO PASSWD.
MOVE SPACES TO GRPNAME.
MOVE ZERO TO DATALEN.
SET TPU-DIP TO TRUE.
*
CALL "TPINITIALIZE" USING TPINFDEF-REC
USER-DATA-REC
TPSTATUS-REC.
IF NOT TPOK
DISPLAY "TPINITIALIZE Failed"
PERFORM EXIT-PROGRAM
END-IF.
*****************************************************
*  Issue a TPCALL
*****************************************************
DO-TPCALL.
MOVE LENGTH OF CARDINFOGRP-REC TO LEN IN TPINTYPE-REC.
MOVE "VIEW32" TO REC-TYPE IN TPINTYPE-REC.
MOVE "CardInfoGrp" TO SUB-TYPE IN TPINTYPE-REC.
MOVE LENGTH OF RESPONSE-REC TO LEN IN TPOUTTYPE-REC.
MOVE "VIEW32" TO REC-TYPE IN TPOUTTYPE-REC.
MOVE "Response" TO SUB-TYPE IN TPOUTTYPE-REC.
MOVE "TESTVIEW" TO SERVICE-NAME.
SET TPBLOCK TO TRUE.
SET TPNOTRAN TO TRUE.
SET TPNOTIME TO TRUE.
SET TPSIGRSTRT TO TRUE.
SET TPCHANGE TO TRUE.
CALL "TPCALL" USING TPSVCDEF-REC
TPINTYPE-REC
CARDINFOGRP-REC
TPOUTTYPE-REC
RESPONSE-REC
TPSTATUS-REC.
IF NOT TPOK
DISPLAY "TPCALL Failed"
DISPLAY "TP STATUS : " TP-STATUS
DISPLAY "TP EVENT : " TPEVENT
DISPLAY "appl return code" APPL-RETURN-CODE
DISPLAY "COBOL Client Failed!"
MOVE TP-STATUS TO STAT-STRING
DISPLAY STAT-STRING
PERFORM EXIT-PROGRAM
END-IF.
DISPLAY "COBOL Client Succeeded!".
DISPLAY "OUTPUT Fist RESPCD " RESPCD in RESPONSE-REC.
DISPLAY "OUTPUT APPLID " APPLID in RESPONSE-REC.
DISPLAY "OUTPUT Last MKTCD  " MKTCD in RESPONSE-REC.
*****************************************************
* Leave TUXEDO
*****************************************************
DO-TPTERM.
CALL "TPTERM" USING TPSTATUS-REC.
IF  NOT TPOK
DISPLAY "TPTERM Failed"
END-IF.
*****************************************************
*Leave Application
*****************************************************
EXIT-PROGRAM.
STOP RUN.

Build and Run instructions

This sample can be run with COBOL IT compiler
 
  1. 1. Copy all above sample file into your working directory
  2. 2. Customize Setenv and  UBBsimple configuration for your environment
  3. 3. Build txconfig: Tmloadcf –y ubbsimple
  4. 4. Create C head file and COBOL COPY BOOK
      1.         viewc32 -C -n  CardInfoGrp_view.v
    •         viewc32 -C -n Response_view.v
  5. 5. Build C Server
  6.         buildserver –f TESTVIEW.c –o TESTVIEW –s TESTVIEW
  7. 6. Build COBOL Client
  8.         buildclient  -C -f COBOLCLI.cbl –o COBOLCLI
  9. 7. Start Tuxedo
  10.         tmboot –y
  11. 8. Run Test Program
  12.         ./COBOLCLI

In a successful case, you will see on your session screen:

COBOL Client Started
COBOL Client Succeeded!
OUTPUT Fist RESPCD Response Code
OUTPUT APPLID APP ID
OUTPUT Last MKTCD  Market code

ULOG File, you will see

TESTVIEW.5233.3578991856.0: Input Message for CardInfoGrpv 24042013
TESTVIEW.5233.3578991856.0: Input Message for MsgPostTime  [06:12:16 PTC]
TESTVIEW.5233.3578991856.0: Input Message for CardNbr [379739073661008]

Add Your Comment