HOWTO:User Exits

From Remain Software
(Redirected from HOWTO:User Exits)
Jump to navigation Jump to search

User Exits

How to Check the Objects in a Transfer

Before or during the transfer you want to do some checking and based on the outcome you want to stop the transfer or remove the object.

Before a Transfer

If you want to check the objects before a transfer you have to use the Exception Mechanism and create an Exception program that does the checking. Then based on the result you can send an escape message that will cancel the transfer. You can also blank the target locations of the object so that it does not get included in the transfer.

Steps:

  1. Create and compile an Exception Program by copying QUSRSRC(OME__03C)
  2. Create an Exception that uses the program (STRXFM)
  3. Create an Exception Selection (STRXSM) that activates the selection on UEP-3 with When to Activate set to 4=Pre-Processing


During a Transfer

If you want to check the objects during a transfer you can use the Action mechanism. If the Action must be critical then place it in an Action Group first. Create an Exception procedure to do the checking. Then create an Action that invokes the Exception procedure by using the STRPRCOMS command. Then based on the result you can set the return status to *TERM to cancel the transfer and start rollback for any object already processed. You can also blank the target locations of the object so that it gets kicked from the transfer.

Further reading

Example of an Exception Procedure

/* ---------------------------------------------------------------- */    
/* Program prevents *QRYDFN obejcts to be processed                 */    
/* they will be removed from the transfer                           */    
/* This is an example exception procedure.                          */    
/* ---------------------------------------------------------------- */    

         /* ------------------------------------------------------- */ 
         /* Program start                                           */ 
         /* ------------------------------------------------------- */ 
            PGM        PARM(&XFUC &XUEP &CRII &FREE &BUF &STAT)        
                                                                       
         /* ------------------------------------------------------- */ 
         /* Declare parameters                                      */ 
         /* ------------------------------------------------------- */ 
            DCL        VAR(&XFUC) TYPE(*CHAR) LEN(10)                  
            DCL        VAR(&XUEP) TYPE(*CHAR) LEN(1)                   
            DCL        VAR(&CRII) TYPE(*CHAR) LEN(1)                   
            DCL        VAR(&FREE) TYPE(*CHAR) LEN(256)                 
            DCL        VAR(&BUF)  TYPE(*CHAR) LEN(1024)                
            DCL        VAR(&STAT) TYPE(*CHAR) LEN(5)                   
                                                                                                                                              
         /* ------------------------------------------------------- */
         /* Initialize the return status with *NORM                 */
         /* ------------------------------------------------------- */
            CHGVAR     VAR(&STAT) VALUE('*NORM')                          
                                                                           
/* ---------------------------------------------------------------- */    
/* Processing starts here.                                          */    
/* This is an example exception procedure.                          */    
/* ---------------------------------------------------------------- */    
                                                                            
         /* ------------------------------------------------------- */      
         /* Pull values from the buffer.                            */      
         /* ------------------------------------------------------- */      
            PULLVAROMS BUF(&BUF) INTL(*V5R1M0) APPL(&APPL) +                
                         OBJC(&OBJC) OBJT(&OBJT) FROL(&FROL)                
                                                                            
         /* ------------------------------------------------------- */      
         /* Test the object code                                    */      
         /* ------------------------------------------------------- */      
            IF         COND(&OBJT *EQ '*QRYDFN') THEN(DO)

            /* This is how to remove this object from the transfer */

            PUSHVAROMS TOOL()
            PUSHVAROMS TSRL()
            PUSHVAROMS TSRF()
            PUSHVAROMS TSRM()
            CHGVAR     VAR(&STAT) VALUE('*TERM')                          
       
            ENDDO                                                           
            ENDPGM

How To remove an object from the transfer at runtime

You can remove a component from the transfer at runtime by blanking the target fields in an exception procedure:

Example of an Exception Procedure

