Submit Recurring Job

From MidrangeWiki
Jump to: navigation, search

Background

If you do not have access to the Advanced Job Scheduler on the IBM i servers, this program can help you to submit a job a recurring number of times. The source consists of the following

 RTVJOBCNT - CMD - Retrieve Job Count
 RTVJOBCN#C - CLLE - Retrieve Job Count CL Program
 SBMRECJOB - CMD - Submit Recurring Job
 SBMRECJB#C - CLLE - Submit recurring Job CL PRogram

Using the program

The program should NOT be run interactively, you should either submit this process, or schedule it in the Job Scheduler.

If you issue the command SBMRECJOB, you have to provide the following fields:

                            Submit Recurring Job (SBMRECJOB)                        
                                                                                 
  Type choices, press Enter.                                                     
                                                                               
  Command to submit  . . . . . . .  _____________________________________________                                             
                                                                               
  _______________________________________________________________________________                                                                             
                                                                               
  _______________________________________________________________________________                                                                             
                                                                               
  _________________ ...        
  Submitted Job Name . . . . . . .   ____________  Character value               
  Submitted Job User Profile . . .   *CURRENT      Character value, *CURRENT     
  Submitted Job Queue to use . . .   *JOBD         Name, *JOBD                   
    Library Name . . . . . . . . .     *LIBL       Character value, *LIBL        
  Allow duplicate jobs?  . . . . .   *YES          *YES, *NO                     
  Number of recurring iterations     2             1-999                         
  Delay between iterations . . . .   60            Delay in seconds (up to 24 hr)
                                                                               
                                                                               
                                                                          Bottom 
  F3=Exit   F4=Prompt   F5=Refresh   F12=Cancel   F13=How to use this display    
  F24=More keys
  • Command to submit: Specify the command here. You can also prompt the command to give the correct values and parameters
  • Submitted Job name: The command specified will be submitted using the specified job name.
  • Submitted Job User Profile: Under which profile should the submitted job run. Can also specify *CURRENT for the user running the current job.
  • Submitted Job queue to use: Specify a jobq to use for the submission. Can also specify *JOBD to use the JOBD from the user profile
  • Allow Duplicate Jobs: If there should always be only one job with this name running, use *NO here. If you do not care whether the previous job ended or not, you can ignore duplicate jobs and specify *YES here
  • Number of recurring iterations: Specify how many times this job will be submitted
  • Delay between iterations: Specify here how may seconds delay should take place between submissions. This behaviour is also governed by the "Allow Duplicate Jobs" parameter:
- Allow Duplicate Jobs = *YES - Delay will be between submissions. If the delay is 60 seconds, every 60 seconds a submission will take place
- Allow Duplicate Jobs = *NO - Delay will be xx number of seconds after the one job ended and the next one is submitted again

