Analysis of a Sample REXX Reporting Program
All of the REXX reporting programs that are shipped with ChangeMan ZMF have the same structure. We describe program CMN010 in this section to illustrate how the reporting programs work and give you guidelines for customizing them if you wish. You can also use the program as a model to develop your own reporting programs.
The source code for report 010, Summary of Planned and Unplanned Packages, is in member CMN010 of the REXX program library.
Introductory Comments
The following code excerpt is typical of the introductory commentary in each reporting program. The introductory comments:
-
Have the word REXX on the first line (required in all REXX programs).
-
Identify the report number and title. In this example the report number is CMN010 and the title is Summary of Planned and Unplanned Packages.
-
Identify the XML services that are called to provide information for the report. Two XML services are called in this example: PARMS and PACKAGE. See the XML Services User Guide for a description of the XML services that the reporting programs call.
-
Identify the parameters that the program passes to the SERXMLRC program, which handles communication between the reporting program and the target XML service.
/* REXX */ 1
/* ****************************************************************** */
/* Copyright 2003-2012 (C) SERENA Software, Inc. */
/* Licensed material. All rights reserved. */
/* ChangeMan is a registered trademark of SERENA (R) Software Inc. */
/* ****************************************************************** */
/* USE OF THE SAMPLE CODE CONTAINED HEREIN IS SUBJECT TO THE TERMS */
/* CONDITIONS OF THE LICENSE AGREEMENT LOCATED IN THE MEMBER LICENSE */
/* ****************************************************************** */
/* Date Author Reason */
/* 2003-06-01 Serena Original version */
/* ****************************************************************** */
/* REXX CMN010 Summary of Planned and Unplanned Packages */ 2
/* */
/* This report makes use of two XML Services */ 3
/* */
/* Service Scope Message Description */
/* */
/* 1 PARMS APL LIST Obtain the list of Appl. names */
/* 2 PACKAGE SUMMARY SERVICE Obtain counts about Package types */
/* and statuses */
/* */
/* Parameters */ 4
/* */
/* Application name 1 to 4 character mnemonic which may */
/* include the asterisk '*' character to */
/* represent a wild card. If omitted '*' */
/* is assumed. Omission is indicated by a '.' */
/* in the parm list. */
/* */
/* Subsystem letter 1 character indicative of the ChangeMan */
/* system that is being reported upon. Must */
/* be present. A '.' indicates the default */
/* subsystem of ' ' (blank). */
/* */
/* TSO userid 1 to 8 character TSO id used to perform */
/* security checking. Required parameter. */
...
/* */
/* Test switch An indicator with the value 'T' which */
/* specifies that diagnostic trace */
/* information is to be sent to the */
/* SERPRINT DD. The default is no value */
/* other words Tracing is Off. */
/* Since this is the last parm a positional */
/* placeholder is not required. */
/* */
/* ****************************************************************** */
...
Mainline Program Logic
The mainline logic of all the reporting programs is the same. Mainline program logic performs the following functions:
-
Gets the input from the user. (See Getting User Input.)
-
Calls a subroutine in the program to validate the user input. (See Validating User Input.)
-
Calls a subroutine in the program to initialize the variables that will be passed to the target XML service. (See Initializing Variables.)
-
Calls a subroutine to set up the XML service call. (See Setting Up the XML Service Call.)
-
Calls a subroutine that makes the call to the target XML service. (See Calling the Target XML Service.)
-
Calls a subroutine to format and print the output.
-
Calls a subroutine to disconnect from ChangeMan ZMF.
These subroutines appear in the Subroutines section of the reporting program. Selected subroutines that are called in our sample CMN010 program are described below. You may want to consider the annotations given for the code excerpts below while you are looking at a complete program source listing.
Getting User Input
The ARG instruction is used to get the user input. The variable names in the ARG instruction correspond to XML tags in the XML services that the program will be calling.
Caution
Be sure to use variable names in the program that differ from the XML tags to avoid double substitution of variable values.
Here’s the ARG instruction used in program CMN010:
/* Read input parms */
arg appname subname tsoname tst
The arguments are:
-
The name of the target application, a pattern that identifies all applications that match the pattern, or an asterisk that identifies all applications that are defined to the target ChangeMan ZMF subsystem.
-
The name of the target ChangeMan ZMF subsystem.
-
The ID of the requesting TSO user.
-
A test switch (optional). This switch, if present, requests that diagnostic trace information be written to the SERPRINT DDname.
Validating User Input
The program calls the common program CMN000 to validate the user input parameters.
The parameters may vary slightly from report to report but as a general rule they consist of an application name/package number, a subsystem letter, a userid and finally, a test option which should only be used under the direction of Customer Support. For example parts of the validation in CMN000 are as follows:
/* Validate Parms */
Validate_Parms:
/* applname must be 1 to 4 characters if present */ 1
if length(applname) > 4 then
do
call Error_Message 'Application name too long'
end
...
/* subsystem must be 1 character from the approved list */ 2
subsyslt = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#@$ '
if length(subname) > 1 | pos(subname,subsyslt) = 0 then
do
call Error_Message 'Subsystem Letter invalid'
end
...
/* userid must be present and 1 to 8 chars */ 3
if length(tsoname) > 8 | length(tsoname) < 1 then
do
call error_message 'Userid invalid'
end
...
/* test switch must be 'T' or ’X’ if present */ 4
/* it can also be absent or denoted with placeholder '.' */
Select
when tst='T' then nop
when tst='X' then nop
when tst='.' then nop
when tst=' ' then nop
otherwise
do
call Error_Message 'Test Switch invalid: must be T, X or blank'
end
end
...
In this example:
-
The application name must be from 1 to 4 characters if it is supplied.
-
The ChangeMan ZMF subsystem name must be 1 character or blank.
-
The TSO userid of the requester must be present and be from 1 to 8 characters.
-
The test switch, if passed, must have the value T or X. If you are having problems, Customer support may ask you to specify the test switch. If so, diagnostic messages are written to the SERPRINT DDname.
Initializing Variables
The following code excerpt shows the subroutine that program CMN010 uses to initialize the variables:
/* Initialize Variables */
Init_Variables:
if appname = '.' | length(appname) = 0 then /* appl name default */ 1
do
appname = '*'
/* end if */
if subname = '.' | length(subname) = 0 then /* subsys default */ 2
do
subname = ' '
end
/* end if */
/* initialize grand totals */ 3
GTSimple = 0
GTComplex = 0
GTSuper = 0
GTPart = 0
GTPPerm = 0
GTPTemp = 0
GTUPerm = 0
GTUTemp = 0
/* set date /time for report header */
headdate=date()
headtime=time()
/* set page counter variables */
pchar =' ' /* asa required, make null if not FBA */
linect = 99 /* expire the line counter to force headings on page 1 */ 4
lines = 55 /* print 55 data lines per page */
linelen = 132 /* report line length (lrecl-1) */
pagect = 0 /* page counter */
return
...
In our sample CMN010 program:
-
The user can input a period or asterisk for the application name or leave it blank. The program treats any of these values as if the user had specified the asterisk to signify all applications that are defined in the target ChangeMan ZMF subsystem.
-
If the subsystem ID is presented to the program as a period or is not supplied, the program assumes a blank subsystem ID.
-
The program initializes the grand totals to be printed in the report.
-
The program sets up line and page counters.
Setting Up the XML Service Call
All XML services expect the calling REXX reporting program to pass a stem variable.
Here’s the subroutine in our sample CMN010 program that sets up the stem variable that is to be passed to the PARMS APPL LIST service.
Note that the variable names used in the reporting program should differ from the XML tag names to avoid double-substitution of variable values.
/* Set variables for XML call */
Init_XMLStem1:
rxrc = 0 /* initialize our return code */
stem = "SER1." /* set outgoing stem name */
SER2. = "" /* initialize outgoing stem */
SER1. = "" /* initialize outgoing stem */
SER1.Subsys = subname /* subsystem name to query */
SER1.Userid = tsoname /* userid */
SER1.Test = tst /* set test value */
SER1.Product = "CMN " /* set product */
SER1.Service = "PARMS" /* set service*/
SER1.Message = "LIST" /* set message */
SER1.Scope = "APL" /* set scope */
SER1.applname = appname /* set application name */
/* set result set to return */
SER1.includeInResult.1 = "applName"
Return
...
A userid of the following form is required on any stem that is passed for security checking:
SER1.Userid = tsoname / userid to use for security validation /
You can code the tsoname as a string, for example, "abcdefg", or use the REXX function USERID(), which will substitute the current TSO userid or, in the case of a batch job, the TSO userid of the job submitter. SERNET will not allow the tsoname to differ from the real userid of the user who is executing or submitting the job.
Calling the Target XML Service
This Serxmlrc subroutine invokes the SERXMLRC program to make the target XML service call. SERXMLRC is the interface between all ChangeMan ZMF reporting programs and the target XML services. SERXMLRC is a member of the SERCOMC.LOAD library. You must use an ADDRESS instruction in REXX to link to this program through the LINKMVS host command environment.
SERXMLRC expects a REXX stem variable as input, and constructs the service request block from the information that is supplied in the stem variable.
After the target service completes execution, the reporting program checks the return code from the service call and processes the results that the service returned if the call was successful.
Note that the SERXMLRC program does not tailor the result set returned by the target XML service. Thus, the statements following the call to SERXMLRC save only the fields that the reporting program needs (the application name or names, in this example) and drops the returned stem variable to minimize the storage used by the REXX variable pool.
Here’s an excerpt from the CMN010 sample program. The excerpt shows:
-
The instruction that calls the SERXMLRC subroutine in the program.
-
The code for the Serxmlrc subroutine, which invokes the SERXMLRC interface program.
-
Drop the stem variable to conserve storage.
/* make first xml service call */
call Serxmlrc 1
/* for each application returned perform 2nd XML call */
do jx=1 to SER1.result.0
call Init_XMLStem2 /* set up 2nd XML call */
call Serxmlrc /* make 2nd XML call */
if rxrc=0 then call Output_result /* if ok, print out result */
end
/* Print out totals */
call Output_Totals
/* terminate ZMF session */
call Disconnect
...
Serxmlrc: 2
address LINKMVS "SERXMLRC stem"
rxrc=rc
if rxrc<>0 then call Diagnose_Error
Return
...
/* Disconnect and set return code */
Disconnect:
arg exitcode
if exitcode =' ' then exitcode ='0'
call Init_XMLstem0
call Serxmlrc
drop SER0. 3
exit exitcode
...
Diagnosing Errors and Formatting Report Output
The error and output-formatting subroutines in the reporting programs are fairly straightforward, so we do not comment on them here:
-
Report output is written to the SYSTSPRT DDname.
-
Diagnostic messages are written to the SERPRINT DDname.
Use an output display facility such as SDSF to view report output.
Disconnecting from ChangeMan ZMF
To explicitly disconnect from ChangeMan ZMF, you must issue an XML disconnect service call with the following service, scope, and message attributes:
<service name=" ">
<message name="DISCONCT">
<scope name="SERVICE">
See the disconnect code above in the frame. You must ensure that you exit the REXX program if a nonzero return code appears in the reply message. Do not issue a second disconnect request or an infinite loop may result.
The following return codes, which signify REXX environmental errors, can originate from calls to SERXMLRC:
Return Code | Meaning |
---|---|
24 | Error returned from the IRXEXCOM call. |
28 | Error in loading IRXEXCOM the first time. |
32 | No input stem variable was passed. |
...
None of these return codes sets a message as there may be no way to pass a message back by means of the stem variable. All other errors should pass through the STATUSxxx stem variable.