/* ---------------------------------------------------------------- */    
/* Program prevents *QRYDFN obejcts to be processed                 */    
/* they will be removed from the transfer                           */    
/* This is an example exception procedure.                          */    
/* ---------------------------------------------------------------- */    

         /* ------------------------------------------------------- */ 
         /* Program start                                           */ 
         /* ------------------------------------------------------- */ 
            PGM        PARM(&XFUC &XUEP &CRII &FREE &BUF &STAT)        
                                                                       
         /* ------------------------------------------------------- */ 
         /* Declare parameters                                      */ 
         /* ------------------------------------------------------- */ 
            DCL        VAR(&XFUC) TYPE(*CHAR) LEN(10)                  
            DCL        VAR(&XUEP) TYPE(*CHAR) LEN(1)                   
            DCL        VAR(&CRII) TYPE(*CHAR) LEN(1)                   
            DCL        VAR(&FREE) TYPE(*CHAR) LEN(256)                 
            DCL        VAR(&BUF)  TYPE(*CHAR) LEN(1024)                
            DCL        VAR(&STAT) TYPE(*CHAR) LEN(5)                   
                                                                                                                                              
         /* ------------------------------------------------------- */
         /* Initialize the return status with *NORM                 */
         /* ------------------------------------------------------- */
            CHGVAR     VAR(&STAT) VALUE('*NORM')                          
                                                                           
/* ---------------------------------------------------------------- */    
/* Processing starts here.                                          */    
/* This is an example exception procedure.                          */    
/* ---------------------------------------------------------------- */    
                                                                            
         /* ------------------------------------------------------- */      
         /* Pull values from the buffer.                            */      
         /* ------------------------------------------------------- */      
            PULLVAROMS BUF(&BUF) INTL(*V5R1M0) APPL(&APPL) +                
                         OBJC(&OBJC) OBJT(&OBJT) FROL(&FROL)                
                                                                            
         /* ------------------------------------------------------- */      
         /* Test the object code                                    */      
         /* ------------------------------------------------------- */      
            IF         COND(&OBJT *EQ '*QRYDFN') THEN(DO)

            /* This is how to remove this object from the transfer */

            PUSHVAROMS TOOL()
            PUSHVAROMS TSRL()
            PUSHVAROMS TSRF()
            PUSHVAROMS TSRM()
            CHGVAR     VAR(&STAT) VALUE('*TERM')                          
       
            ENDDO                                                           
            ENDPGM

How To Change the Target Location of an Object at Runtime

You can change the target location at runtime by using an Action or Exception command CHGVAROMS. You can also create an Exception Procedure that will change the target variables in a program.

Change the Target Location at Runtime

/* ---------------------------------------------------------------- */    
/* Program moves *QRYDFN objects to another library                 */                           */    
/* This is an example exception procedure.                          */    
/* ---------------------------------------------------------------- */    

         /* ------------------------------------------------------- */ 
         /* Program start                                           */ 
         /* ------------------------------------------------------- */ 
            PGM        PARM(&XFUC &XUEP &CRII &FREE &BUF &STAT)        
                                                                       
         /* ------------------------------------------------------- */ 
         /* Declare parameters                                      */ 
         /* ------------------------------------------------------- */ 
            DCL        VAR(&XFUC) TYPE(*CHAR) LEN(10)                  
            DCL        VAR(&XUEP) TYPE(*CHAR) LEN(1)                   
            DCL        VAR(&CRII) TYPE(*CHAR) LEN(1)                   
            DCL        VAR(&FREE) TYPE(*CHAR) LEN(256)                 
            DCL        VAR(&BUF)  TYPE(*CHAR) LEN(1024)                
            DCL        VAR(&STAT) TYPE(*CHAR) LEN(5)                   
                                                                                                                                              
         /* ------------------------------------------------------- */
         /* Initialize the return status with *NORM                 */
         /* ------------------------------------------------------- */
            CHGVAR     VAR(&STAT) VALUE('*NORM')                          
                                                                           
