Dec 14 ’11

Common COBOL/VSE Applications for Use in CICS and Batch Environments

by Garry Hasler in z/Journal

With the introduction of some new Language Environment (LE) z/VSE callable services, the ability for a COBOL program to allow seamless execution from within either the batch or CICS environments became a reality. 

This article demonstrates how to implement some of the new LE z/VSE callable services in a COBOL/VSE program. This will provide the application programmer with the ability to develop COBOL/VSE applications that can be executed seamlessly within either batch or CICS environments. Allowing batch or CICS applications to reuse COBOL/VSE routines will improve time-to-ship and reduce development time. COBOL/VSE routines can be developed so they can be called and used by other more environment-specific routines to perform a common process; for example, as company-specific date/time formatting or extraction, integral file or database access, etc.  
 

Applicable Callable Services Review

First, let’s review the callable services that will provide the functionality to allow a COBOL program to interrogate its environment and make execution directives based upon this information: 

Callable Service Implementation

Using the environment information provided by the CEE5INF service, and then calling the CEESITST bit testing service with the information returned from CEE5INF, we can establish in which environment our COBOL/VSE program is executing. By setting a corresponding 88-level flag, we can create an execution logic flow based on specific processing for the batch or CICS environments. Figure 1 shows how to do this using COBOL/VSE.

 

Case Study Definitions and Code 

Assume the fields in Figure 1 are already defined in the Working-Storage and Linkage sections.

The 0300-check-env paragraph section code would look similar to Figure 2. This section is used to determine the COBOL program’s current execution environment.

The call to CEE5INF returns all the required information on the environment we need to be able to make logical decisions to determine in which environment we’re being executed.

Next, we will use the CEESITST callable service to test the bit values of the returned fields from the CEE5INF call (see Figure 3). Using the CEESITST callable service allows the COBOL program to dissect the bit flag values which indicate environment information returned from the earlier CEE5INF call. We can then set our own local level-88 field to the result and use that wherever we need to perform environment-dependent execution.

 

Environment-Independent Application Considerations

Now that we’ve established within which environment our application is running, we can perform batch- or CICS-specific processing. However, it’s important to remember that even though this COBOL program will be capable of running in either the batch or CICS environment, we need to accommodate the environment that has the least tolerance for COBOL verbs in a “lowest common denominator” implementation. This means our application must respect the limitations imposed on CICS/COBOL programs in both environment execution flows. The idea here is to avoid receiving error message IGZ0011C while attempting to execute our application. See the CICS Application Programming Guide for a list and description of restricted COBOL verbs. 

If there’s a requirement to use one or more of the restricted CICS/COBOL verbs in an application potentially being executed in both batch and CICS environments, then one possible circumvention would be to dynamically call a routine to perform those restricted CICS/COBOL verbs or functions when it has been determined at execution time the environment can support those COBOL verbs or functions. 

Methodology

Using the code in Figure 3, we can now perform specific execution flows based upon our execution environment at run-time. 

Figure 4 shows how we would perform some environment-specific processing based on our execution environment. In the batch environment, we will perform some simple batch functions using available LE callable services; then, we will perform some more CICS-specific-type functions in the CICS environment.

 

Mainline Processing

In Figure 4 we select our target paragraph to be executed based on our earlier detected execution environment (see Figure 3). The code in each of these paragraphs must conform to the CICS/COBOL restrictions irrespective of the actual execution environment. If an unexpected environment has been detected, then a non-zero return code is set and the COBOL/VSE program terminates. After completion, some simple return-code checking is performed. 

For demonstration purposes, our case study will perform termination based on our execution environment. 

In most production situations, a single GOBACK can be used for termination in both the batch and CICS environments. This can also be useful if the environment-independent routine is to be called from other modules. However, if desired, the environment-specific termination method in Figure 4 can be used. 

Next, we will examine the batch-specific paragraph, 0200-batch, in Figure 5. For our batch-specific paragraph, as a simple demonstration, we will call the LE random number generator callable service dynamically to return a random number between 0 and 1, exclusively. This could also be performed as a static call, if desired.

We then convert this random number into a value between one and 100. This number is then displayed in the program output. If the service fails for any reason, the message number associated with the failure is displayed in the program output. 

