Tuesday, December 7, 2010

Understanding the CICS environment from Application Program

          CICS provides different set of APIs for providing the environment information to the application programmer. As a CICS application programmer, understanding the environment under which the program will run is very important. TXSeries for Multiplatforms supports most widely used operating systems like AIX, SOLARIS, HP-UX, WINDOWS. It also provides better connectivity with CICS Transaction Server. Once the program is developed in one operating system, the same program can be used to run on any of the supporting platform and also the transaction/program containing the business logic can be invoked in different ways like a simple LINK, can be trigger transaction, asynchronously started transaction. Getting the environment in application programs provides application programmers to write the business logic in more effected way to run the business logic.
       
          For example, if an application program contains some functions specific to an operating system to perform some business logic, it might work properly in that particular operation system. Later if the same program is tried to run on different platform, it will fail. As a CICS application programmer, consider these issues while developing the application programs. Using the CICS APIs like EXEC CICS INQUIRE, get the operating system details and then validate and enclose such operating system specific functions calls for that operating system only.

          As an example, the following API can be used to get the operating system details from application program.

          EXEC CICS INQUIRE SYSTEM OPSYS(data-area)

        CICS returns a one-byte character that represents the type of operating system on which the transaction is currently running. The following values are returned:

         A represents CICS for AIX.
         H represents CICS for HP-UX.
         L represents CICS for Solaris.
         N represents CICS for Windows.

          Another example to know how the CICS application programs are invoked, as it can be invoked in different ways.

          EXEC CICS INQUIRE TASK STARTCODE(data-area)

   CICS returns upto a two-character value that indicates how this task started. Possible values are:

    D   The task was initiated to process a distributed programming link (DPL) command that did not specify the SYNCONRETURN option. (The task is not allowed to issue syncpoints.)
    DS  The task was initiated to process a distributed programming link (DPL) command that contains the SYNCONRETURN option. (The task is allowed to issue syncpoints.)
    QD  CICS initiated the task to process a transient data queue that had reached trigger level.
    S   Another task initiated this one, using a START command that did not pass data in the FROM option.
    SD  Another task initiated this one, using a START command that passed data in the FROM option.
    TO  The task was initiated to process unsolicited input from a terminal (or another system), and the transaction that is to be executed was determined from the input.
    TP  The task was initiated in response to a RETURN IMMEDIATE command in another task.
    U   CICS created the task internally.

          The following example will provide way to get the process ID from the application program for logging purpose. Even though user can use directly getpid system call, but its syntax is different for different operating systems.

Unix :
    header file: unistd.h
    pid_t getpid(void);

Usage:   printf("The process ID is %d.", getpid());

Windows :
    header file: process.h
    int _getpid(void);

Usage:   printf("The process ID is %d.", _getpid());
 

Instead of using system call directly, application programmer can use the CICS provided API options to get such type of information.

        EXEC CICS INQUIRE TASK PROCESSID(data-area)
       
    PROCESSID(data-area)
          CICS returns a 32-bit binary value that indicates the process ID of the process that is running the transaction that is associated with the task.

        TXSeries for Multiplatforms provides lot of information about the environment under which the application is invoked or running with EXEC CICS INQUIRE SYSTEM and EXEC CICS INQUIRE TASK APIs.

        For More information on the supported options for these APIs, please refer CICS API Command Reference.

Monday, November 22, 2010

Passing arguments to CICS Transactions

          Are you wondering how send the arguments for CICS Transactions. There will be many cases when user wants to call specific logic in the application code based on particular condition. Writing separate programs for each condition and defining separate transaction for each such program will be difficult for an application programmer. Using the power CICS APIs, CICS application programmer can send arguments for a transaction.

          TXSeries for Multi-platforms provides wide verity of CICS APIs. Using EXEC CICS RECEIVE API, user can read the data from terminal. As most of the terminals uses 24x80 screens, each line can have a maximum of 80 characters. Using EXEC CICS RECEIVE API, user can read the 80 characters as described in pseudo code. After reading, user needs to parse the character string based on requirement. The first four characters contains the transaction name. User can use the remaining 75 characters to pass the character arguments for the transaction.