/* ---------------------------------------------------------------- */    
/* Processing starts here.                                          */    
/* This is an example exception procedure.                          */    
/* ---------------------------------------------------------------- */    
                                                                            
         /* ------------------------------------------------------- */      
         /* Pull values from the buffer.                            */      
         /* ------------------------------------------------------- */      
            PULLVAROMS BUF(&BUF) INTL(*V5R1M0) APPL(&APPL) +                
                         OBJC(&OBJC) OBJT(&OBJT) FROL(&FROL)                
                                                                            
         /* ------------------------------------------------------- */      
         /* Test the object code                                    */      
         /* ------------------------------------------------------- */      
            IF         COND(&OBJT *EQ '*QRYDFN') THEN(DO)   

           /* This is how to change the target library */

           PUSHVAROMS TOOL('NEWLIB')
      
           ENDDO                                                           
           ENDPGM

How To Change source file record length for new objects

When a new object is created and the source file does not yet exist in the library the source file is created, the record length is determined as follows:

  • First check the source file length in the dump library
  • If it does not exist use 132 length
  • if program omo008c2u exists then call it (see source file "QUSRSRC" in the TD/OMS library for an example)
  • Does that program fail or does not exist then we create it with the found length

New object create source file

/* ---------------------------------------------------------------- */
/* Description                                                      */
/* ---------------------------------------------------------------- */
/*                                                                  */
/* Program ....: OMO008C2U                                          */
/* Function ...: Creates a source file in the "New Object"          */
/*               process                                            */
/* Parameters .: &NSRF - New Source file                            */
/*               &NSRL - New Source library                         */
/*               &RECL - Proposed record lenght                     */
/*               &STAT - Return status                              */
/*                       *NORM - Source was created normally        */
/*                       *TERM - Sourcefile could not be created    */
/*                                                                  */
/* Compile this program if you want to override the source file     */
/* creation in the 'new object' process of the GUI.                 */
/*                                                                  */
/* ---------------------------------------------------------------- */

            pgm        parm(&NSRF &NSRL &RECL &STAT)

            DCL        VAR(&NSRL) TYPE(*CHAR) LEN(10)
            DCL        VAR(&NSRF) TYPE(*CHAR) LEN(10)
            DCL        VAR(&recl) TYPE(*dec)  LEN(15 6)
            DCL        VAR(&STAT) TYPE(*CHAR) LEN(5)

            MONMSG     MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))

            chgvar     &stat '*NORM'
            CRTSRCPF   FILE(&NSRL/&NSRF) RCDLEN(&RECL) TEXT('Created by +
                         TD/OMS') CCSID(*HEX)
            MONMSG     MSGID(CPF5113 CPF7313)
            RETURN

error:
            chgvar     &stat '*TERM'
            monmsg     (cpf0000 mch0000)
            dmpclpgm
            MONMSG     MSGID(CPF0000)
            ENDPGM

Add Log entries to the TD/OMS Log

TD/OMS has a log that can be viewed with DSPLOGOMS (in the green screen) or through the various "transfer history" actions in the GUI. You can add your own log entries to the TD/OMS log file. The log file name is OMLOG. Adding entries can be done in two ways.

1. Log the last entries from the job log

Suppose you monitor a message and you want to log this message. The construct would be something like this:

  CALL XYZ
  MONMSG CPF0000 exec(do)
    CALL OMX928C
  ENDDO

Calling OMX928C like this will log the last message in the program message queue and put it in the TD/OMS log file.

You may also log your own messages like this:

SNDPGMMSG MSGID(CPF9898) +
         MSGF(QCPFMSG)  +
         MSGDTA('Hello World!') +
         TOPGMQ(*SAME)  
CALL OMX928C

PRE V13.0.1

If you are before TD/OMS version V13.0.1, the message will be added to the TD/OMS log file and removed from the joblog.

V13.0.1 and Higher

If you are on TD/OMS version V13.0.1 or higher, the message will NOT be removed from the joblog. In addition, when you log an ESCAPE message, also all diagnostic messages that precede the escape message will be copied into the TD/OMS log file.


2. Add your own trace and debug messages to the TD/OMS Log

Starting from version 11.1 you can put TD/OMS in debug mode using the STRSD command in the green screen. Service program OMLOGGER contains a number of procedures that enable you to add your debug and trace messages.

You can find examples on how to use the logging facility in member QUSRSRC/LOGTEST.CLLE.