For the second and final stage of our batch execution process example, we perform a static call to the callable service CEE5TSTG as a simple demonstration that will test our access to the address contained in field “test-addr.” As this field is zero, we’re effectively testing our COBOL program’s access to low memory (basically, location zero).Once the service returns, we review the feedback code. Based on the value provided, a message is sent to the COBOL program’s output file to indicate the result of the service. Much of the code from Figure 5 has been taken from the supplied sample IGZTSTG.C in PRD2.SCEEBASE. Paragraph 022-batch is then completed and control returns to the statement following the paragraph call.

Next, we will examine the CICS-specific paragraph, 0200-CICS, in Figure 6. First, we address the current CICS application EIB to ensure that any subsequent CICS calls we may execute that require a valid EIB will complete as expected. Normally, we would be passed the EIB as a parameter, as the CICS translator adds this to our source code; this step is simply to accommodate any possible calls that may not adhere to this standard practice. 

Now we issue the console message in Figure 6, using CICS services just for execution flow tracing purposes. Since we have an EIB, we can see if we have a valid COMMAREA available. We do this by checking the COMMAREA length field contained within the EIB. If this is greater than zero, then a COMMAREA exists. When we have determined if a COMMAREA is available, we then set the relevant 88-level flag to indicate this. 

Next, we attempt to determine how our sample program was called in the CICS environment. We do this by using the EXEC CICS INVOKINGPROG API and comparing the results with a field of eight blanks. If blanks are returned, then we’ve been invoked by a CICS transaction starting. If not, then we were called by another CICS program using CICS services, such as EXEC CICS LINK, etc. 

Our next CICS environment step is to make a static call to another program (see Figure 7). In this simple example, we call the LE z/VSE delay callable service to perform a temporary “wait.” In this invocation, we delay for approximately 2 seconds.

We review the returned feedback code so we know if the delay actually occurred. In a real production situation where the delay may be important, this would allow the program to know if whatever we were waiting for had actually experienced a 2-second interval.           

Again, as a demonstration using the code in Figure 8, we perform a dynamic call in the CICS environment. This is to the same random number generator callable service that we used earlier in the batch execution flow example.

 

Due to the OPEN/READ/WRITE/CLOSE, etc. verbs being restricted in a CICS environment, we demonstrate a VSAM file read in the CICS environment using CICS services. To perform the same processing from this case study module in the batch section would require all I/O processing to be performed in another module that needs to be dynamically called. 

Expected Case Study Output

Figure 9 shows some samples of the output from the program run in both environments.

JCL Considerations

As with any CICS application, our case study and any other COBOL/VSE programs wanting to be executed in both the batch and CICS environments will need to first be passed through the CICS translator. The CICS language interface stub, DFHELII, also needs to be included at link-edit time to provide HLAPI support in the CICS environment. 

It’s also important to ensure that the link-edited PHASE has an entry point of the COBOL routine. This will, in the majority of cases, be done automatically. However, it’s worth pointing out as one of the things to check when developing a new application to be used in both the CICS and batch  environments. 

Available Sample

The COBOL/VSE sample program used in this article case study is available for download. The sample code and compiling JCL are available at ftp://public.dhe.ibm.com/eserver/zseries/zos/vse/download/COBJOURN.txt. This sample includes JCL that can be used to compile, link-edit, and execute (in the batch environment) the case study program and be used as a template for development of new environment-independent COBOL/VSE applications.

 The JCL provided in Figure 9 includes execution of the case study in the batch environment. Three separate LSTQ output members will be produced. The first is the CICS translator output, the second is the compile and link-edit output, and the final member will contain the batch execution output and console log. 

To run the case study in a CICS environment, you will need to define a transaction that has the case study program defined as the target, define the case study as a program, and then make the site-dependent security adjustments to allow for the transaction to be executed. Install the relevant CICS group using the CEDA transaction and then invoke the transaction. The CICS output log, operator console, and terminal used to execute the transaction should all be reviewed to see the complete execution flow. 

Case Study CICS Definitions

Following are some sample DFHCSDUP definitions that could be used to define the case study for execution under CICS: 

DEFINE PROGRAM(COBJOUR) GROUP(???) LANGUAGE(COBOL)

DEFINE TRANS(COBJ) PROGRAM(COBJOUR) GROUP(???) 

Restrictions