Easily Identify What Message a Job Is Waiting On PDF Print E-mail
Programming - APIs
Written by Bruce Vining   
Wednesday, 01 October 2008

With the QUSRJOBI and QMHRCVM APIs and MONBCH2, you know exactly what the message is and how to reply.

 

In a previous article, "Keep Those Batch Jobs Running (Or How to Enjoy Your Off Time)," we saw how to detect when a batch job was waiting for a message to be replied to and how to inform a user of that situation. In that introductory article, we simply sent a generic message indicating that job X was waiting for a response to a message. In this article, we'll enhance the MONBCH program and inform the operator of which exact message the job is waiting on. Note that this enhancement to MONBCH will use a V6R1 feature that is not available on previous releases.

 

The new program, MONBCH2, is shown below with the functional changes highlighted.

 

h dftactgrp(*no)                                                     

                                                                      

dMonBch2          pr                  extpgm('MONBCH2')              

dMonBch2          pi                                                 

                                                                      

dSetup            pr              *                                  

dDelay            pr                                                 

dProcessMsgW      pr                                                 

                                                                      

dListJob          pr                  extpgm('QSYS/QUSLJOB')         

d SpcName                       20    const                          

d Format                         8    const                           

d JobName                       26    const                          

d Status                        10    const                          

d QUSEC                               likeds(QUSEC) options(*nopass) 

d JobType                        1    const options(*nopass)         

d NbrKeyFlds                    10i 0 const options(*nopass)         

d KeyFlds                             likeds(KeyFlds) options(*nopass) 

d ContinHdl                     48    const options(*nopass)           

                                                                       

dSndDtaQMsg       pr                  extpgm('QSYS/QSNDDTAQ')          

d DtaQName                      10    const                            

d DtaQLib                       10    const                            

d DataLen                        5  0 const                            

d Data                       65535    const options(*varsize)          

d KeyLen                         3  0 const options(*nopass)           

d KeyValue                   65535    const options(*varsize :*nopass) 

d Asynch                        10    const options(*nopass)           

d JrnEntry                      10    const options(*nopass)           

                                                                        

 /copy qsysinc/qrpglesrc,qusgen                                        

 /copy qsysinc/qrpglesrc,qusljob                                       

 /copy qsysinc/qrpglesrc,qusec                                         

                                                                        

dGenHdr           ds                  likeds(QUSH0100)              

d                                     based(GenHdrPtr)              

                                                                     

dLstEntry         ds                  likeds(QUSL020001)            

d                                     based(LstPtr)                 

                                                                    

dAttrEntry        ds                  likeds(QUSLKF)                

d                                     based(AttrPtr)                

                                                                    

dKeyFlds          ds                                                 

d KeyValues                     10i 0 dim(25)                       

                                                                    

dUsrSpcName       ds                                                

d Name                          10    inz('MONBCHLJOB')             

d Library                       10    inz('QTEMP')                  

                                                                    

dJobsToList       ds                                                

d JobName                       10    inz('*ALL')               

d JobUser                       10    inz('*ALL')               

d JobNbr                         6    inz('*ALL')               

                                                                

dDtaQMsg          ds                                            

d DtaQJobName                   10                              

d                                1                              

d DtaQJobUsr                    10                              

d                                1                              

d DtaQJobNbr                     6                              

d                                1    inz(':')                  

d DtaQMsgID                      7                               

d                                1                              

d DtaQMsgTxt                   256                              

                                                                

dPSDS            sds           429    qualified                  

d Line                   21     28                              

d MsgID                  40     46                                  

d ExcpDta                91    170                                  

d JobName               244    253                                   

d JobUser               254    263                                  

d JobNbr                264    269                                  

                                                                    

dLstCount         s             10i 0                               

dAttrCount        s             10i 0                               

dAttrValue        s            100    based(AtrValPtr)              

dNbrKeyFlds       s             10i 0                                

dContinue         s               n   inz(*on)                      

dMonBchCtl        s              1    dtaara('VININGTST/MONBCHCTL') 

                                                                    

dDtaQName         c                   'MESSAGES'                    