Source Code - SBMRECJOB

            CMD        PROMPT('Submit Recurring Job')                 
            PARM       KWD(SBMCMD) TYPE(*CMDSTR) LEN(5000) MIN(1) +   
                         PROMPT('Command to submit')                  
            PARM       KWD(SBMJOB) TYPE(*CHAR) LEN(10) MIN(1) +       
                         PROMPT('Submitted Job Name')                 
            PARM       KWD(SBMUSR) TYPE(*CHAR) LEN(10) +              
                         DFT(*CURRENT) SPCVAL((*CURRENT)) +           
                         PROMPT('Submitted Job User Profile')         
            PARM       KWD(SBMJOBQ) TYPE(QUAL1) PROMPT('Submitted +   
                         Job Queue to use')                           
            PARM       KWD(SBMDUP) TYPE(*CHAR) LEN(4) RSTD(*YES) +    
                         DFT(*YES) VALUES(*YES *NO) PROMPT('Allow +   
                         duplicate jobs?')                            
            PARM       KWD(ITERATION) TYPE(*DEC) LEN(3 0) DFT(2) +    
                         RANGE(1 999) PROMPT('Number of recurring +   
                         iterations')                                 
            PARM       KWD(DELAY) TYPE(*DEC) LEN(5) DFT(60) RANGE(1 + 
                         86400) CHOICE('Delay in seconds (up to 24 +  
                         hr)') PROMPT('Delay between iterations')     
                        hr)') PROMPT('Delay between iterations')     
 QUAL1:    QUAL       TYPE(*NAME) LEN(10) DFT(*JOBD) SPCVAL((*JOBD)) 
           QUAL       TYPE(*CHAR) LEN(10) DFT(*LIBL) +               
                        SPCVAL((*LIBL)) PROMPT('Library Name')       
  • Compile with
 CRTCMD ??CMD(SBMRECJOB)                   
      ??PGM(*LIBL/SBMRECJB#C)                    
      ?*SRCFILE(ZOPSLIB/QCMDSRC)                 
      ?*SRCMBR(SBMRECJOB)                        
        ALLOW(*BATCH *BPGM *BREXX *EXEC *BMOD)   
      ??REPLACE(*NO)         

Source Code - SBMRECJB#C

 BEGIN:      PGM        PARM(&SBMCMD &SBMJOB &SBMUSR &SBMJOBQ +        
                         &SBMDUP &SBMITER &DELAY)                     
                                                                      
 /*-------------------------------------------------------------------*/
 /*   PASSED Variables                                                */
 /*-------------------                                                */
 /*                                                                   */
            DCL        VAR(&SBMCMD) TYPE(*CHAR) LEN(5000)             
            DCL        VAR(&SBMJOB) TYPE(*CHAR) LEN(10)               
            DCL        VAR(&SBMUSR) TYPE(*CHAR) LEN(10)               
            DCL        VAR(&SBMJOBQ) TYPE(*CHAR) LEN(20)              
            DCL        VAR(&SBMDUP) TYPE(*CHAR) LEN(4)                
            DCL        VAR(&SBMITER) TYPE(*DEC) LEN(3 0)              
            DCL        VAR(&DELAY) TYPE(*DEC) LEN(5 0)                
                                                                      
 /*                                                                   */
 /*   PROGRAM Variables                                               */
 /*--------------------                                               */
 /*                                                                   */
            DCL        VAR(&COUNTER) TYPE(*INT)                       
            DCL        VAR(&JOBCOUNT) TYPE(*DEC) LEN(8 0)             
            DCL        VAR(&SBMSTRING) TYPE(*CHAR) LEN(6000)          
            DCL        VAR(&ITERATION) TYPE(*INT)                     
            DCL        VAR(&JOBQ) TYPE(*CHAR) LEN(10)                 
            DCL        VAR(&JOBQLIB) TYPE(*CHAR) LEN(10)              
            DCL        VAR(&JOBQVAL) TYPE(*CHAR) LEN(22)              
 /*                                                                   */
 /* Settings for input parameters                                     */
 /*                                                                   */
 /*                                                                   */
 /*   Standard Error Handling variables                               */
 /*------------------------------------                               */
 /*                                                                   */
                                                                      
            DCL        VAR(&MSGID) TYPE(*CHAR) LEN(7) /* Error +      
                         Message Identifier */                        
            DCL        VAR(&MSGDTA) TYPE(*CHAR) LEN(256) /* Error +   
                         Message Data */                              
            DCL        VAR(&MSGFILNAM) TYPE(*CHAR) LEN(10) /* Error + 
                         Message File Name */                         
            DCL        VAR(&MSGFILLIB) TYPE(*CHAR) LEN(10) /* Error + 
                         Message File Name */                         
 /* ----------------------------------------------------------------- */
 /* Program Code Starts Here                                          */
 /* ------------------------                                          */
 /*                                                                   */
                                                                      
 /* MONITOR FOR UNEXPECTED ERROR MESSAGES                             */
                                                                      
            MONMSG     MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))        
 /*                                                                   */
 /*                                                                   */
 /*   Reset counters first                                            */
 /*------------------------------------------------------------       */
 /*                                                                   */
            CHGVAR     VAR(&COUNTER) VALUE(0)                         
            CHGVAR     VAR(&JOBCOUNT) VALUE(0)                        
            CHGVAR     VAR(&ITERATION) VALUE(&SBMITER)                
 /*                                                                   */
 /*                                                                   */
 /*   Check if the user exist, if not, retrieve current user profile  */
 /*------------------------------------------------------------       */
 /*                                                                   */
            IF         COND(&SBMUSR *EQ '*CURRENT') THEN(RTVJOBA +    
                         USER(&SBMUSR))                               
            CHKOBJ     OBJ(&SBMUSR) OBJTYPE(*USRPRF)                  
            MONMSG     MSGID(CPF0000) EXEC(DO)                        
            RTVJOBA    USER(&SBMUSR)                                  
            ENDDO                                                     
 /*                                                                   */
 /*                                                                   */
 /*   Check if the job queue exist. If not, set JOBQ to *JOBD         */
 /*------------------------------------------------------------       */
 /*                                                                   */
            CHGVAR     VAR(&JOBQ) VALUE(%SST(&SBMJOBQ 1 10))          
            CHGVAR     VAR(&JOBQLIB) VALUE(%SST(&SBMJOBQ 11 10))      
            SELECT                                                    
            WHEN       COND(&JOBQ *EQ '*JOBD') THEN(DO)               
            CHGVAR     VAR(&JOBQVAL) VALUE('*JOBD')                   
            ENDDO                                                     
            /**/                                                      
            WHEN       COND(&JOBQ *NE '*JOBD') THEN(DO)               
            CHGVAR     VAR(&JOBQVAL) VALUE(&JOBQLIB *TCAT '/' *TCAT + 
                         &JOBQ)                                       
            CHKOBJ     OBJ(&JOBQLIB/&JOBQ) OBJTYPE(*JOBQ)             
            MONMSG     MSGID(CPF0000) EXEC(DO)                        
            CHGVAR     VAR(&JOBQVAL) VALUE('*JOBD')                   
            ENDDO                                                     
            ENDDO                                                     
            ENDSELECT                                                 
 /*                                                                   */
 /*                                                                   */
 /*   Setup the command now, write entries to the joblog              */
 /*------------------------------------------------------------       */
 /*                                                                   */
            CHGVAR     VAR(&SBMSTRING) VALUE('SBMJOB CMD(' *TCAT +    
                         &SBMCMD *TCAT ') JOB(' *TCAT &SBMJOB +       
                         *TCAT ') USER(' *TCAT &SBMUSR *TCAT ') +     
                         CURLIB(*USRPRF) INLLIBL(*JOBD) JOBQ(' +      
                         *TCAT &JOBQVAL *TCAT ')')                    
            SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('Cmd to +  
                         submit -' *BCAT %TRIM(&SBMCMD))              
            SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('Delay +   
                         time in seconds - ' *TCAT %CHAR(&DELAY))     
            SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('Submit +  
                         user - ' *BCAT &SBMUSR)                      
            SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('Submit +  
                         job name - ' *BCAT &SBMJOB)                  
                                                                      
 /*                                                                   */
 /*                                                                   */
 /*   Go into the for loop here.                                      */
 /*------------------------------------------------------------       */
 /*                                                                   */
            DOFOR      VAR(&COUNTER) FROM(1) TO(&ITERATION)           
            SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) +                 
                         MSGDTA('Iteration - ' *BCAT +                
                         %CHAR(&COUNTER) *BCAT 'of' *BCAT +           
                         %CHAR(&ITERATION))                           
 /*                                                                   */        
 /*   Check if job is already running.                                */        
 /*------------------------------------------------------------       */        
 /*                                                                   */        
            RTVJOBCNT JOB(&SBMJOB) USER(&SBMUSR) +                    
                         COUNT(&JOBCOUNT)                                     
            MONMSG     MSGID(CPF0000)                                         
            SELECT                                                            
            /* If job is not active, or Submit Duplicates is yes, submit it */
            WHEN       COND(&JOBCOUNT = 0 *OR &SBMDUP = '*YES') +             
                         THEN(DO)                                             
            SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) +                         
                         MSGDTA('-- Submitting job ' *BCAT &SBMJOB +          
                         *BCAT ' for user ' *BCAT &SBMUSR)                    
            CALL       PGM(QCMDEXC) PARM(&SBMSTRING 6000)                     
            ENDDO                                                             
            OTHERWISE  CMD(DO)                                                
            SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('-- Job +          
                         ' *BCAT &SBMJOB *BCAT ' NOT submitted for +          
                         user ' *BCAT &SBMUSR)                                
            ENDDO                                                     
            ENDSELECT                                                 
 /*                                                                   */
 /*                                                                   */
 /*   Delay the job now for the specified number of minutes           */
 /*------------------------------------------------------------       */
 /*                                                                   */
            DLYJOB     DLY(&DELAY)                                    
            ENDDO                                                     
                                                                      
 /*                                                                   */
 /*  GO TO NORMAL PROGRAM END                                         */
 /* -------------------------------------------                       */
 /*                                                                   */
                                                                      
            GOTO       CMDLBL(EXIT)                                   
 /*                                                                   */
 /* ----------------------------------------------------------------- */
 /* UNEXPECTED ERROR ROUTINE                                          */
 /* ------------------------                                          */
 /*                                                                   */
 ERROR:                                                                
            RCVMSG     MSGTYPE(*EXCP) MSGDTA(&MSGDTA) MSGID(&MSGID) + 
                         MSGF(&MSGFILNAM) MSGFLIB(&MSGFILLIB)         
            SNDPGMMSG  MSGID(&MSGID) MSGF(&MSGFILLIB/&MSGFILNAM) +    
                         MSGDTA(&MSGDTA) MSGTYPE(*ESCAPE)             
 /*                                                                   */
 /* ----------------------------------------------------------------- */
 /* ALL ROADS LEAD TO EXIT                                            */
 /* ----------------------                                            */
 /*                                                                   */
  EXIT:                                                                 
            RETURN                                                    
            ENDPGM

Source Code - RTVJOBCNT

             CMD        PROMPT('Count active jobs for user')         
               /* CPP CHGACTJOB */                                   
             PARM       KWD(JOB) TYPE(*GENERIC) LEN(10) +            
                          SPCVAL((*ALL)) MIN(1) PROMPT('Job name:')  
             PARM       KWD(USER) TYPE(*NAME) LEN(10) DFT(*ALL) +    
                          SPCVAL((*ALL) (*CURRENT)) PROMPT('User +   
                          name:')                                    
             PARM       KWD(COUNT) TYPE(*DEC) LEN(8 0) RTNVAL(*YES) +
                          PROMPT('Count of active jobs')             
/*  DEP        CTL(&USER *EQ *ALL) PARM((&JOB *NE *ALL)) +           
                 NBRTRUE(*EQ 1) MSGID(USR3C01)      */               


Source Code - RTVJOBC#C

BEGIN:      PGM        PARM(&JOB &USER &COUNTER)                       
                                                                       
/**/                                                                    
/*   PASSED Variables                                                */ 
/*-------------------                                                */ 
/**/                                                                    
            DCL        VAR(&JOB) TYPE(*CHAR) LEN(10) +                 
                         /* Input job name */                          
            DCL        VAR(&USER) TYPE(*CHAR) LEN(10) +                
                         /* Input user name */                         
            DCL        VAR(&COUNTER) TYPE(*DEC) LEN(8 0) /* Counter +  
                         Value that will be returned to caller +       
                         program */                                    
                                                                       
/*                                                                   */
/* Local variables                                                   */
/*                                                                   */
/**/                                                                    
/*   PROGRAM Variables                                               */
/*--------------------                                               */
/**/                                                                   
                                                                       
             DCL        VAR(&NUMBER) TYPE(*CHAR) LEN(6) +              
                          /* Current job number */                     
             DCL        VAR(&USRSPC) TYPE(*CHAR) LEN(20) +             
                          VALUE('CHGA      QTEMP     ') +              
                          /* User space name for APIs */               
             DCL        VAR(&EUSRSPC) TYPE(*CHAR) LEN(10) +            
                          /* User space name for commands */           
             DCL        VAR(&JOBNAME) TYPE(*CHAR) LEN(26) +            
                          VALUE('                    *ALL  ') +        
                          /* Full job name for list job  */            
             DCL        VAR(&BIN4) TYPE(*CHAR) LEN(4) +                
                          /* Number of jobs for list job and +         
                             User space offset in binary 4 form */     
             DCL        VAR(&LOOP) TYPE(*DEC) LEN(8 0) +               
                          /* Number of jobs from list job */           
                                                                       
/**/                                                                   
/*   Standard Error Handling variables                               */
/*------------------------------------                               */
/**/                                                                   
             DCL        VAR(&MSGID) TYPE(*CHAR) LEN(7) /* Error +      
                          Message Identifier */                        
             DCL        VAR(&MSGDTA) TYPE(*CHAR) LEN(256) /* Error +   
                          Message Data */                              
             DCL        VAR(&MSGFILNAM) TYPE(*CHAR) LEN(10) /* Error + 
                          Message File Name */                         
             DCL        VAR(&MSGFILLIB) TYPE(*CHAR) LEN(10) /* Error + 
                          Message File Name */                         
/**/                                                                   
/*   --------------------------------------                          */
/*         Program Code Starts Here                                  */
/*   --------------------------------------                          */
/**/                                                                   
                                                                       
/**/                                                                   
/* MONITOR FOR UNEXPECTED ERROR MESSAGES                             */
/* -------------------------------------                             */
/**/                                                                   
             MONMSG     MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))        
                                                                       
/**/                                                                   
/* Main sections starts here.                                        */
/*------------------------------------------------------------       */
/**/                                                                   
                                                                       
/**/                                                                   
/* Retrieve job number to use for local user space name              */
/*------------------------------------------------------------       */
/**/                                                                   
             RTVJOBA    NBR(&NUMBER)                                   
             CHGVAR     VAR(%SST(&USRSPC 5 6)) VALUE(&NUMBER)          
             CHGVAR     VAR(&EUSRSPC) VALUE(%SST(&USRSPC 1 10))        
                                                                       
/**/                                                                   
/* Delete user space if it already exists                            */
/*------------------------------------------------------------       */
/**/                                                                   
             DLTUSRSPC  USRSPC(QTEMP/&EUSRSPC)                         
             MONMSG CPF0000                                            
                                                                       
/**/                                                                   
/* Create user space                                                 */
/*------------------------------------------------------------       */
/**/                                                                   
             CALL       PGM(QUSCRTUS) PARM(&USRSPC 'RTVJOBCNT ' +      
                          X'00000100' ' ' '*ALL      ' 'RTVJOBCNT +    
                          TEMPORARY USER SPACE                    ')   
                                                                       
/**/                                                                   
/* Setup the job name                                                */
/*------------------------------------------------------------       */
/**/                                                                   
             CHGVAR     VAR(%SST(&JOBNAME 1 10)) VALUE(&JOB)           
             CHGVAR     VAR(%SST(&JOBNAME 11 10)) VALUE(&USER)         
                                                                       
/**/                                                                   
/* List the active jobs with the specified job name                  */
/*------------------------------------------------------------       */
/**/                                                                   
             CALL       PGM(QUSLJOB) PARM(&USRSPC 'JOBL0100' +         
                          &JOBNAME '*ACTIVE   ')                       
                                                                       
/**/                                                                   
/* Retrieve the number of entries returned, and convert to decimal   */
/*----------------------------------------------------------------   */
/**/                                                                   
             CALL QUSRTVUS (&USRSPC X'00000085' X'00000004' +          
                            &BIN4)                                     
             CHGVAR     &LOOP      %BINARY(&BIN4)                      
             CHGVAR     VAR(&COUNTER) VALUE(&LOOP)                     
             GOTO       CMDLBL(ALLDONE)                                
                                                                       
/**/                                                                   
/*   --------------------------------------                          */
/*         UNEXPECTED ERROR ROUTINE                                  */
/*   --------------------------------------                          */
/**/                                                                    
 ERROR:                                                                 
             RCVMSG     MSGTYPE(*EXCP) MSGDTA(&MSGDTA) MSGID(&MSGID) +  
                          MSGF(&MSGFILNAM) MSGFLIB(&MSGFILLIB)          
             SNDPGMMSG  MSGID(&MSGID) MSGF(&MSGFILLIB/&MSGFILNAM) +     
                          MSGDTA(&MSGDTA) MSGTYPE(*ESCAPE)              
                                                                        
/**/                                                                    
/*   --------------------------------------                          */ 
/*      ALL ROADS LEAD TO EXIT                                       */ 
/*   --------------------------------------                          */ 
/**/                                                                    
 /*                                                                   */
 /* All done. Now delete temporary user space that we created.        */
 /*                                                                   */
                                                                        
 ALLDONE:    DLTUSRSPC  USRSPC(QTEMP/&EUSRSPC)                          
             MONMSG CPF0000                                             
             RETURN                                                     
             ENDPGM