void main (void)
{
     cics_char_t TextBuffer [80];
     cics_sshort_t TextLength = 80;
     memset(TextBuffer, ' ', 79);
     TextBuffer [79] = '\0';

     EXEC CICS RECEIVE
               INTO(Text_Buffer)
               LENGTH(TextLength);

     /* Read the Trasaction character arguments */
     /* 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 */
     /* SAMP 1*/                  /* SAMP is the transaction and '1' is the argument */
     /* SAMP 2*/                  /* SAMP is the transaction and '2' is the argument */
     /* SAMP 3*/                  /* SAMP is the transaction and '3' is the argument */
     /* SAMP 111 2 33*/          

     if (Text_Buffer [4]  != ' ')
           print(Error Message/Usage)
     switch(Text_Buffer [5])
     {
           case '1' :  Business Logic 1;
                       break;
           case '2' :  Business Logic 2;
                       break;
           case '3' :  Business Logic 3;
                       break;
           .
           .
           .
           .   
           Default  :  Business Logic ;
                       break;         
     }
  //     Business Logic   //
}

     User can also pass multiple arguments to the transaction using some delimiter. But in application program it needs to be parsed based on the delimiter or by using some tokenizing techniques.

Region attach at RegionPoolBase may fail when SafetyLevel is set to normal

Setting SafetyLevel=normal can cause cicsas failure in scenarios where a library or application loaded in the cicsas executes shmat call with shmaddr set to NULL.

Reason:
When you set the SafetyLevel to normal in the RD.stanza, the region attaches and detaches itself at the address specified in RegionPoolBase attribute of RD.stanza with every cics api call. If shmat is used in the application program or in other products (like DB2 or MQ or any other product whose library gets loaded into the cicsas memory) which is being used in conjunction with TXSeries for attaching to the shared memory and passes NULL as a second argument (shmaddr) for shmat, the shared memory is attached at the first available address as selected by the Operating System.
It is possible that the Operating System can assign the same address as RegionPoolBase address. So, the next time when the TXSeries region tries to attach to the address specified in RD.stanza for RegionPoolBase, it fails with EINVAL.

Symptom:
The following message gets recorded in symrecs file:


SYMPTOMS = TIME/"09/22/10 12:37:08.927364556" REGION/TEST PROD/5724AX710 LVLS/710 MOD/"@(#)conco, 17:23:35, Jul 27 2010" FUNC/ConCO_WaitForAnyAMChild LINE/676 MS/010089 MSN/367 SRC/2 PRCS/0 ABCODE/ SRVID/5 PID/1437874 TID/7 PROC/cicsam
SECONDARY SYMPTOMS = Child(PID 250074) returned with exit value 6

Solution:
Set SafetyLevel=none in this scenario, which will make the cicsas to remain attached to the region pool throughout the lifetime of the cicsas.

Sunday, November 7, 2010

Automating TXSeries with Mainframe

Like we saw how to send emails from TXSeries, we can also do several things on mainframe viz. Starting a CICS region, Uploading and Compiling programs etc.

First you need to have an extrapartition TDQ defined in TXSeries. This TDQ output should be redirected to ksh.

With Mainframe we can talk over ftp using the QUOTE command and with filetype=jes. When filetype=JES is set, whatever you upload, is submitted to the JES system as the JCL. On other hands when download (GET) command is used in this JES mode, the job output can be retrieved from mainframe. We will see some example FTP sessions for various tasks on mainframe.

1) Creating a PDS (submitting a JCL to create a PDS)
MFUSER=KAILAS
MFPASS=mypasswd
cat > temp.jcl << EOFJCL
//${MFUSER}1 JOB A1,'${MFUSER}',CLASS=A,MSGCLASS=H,MSGLEVEL=(1,1),
// NOTIFY=&SYSUID
//PERFS1 EXEC PGM=IEFBR14
//SYSPRINT DD SYSOUT=A
//SOURC DD UNIT=SYSDA,SPACE=(CYL,(10,5,10)),
// DSN=${MFUSER}.PERF.SOURCES,DISP=(NEW,CATLG,DELETE),
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=8000)
//
EOFJCL
cat > temp.inp << EOFINP
user
${MFUSER} ${MFPASS}
prompt
quote site filetype=jes jesjobname=${MFUSER}* jesstatus=all jesowner=${MFUSER}
put temp.jcl
exit
EOFINP
ftp -n -v mainframeip < temp.inp