dDtaQLib          c                   'VININGTST'                   

                                                                    

 /free                                                              

                                                                     

  monitor;                                                          

                                                                    

  GenHdrPtr = Setup();                                               

                                                                    

  dow Continue;                                                     

      ListJob( UsrSpcName :'JOBL0200' :JobsToList :'*ACTIVE'        

              :QUSEC :'B' :NbrKeyFlds :KeyFlds :*blanks);           

                                                                    

      // Check to see if the list is complete                       

      if (GenHdr.QUSIS = 'C') or (GenHdr.QUSIS = 'P');              

                                                                     

         // Get to the first list entry and process the list        

         LstPtr = GenHdrPtr + GenHdr.QUSOLD;                        

                                                                     

         for LstCount = 1 to GenHdr.QUSNBRLE;                       

             // Get first attribute and process all returned        

             if LstEntry.QUSJIS = ' ';                                 

                AttrPtr = LstPtr + %size(QUSL020001);                  

                for AttrCount = 1 to LstEntry.QUSNBRFR;                

                    AtrValPtr = AttrPtr + %size(QUSLKF);               

                    select;                                             

                       when AttrEntry.QUSKF = 0101;                    

                            if %subst(AttrValue :1 :AttrEntry.QUSLD00) 

                                 = 'MSGW';                             

                               ProcessMsgW();                          

                            endif;                                     

                    endsl;                                             

                    AttrPtr += AttrEntry.QUSLFIR;                       

                endfor;                                                

             endif;                                                    

             LstPtr += GenHdr.QUSSEE;                                  

         endfor;                                                        

         Delay();                                                      

      else;                                                            

         DtaQJobName = PSDS.JobName;                                    

         DtaQJobUsr = PSDS.JobUser;                                    

         DtaQJobNbr = PSDS.JobNbr;                                     

         DtaQMsgID = *blanks;                                          

         DtaQMsgTxt =                                                   

                   'MONBCH is unable to access batch job information.';

         SndDtaQMsg( DtaQName :DtaQLib :%len(%trimr(DtaQMsg)):DtaQMsg);

         *inlr = *on;                                                   

         return;                                                       

      endif;                                                           

  enddo;                                                               

                                                                        

  *inlr = *on;                                                         

  return;                                                              

                                                                        

  on-error;                                                            

     DtaQJobName = PSDS.JobName;                                     

     DtaQJobUsr = PSDS.JobUser;                                      

     DtaQJobNbr = PSDS.JobNbr;                                        

     DtaQMsgID = *blanks;                                            

     DtaQMsgTxt = 'Job failed at statement ' + PSDS.Line +           

                  ' with message ' + PSDS.MsgID +                    

                  ': ' + PSDS.ExcpDta;                               

     SndDtaQMsg( DtaQName :DtaQLib :%len(%trimr(DtaQMsg)) :DtaQMsg); 

                                                                     

     return;                                                          

                                                                     

  endmon;                                                            

                                                                     

 /end-free                                                            

                                                                     

 *****************************************************************   

                                                                      

pProcessMsgW      b                                                  

                                                                     

dProcessMsgW      pr                                                 

dProcessMsgW      pi                                                  

                                                                     

dRJobI            pr                  extpgm('QSYS/QUSRJOBI')        

d RcvVar                         1    options(*varsize)              

d LenRcvVar                     10i 0 const                          

d Format                         8    const                          

d JobID                         26    const                          

d IntJobID                      16    const                           

d QUSEC                               likeds(QUSEC) options(*nopass) 

d ResetStats                     1    const options(*nopass)         

                                                                     

dRcvMsg           pr                  extpgm('QSYS/QMHRCVM')         

d RcvVar                         1    options(*varsize)              

d LenRcvVar                     10i 0 const                          

d Format                         8    const                      

d QualMsgQ                      20    const                      

d MsgType                       10    const                      

d MsgKey                         4    const                      

d WaitTime                      10i 0 const                       

d MsgAction                     10    const                      

d QUSEC                               likeds(QUSEC)              

d CCSID                         10i 0 const options(*nopass)     

d AlwDftRspRjct                 10    const options(*nopass)     

                                                                 

 /copy qsysinc/qrpglesrc,qmhrcvm                                 

 /copy qsysinc/qrpglesrc,qusrjobi                               

                                                                    

dMHRcvVar         ds                  likeds(QMHM0200)             

d                                     based(MHRcvVarPtr)           

                                                                   

dMsgTxt           s          32767    based(MsgTxtPtr)             

                                                                   

 /free                                                             

                                                                    

  monitor;

  RJobI ( QUSI020000 :%size(QUSI020000) :'JOBI0200' :'*INT'        

         :LstEntry.QUSIJI00 :QUSEC);                               

  if ((QUSMR01 = '1') and (QUSMK <> *loval));                      

     DtaQJobName = QUSJN03;                                         

     DtaQJobUsr = QUSUN03;                                         

     DtaQJobNbr = QUSJNBR03;                                       

                                                                   

     RcvMsg( QMHM0200 :8 :'RCVM0200' :(QUSMQ + QUSMQLIB) :'*INQ'       

            :QUSMK :0 :'*SAME' :QUSEC);                                

     MHRcvVarPtr = %alloc(QMHBAVL01);                                  

     RcvMsg( MHRcvVar :QMHBAVL01 :'RCVM0200' :(QUSMQ + QUSMQLIB)       

            :'*INQ' :QUSMK :0 :'*SAME' :QUSEC);                        

     DtaQMsgID = MHRcvVar.QMHMI02;                                     

     MsgTxtPtr = (%addr(MHRcvVar) +%size(QMHM0200) +MHRcvVar.QMHLDRTN);

     if MHRcvVar.QMHLMRTN <= %size(DtaQMsgTxt);                        

        DtaQMsgTxt = *blanks;                                          

        DtaQMsgTxt = %subst(MsgTxt :1 :MHRcvVar.QMHLMRTN);             

     else;                                                              

        DtaQMsgTxt = %subst(MsgTxt :1 :%size(DtaQMsgTxt));             

     endif;                                                            

     SndDtaQMsg( DtaQName :DtaQLib :%len(%trimr(DtaQMsg)) :DtaQMsg);   

     dealloc MHRcvVarPtr;