diff --git a/endevor/Field-Developed-Programs/Miscellaneous-items/BUMPJOB.rex b/endevor/Field-Developed-Programs/Miscellaneous-items/BUMPJOB.rex new file mode 100644 index 0000000..d6dab6a --- /dev/null +++ b/endevor/Field-Developed-Programs/Miscellaneous-items/BUMPJOB.rex @@ -0,0 +1,20 @@ +/* REXX */ +/* Bump the last character on a Jobname to next value */ +/* select is either empty/next for next character */ +/* or j/jump for a big gap */ + Trace O + Arg jobname select + Rotation = '12345678901', + 'ABCDEFGHIJKLMNOPQRSTUVWXYZA', + '@#$@' + jobname = word(jobname,1) + lastchar = Substr(jobname,Length(jobname)) + locatchar = Pos(lastchar,Rotation) + If select = 'j' | select = 'jump' then, + wherenext = (locatchar + length(Rotataton) // 2 + Else, + wherenext = locatchar + 1 + overlaychar = Substr(Rotation,wherenext,1) + wheretohit = Min(Length(jobname)+1,8) + nextJobname = overlay(overlaychar,jobname,wheretohit) + Return nextJobname diff --git a/endevor/Field-Developed-Programs/Miscellaneous-items/GETACCTC.rex b/endevor/Field-Developed-Programs/Miscellaneous-items/GETACCTC.rex new file mode 100644 index 0000000..aa35080 --- /dev/null +++ b/endevor/Field-Developed-Programs/Miscellaneous-items/GETACCTC.rex @@ -0,0 +1,16 @@ +/* REXX */ +/* Find and return the Accounting code value for current user/job */ + + start = 540 /* it starts here */ + start = D2X(start) + TCB_Addr = C2D(Storage(start,4)) /* Current TCB Addr */ + JSCB_Addr = C2D(Storage(D2X(TCB_Addr+180),4)) + + JCT_Addr = C2D(Storage(D2X(JSCB_Addr+260),4)) + + ACT_Addr = C2D(Storage(D2X(JCT_Addr+56),3)) + ACT_Area = Storage(D2X(ACT_Addr),110) + ACT_len = C2D(Substr(ACT_Area,49,1)) + ACT_code = Substr(ACT_Area,50,ACT_len) + + Return ACT_code diff --git a/endevor/Field-Developed-Programs/Miscellaneous-items/GTUNIQUE.rex b/endevor/Field-Developed-Programs/Miscellaneous-items/GTUNIQUE.rex new file mode 100644 index 0000000..800b396 --- /dev/null +++ b/endevor/Field-Developed-Programs/Miscellaneous-items/GTUNIQUE.rex @@ -0,0 +1,25 @@ + /* REXX */ + /* Build a unique 8-byte name from date and time */ + + numbers = '123456789' ; + characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' ; + ToDay = DATE(O) ; + Year = SUBSTR(ToDay,1,2) + 1; + Year = SUBSTR(characters||characters||characters||characters,Year,1) + Month = SUBSTR(ToDay,4,2) ; + Month = SUBSTR(characters,Month,1) ; + Day = SUBSTR(ToDay,7,2) ; + + Day = SUBSTR(characters || numbers,Day,1) ; + NOW = TIME() ; + Hour = SUBSTR(NOW,1,2) ; + IF Hour = '00' THEN Hour = '0' + ELSE + Hour = SUBSTR(characters,Hour,1) ; + Minute = SUBSTR(NOW,4,2) ; + second = SUBSTR(NOW,7,2) ; + Unique_Name = Year || Month || Day || Hour ||, + Minute || second ; + SA= "Unique Member name is " Unique_Name + + Return Unique_Name diff --git a/endevor/Field-Developed-Programs/Miscellaneous-items/QMATCH.rex b/endevor/Field-Developed-Programs/Miscellaneous-items/QMATCH.rex new file mode 100644 index 0000000..03faef0 --- /dev/null +++ b/endevor/Field-Developed-Programs/Miscellaneous-items/QMATCH.rex @@ -0,0 +1,18 @@ + /* REXX */ + PARSE ARG Parm1 Parm2 + +/* Check to see if Parm1 is selected (or matches) Parm2 */ +/* Allowing for Parm2 to have wildcard characters */ + + If Parm1 = Parm2 then Return(1) + + If Parm1 ='*' | Parm2 ='*' then Return(1) + whereAsterisk = Pos('*',Parm2) + If whereAsterisk = 0 then Return(0) + If whereAsterisk > 1 then whereAsterisk = whereAsterisk - 1; + + If Substr(Parm1,1,whereAsterisk) = , + Substr(Parm2,1,whereAsterisk) then Return(1) + + Return(0) + diff --git a/endevor/Field-Developed-Programs/Miscellaneous-items/WAITFILE.rex b/endevor/Field-Developed-Programs/Miscellaneous-items/WAITFILE.rex new file mode 100644 index 0000000..e6f7019 --- /dev/null +++ b/endevor/Field-Developed-Programs/Miscellaneous-items/WAITFILE.rex @@ -0,0 +1,46 @@ + /* REXX */ + /* Loop in Wait status until named file appears */ + /* Return 0 if file never appears after all waits */ + /* Return # for number of seconds used waiting */ + + Arg WaitForFilename MaxLoops WaitSeconds + + STRING = "ALLOC DD(WAITFILE)", + " DA('"WaitForFilename"') SHR REUSE" + seconds = WaitSeconds /* Number of Seconds to wait if needed */ + + Do MaxLoops + /* or at least until the file is available */ + Do Loop# = 1 to MaxLoops + CALL BPXWDYN STRING; + MyResult = RESULT ; + If MyResult = 0 then Return (Loop# * WaitSeconds) + Say 'WAITFILE is waiting for' WaitForFilename + Call WaitAwhile + End /* Do MaxLoops */ + + Return 0 + +WaitAwhile: + /* */ + /* A resource is unavailable. Wait awhile and try */ + /* accessing the resource again. */ + /* */ + /* The length of the wait is designated in the parameter */ + /* value which specifies a number of seconds. */ + /* A parameter value of '000003' causes a wait for 3 seconds. */ + /* */ + /*seconds = Abs(seconds) */ + /*seconds = Trunc(seconds,0) */ + Say "Waiting for" seconds "seconds at " DATE(S) TIME() + /* AOPBATCH and BPXWDYN are IBM programs */ + CALL BPXWDYN "ALLOC DD(STDOUT) DUMMY SHR REUSE" + CALL BPXWDYN "ALLOC DD(STDERR) DUMMY SHR REUSE" + CALL BPXWDYN "ALLOC DD(STDIN) DUMMY SHR REUSE" + + /* AOPBATCH and BPXWDYN are IBM programs */ + parm = "sleep "seconds + Address LINKMVS "AOPBATCH parm" + + Return + diff --git a/endevor/Field-Developed-Programs/Processor-Tools-and-Processor-Snippets/BUMPJOB.rex b/endevor/Field-Developed-Programs/Processor-Tools-and-Processor-Snippets/BUMPJOB.rex new file mode 100644 index 0000000..add9e10 --- /dev/null +++ b/endevor/Field-Developed-Programs/Processor-Tools-and-Processor-Snippets/BUMPJOB.rex @@ -0,0 +1,20 @@ +/* REXX */ +/* Bump the last character on a Jobname to next value */ +/* select is either empty/next for next character */ +/* or j/jump for a big gap */ + Trace O + Arg jobname select + Rotation = '12345678901', + 'ABCDEFGHIJKLMNOPQRSTUVWXYZA', + '@#$@' + jobname = word(jobname,1) + lastchar = Substr(jobname,Length(jobname)) + locatchar = Pos(lastchar,Rotation) + If select = 'j' | select = 'jump' then, + wherenext = (locatchar + length(Rotataton) // 2 + Else, + wherenext = locatchar + 1 + overlaychar = Substr(Rotation,wherenext,1) + wheretohit = Min(Length(jobname)+1,8) + nextJobname = overlay(overlaychar,jobname,wheretohit) + Return nextJobname diff --git a/endevor/Field-Developed-Programs/Processor-Tools-and-Processor-Snippets/GTUNIQUE.rex b/endevor/Field-Developed-Programs/Processor-Tools-and-Processor-Snippets/GTUNIQUE.rex new file mode 100644 index 0000000..2d9999a --- /dev/null +++ b/endevor/Field-Developed-Programs/Processor-Tools-and-Processor-Snippets/GTUNIQUE.rex @@ -0,0 +1,25 @@ + /* REXX */ + /* Build a unique 8-byte name from date and time */ + + numbers = '123456789' ; + characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' ; + ToDay = DATE(O) ; + Year = SUBSTR(ToDay,1,2) + 1; + Year = SUBSTR(characters||characters||characters||characters,Year,1) + Month = SUBSTR(ToDay,4,2) ; + Month = SUBSTR(characters,Month,1) ; + Day = SUBSTR(ToDay,7,2) ; + + Day = SUBSTR(characters || numbers,Day,1) ; + NOW = TIME() ; + Hour = SUBSTR(NOW,1,2) ; + IF Hour = '00' THEN Hour = '0' + ELSE + Hour = SUBSTR(characters,Hour,1) ; + Minute = SUBSTR(NOW,4,2) ; + second = SUBSTR(NOW,7,2) ; + Unique_Name = Year || Month || Day || Hour ||, + Minute || second ; + SA= "Unique Member name is " Unique_Name + + Return Unique_Name diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/C1UEXTR7.rex b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/C1UEXTR7.rex new file mode 100644 index 0000000..16973bb --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/C1UEXTR7.rex @@ -0,0 +1,248 @@ +/* rexx */ + /* Make CAST actions always be batch... */ + /* Values to be set for your site...... */ + /* Build a JCL model, and name its location here.... */ + CastPackageModel = your.hlq.SKELS(CASTPKGE)' + CastPackageModel = '' + /* Name a work dataset to be created then deleted... */ + CastPackageJCL = USERID()".C1UEXTR7.SUBMIT" + /* If wanting to limit the use of this exit, uncomment... */ +/* If USERID() /= 'IBMUSER' then exit */ + STRING = "ALLOC DD(SYSTSPRT) SYSOUT(A) " + CALL BPXWDYN STRING; + STRING = "ALLOC DD(SYSTSIN) DUMMY" + CALL BPXWDYN STRING; + /* If C1UEXTR7 is allocated to anything, turn on Trace */ + WhatDDName = 'C1UEXTR7' + CALL BPXWDYN "INFO FI("WhatDDName")", + "INRTDSN(DSNVAR) INRDSNT(myDSNT)" + if RESULT = 0 then Trace ?r + Sa= 'You called C1UEXTR7 ' + Message = '' + MessageCode = ' ' + /* Values to be set for your site...... */ + /* For package REVIEW (APPROVE/DENY)..... */ + /* Enter location of Approver Group sequencing ... */ + ApproverGroupSequence= 'YOURSITE.NDVR.PARMLIB(APPROVER)' + ApproverGroupSequence= '' + /* Do you want all CAST actions to be peformed in Batch? */ + Force_CAST_in_Batch = 'Y' ; /* Y/N */ + Force_CAST_in_Batch = 'N' ; /* Y/N */ + Cast_with_SonarQube= 'N' /* Y/N/?=Check Notes and pkg content*/ + Cast_with_SonarQube= 'Y' /* Y/N/?=Check Notes and pkg content*/ + Arg Parms + sa= 'Parms len=' Length(Parms) + MyRc = 0 + /* Parms from C1UEXT07 is a string of REXX statements */ + Interpret Parms + /* Is package ready to be automatically Executed..... */ + IF PHDR_PACKAGE_STATUS = 'APPROVED' &, + PECB_BEF_AFTER_LITERAL = 'AFTER' &, + (PECB_FUNCTION_LITERAL = 'CAST' |, + PECB_FUNCTION_LITERAL = 'REVIEW') Then, + Do + PKGEXECT_Parm = Copies(' ',055) + PKGEXECT_Parm = Overlay(PECB_PACKAGE_ID ,PKGEXECT_Parm,001) + PKGEXECT_Parm = Overlay(PHDR_PKG_ENV ,PKGEXECT_Parm,018) + PKGEXECT_Parm = Overlay(PHDR_PKG_STGID ,PKGEXECT_Parm,026) + PKGEXECT_Parm = Overlay(REXX_EXEC_MODE ,PKGEXECT_Parm,028) + PKGEXECT_Parm = Overlay(PHDR_PKG_CREATE_USER,PKGEXECT_Parm,029) + PKGEXECT_Parm = Overlay(PHDR_PKG_UPDATE_USER,PKGEXECT_Parm,037) + PKGEXECT_Parm = Overlay(PHDR_PKG_CAST_USER ,PKGEXECT_Parm,045) + Call PKGEXECT PKGEXECT_Parm + Exit + End + /* Is package ready to be CAST in batch ............. */ + /* Does PACKAGE builder indicate the package has COBOL ? */ + thisPackageHasCobol = 'N' + If Substr(PREQ_PACKAGE_COMMENT,47,4) = '+COB' then, + thisPackageHasCobol = 'Y' + If Cast_with_SonarQube= 'Y' & thisPackageHasCobol = 'Y' then, + Do + /* Does user want to BYPASS SonarQube for this package ? */ + AllNotes = , + PHDR_PKG_NOTE1 || PHDR_PKG_NOTE2 || PHDR_PKG_NOTE3 ||, + PHDR_PKG_NOTE4 || PHDR_PKG_NOTE5 || PHDR_PKG_NOTE6 ||, + PHDR_PKG_NOTE7 || PHDR_PKG_NOTE8 + If Pos('BYPASS SONARQUBE',AllNotes) > 0 then, + Cast_with_SonarQube= 'N' + End + /* If Going to interface with SonarQube, do CAST in Batch */ + /* if foreground, re-Submit in Batch */ + IF Cast_with_SonarQube= 'Y' &, + thisPackageHasCobol= 'Y' &, + PECB_FUNCTION_LITERAL = 'CAST' &, + PECB_BEF_AFTER_LITERAL = 'BEFORE' &, + PECB_MODE = "T" then, /* TSO foreground */ + Do + Call SubmitBatchCAST + Exit + End + /* If Going to interface with SonarQube, do CAST in Batch */ + /* if Batch, engage the interface with SonarQube */ + IF Cast_with_SonarQube= 'Y' &, + thisPackageHasCobol= 'Y' &, + PECB_FUNCTION_LITERAL = 'CAST' &, + PECB_BEF_AFTER_LITERAL = 'BEFORE' &, + PECB_MODE = "B" then, /* TSO foreground */ + Do + Message = SONRQUBE(PECB_PACKAGE_ID) + If Message /= '' then, + Do + MyRc = 8 + Call SetExitReturnInfo + End + Exit + End + EXIT + If Substr(PHDR_PKG_NOTE5,1,5) = 'TRACE' then TraceRc = 1 + IF PHDR_PACKAGE_STATUS = 'APPROVED' &, + PECB_BEF_AFTER_LITERAL = 'AFTER' &, + (PECB_FUNCTION_LITERAL = 'CAST' |, + PECB_FUNCTION_LITERAL = 'REVIEW') Then, + Do + PKGEXECT_Parm = Copies(' ',055) + PKGEXECT_Parm = Overlay(PECB_PACKAGE_ID ,PKGEXECT_Parm,001) + PKGEXECT_Parm = Overlay(PHDR_PKG_ENV ,PKGEXECT_Parm,018) + PKGEXECT_Parm = Overlay(PHDR_PKG_STGID ,PKGEXECT_Parm,026) + PKGEXECT_Parm = Overlay(REXX_EXEC_MODE ,PKGEXECT_Parm,028) + PKGEXECT_Parm = Overlay(PHDR_PKG_CREATE_USER,PKGEXECT_Parm,029) + PKGEXECT_Parm = Overlay(PHDR_PKG_UPDATE_USER,PKGEXECT_Parm,037) + PKGEXECT_Parm = Overlay(PHDR_PKG_CAST_USER ,PKGEXECT_Parm,045) + Call PKGEXECT PKGEXECT_Parm + Exit + End + /* Enforce packages to be Backout Enabled */ + IF PREQ_BACKOUT_ENABLED /= 'Y' then, + Do + Message = 'Package made to be Backout enabled' + MyRc = 4 + hexAddress = D2X(Address_PREQ_BACKOUT_ENABLED) + storrep = STORAGE(hexAddress,,'Y') + Call SetExitReturnInfo + End; + Exit +SubmitBatchCAST: + /* Preparing to CAST The package... */ + If PREQ_PKG_CAST_COMPVAL = 'Y' then, + CastOption = ' OPTION VALIDATE COMPONENTS' + Else, + If PREQ_PKG_CAST_COMPVAL = 'W' then, + CastOption = ' OPTION VALIDATE COMPONENT WITH WARNING' + Else, + CastOption = ' OPTION DO NOT VALIDATE COMPONENT' + /* Variable settings for each site ---> */ + WhereIam = WHERE@M1() + interpret 'Call' WhereIam "'MyDATALibrary'" + MyDATALibrary = Result + interpret 'Call' WhereIam "'MySEN2Library'" + MySEN2Library = Result + interpret 'Call' WhereIam "'MySENULibrary'" + MySENULibrary = Result + interpret 'Call' WhereIam "'AltIDAcctCode'" + AltIDAcctCode = Result + interpret 'Call' WhereIam "'MySENULibrary'" + MySENULibrary = Result + interpret 'Call' WhereIam "'AltIDJobClass'" + AltIDJobClass = Result + /* <---- Variable settings for each site */ + Sa= 'Running C1UEXTR7 ' + /* Allocate and prepare files for ENBPIU00 execution */ + /* OPTIONS will contain date and time values */ + /* */ + STRING = "ALLOC DD(OPTIONS) LRECL(80) BLKSIZE(27920) ", + " DSORG(PS) ", + " SPACE(1,1) RECFM(F,B) TRACKS ", + " NEW UNCATALOG REUSE "; + CALL BPXWDYN STRING; + QUEUE " $nomessages = 'Y' " ; + QUEUE " Package = '"PECB_PACKAGE_ID"'" ; + QUEUE " Userid = '"USERID()"'" ; + QUEUE " Userjob = '"USERID()|| SUBSTR(Package,1,1)"'" + QUEUE " AltIDAcctCode = '"AltIDAcctCode"'" + QUEUE " MySEN2Library = '"MySEN2Library"'" + QUEUE " MySENULibrary = '"MySENULibrary"'" + QUEUE " AltIDJobClass = '"AltIDJobClass"'" + QUEUE " CastOption = '"CastOption"'" + "EXECIO " QUEUED() "DISKW OPTIONS (FINIS" + /* */ + /* TABLE is simple to allow the CAST */ + /* */ + STRING = "ALLOC DD(TABLE) LRECL(80) BLKSIZE(8000) ", + " DSORG(PS) ", + " SPACE(1,1) RECFM(F,B) TRACKS ", + " NEW UNCATALOG REUSE "; + CALL BPXWDYN STRING; + QUEUE "* Do " + QUEUE " * " + "EXECIO 2 DISKW TABLE (FINIS" + STRING = 'ALLOC DD(MODEL) ', + "DA('"MySEN2Library"(CASTPKGE)') SHR REUSE " + CALL BPXWDYN STRING; + /* TBLOUT is assigned to a temporary dataset to receive the jcl */ + /* */ + STRING = "ALLOC DD(TBLOUT) LRECL(80) BLKSIZE(27920) ", + " DA("CastPackageJCL") ", + " DSORG(PS) ", + " SPACE(1,1) RECFM(F,B) TRACKS ", + " NEW CATALOG REUSE "; + CALL BPXWDYN STRING; + /* */ + /* Now call ENBPIU00 which does the rest */ + /* */ + "ENBPIU00 M 1 " + "EXECIO 0 DISKW TBLOUT (FINIS" + CALL BPXWDYN "FREE DD(OPTIONS)" ; + CALL BPXWDYN "FREE DD(TABLE)" ; + CALL BPXWDYN "FREE DD(MODEL)" ; + Call Submit_n_save_jobInfo ; + Message = JobData + MyRc = 8 + PACKAGE = PECB_PACKAGE_ID + MessageCode = 'U033' + Call SetExitReturnInfo + CALL BPXWDYN "FREE DD(TBLOUT) DELETE" + Return +Submit_n_save_jobInfo: /* submit CastPackageModel job and save job info */ + If TraceRc = 1 then Say 'Submit_n_save_jobInfo:' + Address TSO "PROFILE NOINTERCOM" /* turn off msg notific */ + CALL MSG "ON" + CALL OUTTRAP "out." + ADDRESS TSO "SUBMIT '"CastPackageJCL"'" ; + If RC > 4 then, + Do + MyRC = 8 + Message = 'Cannot find Element member to submit.' + Call SetExitReturnInfo + Exit(12) + End + CALL OUTTRAP "OFF" + Address TSO "PROFILE INTERCOM" /* turn on msg notific */ + JobData = Strip(out.1); + jobinfo = Word(JobData,2) ; + If jobinfo = 'JOB' then, + jobinfo = Word(JobData,3) ; + SelectJobName = Word(Translate(jobinfo,' ',')('),1) ; + SelectJobNumber = Word(Translate(jobinfo,' ',')('),2) ; + Return; +SetExitReturnInfo: + If TraceRc = 1 then Say 'SetExitReturnInfo: ' + hexAddress = D2X(Address_PECB_MESSAGE) + storrep = STORAGE(hexAddress,,Message) + hexAddress = D2X(Address_PECB_ERROR_MESS_LENGTH) + storrep = STORAGE(hexAddress,,'0084'X) + hexAddress = D2X(ADDRESS_PECB_MODS_MADE_TO_PREQ) + storrep = STORAGE(hexAddress,,'Y') + If MessageCode /= ' ' then, + Do + hexAddress = D2X(Address_PECB_MESSAGE_ID) + storrep = STORAGE(hexAddress,,MessageCode) + End +/* Set the return code for the exit */ +/* for PECB-NDVR-EXIT-RC */ + hexAddress = D2X(Address_PECB_NDVR_EXIT_RC) + If MyRc = 4 then, + storrep = STORAGE(hexAddress,,'00000004'X) + Else, + storrep = STORAGE(hexAddress,,'00000008'X) + RETURN ; diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/C1UEXTT7.cob b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/C1UEXTT7.cob new file mode 100644 index 0000000..15c39c8 --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/C1UEXTT7.cob @@ -0,0 +1,727 @@ + PROCESS DYNAM OUTDD(DISPLAYS) + IDENTIFICATION DIVISION. + PROGRAM-ID. C1UEXT07. + ***************************************************************** + * DESCRIPTION: THIS PGM IS CALLED for misc Package actions. + * It gathers Endevor info from the exit blocks * + * then calls REXX program C1UEXTR7. * + * Together they can force CAST actions to be in Batch. * + ***************************************************************** + ENVIRONMENT DIVISION. + INPUT-OUTPUT SECTION. + FILE-CONTROL. + ** + DATA DIVISION. + FILE SECTION. + + WORKING-STORAGE SECTION. + + COPY NOTIFYDS. + + 01 WS-VGET PIC X(8) VALUE 'VGET '. + 01 WS-PROFILE PIC X(8) VALUE 'PROFILE '. + 01 WS-ISPLINK PIC X(8) VALUE 'ISPLINK ' . + + 01 WS-C1BJC1-JOBCARD PIC X(80) . + 01 WS-C1BJC1 PIC X(08) VALUE '(C1BJC1)'. + + 01 WS-C1PJC1-JOBCARD PIC X(80) . + 01 WS-C1PJC1 PIC X(08) VALUE '(C1PJC1)'. + + 01 WS-CALLING-REASON PIC X(24). + + 01 WS-VARIABLES. + 03 WS-POINTER PIC 9(09) COMP. + 03 WS-WORK-ADDRESS-ADR PIC 9(09) COMP SYNC . + 03 WS-WORK-ADDRESS-PTR REDEFINES WS-WORK-ADDRESS-ADR + USAGE IS POINTER . + + 03 WS-PECB-REQUEST-RETURNCODE PIC 9999 . + 03 WS-PECB-NDVR-HIGH-RC PIC 9999 . + + 03 WS-DISPLAY-NUMBER-FOR4 PIC 9(04) . + 03 WS-DISPLAY-NUMBER-FOR9 PIC 9(09) . + 00490200 + 01 PGM PIC X(8). + 01 MYSMTP-MESSAGE PIC X(80). + 01 MYSMTP-USERID PIC X(8). + 01 MYSMTP-FROM PIC X(50). + 01 MYSMTP-SUBJECT PIC X(50). + 01 MYSMTP-TEXT. + 03 MYSMTP-COUNTER PIC 9(2). + 03 MYSMTP-MSG-TEXT. + 05 MYSMTP-LINE PIC X(133) OCCURS 99. + 01 MYSMTP-URL PIC X(1). + 01 MYSMTP-EMAIL-IDS. + 03 FILLER PIC X(09) + OCCURS 320 . + 03 FILLER PIC X(8). + 01 MYSMTP-EMAIL-ID-SIZE PIC 9(8). + + 01 WS-ADDRESSES. + 03 ADDRESS-MYSMTP-MESSAGE PIC 9(09) . + 03 ADDRESS-MYSMTP-USERID PIC 9(09) . + 03 ADDRESS-MYSMTP-FROM PIC 9(09) . + 03 ADDRESS-MYSMTP-SUBJECT PIC 9(09) . + 03 ADDRESS-MYSMTP-TEXT PIC 9(09) . + 03 ADDRESS-MYSMTP-URL PIC 9(09) . + 03 ADDRESS-MYSMTP-EMAIL-IDS PIC 9(09) . + 00510000 + 03 ADDRESS-PECB-NDVR-EXIT-RC PIC 9(09) . + 03 ADDRESS-PECB-MESSAGE-ID PIC 9(09) . + 03 ADDRESS-PECB-MESSAGE PIC 9(09) . + 03 ADDRESS-PECB-ERROR-MESS-LENGTH PIC 9(09) . + 03 ADDRESS-PECB-MODS-MADE-TO-PREQ PIC 9(09) . + 03 ADDRESS-PREQ-SHARE-ENABLED PIC 9(09) . + 03 ADDRESS-PREQ-BACKOUT-ENABLED PIC 9(09) . + + 01 BPXWDYN PIC X(8) VALUE 'BPXWDYN'. + 01 ALLOC-STRING. + 05 ALLOC-LENGTH PIC S9(4) BINARY VALUE 100. + 05 ALLOC-TEXT PIC X(100). + + 01 IRXJCL PIC X(6) VALUE 'IRXJCL'. + 01 IRXEXEC-PGM PIC X(08) VALUE 'IRXEXEC'. + + * + * DEFINE THE IRXEXEC DATA AREAS AND ARG BLOCKS + * + 77 WS-INX PIC 9(08) COMP . + 77 FLAGS PIC S9(8) BINARY. + 77 REXX-RETURN-CODE PIC S9(8) BINARY. + 77 DUMMY-ZERO PIC S9(8) BINARY. + 77 LPAR-ID PIC X(04). + 88 DO-NOT-PROCESS-LPAR VALUE 'SKIP'. + 77 ARG1 PIC X(16). + 77 UPDPRINT-FILE-STATUS PIC X(02). + 77 ARGUMENT-PTR POINTER. + 77 EXECBLK-PTR POINTER. + 77 ARGTABLE-PTR POINTER. + 77 EVALBLK-PTR POINTER. + 77 TEMP-PTR POINTER. + + 01 EXECBLK. + 05 EXECBLK-ACRYN PIC X(08) VALUE 'IRXEXECB'. + 05 EXECBLK-LENGTH PIC S9(8) BINARY + VALUE 48. + 05 EXECBLK-RESERVED PIC S9(8) BINARY + VALUE 0. + 05 EXECBLK-MEMBER PIC X(08) VALUE 'C1UEXTR7'. + 05 EXECBLK-DDNAME PIC X(08) VALUE 'REXFILE7'. + 05 EXECBLK-SUBCOM PIC X(08) VALUE SPACES. + 05 EXECBLK-DSNPTR POINTER VALUE NULL. + 05 EXECBLK-DSNLEN PIC 9(04) COMP + VALUE 0. + + 01 EVALBLK. + 05 EVALBLK-EVPAD1 PIC S9(8) BINARY + VALUE 0. + 05 EVALBLK-EVSIZE PIC S9(8) BINARY + VALUE 34. + 05 EVALBLK-EVLEN PIC S9(8) BINARY + VALUE 0. + 05 EVALBLK-EVPAD2 PIC S9(8) BINARY + VALUE 0. + 05 EVALBLK-EVDATA PIC X(256). + + 01 ARGUMENT. + 02 ARGUMENT-1 OCCURS 1 TIMES. + 05 ARGSTRING-PTR POINTER. + 05 ARGSTRING-LENGTH PIC S9(8) BINARY. + 02 ARGSTRING-LAST1 PIC S9(8) BINARY + VALUE -1. + 02 ARGSTRING-LAST2 PIC S9(8) BINARY + VALUE -1. + + * The block of data below can be used with either an + * IRXJCL or IRXEXEC call to the rexx program C1UEXTR7. + * IRXJCL is used when running in batch (batch CAST) . + * IRXEXEC is used when running in foreground (CAST or APPROVE). + 01 PKG-C1UEXTR7-PARMS-IRXJCL. + 02 PKG-C1UEXTR7-PARMS-IRXJCL-TOP. + 03 PARM-LENGTH PIC X(2) VALUE X'0BC1'. + 03 REXX-NAME PIC X(8) VALUE 'C1UEXTR7'. + 03 FILLER PIC X(1) VALUE SPACE . + 02 PKG-C1UEXTR7-PARMS-IRXEXEC. + 03 WS-REXX-STATEMENTS PIC X(3000). + + LINKAGE SECTION. + COPY PKGXBLKS. + + PROCEDURE DIVISION USING + PACKAGE-EXIT-BLOCK + PACKAGE-REQUEST-BLOCK + PACKAGE-EXIT-HEADER-BLOCK + PACKAGE-EXIT-FILE-BLOCK + PACKAGE-EXIT-ACTION-BLOCK + PACKAGE-EXIT-APPROVER-MAP + PACKAGE-EXIT-BACKOUT-BLOCK + PACKAGE-EXIT-SHIPMENT-BLOCK + PACKAGE-EXIT-SCL-BLOCK. + **** + IF PECB-USER-BATCH-JOBNAME(1:7) NOT = 'IBMUSER' AND + PECB-USER-BATCH-JOBNAME(1:7) NOT = 'PL05958' + GOBACK. + **** + +********* DISPLAY 'C1UEXT07: GOT INTO C1UEXTT7'. +********* MOVE PECB-FUNCTION-CODE TO WS-DISPLAY-NUMBER-FOR9. +********* DISPLAY 'PECB-FUNCTION-CODE=' WS-DISPLAY-NUMBER-FOR9. + + IF SETUP-EXIT-OPTIONS + MOVE ZERO TO PECB-UEXIT-HOLD-FIELD +********* to enforce package create rules + MOVE 'Y' TO PECB-BEFORE-CREATE-BLD + MOVE 'Y' TO PECB-BEFORE-CREATE-COPY + MOVE 'Y' TO PECB-BEFORE-CREATE-EDIT + MOVE 'Y' TO PECB-BEFORE-CREATE-IMPT + MOVE 'Y' TO PECB-BEFORE-REV-APPR +********* to enforce Approver Group Sequencing + MOVE 'Y' TO PECB-AFTER-REV-APPR +********* to enforce package backout = Y + MOVE 'Y' TO PECB-BEFORE-CAST +********* to enforce Approver Group Sequencing + MOVE 'Y' TO PECB-AFTER-CAST + MOVE 'Y' TO PECB-MID-CAST +********* MOVE 'Y' TO PECB-BEFORE-MOD-IMPT +********* MOVE 'Y' TO PECB-AFTER-RESET +********* MOVE 'Y' TO PECB-AFTER-DELETE + MOVE ZEROS TO RETURN-CODE + GOBACK. + + MOVE 0 TO PECB-NDVR-EXIT-RC. + MOVE SPACES TO WS-REXX-STATEMENTS . + +********* If just starting out, request Approver Group info + IF PECB-REQUEST-RETURNCODE = 0 AND PECB-AFTER AND + (CAST-PACKAGE OR REVIEW-PACKAGE) + PERFORM 1000-ALLOCATE-REXFILE + MOVE 'Y' TO PECB-REQ-APPROVER-REC + GOBACK + ELSE +********* If Before the CAST, just pass Package info to the REXX + IF (PECB-BEFORE OR PECB-MID) AND + (CREATE-PACKAGE OR CAST-PACKAGE) + IF CREATE-PACKAGE + MOVE 'Before CREATE' TO WS-CALLING-REASON + ELSE + MOVE 'Before CAST' TO WS-CALLING-REASON + END-IF + PERFORM 1000-ALLOCATE-REXFILE + PERFORM 0500-CALL-C1UEXTR7-REXX + PERFORM 2000-FREE-REXFILES + GOBACK + END-IF . + +********* If we just received an Appprover Group block, +********* pass it to the REXX and ask for more... + IF PECB-SUCCESSFUL-RECORD-SENT + MOVE PAPP-SEQUENCE-NUMBER TO WS-DISPLAY-NUMBER-FOR4 + MOVE SPACES TO WS-CALLING-REASON + STRING 'Approver Group #' + WS-DISPLAY-NUMBER-FOR4 + DELIMITED BY SIZE + INTO WS-CALLING-REASON + END-STRING + PERFORM 0500-CALL-C1UEXTR7-REXX + MOVE 'Y' TO PECB-REQ-APPROVER-REC + GOBACK + END-IF . + +********* Endevor says 'no more Appprover Group blocks' +********* tell REXX and let it decide on email + IF PECB-END-OF-FILE-FOR-REC-TYP OR + PECB-NO-RECORDS-FOUND + MOVE 'NO MORE Approver Grps ' TO WS-CALLING-REASON + PERFORM 0500-CALL-C1UEXTR7-REXX + IF MYSMTP-COUNTER NUMERIC AND + MYSMTP-COUNTER GREATER THAN '00' AND + MYSMTP-EMAIL-IDS(1:1) GREATER THAN SPACE + MOVE 'BC1PMLIF' TO PGM + PERFORM 0900-SEND-EMAILS + END-IF + PERFORM 2000-FREE-REXFILES + GOBACK + END-IF . + + + 0100-MAIN-EXIT. + GOBACK. + + 0500-CALL-C1UEXTR7-REXX. + + * Give addresses of updatable fields to the REXX. + * MAKES A CALL TO THE REXX ROUTINE C1UEXTR7. + + SET WS-WORK-ADDRESS-PTR TO + ADDRESS OF MYSMTP-MESSAGE . + MOVE WS-WORK-ADDRESS-ADR + TO ADDRESS-MYSMTP-MESSAGE. + + SET WS-WORK-ADDRESS-PTR TO + ADDRESS OF MYSMTP-USERID . + MOVE WS-WORK-ADDRESS-ADR + TO ADDRESS-MYSMTP-USERID . + + SET WS-WORK-ADDRESS-PTR TO + ADDRESS OF MYSMTP-FROM . + MOVE WS-WORK-ADDRESS-ADR + TO ADDRESS-MYSMTP-FROM . + + SET WS-WORK-ADDRESS-PTR TO + ADDRESS OF MYSMTP-SUBJECT . + MOVE WS-WORK-ADDRESS-ADR + TO ADDRESS-MYSMTP-SUBJECT. + + SET WS-WORK-ADDRESS-PTR TO + ADDRESS OF MYSMTP-TEXT . + MOVE WS-WORK-ADDRESS-ADR + TO ADDRESS-MYSMTP-TEXT . + + SET WS-WORK-ADDRESS-PTR TO + ADDRESS OF MYSMTP-URL . + MOVE WS-WORK-ADDRESS-ADR + TO ADDRESS-MYSMTP-URL . + + MOVE SPACES TO MYSMTP-EMAIL-IDS . + + SET WS-WORK-ADDRESS-PTR TO + ADDRESS OF MYSMTP-EMAIL-IDS . + MOVE WS-WORK-ADDRESS-ADR + TO ADDRESS-MYSMTP-EMAIL-IDS . + SET WS-WORK-ADDRESS-PTR TO + ADDRESS OF MYSMTP-EMAIL-ID-SIZE . + COMPUTE MYSMTP-EMAIL-ID-SIZE = + WS-WORK-ADDRESS-ADR - 4 - + ADDRESS-MYSMTP-EMAIL-IDS . + + + SET WS-WORK-ADDRESS-PTR TO + ADDRESS OF PECB-NDVR-EXIT-RC . + MOVE WS-WORK-ADDRESS-ADR + TO ADDRESS-PECB-NDVR-EXIT-RC. + + SET WS-WORK-ADDRESS-PTR TO + ADDRESS OF PECB-MESSAGE . + MOVE WS-WORK-ADDRESS-ADR + TO ADDRESS-PECB-MESSAGE . + + SET WS-WORK-ADDRESS-PTR TO + ADDRESS OF PECB-ERROR-MESS-LENGTH . + MOVE WS-WORK-ADDRESS-ADR + TO ADDRESS-PECB-ERROR-MESS-LENGTH. + + SET WS-WORK-ADDRESS-PTR TO + ADDRESS OF PECB-MODS-MADE-TO-PREQ . + MOVE WS-WORK-ADDRESS-ADR + TO ADDRESS-PECB-MODS-MADE-TO-PREQ. + + SET WS-WORK-ADDRESS-PTR TO + ADDRESS OF PECB-MESSAGE-ID. + MOVE WS-WORK-ADDRESS-ADR + TO ADDRESS-PECB-MESSAGE-ID . + + SET WS-WORK-ADDRESS-PTR TO + ADDRESS OF PREQ-SHARE-ENABLED. + MOVE WS-WORK-ADDRESS-ADR + TO ADDRESS-PREQ-SHARE-ENABLED . + + SET WS-WORK-ADDRESS-PTR TO + ADDRESS OF PREQ-BACKOUT-ENABLED. + MOVE WS-WORK-ADDRESS-ADR + TO ADDRESS-PREQ-BACKOUT-ENABLED . + + MOVE PECB-REQUEST-RETURNCODE TO + WS-PECB-REQUEST-RETURNCODE. + + MOVE PECB-NDVR-HIGH-RC TO + WS-PECB-NDVR-HIGH-RC . + + ***** + ***** / Convert COBOL exit block Datanames into Rexx \ + ***** + ***** + MOVE 1 TO WS-POINTER. + + STRING + 'PECB_PACKAGE_ID = "' PECB-PACKAGE-ID '";' + 'PECB_FUNCTION_LITERAL="' PECB-FUNCTION-LITERAL '";' + 'PECB_SUBFUNC_LITERAL="' PECB-SUBFUNC-LITERAL '";' + 'PECB_BEF_AFTER_LITERAL="' PECB-BEF-AFTER-LITERAL '";' + 'PECB_USER_BATCH_JOBNAME="' PECB-USER-BATCH-JOBNAME '";' + 'PREQ_PKG_CAST_COMPVAL="' PREQ-PKG-CAST-COMPVAL '";' + 'PHDR_PKG_SHR_OPTION ="' PHDR-PKG-SHR-OPTION '";' + 'PHDR_PKG_ENV ="' PHDR-PKG-ENV '";' + 'PHDR_PKG_STGID ="' PHDR-PKG-STGID '";' + 'PECB_MODE = "' PECB-MODE '";' + 'PECB_AUTOCAST ="' PECB-AUTOCAST '";' + 'PECB_ACT_REC_EXIST_FLAG="' PECB-ACT-REC-EXIST-FLAG '";' + 'PECB_APP_REC_EXIST_FLAG="' PECB-APP-REC-EXIST-FLAG '";' + 'PECB_BAC_REC_EXIST_FLAG="' PECB-BAC-REC-EXIST-FLAG '";' + 'PECB_REQUEST_RETURNCODE=' WS-PECB-REQUEST-RETURNCODE ';' + 'PECB_NDVR_HIGH_RC = ' WS-PECB-NDVR-HIGH-RC ';' + 'PREQ_BACKOUT_ENABLED="' PREQ-BACKOUT-ENABLED '";' + 'Address_PREQ_BACKOUT_ENABLED=' + ADDRESS-PREQ-BACKOUT-ENABLED ';' + 'PREQ_SHARE_ENABLED="' PREQ-SHARE-ENABLED '";' + 'Address_PREQ_SHARE_ENABLED=' + ADDRESS-PREQ-SHARE-ENABLED ';' + 'Address_PECB_MODS_MADE_TO_PREQ=' + ADDRESS-PECB-MODS-MADE-TO-PREQ ';' + 'Address_PECB_NDVR_EXIT_RC=' + ADDRESS-PECB-NDVR-EXIT-RC ';' + 'Address_PECB_MESSAGE_ID=' ADDRESS-PECB-MESSAGE-ID ';' + 'Address_PECB_ERROR_MESS_LENGTH = ' + ADDRESS-PECB-ERROR-MESS-LENGTH ';' + 'Address_PECB_MESSAGE = ' ADDRESS-PECB-MESSAGE ';' + 'Address_MYSMTP_MESSAGE=' ADDRESS-MYSMTP-MESSAGE ';' + 'Address_MYSMTP_USERID =' ADDRESS-MYSMTP-USERID ';' + 'Address_MYSMTP_FROM =' ADDRESS-MYSMTP-FROM ';' + 'Address_MYSMTP_SUBJECT=' ADDRESS-MYSMTP-SUBJECT ';' + 'Address_MYSMTP_TEXT =' ADDRESS-MYSMTP-TEXT ';' + 'Address_MYSMTP_URL =' ADDRESS-MYSMTP-URL ';' + 'Address_MYSMTP_EMAIL_IDS=' + ADDRESS-MYSMTP-EMAIL-IDS ';' + 'MYSMTP_EMAIL_ID_SIZE=' + MYSMTP-EMAIL-ID-SIZE ';' + DELIMITED BY SIZE + INTO WS-REXX-STATEMENTS + WITH POINTER WS-POINTER . + +********* For these text fields, make sure none use a double quote +********* character. This ensures the integrity of the REXX + IF REVIEW-PACKAGE OR + (CAST-PACKAGE AND PECB-AFTER) + MOVE PAPP-QUORUM-COUNT TO WS-DISPLAY-NUMBER-FOR4 + STRING + 'CALL_REASON="' WS-CALLING-REASON '";' + 'PAPP_GROUP_NAME ="' PAPP-GROUP-NAME '";' + 'PAPP_GROUP_NAME ="' PAPP-GROUP-NAME '";' + 'PAPP_ENVIRONMENT="' PAPP-ENVIRONMENT '";' + 'PAPP_QUORUM_COUNT="' WS-DISPLAY-NUMBER-FOR4 '";' + 'PAPP_APPROVER_FLAG="' PAPP-APPROVER-FLAG '";' + 'PAPP_APPR_GRP_TYPE="' PAPP-APPR-GRP-TYPE '";' + 'PAPP_APPR_GRP_DISQ="' PAPP-APPR-GRP-DISQ '";' + DELIMITED BY SIZE + 'PAPP_APPROVAL_IDS= "' + DELIMITED BY SIZE + INTO WS-REXX-STATEMENTS + WITH POINTER WS-POINTER + END-STRING + PERFORM VARYING WS-INX FROM 1 BY 1 UNTIL + WS-INX GREATER THAN PAPP-APPROVER-NUMBER + STRING PAPP-APPROVAL-ID(WS-INX) ' ' + DELIMITED BY SIZE + INTO WS-REXX-STATEMENTS + WITH POINTER WS-POINTER + END-STRING + END-PERFORM + STRING '";' + 'PAPP_APPROVAL_FLAGS= "' + DELIMITED BY SIZE + INTO WS-REXX-STATEMENTS + WITH POINTER WS-POINTER + END-STRING + + PERFORM VARYING WS-INX FROM 1 BY 1 UNTIL + WS-INX GREATER THAN PAPP-APPROVER-NUMBER + STRING PAPP-APPROVAL-FLAG(WS-INX) ' ' + DELIMITED BY SIZE + INTO WS-REXX-STATEMENTS + WITH POINTER WS-POINTER + END-STRING + END-PERFORM + STRING '";' + DELIMITED BY SIZE + INTO WS-REXX-STATEMENTS + WITH POINTER WS-POINTER + END-STRING + END-IF. + +******* Replace any double quote characters in data to be passed + IF CAST-PACKAGE + INSPECT PREQ-PACKAGE-COMMENT REPLACING ALL '"' BY X'7D' + INSPECT PHDR-PKG-NOTE1 REPLACING ALL '"' BY X'7D' + INSPECT PHDR-PKG-NOTE2 REPLACING ALL '"' BY X'7D' + INSPECT PHDR-PKG-NOTE3 REPLACING ALL '"' BY X'7D' + INSPECT PHDR-PKG-NOTE4 REPLACING ALL '"' BY X'7D' + INSPECT PHDR-PKG-NOTE5 REPLACING ALL '"' BY X'7D' + INSPECT PHDR-PKG-NOTE6 REPLACING ALL '"' BY X'7D' + INSPECT PHDR-PKG-NOTE7 REPLACING ALL '"' BY X'7D' + INSPECT PHDR-PKG-NOTE8 REPLACING ALL '"' BY X'7D' + STRING + 'CALL_REASON="' WS-CALLING-REASON '";' + 'PREQ_PACKAGE_COMMENT = "' PREQ-PACKAGE-COMMENT '";' + 'PHDR_PACKAGE_TYPE = "' PHDR-PACKAGE-TYPE '";' + 'PHDR_PACKAGE_STATUS = "' PHDR-PACKAGE-STATUS '";' + 'PHDR_PKG_BACKOUT_STATUS="' PHDR-PKG-BACKOUT-STATUS '";' + 'PHDR_PKG_CREATE_USER = "' PHDR-PKG-CREATE-USER '";' + 'PHDR_PKG_CAST_USER = "' PHDR-PKG-CAST-USER '";' + 'PHDR_PKG_NOTE1 = "' PHDR-PKG-NOTE1 '";' + 'PHDR_PKG_NOTE2 = "' PHDR-PKG-NOTE2 '";' + 'PHDR_PKG_NOTE3 = "' PHDR-PKG-NOTE3 '";' + 'PHDR_PKG_NOTE4 = "' PHDR-PKG-NOTE4 '";' + 'PHDR_PKG_NOTE5 = "' PHDR-PKG-NOTE5 '";' + 'PHDR_PKG_NOTE6 = "' PHDR-PKG-NOTE6 '";' + 'PHDR_PKG_NOTE7 = "' PHDR-PKG-NOTE7 '";' + 'PHDR_PKG_NOTE8 = "' PHDR-PKG-NOTE8 '";' + 'PHDR_PKG_CAST_COMPVAL = "' PHDR-PKG-CAST-COMPVAL '";' + DELIMITED BY SIZE + INTO WS-REXX-STATEMENTS + WITH POINTER WS-POINTER + END-STRING + END-IF. + + ***** \ Convert COBOL exit block Datanames into Rexx / + ***** + + MOVE 'C1UEXTR7' TO EXECBLK-MEMBER . + MOVE 3000 TO ARGSTRING-LENGTH(1) + + IF PECB-TSO-MODE + CALL 'SET-ARG1-POINTER' USING ARGUMENT-PTR + PKG-C1UEXTR7-PARMS-IRXEXEC + PERFORM 0800-REXX-CALL-VIA-IRXEXEC + MOVE 0 TO PECB-NDVR-HIGH-RC + ELSE +********* DISPLAY 'C1UEXT07: Running in Batch ' + CALL IRXJCL USING PKG-C1UEXTR7-PARMS-IRXJCL . + + IF RETURN-CODE NOT = 0 + DISPLAY 'C1UEXT07: BAD CALL TO IRXJCL - RC = ' + RETURN-CODE + END-IF + + MOVE 0 TO RETURN-CODE + . + 0800-REXX-CALL-VIA-IRXEXEC. + *--- GET THE ADDRESS OF THE ARGUMENT(S) TO BE PASSED TO IXREXEC + *--- AND LOAD INTO THE ARGUMENT TABLES +******* IF PECB-USER-BATCH-JOBNAME(1:7) = 'PL05958' +******* DISPLAY 'C1UEXT07: SETTING UP REXX EXECUTION' +******* ' FOR PACKAGE 'PECB-PACKAGE-ID +******* END-IF . + SET ARGSTRING-PTR (1) TO ARGUMENT-PTR . + CALL 'SET-ARGUMENT-POINTER' USING ARGTABLE-PTR + ARGUMENT . + CALL 'SET-EXECBLK-POINTER' USING EXECBLK-PTR + EXECBLK . + CALL 'SET-EVALBLK-POINTER' USING EVALBLK-PTR + EVALBLK . + *--- SET FLAGS TO HEX 20000000 + * I.E. EXEC INVOKED AS SUBROUTINE + MOVE 536870912 TO FLAGS + MOVE 0 TO REXX-RETURN-CODE . + +********* DISPLAY 'C1UEXT07: CALLING IRXEXC ' +********* PECB-PACKAGE-ID . + *--- CALL THE REXX EXEC --- + CALL IRXEXEC-PGM USING EXECBLK-PTR + ARGTABLE-PTR + FLAGS + DUMMY-ZERO + DUMMY-ZERO + EVALBLK-PTR + DUMMY-ZERO + DUMMY-ZERO + DUMMY-ZERO . + + IF REXX-RETURN-CODE NOT = 0 + DISPLAY 'C1UEXT07: IRXEXEC RETURN CODE = ' + REXX-RETURN-CODE + END-IF + + CANCEL IRXEXEC-PGM + . + + 0900-SEND-EMAILS. + +********** DISPLAY 'C1UEXTT7: MYSMTP-MESSAGE=' MYSMTP-MESSAGE . +********** DISPLAY 'C1UEXTT7: MYSMTP-FROM =' MYSMTP-FROM . +********** DISPLAY 'C1UEXTT7: MYSMTP-SUBJECT=' MYSMTP-SUBJECT . +********** DISPLAY 'C1UEXTT7: MYSMTP-TEXT ' MYSMTP-TEXT(1:80). + + MOVE 1 TO WS-POINTER. + + PERFORM UNTIL + MYSMTP-EMAIL-IDS(WS-POINTER:1) = LOW-VALUES OR + MYSMTP-EMAIL-IDS(WS-POINTER:8) + LESS THAN OR EQUAL SPACES OR + WS-POINTER GREATER THAN OR EQUAL + MYSMTP-EMAIL-ID-SIZE + MOVE SPACES TO MYSMTP-USERID + UNSTRING MYSMTP-EMAIL-IDS + DELIMITED BY SPACE + INTO MYSMTP-USERID + WITH POINTER WS-POINTER + END-UNSTRING + + IF MYSMTP-USERID NOT = SPACES +********** DISPLAY 'C1UEXTT7: Emailing ' MYSMTP-USERID +********** ' WS-POINTER=' WS-POINTER ' ' +********** MYSMTP-EMAIL-IDS(WS-POINTER:60) + CALL PGM USING MYSMTP-MESSAGE + MYSMTP-USERID + MYSMTP-FROM + MYSMTP-SUBJECT + MYSMTP-TEXT + MYSMTP-URL + END-IF + + IF RETURN-CODE > 0 + DISPLAY 'CALL BC1PMLIF RC = ' RETURN-CODE + DISPLAY MYSMTP-MESSAGE + END-IF +********** ADD 1 TO WS-POINTER + END-PERFORM. + + *----------------------------------------------------------------- + + 1000-ALLOCATE-REXFILE. + + MOVE SPACES TO ALLOC-TEXT. + + IF PECB-BATCH-MODE + STRING 'ALLOC DD(SYSEXEC) ', + 'DA(YOURSITE.NDVR.REXX)' + DELIMITED BY SIZE + ' SHR REUSE' + DELIMITED BY SIZE + INTO ALLOC-TEXT + END-STRING + ELSE + STRING 'ALLOC DD(REXFILE7) ', + 'DA(YOURSITE.NDVR.REXX)' + DELIMITED BY SIZE + ' SHR REUSE' + DELIMITED BY SIZE + INTO ALLOC-TEXT + END-STRING + END-IF. + + PERFORM 9000-DYNAMIC-ALLOC-DEALLOC . + +********** MOVE 'CONCAT DDLIST(REXFILE,REXFILE2)' +********** TO ALLOC-TEXT . +********** +********** PERFORM 9000-DYNAMIC-ALLOC-DEALLOC . + + ***************************************************************** + ** DYNAMICALLY DE-ALLOCATE UNNEEDED REXX FILES + ***************************************************************** + 2000-FREE-REXFILES. + + MOVE SPACES TO ALLOC-TEXT. + + IF PECB-BATCH-MODE + MOVE 'FREE DD(SYSEXEC)' TO ALLOC-TEXT + ELSE + MOVE 'FREE DD(REXFILE7)' TO ALLOC-TEXT + END-IF. + + + PERFORM 9000-DYNAMIC-ALLOC-DEALLOC + . + ***************************************************************** + ** CALL BPXWDYN TO PREFORM REQUIRED REXX FUNCTIONS + ***************************************************************** + 9000-DYNAMIC-ALLOC-DEALLOC. + + CALL BPXWDYN USING ALLOC-STRING + + IF RETURN-CODE NOT = ZERO + DISPLAY 'C1UEXT07: ALLOCATION FAILED: RETURN CODE = ' + RETURN-CODE + DISPLAY ALLOC-TEXT + END-IF + +********* DISPLAY ALLOC-TEXT . + MOVE SPACES TO ALLOC-TEXT + . + + + ****************************************************************** + * BEGIN NESTED PROGRAMS USED TO SET THE POINTERS OF DATA AREAS + * THAT ARE BEING PASSED TO IRXEXEC SO THAT A REXX ROUTINE CAN + * PASS DATA (OTHER THAN A RETURN CODE) BACK TO A COBOL PROGRAM. + ****************************************************************** + + ******** SET-ARG1-POINTER ******** + IDENTIFICATION DIVISION. + PROGRAM-ID. SET-ARG1-POINTER. + ENVIRONMENT DIVISION. + DATA DIVISION. + WORKING-STORAGE SECTION. + LINKAGE SECTION. + 77 ARG-PTR POINTER. + 77 ARG1 PIC X(16). + PROCEDURE DIVISION USING ARG-PTR + ARG1. + SET ARG-PTR TO ADDRESS OF ARG1 + GOBACK. + END PROGRAM SET-ARG1-POINTER. + + ******** SET-ARGUMENT-POINTER ******** + IDENTIFICATION DIVISION. + PROGRAM-ID. SET-ARGUMENT-POINTER. + ENVIRONMENT DIVISION. + DATA DIVISION. + WORKING-STORAGE SECTION. + LINKAGE SECTION. + 77 ARGTABLE-PTR POINTER. + 01 ARGUMENT. + 02 ARGUMENT-1 OCCURS 1 TIMES. + 05 ARGSTRING-PTR POINTER. + 05 ARGSTRING-LENGTH PIC S9(8) BINARY. + 02 ARGSTRING-LAST1 PIC S9(8) BINARY. + 02 ARGSTRING-LAST2 PIC S9(8) BINARY. + PROCEDURE DIVISION USING ARGTABLE-PTR + ARGUMENT. + SET ARGTABLE-PTR TO ADDRESS OF ARGUMENT + GOBACK. + END PROGRAM SET-ARGUMENT-POINTER. + + ******** SET-EXECBLK-POINTER ******** + IDENTIFICATION DIVISION. + PROGRAM-ID. SET-EXECBLK-POINTER. + ENVIRONMENT DIVISION. + DATA DIVISION. + WORKING-STORAGE SECTION. + LINKAGE SECTION. + 77 EXECBLK-PTR POINTER. + 01 EXECBLK. + 03 EXECBLK-ACRYN PIC X(8). + 03 EXECBLK-LENGTH PIC 9(4) COMP. + 03 EXECBLK-RESERVED PIC 9(4) COMP. + 03 EXECBLK-MEMBER PIC X(8). + 03 EXECBLK-DDNAME PIC X(8). + 03 EXECBLK-SUBCOM PIC X(8). + 03 EXECBLK-DSNPTR POINTER. + 03 EXECBLK-DSNLEN PIC 9(4) COMP. + PROCEDURE DIVISION USING EXECBLK-PTR + EXECBLK. + SET EXECBLK-PTR TO ADDRESS OF EXECBLK + GOBACK. + END PROGRAM SET-EXECBLK-POINTER. + + ******** SET-EVALBLK-POINTER ******** + IDENTIFICATION DIVISION. + PROGRAM-ID. SET-EVALBLK-POINTER. + ENVIRONMENT DIVISION. + DATA DIVISION. + WORKING-STORAGE SECTION. + LINKAGE SECTION. + 77 EVALBLK-PTR POINTER. + 01 EVALBLK. + 03 EVALBLK-EVPAD1 PIC 9(4) COMP. + 03 EVALBLK-EVSIZE PIC 9(4) COMP. + 03 EVALBLK-EVLEN PIC 9(4) COMP. + 03 EVALBLK-EVPAD2 PIC 9(4) COMP. + 03 EVALBLK-EVDATA PIC X(256). + PROCEDURE DIVISION USING EVALBLK-PTR + EVALBLK. + SET EVALBLK-PTR TO ADDRESS OF EVALBLK + GOBACK. + END PROGRAM SET-EVALBLK-POINTER. + *--- END OF MAIN PROGRAM + END PROGRAM C1UEXT07. diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/CAST#JCL.jcl b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/CAST#JCL.jcl new file mode 100644 index 0000000..7a8087b --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/CAST#JCL.jcl @@ -0,0 +1,22 @@ +//&Jobname JOB (&MyAccountingCode), +// 'CAST PACKAGE',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID +//*==================================================================* +// JCLLIB ORDER=(&MySEN2Library, +// &MySENULibrary) +//*==================================================================* +//*===== If you want all package CAST actions to be performed * +//*===== in batch, then set the Force_CAST_in_Batch option in * +//*===== C1UEXTR7, and this JCL will submit a batch CAST. * +//*==================================================================* +//ENBP1000 EXEC PGM=NDVRC1,PARM=ENBP1000, CAST#JCL +// DYNAMNBR=1500,REGION=4096K +// INCLUDE MEMBER=STEPLIB +//*C1UEXTR7 DD DUMMY <- Trace REXX exit +//ENPSCLIN DD * + CAST PACKAGE '&PECB_PACKAGE_ID'. +//C1MSGS1 DD SYSOUT=* +//C1MSGS2 DD SYSOUT=* +//REPORT DD SYSOUT=* +//SYSUDUMP DD SYSOUT=* +//SYMDUMP DD DUMMY +//JCLOUT DD DUMMY diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/CASTPKGE.skl b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/CASTPKGE.skl new file mode 100644 index 0000000..ae18cb6 --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/CASTPKGE.skl @@ -0,0 +1,22 @@ +//&Jobname JOB (&MyAccountingCode), +// 'CAST PACKAGE',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID +//*==================================================================* +// JCLLIB ORDER=(&MySEN2Library, +// &MySENULibrary) +//*==================================================================* +//*===== If you want all package CAST actions to be performed * +//*===== in batch, then set the Force_CAST_in_Batch option in * +//*===== C1UEXTR7, and this JCL will submit a batch CAST. * +//*==================================================================* +//ENBP1000 EXEC PGM=NDVRC1,PARM=ENBP1000, CAST#JCL +// DYNAMNBR=1500,REGION=4096K +// INCLUDE MEMBER=STEPLIB +//*C1UEXTR7 DD DUMMY <- Trace REXX exit +//ENPSCLIN DD * + CAST PACKAGE '&PECB_PACKAGE_ID'. +//C1MSGS1 DD SYSOUT=* +//C1MSGS2 DD SYSOUT=* +//REPORT DD SYSOUT=* +//SYSUDUMP DD SYSOUT=* +//SYMDUMP DD DUMMY +//JCLOUT DD DUMMY diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/FTP#INC.skl b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/FTP#INC.skl new file mode 100644 index 0000000..db8835e --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/FTP#INC.skl @@ -0,0 +1,15 @@ +//*---------- +//FTP1 DD *,SYMBOLS=JCLONLY FTP#INC + OPEN '&IPADDRSS' + ASCII +//FTP2 DD * <- All kinds of Stage info FTP#INC + PUT '&Dataset(&Member)' + + &Member.&extension +//FTP2XX DD * <- All kinds of Stage info **NOT USED** FTP#INC + PUT '&Dataset(&Member)' + + \&Folder\&Member.&extension +//FTP3 DD * <- All kinds of Stage info FTP#INC + PUT '&SonarWorkfile(TRANSMIT)' + + &uniqueName.lst + QUIT +//*---------- diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/FTP#RUN.skl b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/FTP#RUN.skl new file mode 100644 index 0000000..388f50f --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/FTP#RUN.skl @@ -0,0 +1,10 @@ +//*================================================================ +//FTP#RUN EXEC PGM=FTP,COND=(4,LT) FTP#RUN +//ABNLIGNR DD DUMMY +//SYSPRINT DD SYSOUT=* +//SYSABEND DD SYSOUT=* +//NETRC DD DISP=SHR,DSN=&SYSUID..ENDEVOR.NETRC(SHIPPING) +//SYSOUT DD SYSOUT=* +//OUTPUT DD SYSOUT=* +//INPUT DD * FTP#RUN +//*================================================================ diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/README.md b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/README.md new file mode 100644 index 0000000..5f8bf08 --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/README.md @@ -0,0 +1,65 @@ +# SonarQube Interface to Endevor + +Items in this folder provide an example method for interfacing SonarQube with Endevor. They allow Endevor to initiate a SonarQube analysis for an Endevor package, receive the quality gates response from the SonarQube analysis, and pass or fail the CAST of the package depending on the results. + +These samples are provided as is and are not officially supported (see [license](https://github.com/BroadcomMFD/broadcom-product-scripts/blob/main/LICENSE +) for more information). + +Features of this solution are easily tailorable to the requirements at your site. By default they include: + +1. During a package CAST, an analysis of the pckage content and package notes is done. + - It is determined whether the Package has at least one COBOL element. Element types of COB* or CBL* make the determination, but you can designate your own manner of recognition. + - If any of the Package note lines can begin with the text "BYPASS SONARQUBE", no SonarQube analysis will be done. If it becomes necessary to bypass the SonarQube processing, then a simple update of the package notes will bypass the SonarQube analysis. +2. If package contains COBOL elements, and the BYPASS is not selected, and the package is being CAST in TSO foreground, then the CAST action is resubmitted in Batch. Since it may be necessary to wait for time-consuming actions to complete, it is best for this process to run in batch. +3. All COBOL programs in the package are identified, and ACM queries are used for identifying input components. Input components such as copybooks, do not need to be included in the package. Rather, the ACM information for packaged COBOL elements will bring copybooks into the SonarQube analysis. +4. Packaged COBOL elements are RETRIEVEd into a PDS. +5. A separate (second) JOB is constructed and submitted. The steps of the separate job include: + - Reports back to the Endevor exit (running as job #1 doing a CAST) that the second job is running + - COBOL and copybook members are transmittted to the SonarQube server. Cobol members are transmitted from the RETRIEVE dataset. Copybook members are transmitted from datasets named in the ACM references. + - Reports back to the Endevor exit that the member transmissions are completed + - Executes a SonarQube analysis. + - Transmits the SonarQube results back to the site running the Endevor CAST. + +6. The Endevor exit waits for confirmation that the separate job is running, and displays messages accordingly +7. The Endevor exit waits for confirmation that the file transmissions are done, and displays messages accordingly. +8. The Endevor exit waits for the return of the SonarQube analysis, and displays messages accordingly. +9. If any of the expected results are not returned, or the analysis indicates a code analysis failure, the package CAST is made to Fail. + +Processing logic is primarily found in REXX, JCL and Python members. The Python member orchestrates the SonarQube activity. File transmissions are performed using XCOM, in these examples, but they easily be swapped out for members that use your transmission tool. + + + +Some supporting items are not found in this folder, since they are utilities, or already contribute to other solutions. They can be found in other locations of this GitHub, including: + +**[@SITE.rex](https://github.com/BroadcomMFD/broadcom-product-scripts/blob/main/endevor/Field-Developed-Programs/Package-Automation/%40site.rex)** the member to be renamed with an "@" and your lpar name. Its content has Lpar-specific details, allowing other software items to be void of details, and able to run anywhere unchanged. See the description for **[@siteMult.rex](https://github.com/BroadcomMFD/broadcom-product-scripts/tree/main/endevor/Shipments-for-Multiple-Destinations%20(zowe))** + + +**[BUMPJOB.rex](https://github.com/BroadcomMFD/broadcom-product-scripts/blob/SonarQube-Interface-with-Endevor/endevor/Field-Developed-Programs/Miscellaneous-items/BUMPJOB.rex)** for bumping an existing jobname to render a new job name + +**[GETACCT.rex](https://github.com/BroadcomMFD/broadcom-product-scripts/blob/main/endevor/Automated-Test-Facility-Using-Test4Z/GETACCTC.rex)** for obtaining and re-using the users accounting code information + +**[GTUNIQUE.rex](https://github.com/BroadcomMFD/broadcom-product-scripts/blob/SonarQube-Interface-with-Endevor/endevor/Field-Developed-Programs/Miscellaneous-items/GTUNIQUE.rex)** for obtaining a unique 8-byte name from the current date and time. + +**[QMATCH.rex](https://github.com/BroadcomMFD/broadcom-product-scripts/blob/SonarQube-Interface-with-Endevor/endevor/Field-Developed-Programs/Miscellaneous-items/QMATCH.rex)** for comparing two text strings, where one or both may have wild-carded values. + + +**[WAITFILE.rex](https://github.com/BroadcomMFD/broadcom-product-scripts/blob/SonarQube-Interface-with-Endevor/endevor/Field-Developed-Programs/Miscellaneous-items/WAITFILE.rex)** for looping through wait periods of time, until a specific file becomes available. + +**[WHERE@M1](https://github.com/BroadcomMFD/broadcom-product-scripts/blob/main/endevor/Field-Developed-Programs/Package-Automation/WHERE%40M1.rex)** the utility used for supporting diversity of dataset names, and other differences, by Lpar. + +This code in the SONRQUBE.rexx is used for identifying COBOL elements and copybooks. You might need to tweak it for your site: + +The cobol element type is expected to begin with COB or CBL + + COBOL_Element_Types = 'COB* CBL*' + COBOL_Compile_StepNames = 'COMPILE COMP CMP COB' + +Then the compile step should be one of those above. + +The ProcessCopybookMembers routine looks for Input components from SYSLIB in a compile step. + +When the process runs, it places members into the dataset you name as the **SonarWorkfile**. You can use the members to see details of actions performed, and to help resolve issues. + +Use the SonarQube.bat commmand to bring the items together for your mainframe. + + diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SCAN#SCL.rex b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SCAN#SCL.rex new file mode 100644 index 0000000..e97e722 --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SCAN#SCL.rex @@ -0,0 +1,171 @@ +/* REXX */ +/* ---------------------------------------------------------- */ +/* Scan Endevor element-level SCL, parse the words, and */ +/* write out into a format that other processes can use. */ +/* ---------------------------------------------------------- */ +/* */ + /* If SCAN#SCL is allocated to anything, turn on Trace */ + WhatDDName = 'SCAN#SCL' + CALL BPXWDYN "INFO FI("WhatDDName")", + "INRTDSN(DSNVAR) INRDSNT(myDSNT)" + If Substr(DSNVAR,1,1) /= ' ' then Trace R + + /* Either Allocate SCL in the JCL, or name SCL dataset here */ + Arg Parameters; + Format = 'Table' /* Table or Rexx */ + If Words(Parameters) > 1 then Format = Word(Parameters,2) + SCLDataset = Word(Parameters,1) + + If Pos('.',SCLDataset) = 0 & Words(Parameters) = 1 then, + Format = Word(Parameters,1) + If Pos('.',SCLDataset) > 0 then, + CALL BPXWDYN, + "ALLOC DD(SCL) DA("SCLDataset") SHR REUSE" + + "EXECIO * DISKR SCL (Stem scl. Finis" + If RC > 4 then, + Do + Say 'SCAN#SCL- unable to find input SCL' + Exit(8) + End + If scl.0 > 0 then, + Do + Result = , + Left('Command',8), + Left('Envmnt',8), + Left('S',1), + Left('System',8), + Left('Subsys',8), + Left('Type',8), + 'Element ' + If Format = 'TABLE' then, + Result = "*" || Result + Else, + Result = "SCL.000000 ='" || Result || " '" + Queue Result + End; + + /* Establish Defaults */ + Count = 0 + DfltC1Envmnt = ' ' + DfltC1Stgid = ' ' + DfltC1System = ' ' + DfltC1Subsys = ' ' + DfltC1Element = ' ' + DfltC1ElType = ' ' + + Do s# = 1 to scl.0 + Call FindStatement + Call ProcessStatement + End; + + "EXECIO" QUEUED() "DISKW RESULTS (Finis" + + Exit + +FindStatement: + + Statement = ' ' + + Do Forever + sclLine = Strip(scl.s#,'T') + If Substr(sclLine,1,1) /= '*' then, + Statement = Statement sclLine + If Substr(Statement,Length(Statement),1) = '.' then Return; + if s# = scl.0 then Return; + s# = s# + 1; + End; /* Do forever */ + + Return; + +ProcessStatement: + + Classifications = 'ENV ENVIRONMENT SYS SYSTEM SUB SUBSYSTEM ', + 'TYP TYPE STA STAGE ELE ELEMENT ' + Commands = 'SET MOV MOVE TRA TRANSFER GEN GENERATE ', + ' DEL DELETE ' + + thisCommand = Word(Statement,1) + If Words(Statement) < 1 Then Return; + + C1Envmnt = DfltC1Envmnt + C1Stgid = DfltC1Stgid + C1System = DfltC1System + C1Subsys = DfltC1Subsys + C1Element= DfltC1Element + C1ElType = DfltC1ElType + + If Words(Statement) > 1 Then, + Do w# = 2 to Words(Statement) +/* MG added Translate */ + thisWord = Translate(Word(Statement,w#)) + If w# < Words(Statement) then, + nextWord = Word(Statement,w#+1) + Else, + nextWord = ' ' + If (thisWord = 'CCID' |, + thisWord = 'COMMENT' ) &, + Substr(nextWord,1,1) = "'" then, + Do + w# = w# + 1 + whereAmI = Wordindex(Statement,w#) + whereQuote = Pos("'",Statement,whereAmi+1) + if whereQuote <= whereAmI then Iterate; + Do forever; + If WordIndex(Statement,w#+1) > whereQuote then Leave; + w# = w# + 1; + sa= WordIndex(Statement,w#+1) whereQuote + End; /* Do forever */ + Iterate; + End + + nextWord = Strip(nextWord,'B',"'"); + nextWord = Strip(nextWord,'B','"'); + + If thisWord = 'OPTIONS' then Leave ; + If WordPos(thisWord,Classifications) = 0 then iterate; + + If thisCommand = 'SET' then, + Do + If Substr(thisWord,1,3) = 'ENV' then DfltC1Envmnt = nextWord + If Substr(thisWord,1,3) = 'STA' then DfltC1Stgid = nextWord + If Substr(thisWord,1,3) = 'SYS' then DfltC1System = nextWord + If Substr(thisWord,1,3) = 'SUB' then DfltC1Subsys = nextWord + If Substr(thisWord,1,3) = 'ELE' then DfltC1Element= nextWord + If Substr(thisWord,1,3) = 'TYP' then DfltC1ElType = nextWord + End + Else, + Do + If Substr(thisWord,1,3) = 'ENV' then C1Envmnt = nextWord + If Substr(thisWord,1,3) = 'STA' then C1Stgid = nextWord + If Substr(thisWord,1,3) = 'SYS' then C1System = nextWord + If Substr(thisWord,1,3) = 'SUB' then C1Subsys = nextWord + If Substr(thisWord,1,3) = 'ELE' then C1Element= nextWord + If Substr(thisWord,1,3) = 'TYP' then C1ElType = nextWord + End + w# = w# + 1 + End; /* Do w# = 2 to Words(Statement) */ + + If thisCommand = 'SET' then Return ; + If Length(C1Element) > 10 then, + C1Element = Translate(C1Element,'_',' '); + + Count = Count + 1 + ShowCount = Right(Count,6,'0') + Result =, + Left(thisCommand,8), + Left(C1Envmnt,8), + Left(C1Stgid,1), + Left(C1System,8), + Left(C1Subsys,8), + Left(C1ElType,8), + Left(C1Element,10) + If Format = 'TABLE' then, + Result = " " || Result + Else, + Result = 'SCL.'ShowCount "='" || Result || "'" +/* MG added Translate */ + Result = Translate(Result) + Queue Result + + Return; diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARMDL.skl b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARMDL.skl new file mode 100644 index 0000000..1b39f89 Binary files /dev/null and b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARMDL.skl differ diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARPRM.skl b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARPRM.skl new file mode 100644 index 0000000..fd3b3b0 --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARPRM.skl @@ -0,0 +1,8 @@ + NOTHING NOTHING SETUP 0 + MDL#JOB JCL#JOB NOTHING 1 + MDL#RCV JCL#RCV NOTHING 1 + MDL#RUN JCL#RUN NOTHING 1 + MODEL TBLOUT NOTHING 1 + NOTHING REPORT WAIT#1 1 + NOTHING REPORT WAIT#2 1 + NOTHING REPORT WAIT#3 1 diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARSET.skl b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARSET.skl new file mode 100644 index 0000000..95e50ce --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARSET.skl @@ -0,0 +1,13 @@ +* SETUP INPUT FOR THE FOREGROUND TABLE TOOL STEP DUING CAST +* If $row# = 0 then $SkipRow = 'Y' + uniqueName = GTUNIQUE() + ReportingPFX = USERID() || '.SONRQUBE.'uniqueName'.RESULTS' + $QuietMessages = 'Y' /* Bypass messages Y/N */ + myJob = MVSVAR('SYMDEF','JOBNAME' ) + Jobname = BUMPJOB(myJob) j + OrderLibrary = '&MYISPSLB' + SonarWorkfile = '&SONARWRK' + TransmitMethod = 'XCOM' + TransmitMethod = 'FTP' + TransmitCOND = 0 /* Skip step if prev > TransmitCOND */ + TransmitCOND = 4 /* Skip step if prev > TransmitCOND */ diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARTBL.skl b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARTBL.skl new file mode 100644 index 0000000..2de5ddc --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARTBL.skl @@ -0,0 +1,3 @@ +* DO + * +*** Table for Table Tool step during Package Cast diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARW#1.skl b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARW#1.skl new file mode 100644 index 0000000..0beb4da --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARW#1.skl @@ -0,0 +1,17 @@ +* WAIT#1 for the SonarQube job to start + If $row# = 0 then $SkipRow = 'Y' + Say 'Jobname=' Jobname + Say 'myJob=' myJob + Say 'Execio 0 DISKW TBLOUT (Finis' + "Execio 0 DISKW TBLOUT (Finis" +* + ReportingDSN = ReportingPFX || '.#1' + say "ReportingDSN=" ReportingDSN +* a short wait to see if the submitted job starts + wait1 = WAITFILE(ReportingDSN 45 1) + say "ReportingDSN " ReportingDSN "is returned after" wait1 "secs" + if wait1 = 0 then, + + Do; Say '#1 is lost'; Exit(11); end + cmd = "ALLOC DD(STATUS1) DA("ReportingDSN") SHR REUSE " + CALL BPXWDYN cmd + MODEL = 'STATUS1' diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARW#2.skl b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARW#2.skl new file mode 100644 index 0000000..aa5538f --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARW#2.skl @@ -0,0 +1,14 @@ +* WAIT#2 input for file transmission to complete + If $row# = 0 then $SkipRow = 'Y' + ReportingDSN = ReportingPFX || '.#2' +* a longer wait for the File Transmission to finish + wait2 = (wait1 * 1.5) % 1 + wait2 = max(wait2,5) + Say 'SONARW#2 - waiting' wait2 'seconds between check loops' + wait2 = WAITFILE(ReportingDSN 25 wait2) + say "ReportingDSN " ReportingDSN "is returned after" wait2 "secs" + if wait2 = 0 then, + + Do; Say '#2 is lost'; Exit(12); end + cmd = "ALLOC DD(STATUS2) DA("ReportingDSN") SHR REUSE " + CALL BPXWDYN cmd + MODEL = 'STATUS2' diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARW#3.skl b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARW#3.skl new file mode 100644 index 0000000..17bf27d --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONARW#3.skl @@ -0,0 +1,13 @@ +* WAIT#2 wait for the SonarQube analysis to complete + If $row# = 0 then $SkipRow = 'Y' + ReportingDSN = ReportingPFX || '.#3' +* LONGEST wait for the SonarQube Analysis to finish + wait3 = (wait2 * 1.5) % 1 + wait3 = max(wait3,10) + wait3 = WAITFILE(ReportingDSN 55 wait3) + say "ReportingDSN " ReportingDSN "is returned after" wait3 "secs" + if wait3 = 0 then, + + Do; Say '#2 is lost'; Exit(13); end + cmd = "ALLOC DD(STATUS3) DA("ReportingDSN") SHR REUSE " + CALL BPXWDYN cmd + MODEL = 'STATUS3' diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONRQUBE.rex b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONRQUBE.rex new file mode 100644 index 0000000..b939b24 --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SONRQUBE.rex @@ -0,0 +1,527 @@ +/* rexx */ + /* If wanting to limit the use of this exit, uncomment... */ + If USERID() /= 'ibmuser' then exit + + /* If SONRQUBE is allocated to anything, turn on Trace */ + WhatDDName = 'SONRQUBE' + CALL BPXWDYN "INFO FI("WhatDDName")", + "INRTDSN(DSNVAR) INRDSNT(myDSNT)" + If RESULT = 0 then Trace r + + Arg PECB_PACKAGE_ID . + + Sa= 'You called SONRQUBE ' + /* Variable settings for each site ---> */ + WhereIam = WHERE@M1() + interpret 'Call' WhereIam "'MySENULibrary'" + MySENULibrary = Result + interpret 'Call' WhereIam "'MySEN2Library'" + MySEN2Library = Result + interpret 'Call' WhereIam "'MyCLS0Library'" + MyCLS0Library = Result + interpret 'Call' WhereIam "'MyCLS2Library'" + MyCLS2Library = Result + interpret 'Call' WhereIam "'MyHomeAddress'" + MyHomeAddress = Result + interpret 'Call' WhereIam "'AltIDAcctCode'" + AltIDAcctCode = Result + + Message = '' + MessageCode = ' ' + + /* Interfacing with SonarQube during package CAST in Batch */ + /* Local selections here... */ + + COBOL_Element_Types = 'COB* CBL*' + COBOL_Compile_StepNames = 'COMPILE COMP CMP COB' + + TransmitMethod = 'FTP' /* **chose one ** */ + TransmitMethod = 'XCOM' /* **chose one ** */ + Call GetUnique_Name + SonarDSNPrefix = USERID()'.SONRQUBE.' || Unique_Name + TransmitTable = "" + + Call Allocate_Files_For_CSV_and_API + Elements.0 = 0 + Call ProcessPackageSCL + If COBOLinPackage = 'Y' then, + Do + Call RETRIEVE_Cobol_Elements + Call Use_ENTBJAPI_For_BX_Info + Call SubmitandWaitForSonarQube + If myRC > 4 then, + Do + message = 'SONRQUBE -', + 'Package Failed the SonarQube Analysis' + MyRc = 8 + End /* If myRC > 4 */ + Else, + Do + MyRc = 4 + message = 'SONRQUBE -', + 'Package passed a SonarQube Analysis' + message = '' + End /* Else */ + End; /* If COBOLinPackage = 'Y' ... */ + + Call FREE_Files_For_CSV_and_API + + Return message + +GetUnique_Name: + + Unique_Name = GTUNIQUE() + If TraceRQ = 'Y' then, + SAY "Unique Member name is " Unique_Name + + Return + +Allocate_Files_For_CSV_and_API: + + STRING = "ALLOC DD(C1MSGS1) DUMMY " + CALL BPXWDYN STRING; + STRING = "ALLOC DD(BSTERR) DA(*) " + CALL BPXWDYN STRING; + STRING = "ALLOC DD(BSTAPI) DA(*) " + CALL BPXWDYN STRING; + + STRING = "ALLOC DD(MSGFILE) LRECL(133) BLKSIZE(26600) ", + " DSORG(PS) ", + " SPACE(5,5) RECFM(F,B) TRACKS ", + " NEW UNCATALOG REUSE "; + CALL BPXWDYN STRING; + + Return; + +FREE_Files_For_CSV_and_API: + + CALL BPXWDYN STRING; + STRING = "FREE DD(C1MSGS1)" ; + CALL BPXWDYN STRING; + STRING = "FREE DD(BSTERR)" ; + CALL BPXWDYN STRING; + STRING = "FREE DD(BSTAPI)" ; + CALL BPXWDYN STRING; + STRING = "FREE DD(MSGFILE)"; + CALL BPXWDYN STRING; + + Return; + +ProcessPackageSCL: + + /* Do an EXPORT to Capture the Package SCL */ + SonarWorkfile = SonarDSNPrefix || '.SONARWRK' + SonarCOBOL = SonarDSNPrefix || '.SONARCOB' + + STRING = "ALLOC DD(WRKFILE) LRECL(080) BLKSIZE(24000) ", + " DA("SonarWorkfile") ", + " DSORG(PO) DSNTYPE(LIBRARY) DIR(9) ", + " SPACE(5,5) RECFM(F,B) CYL ", + " NEW CATALOG REUSE "; + CALL BPXWDYN STRING; + CALL BPXWDYN "FREE DD(WRKFILE)" + + STRING = "ALLOC DD(COBOL) LRECL(080) BLKSIZE(24000) ", + " DA("SonarCOBOL") ", + " DSORG(PO) DSNTYPE(LIBRARY) DIR(9) ", + " SPACE(5,5) RECFM(F,B) CYL ", + " NEW CATALOG REUSE "; + CALL BPXWDYN STRING; + CALL BPXWDYN "FREE DD(COBOL) " + + STRING = "ALLOC DD(SCL) DA("SonarWorkfile"(SCL)) SHR REUSE" + CALL BPXWDYN STRING; + + STRING="ALLOC DD(ENPSCLIN) DA("SonarWorkfile"(SCLEXPRT)) SHR REUSE" + CALL BPXWDYN STRING; + QUEUE "EXPORT PACKAGE '"PECB_PACKAGE_ID"'" + QUEUE " TO DDN 'SCL' ." + "EXECIO 2 DISKW ENPSCLIN (FINIS "; /* count queued */ + + ADDRESS LINK 'ENBP1000' ; /* run from CSIQAUTH*/ + call_rc = rc ; + + CALL BPXWDYN "FREE DD(ENPSCLIN)" ; + + STRING = "ALLOC DD(RESULTS) DA("SonarWorkfile"(PKGTBL)) SHR REUSE" + CALL BPXWDYN STRING; + + /* Use SCAN#SCL to create a TABLE from the SCL content */ + Call SCAN#SCL 'TABLE' + + CALL BPXWDYN "FREE DD(SCL)" ; + + /* Use TableTool to create multiple outputs */ + STRING = "ALLOC DD(TABLE) DA("SonarWorkfile"(PKGTBL)) SHR REUSE" + CALL BPXWDYN STRING; + + STRING="ALLOC DD(PARMLIST) DA("SonarWorkfile"(PARMLST1)) SHR REUSE" + CALL BPXWDYN STRING; + QUEUE " NOTHING NOTHING OPTIONS0 0 " + QUEUE " HEADING1 TBLOUT1 OPTIONS$ 1 " + QUEUE " HEADING3 TBLOUT3 NOTHING 1 " + QUEUE " MODEL1 TBLOUT1 OPTIONS# A " + "EXECIO 4 DISKW PARMLIST (FINIS "; /* count queued */ + + STRING="ALLOC DD(OPTIONS0) DA("SonarWorkfile"(OPTIONS0)) SHR REUSE" + CALL BPXWDYN STRING; + QUEUE " $MultiplePDSmemberOuts = 'Y' /* mult PDS mbr outputs */ " + "EXECIO 1 DISKW OPTIONS0 (FINIS "; + + STRING="ALLOC DD(OPTIONS$) DA("SonarWorkfile"(OPTIONS$)) SHR REUSE" + CALL BPXWDYN STRING; + ReportingPFX = USERID() || '.SONRQUBE.'Unique_Name'.RESULTS' + myJob = MVSVAR('SYMDEF','JOBNAME' ) + Jobname = BUMPJOB(myJob) + + QUEUE " COBOL_Element_Types = '"COBOL_Element_Types"'" + QUEUE " COBOL_Compile_StepNames = '"COBOL_Compile_StepNames"'" + QUEUE " Package = '"PECB_PACKAGE_ID"'" + QUEUE " MyHomeAddress = '"MyHomeAddress"'" + QUEUE " SonarCOBOL = '"SonarCOBOL"'" + QUEUE " Unique_Name = '"Unique_Name"'" + QUEUE " AltIDAcctCode = '"AltIDAcctCode"'" + QUEUE " SonarWorkfile = '"SonarWorkfile"'" + QUEUE " MySENULibrary = '"MySENULibrary"'" + QUEUE " MySEN2Library = '"MySEN2Library"'" + QUEUE " MyCLS0Library = '"MyCLS0Library"'" + QUEUE " MyCLS2Library = '"MyCLS2Library"'" + QUEUE " TransmitMethod = '"TransmitMethod"'" + QUEUE " ReportingPFX = '"ReportingPFX"'" + QUEUE " Userid = '"USERID()"'" + QUEUE " myJob = '"myJob"'" + QUEUE " Jobname = '"Jobname"'" + "EXECIO 17 DISKW OPTIONS$ (FINIS "; /* count queued */ + CALL BPXWDYN "ALLOC DD(NOTHING) DUMMY" + + STRING="ALLOC DD(HEADING1) DA("SonarWorkfile"(HEADING1)) SHR REUSE" + CALL BPXWDYN STRING; + QUEUE " SET TO DSN '"SonarCOBOL"'." + QUEUE " SET OPTIONS REPLACE NO SIGNOUT. " + "EXECIO 2 DISKW HEADING1 (FINIS "; + + STRING="ALLOC DD(MODEL1) DA("SonarWorkfile"(MODEL1)) SHR REUSE" + CALL BPXWDYN STRING; + QUEUE " RETRIEVE ELEMENT &Element " + QUEUE " FROM ENVIRONMENT &Envmnt STAGE &S " + QUEUE " SYSTEM &System SUBSYSTEM &Subsys TYPE &Type . " + "EXECIO 3 DISKW MODEL1 (FINIS "; + + STRING="ALLOC DD(OPTIONS#) DA("SonarWorkfile"(OPTIONS#)) SHR REUSE" + CALL BPXWDYN STRING; + Queue "$NumberModelsAndTblouts= 3 " + Queue "HaveCobol = 0 " + Queue "Do w# = 1 to Words(COBOL_Element_Types) ; + " + Queue " HaveCobol=QMATCH(Type Word(COBOL_Element_Types,w#)); +" + Queue " If HaveCobol = 1 then Do; $my_rc = 1; Leave; End; + " + Queue "End; " + Queue "If HaveCobol = 0 then $SkipRow='Y' " + Queue "AEELM= COPIES(' ',80); " + Queue "AEELM= Overlay('AEELMBC ',AEELM,1) ; " + Queue "AEELM= Overlay(Envmnt,AEELM,10) ; /* Env */ " + Queue "AEELM= Overlay(S,AEELM,18) ; /* stg id */ " + Queue "AEELM= Overlay(System,AEELM,19) ; /* Sys */ " + Queue "AEELM= Overlay(Subsys,AEELM,27) ; /* Sub */ " + Queue "AEELM= Overlay(Element,AEELM,35) ; /* Ele */ " + Queue "AEELM= Overlay(Type,AEELM,45); /* Typ */ " + Queue "* " + Queue "Element = Left(Element,08) " + "EXECIO 17 DISKW OPTIONS# (FINIS "; /* count queued */ + + STRING="ALLOC DD(MODEL2) DA("SonarWorkfile"(MODEL2)) SHR REUSE" + CALL BPXWDYN STRING; + Queue "AACTL MSGFILE COMPLIST " + Queue "&AEELM " + Queue "RUN " + "EXECIO 3 DISKW MODEL2 (FINIS "; + + STRING="ALLOC DD(HEADING3) DA("SonarWorkfile"(HEADING3)) SHR REUSE" + CALL BPXWDYN STRING; + Queue "* Folder-- Member-- ", + "Dataset------------------------------------- " + "EXECIO 1 DISKW HEADING3 (FINIS "; + + STRING="ALLOC DD(MODEL3) DA("SonarWorkfile"(MODEL3)) SHR REUSE" + CALL BPXWDYN STRING; + Queue " COBOL &Element &SonarCOBOL " + "EXECIO 1 DISKW MODEL3 (FINIS "; + + STRING="ALLOC DD(TRAILER2) DA("SonarWorkfile"(TRAILER2)) SHR REUSE" + CALL BPXWDYN STRING; + Queue "AACTLY " + Queue "RUN " + Queue "QUIT " + "EXECIO 3 DISKW TRAILER2 (FINIS "; + + STRING="ALLOC DD(TBLOUT1) DA("SonarWorkfile"(RETRIEVE)) SHR REUSE" + CALL BPXWDYN STRING; + STRING="ALLOC DD(TBLOUT2) DA("SonarWorkfile"(AEELMBC)) SHR REUSE" + CALL BPXWDYN STRING; + STRING="ALLOC DD(TBLOUT3) DA("SonarWorkfile"(TRANSMIT)) SHR REUSE" + CALL BPXWDYN STRING; + + If TraceRQ = 'Y' then Trace R + myRC = ENBPIU00("PARMLIST") + If myRC = 1 then COBOLinPackage = 'Y' + + CALL BPXWDYN "FREE DD(SCL) " ; + CALL BPXWDYN "FREE DD(ENPSCLIN)" ; + CALL BPXWDYN "FREE DD(RESULTS) " ; + + CALL BPXWDYN "FREE DD(TABLE) " ; + CALL BPXWDYN "FREE DD(PARMLIST)" ; + CALL BPXWDYN "FREE DD(OPTIONS$) " ; + CALL BPXWDYN "FREE DD(NOTHING) " ; + CALL BPXWDYN "FREE DD(HEADING1)" ; + CALL BPXWDYN "FREE DD(MODEL1) " ; + CALL BPXWDYN "FREE DD(OPTIONS#)" ; + CALL BPXWDYN "FREE DD(OPTIONS$)" ; + CALL BPXWDYN "FREE DD(MODEL2) " ; + CALL BPXWDYN "FREE DD(HEADING3)" ; + CALL BPXWDYN "FREE DD(MODEL3) " ; + CALL BPXWDYN "FREE DD(TRAILER2)" ; + CALL BPXWDYN "FREE DD(TBLOUT1) " ; + CALL BPXWDYN "FREE DD(TBLOUT2) " ; + CALL BPXWDYN "FREE DD(TBLOUT3) " ; + + RETURN ; + +RETRIEVE_Cobol_Elements: + + STRING="ALLOC DD(BSTIPT01) DA("SonarWorkfile"(RETRIEVE)) SHR REUSE" + CALL BPXWDYN STRING; + + ADDRESS LINK 'C1BM3000' + + RETURN ; + +Use_ENTBJAPI_For_BX_Info: + + /* See your CSIQJCL(BC1JAAPI) */ + /* V - COLUMN 6 = FORMAT SETTING */ + /* = ' ' FOR NO FORMAT, JUST EXTRACT ELEMENT */ + /* = 'B' FOR ENDEVOR BROWSE DISPLAY FORMAT */ + /* = 'C' FOR ENDEVOR CHANGE DISPLAY FORMAT */ + /* = 'H' FOR ENDEVOR HISTORY DISPLAY FORMAT */ + /* V - COLUMN 7 = Replay TYPE SETTING */ + /* = 'E' FOR ELEMENT */ + /* = 'C' FOR COMPONENT */ + /* VVVVVVVV - COLUMN 10-17 ENVIRONMENT NAME */ + /* V - COLUMN 18 = STAGE ID */ + /* VVVVVVVV - COLUMN 19-26 SYSTEM NAME */ + /* VVVVVVVV - COLUMN 27-34 SUBSYSTEM NAME */ + /* COLUMN 35-44 = ELEMENT NAME VVVVVVVVVV */ + /* COLUMN 45-52 = TYPE NAME VVVVVVVV */ + /* */ + + Sa= 'Use_ENTBJAPI_For_BX_Info' + + STRING="ALLOC DD(SYSIN) DA("SonarWorkfile"(AEELMBC)) SHR REUSE" + CALL BPXWDYN STRING; + + + STRING = "ALLOC DD(COMPLIST) LRECL(200) BLKSIZE(20000) ", + " DSORG(PS) ", + " SPACE(5,15) RECFM(F,B) TRACKS ", + " MOD UNCATALOG REUSE "; + CALL BPXWDYN STRING; + + /* Call Built-in API program for COBOL source extracts */ + /* and COBOL component List requests. */ + ADDRESS LINK "ENTBJAPI" + + CALL BPXWDYN "FREE DD(SYSIN) " + + "EXECIO * DISKR COMPLIST (Stem cmplist. FINIS "; + CALL BPXWDYN "FREE DD(COMPLIST)" + + sa= cmplist.0 + If cmplist.0 = 0 then Return; + + Call ProcessCopybookMembers; + Call UpdateSonarTransmitTable; + Drop element. + + RETURN ; + +ProcessCopybookMembers: + + Do rec# = 1 to cmplist.0 + complist = Substr(cmplist.rec#,73) + If Substr(complist,1,22) = Copies('-',22) then, + thisSection = Word(complist,2) + If thisSection /= 'INPUT' then iterate; + If Word(complist,1) = 'STEP:' then, + Do + StepName = Word(complist,2) + DDname = Substr(Word(complist,3),4) + DatasetName = Substr(Word(complist,5),5) + Iterate + End + If Substr(Word(complist,5),3,1) = ':' &, + WordPos(StepName,COBOL_Compile_StepNames) > 0 &, + DDname = 'SYSLIB' then, + Do + member = Word(complist,2) + entry = "COPYBOOK,"member","DatasetName + If Wordpos(entry,TransmitTable) = 0 then, + TransmitTable = TransmitTable entry + End + End; /* Do rec# = 1 to cmplist.0 */ + + RETURN ; + +UpdateSonarTransmitTable: + + STRING =, + "ALLOC DD(SONARXMT) DA("SonarWorkfile"(TRANSMIT)) SHR REUSE" + CALL BPXWDYN STRING; + "Execio * DISKR SONARXMT (Stem xmit. Finis" + xm# = xmit.0 + + Do w# = 1 to Words(TransmitTable) + xm# = xm# + 1 + transtable = Word(TransmitTable,w#) + Parse var transtable folder ',' member ',' dataset + entry = " " left(folder,8) left(member,10) dataset + xmit.xm# = entry + End; /* Do w# = 1 to Words(TransmitTable) */ + + "Execio * DISKW SONARXMT (Stem xmit. Finis" + + transtable = "" + RETURN ; + +SubmitandWaitForSonarQube: + + /* Allocate files for a TableTool driven submission of the + SonarQube job, and a series of waits for parts of the job + to complete. + A TABLE TOOL step running with the PARMLIST option + (see PARMLST2 in the SonarWorkfile) + orchestrates the submission of the SONARJOB and the + the wait steps for the job completion. + */ + + STRING="ALLOC DD(SETUP) DA("SonarWorkfile"(OPTIONS$)) SHR REUSE" + CALL BPXWDYN STRING; + + STRING="ALLOC DD(PARMLIST) DA("SonarWorkfile"(PARMLST2)) SHR REUSE" + CALL BPXWDYN STRING; + Queue "NOTHING NOTHING SETUP 0" + Queue "MDL#JOB "TransmitMethod"#JOB NOTHING 1" + Queue "MDL#RCV "TransmitMethod"#RCV NOTHING 1" + Queue "MDL#RUN "TransmitMethod"#RUN NOTHING 1" + Queue "MODEL4 TBLOUT NOTHING 1" + Queue "TBLOUT READER NOTHING 1" + Queue "NOTHING REPORT WAIT#1 1" + Queue "NOTHING REPORT WAIT#2 1" + Queue "NOTHING REPORT WAIT#3 1" + "EXECIO 9 DISKW PARMLIST (FINIS "; + + STRING="ALLOC DD(MDL#JOB) ", + "DA("MySEN2Library"("TransmitMethod"#JOB) SHR REUSE" + CALL BPXWDYN STRING; + STRING="ALLOC DD(MDL#RCV) ", + "DA("MySEN2Library"("TransmitMethod"#RCV) SHR REUSE" + CALL BPXWDYN STRING; + STRING="ALLOC DD(MDL#RUN) ", + "DA("MySEN2Library"("TransmitMethod"#RUN) SHR REUSE" + CALL BPXWDYN STRING; + + STRING="ALLOC DD("TransmitMethod"#JOB) ", + "DA("SonarWorkfile"("TransmitMethod"#JOB) SHR REUSE" + CALL BPXWDYN STRING; + STRING="ALLOC DD("TransmitMethod"#RCV) ", + "DA("SonarWorkfile"("TransmitMethod"#RCV) SHR REUSE" + CALL BPXWDYN STRING; + STRING="ALLOC DD("TransmitMethod"#RUN) ", + "DA("SonarWorkfile"("TransmitMethod"#RUN) SHR REUSE" + CALL BPXWDYN STRING; + + STRING = "ALLOC DD(READER) SYSOUT(A) WRITER(INTRDR) REUSE " ; + CALL BPXWDYN STRING; + + /* Replicate the next several files for improved visibility */ + STRING="ALLOC DD(TEMP#1) DA("MySEN2Library"(SONARW#1)) SHR REUSE" + CALL BPXWDYN STRING; + "EXECIO * DISKR TEMP#1 (Stem wait. Finis" + CALL BPXWDYN "FREE DD(TEMP#1) " + STRING="ALLOC DD(WAIT#1) DA("SonarWorkfile"(WAIT#1)) SHR REUSE" + CALL BPXWDYN STRING; + "EXECIO * DISKW WAIT#1 (Stem wait. Finis" + + Drop wait. + STRING="ALLOC DD(TEMP#2) DA("MySEN2Library"(SONARW#2)) SHR REUSE" + CALL BPXWDYN STRING; + "EXECIO * DISKR TEMP#2 (Stem wait. Finis" + CALL BPXWDYN "FREE DD(TEMP#2) " + STRING="ALLOC DD(WAIT#2) DA("SonarWorkfile"(WAIT#2)) SHR REUSE" + CALL BPXWDYN STRING; + "EXECIO * DISKW WAIT#2 (Stem wait. Finis" + + Drop wait. + STRING="ALLOC DD(TEMP#3) DA("MySEN2Library"(SONARW#3)) SHR REUSE" + CALL BPXWDYN STRING; + "EXECIO * DISKR TEMP#3 (Stem wait. Finis" + CALL BPXWDYN "FREE DD(TEMP#3) " + STRING="ALLOC DD(WAIT#3) DA("SonarWorkfile"(WAIT#3)) SHR REUSE" + CALL BPXWDYN STRING; + "EXECIO * DISKW WAIT#3 (Stem wait. Finis" + + STRING="ALLOC DD(TEMPMD) DA("MySEN2Library"(SONARMDL)) SHR REUSE" + CALL BPXWDYN STRING; + "EXECIO * DISKR TEMPMD (Stem mdl. Finis" + CALL BPXWDYN "FREE DD(TEMPMD) " + STRING="ALLOC DD(MODEL4) DA("SonarWorkfile"(MODEL4)) SHR REUSE" + CALL BPXWDYN STRING; + "EXECIO * DISKW MODEL4 (Stem mdl. Finis" + + STRING="ALLOC DD(TABLE) DA("MySEN2Library"(SONARTBL)) SHR REUSE" + CALL BPXWDYN STRING; + STRING="ALLOC DD(NOTHING) DUMMY" + CALL BPXWDYN STRING; + STRING="ALLOC DD(SYSTSPRT) SYSOUT(A) " + CALL BPXWDYN STRING; + STRING="ALLOC DD(REPORT) SYSOUT(A) " + CALL BPXWDYN STRING; + STRING = "ALLOC DD(TBLOUT) DA("SonarWorkfile"(SONARJOB) SHR REUSE" + CALL BPXWDYN STRING; + + /* The next statement does the submit and wait */ + myRC = ENBPIU00("PARMLIST") + + CALL BPXWDYN "FREE DD(REPORT) " + CALL BPXWDYN "FREE DD(PARMLIST)" + CALL BPXWDYN "FREE DD(SETUP) " + CALL BPXWDYN "FREE DD(WAIT#1) " + CALL BPXWDYN "FREE DD(WAIT#2) " + CALL BPXWDYN "FREE DD(WAIT#3) " + CALL BPXWDYN "FREE DD(MODEL4) " + CALL BPXWDYN "FREE DD(TABLE) " + CALL BPXWDYN "FREE DD(NOTHING) " + CALL BPXWDYN "FREE DD(SYSTSPRT)" + CALL BPXWDYN "FREE DD(TBLOUT) " + + If myRC = 11 then, + message = 'SONRQUBE - could not submit the SonarQube job' + If myRC = 12 then, + message = 'SONRQUBE - File transmissions failed ' + If myRC = 13 then, + message = 'SONRQUBE - could not initiate SonarQube', + ' analysis' + + If myRC < 8 then, + Do + STRING="ALLOC DD(RESULTS)", + " DA("SonarWorkfile".RESULTS) SHR REUSE" + CALL BPXWDYN STRING; + "Execio * DISKR RESULTS (Stem rslt. Finis" + CALL BPXWDYN "FREE DD(RESULTS)" + lastline# = rslt.0 + lastline = rslt.lastline# + If Pos('Status: SUCCESS ',lastline) = 0 then myRc= 8 + End /* If myRC < 8 */ + + RETURN ; + diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SonarDriver.py b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SonarDriver.py new file mode 100644 index 0000000..90e92d5 --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/SonarDriver.py @@ -0,0 +1,172 @@ +import os +import sys +import subprocess +import time +import requests +import json +import logging +import textwrap +# +logging.basicConfig( + filename='/opt/xxx/scripts/scanjob.log', # Provide your log file and its path + filemode='a', + format='%(asctime)s - %(levelname)s - %(message)s', + level=logging.DEBUG +) + +#CUSTOMIZE ALL THE FOLLOWING FIELDS TO YOUR VALUES +INBOUND_DIR = "/opt/xxx/inbound" +OUTBOUND_DIR = "/opt/xxx/outbound" +SONAR_SCANNER_PATH = "/opt/sonar-scanner/bin/sonar-scanner" +SONAR_HOST_URL = "https://" +SONAR_PROJECT_KEY = "= paging.get("total", 0): + break + params["p"] += 1 + return issues + +def main(): + if len(sys.argv) != 3: + logging.error("Usage: python3 script.py ") + sys.exit(1) + + config_filename = sys.argv[1] + config_path = os.path.join(INBOUND_DIR, config_filename) + output_filename = sys.argv[2] + + try: + with open(config_path, 'r') as f: + lines = f.readlines()[1:] + + + files_received = [] + + for line in lines: + parts = line.strip().split() + if len(parts) < 2: + continue + file_type, member = parts[0], parts[1] + extension = ".cbl" if file_type.upper() == "COBOL" else ".cpy" if file_type.upper() == "COPYBOOK" else "" + if extension: + files_received.append(f"{member}{extension}") + + ##Specify the path where your script needs to run from. In this sceneario above Inbound & Outbound folder structures. + os.chdir("/opt/xxx") + + # Run SonarScanner + run_sonar_scanner() + + # Wait for analysis to complete + ce_task_id = get_ce_task_id() + wait_for_analysis_completion(ce_task_id) + + # Retrieve analysis results + issues = get_analysis_results() + + # Organize issues by file + issues_by_file = {} + for issue in issues: + component = issue.get("component", "") + rel_path = component.split(":", 1)[-1] + base_name = os.path.basename(rel_path) + if base_name not in issues_by_file: + issues_by_file[base_name] = [] + issues_by_file[base_name].append({ + "type": issue.get("type"), + "severity": issue.get("severity"), + "message": issue.get("message") + }) + + # Write results to output file + output_path = os.path.join(OUTBOUND_DIR, output_filename) + with open(output_path, 'w',encoding='utf-8') as out: + wrapper = textwrap.TextWrapper(width=131, subsequent_indent=' ') + for file in files_received: + out.write(f" Analysis results for {file}:\n") + file_issues = issues_by_file.get(file, []) + if file_issues: + for issue in file_issues: + line = f" - [{issue['severity']}] {issue['type']}: {issue['message']}" + wrapped_lines = wrapper.wrap(line) + for wrapped_line in wrapped_lines: + out.write(f"{wrapped_line}\n") + else: + out.write(" - No issues found.\n") + out.write("\n") + out.write("Status: SUCCESS\n") + + logging.info(f"Processed {len(files_received)} files. Output written to {output_path}") + + + # Delete processed files + for file in files_received: + file_path = os.path.join(INBOUND_DIR, file) + if os.path.exists(file_path): + os.remove(file_path) + + except Exception as e: + logging.error(f"Error processing file: {e}") + sys.exit(1) + +if __name__ == "__main__": + main() + diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/XCOM#INC.skl b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/XCOM#INC.skl new file mode 100644 index 0000000..6295f8f --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/XCOM#INC.skl @@ -0,0 +1,20 @@ +//XCOM1 DD DATA,DLM=QQ,SYMBOLS=JCLONLY XCOM#INC +TYPE=SEND +IPNAME=12.345.678.9 +IPPORT=8044 +CKPT=0 +FILEOPT=REPLACE +FILETYPE=FILE +USERID=root +PASSWORD= +* +QQ +//XCOM2 DD *,SYMBOLS=JCLONLY XCOM#INC +FILE=/your/uss/inbound/&Member.&extension +LFILE=&Dataset(&Member) +* +NEWXFER +//XCOM3 DD * XCOM#INC +FILE=/your/uss/inbound/&Unique_Name.lst +LFILE=&SonarWorkfile(TRANSMIT) +* diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/XCOM#JOB.skl b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/XCOM#JOB.skl new file mode 100644 index 0000000..951b81d --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/XCOM#JOB.skl @@ -0,0 +1,21 @@ +//*------------------------------------------------------------------- +//XCOM#JOB EXEC PGM=XCOMJOB, <- Exec SonarQube Analysis XCOM#JOB +// PARM=('TYPE=EXECUTE'),COND=(4,LT) +//STEPLIB DD DISP=SHR, +// DSN=your.XCOM.CBXGLOAD * XCOM LOAD MODULES +// DD DISP=SHR, +// DSN=CEE.SCEERUN * IBM LE RUNTIME +//XCOMCNTL DD DISP=SHR, +// DSN=your.XCOM.CBXGPARM * CONTROL LIBRARY +//CAOESTOP DD DUMMY +//SYSIN01 DD * XCOM#JOB +TYPE=SEND +IPNAME=12.345.678.9 +IPPORT=8044 +CKPT=0 +FILEOPT=REPLACE +FILETYPE=JOB +LFILE=&SonarWorkfile(LINUX) +USERID=root +PASSWORD= +//*--------------------------------------------------------XCOM#JOB--- diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/XCOM#RCV.skl b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/XCOM#RCV.skl new file mode 100644 index 0000000..42bb2fd --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/XCOM#RCV.skl @@ -0,0 +1,24 @@ +//*------------------------------------------------------------------- +//XCOM#RCV EXEC PGM=XCOMJOB, <- Receive Results XCOM#RCV +// PARM=('TYPE=EXECUTE'),COND=(4,LT) +//STEPLIB DD DISP=SHR, +// DSN=your.XCOM.CBXGLOAD * XCOM LOAD MODULES +// DD DISP=SHR, +// DSN=CEE.SCEERUN * IBM LE RUNTIME +//XCOMCNTL DD DISP=SHR, +// DSN=your.XCOM.CBXGPARM * CONTROL LIBRARY +//CAOESTOP DD DUMMY +//SYSIN01 DD * XCOM#RUN +TYPE=RECEIVE +IPNAME=12.345.678.9 +IPPORT=8044 +CKPT=0 +FILEOPT=REPLACE +FILETYPE=FILE +CODE=UTF8 +REMOTE_CHARSET=UTF8 +LFILE=&SonarWorkfile.RESULTS +FILE=/opt/xfer/outbound/&Unique_Name.rslt +USERID=root +PASSWORD= +//*--------------------------------------------------------XCOM#RCV--- diff --git a/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/XCOM#RUN.skl b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/XCOM#RUN.skl new file mode 100644 index 0000000..1744529 --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube-interface-to-Endevor/XCOM#RUN.skl @@ -0,0 +1,14 @@ +//*------------------------------------------------------------------- +//XCOM#RUN EXEC PGM=XCOMJOB, <- Exec SonarQube Analysis XCOM#RUN +// PARM=('TYPE=EXECUTE'),COND=(4,LT) +//STEPLIB DD DISP=SHR, +// DSN=your.XCOM.CBXGLOAD * XCOM LOAD MODULES +// DD DISP=SHR, +// DSN=CEE.SCEERUN * IBM LE RUNTIME +//XCOMCNTL DD DISP=SHR, +// DSN=your.XCOM.CBXGPARM * CONTROL LIBRARY +//CAOESTOP DD DUMMY +//*-------- +//SYSIN01 DD DSN=&&COMMANDS,DISP=(OLD,DELETE) XCOM#RUN +//*------------------------------------------------------------------- +//*--------------------------------------------------------XCOM#RUN--- diff --git a/endevor/Field-Developed-Programs/SonarQube.bat b/endevor/Field-Developed-Programs/SonarQube.bat new file mode 100644 index 0000000..f461ccf --- /dev/null +++ b/endevor/Field-Developed-Programs/SonarQube.bat @@ -0,0 +1,72 @@ +REM In Windows, execute this command file to collect all Package +@ECHO OFF +ECHO ./ ADD NAME=@README > SonarQube.moveout +ECHO These items come from the Endevor GitHub at >> SonarQube.moveout +ECHO https://github.com/BroadcomMFD/broadcom-product-scripts >> SonarQube.moveout +ECHO ------------------------------------------------------- >> SonarQube.moveout +ECHO These are rex/CSIQCLS0 : BUMPJOB C1UEXTR7 DTADJUST GETACCTC GTUNIQUE WAITFILE >> SonarQube.moveout +ECHO These are skl/CSIQSENU : CAST#JCL FTP#INC FTP#RCV FTP#RUN SONARMDL SONARPRM SONARSET SONARTBL SONARW#1 SONARW#2 SONARW#3 XCOM#INC XCOM#JOB XCOM#RCV XCOM#RUN >> SonarQube.moveout +ECHO ./ ADD NAME=BUMPJOB >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\BUMPJOB.rex >> SonarQube.moveout +ECHO. >> SonarQube.moveout +ECHO ./ ADD NAME=C1UEXTR7 >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\C1UEXTR7.rex >> SonarQube.moveout +ECHO. >> SonarQube.moveout +ECHO ./ ADD NAME=DTADJUST >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\DTADJUST.rex >> SonarQube.moveout +ECHO. >> SonarQube.moveout +ECHO ./ ADD NAME=GETACCTC >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\GETACCTC.rex >> SonarQube.moveout +ECHO. >> SonarQube.moveout +ECHO ./ ADD NAME=GTUNIQUE >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\GTUNIQUE.rex >> SonarQube.moveout +ECHO. >> SonarQube.moveout +ECHO ./ ADD NAME=WAITFILE >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\WAITFILE.rex >> SonarQube.moveout +ECHO. >> SonarQube.moveout +ECHO ./ ADD NAME=CAST#JCL >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\CAST#JCL.skl >> SonarQube.moveout +ECHO. >> SonarQube.moveout +ECHO ./ ADD NAME=FTP#INC >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\FTP#INC.skl >> SonarQube.moveout +ECHO. >> SonarQube.moveout +ECHO ./ ADD NAME=FTP#RCV >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\FTP#RCV.skl >> SonarQube.moveout +ECHO. >> SonarQube.moveout +ECHO ./ ADD NAME=FTP#RUN >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\FTP#RUN.skl >> SonarQube.moveout +ECHO. >> SonarQube.moveout +ECHO ./ ADD NAME=SONARMDL >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\SONARMDL.skl >> SonarQube.moveout +ECHO. >> SonarQube.moveout +ECHO ./ ADD NAME=SONARPRM >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\SONARPRM.skl >> SonarQube.moveout +ECHO. >> SonarQube.moveout +ECHO ./ ADD NAME=SONARSET >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\SONARSET.skl >> SonarQube.moveout +ECHO. >> SonarQube.moveout +ECHO ./ ADD NAME=SONARTBL >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\SONARTBL.skl >> SonarQube.moveout +ECHO. >> SonarQube.moveout +ECHO ./ ADD NAME=SONARW#1 >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\SONARW#1.skl >> SonarQube.moveout +ECHO. >> SonarQube.moveout +ECHO ./ ADD NAME=SONARW#2 >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\SONARW#2.skl >> SonarQube.moveout +ECHO. >> SonarQube.moveout +ECHO ./ ADD NAME=SONARW#3 >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\SONARW#3.skl >> SonarQube.moveout +ECHO. >> SonarQube.moveout +ECHO ./ ADD NAME=XCOM#INC >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\XCOM#INC.skl >> SonarQube.moveout +ECHO. >> SonarQube.moveout +ECHO ./ ADD NAME=XCOM#JOB >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\XCOM#JOB.skl >> SonarQube.moveout +ECHO. >> SonarQube.moveout +ECHO ./ ADD NAME=XCOM#RCV >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\XCOM#RCV.skl >> SonarQube.moveout +ECHO. >> SonarQube.moveout +ECHO ./ ADD NAME=XCOM#RUN >> SonarQube.moveout +TYPE SonarQube-interface-to-Endevor\XCOM#RUN.skl >> SonarQube.moveout +ECHO. >> SonarQube.moveout +REM