2) uploading a member to your PDS
cat > temp.inp << EOFINP
user
${MFUSER} ${MFPASS}
cd PERF.SOURCES
prompt
put PRFSRVIP
exit
EOFINP
ftp -n -v mainframeip <> NULL

3) Testing the status and results of JCL submitted and getting spool output to your local machine
cat > temp.inp << EOFINP
user
${MFUSER} ${MFPASS}
prompt
quote site filetype=jes jesjobname=${MFUSER}* jesstatus=all jesowner=${MFUSER}
dir ${JOBNO}
exit
EOFINP
STATUS="1"
until [[ $STATUS = "OUTPUT" ]] ; do
ftp -n -v mainframeip < temp.inp
STATUS=`grep ${JOBNO} NULL | awk '{print $4}'`
done

5) issuing operator commands using this technique
you can fire operator commands using following JCL
/*$VS,'S MYCICS1'
The command inside single quote is the command to be used on console

Notes:
1. JESINTERFACELVEL=2 should be set on the ftp server running in Mainframe.

Sending emails through TXSeries

Sending emails through TXSeries.

Often processing programs need to notify their results, status and events to users through emails. TXSeries is a transaction manager used widely to process transactions. Under TXSeries also we can achieve the functionality of sending emails using some Operating System techniques.

TXSeries has extrapartition TD Queues which can be used by programs to send emails to outside world. An Extrapartition TDQ is actually a flat file where records are logged. This flat file can be redirected to a smtp server using netcat command and thus emails can be sent by the programs running under TXSeries.

Below given is an example configuration to send mails.
1. Create an extrapartion TDQ in the region.
cicsadd -c tdd -r $REGION EMLS DestType=extrapartition ExtrapartitionFile=emails.txt RSLKey=public MaxSize=0 RecordLen=128

2. After starting the region use follwing command to send our mail commands from TXSeries program to smtp server:
tail -f emails.txt | nc your.smtphost.com 25
OR
tail -f emails.txt | netcat -h127.0.0.1 -p25

3. From the program WRITEQ TD cics api should be executed to output the text on the extrapartition file.
EXEC CICS WRITEQ TD QUEUE("EMLS") FROM(W-TEXT)

4. Above api will send 1 line of text in the output file. To send the email, we need to send the whole text given here:
HELO your.smtphost.com
MAIL FROM:
RCPT TO:
DATA
Mail Body (Status/Results)
.
QUIT

Keep doing point number 4 in a loop to send multiple mails.

Monday, November 1, 2010

invhariharan's blog: Ways to monitor a TXSeries (CICS) system

invhariharan's blog: Ways to monitor a TXSeries (CICS) system: "The CICS TS for the z environment has a rich set of monitoring tools available from both IBM and the third-party vendors. Though TXSeries (C..."

Thursday, October 28, 2010

Renaming CICS Regions

Renaming a region in TXSeries is not as straightforward as renaming a folder on your desktop. The Region name is used in multiple places -As a prefix in creating sfs files, as an entry in the cicssrcdb ( Remember the subsystems blog ? ), the region environment file is created with its name etc..

So, if you do find yourself in a situation where you want to rename your region, there is a simple way to do so.
And no, there is NO "cicscp restart region blah blah ... "

Here is how you do it :

1) Navigate to CICSREGIONS directory which is /var/cics_regions on Unix systems and C:\var\cics_regions in Windows

2) Run the following command :
" cicsexport -r (Your Region Name) -o (Output File)"

Example : cicsexport -r Arena -o OutFile
This should ensure that an output file is created which contains all your region information. Now this regions is shippable to any other machine in a CICS understandable format.

3) Now Run this Command :
"cicsimport -r (New Region Name) -o (Output File) "

Example : "cicsimport -r ARENA -i OutFile"

Take Care that the file in -i option is the same file you created with cicsexport.

4) Now start your region using this command :
"cicscp start region ARENA StartType=cold"

Note : Did you notice that the region names are case sensitive? This might be a reason to rename your regions in case you want it to Communicate with a region on CICS on z/os.

You have now renamed your region! Good to go.