Blog Summary

  • This blog answers the question “How do I avoid coding the CICSplex name in my CPSM API programs?”
  • No hardcoded CICSplex equals greater source flexibility when transitioning code between environments
  • An associated sample COBOL program is available
  •                

The CICSPlex SM API can be used to obtain lots of useful CICSplex related data. Typically, programs using the API issue an EXEC CPSM CONNECT with the CICSplex name supplied as a parameter. The full range of CICSPlex SM API commands can then be used on the associated CICSplex.

However, what if you want to avoid hard coding the CICSplex name within your program? For example, to avoid having to change applications as they transition between Test and Production environments, or where the CICSplex name is unknown. Don’t worry help is at hand!

Programmatically determining the CICSplex name:
I’ve written a simple COBOL program which demonstrates how this can be achieved, which you can view or download from our GitHub repository. The program follows the steps outlined below (note that the following code snippets are highlights, please refer to the program source for the full code including full error checking) :

Step 1: Find out where your CICSPlex SM API program is running
Issuing the EXEC CICS ASSIGN returns the APPLID of the CICS region where your CICSPlex SM program is executing.

EXEC CICS ASSIGN
   APPLID(WS-APPLID)
END-EXEC.

Step 2: Establish a connection to CICSPlex SM
You don’t have to specify the CICSplex name on EXEC CPSM CONNECT. Connecting with just the version number gives you access to some of the CICSPlex SM tables – including the CMASPLEX table which we’ll need shortly.

MOVE '0540' TO WS-CPSM-VERSION.

EXEC CPSM CONNECT
          VERSION(WS-CPSM-VERSION)
          THREAD(WS-THREAD-CICSPLEX)
          RESPONSE(WS-RESPONSE)
          REASON(WS-REASON)
END-EXEC.

Step 3: Query CICSPlex SM for the CICSplexes known to the CMAS your region is managed by
You can issue EXEC CPSM GET on the CMASPLEX table,

INITIALIZE WS-CPSM-TEMPORARY.
MOVE 'CMASPLEX'         TO  WS-CPSM-TEMPORARY-OBJECT.
MOVE CMASPLEX-TBL-LEN   TO  WS-CPSM-TEMPORARY-LENGTH.
MOVE 0                  TO  WS-CPSM-TEMPORARY-COUNT.
MOVE WS-THREAD-CICSPLEX TO  WS-CPSM-TEMPORARY-THREAD. 
...

MOVE 0 TO WS-CPSM-TEMPORARY-COUNT
EXEC CPSM GET
          OBJECT(WS-CPSM-TEMPORARY-OBJECT)
          COUNT(WS-CPSM-TEMPORARY-COUNT)
          RESULT(WS-CPSM-TEMPORARY-RESULT-SET)
          THREAD(WS-CPSM-TEMPORARY-THREAD)
          RESPONSE(WS-RESPONSE)
          REASON(WS-REASON)
END-EXEC  

and then PERFORM a loop which FETCHes each CICSplex and stores the name into an array.

MOVE WS-CPSM-TEMPORARY-RESULT-SET
                             TO WS-CPSM-CMASPLEX-RESULT-SET.
MOVE WS-CPSM-TEMPORARY-COUNT TO WS-CPSM-CMASPLEX-COUNT.

*
*    Initialise the array for storing the CICSPLEX names
*    and the counter to drive the subscript.
*
MOVE SPACES TO WS-CICSPLEX-NAME-ARRAY.
MOVE 0 TO WS-CICSPLEX-NAME-CNT.



*
*    Loop around the number of returned CMASPLEX records
*    fetching each in turn.
*
PERFORM VARYING WS-TEMP-RECORDS-1
        FROM 1 BY 1
        UNTIL WS-TEMP-RECORDS-1 > WS-CPSM-CMASPLEX-COUNT

*
*       Retrieve (FETCH) the next record returned in the
*       Result Set
*
MOVE CMASPLEX-TBL-LEN TO WS-CPSM-TEMPORARY-LENGTH

MOVE WS-CPSM-TEMPORARY-LENGTH TO WS-DISPLAY-LENGTH

EXEC CPSM FETCH INTO(CMASPLEX)
                LENGTH(WS-CPSM-TEMPORARY-LENGTH)
                RESULT(WS-CPSM-CMASPLEX-RESULT-SET)
                THREAD(WS-THREAD-CICSPLEX)
                RESPONSE(WS-RESPONSE)
                REASON(WS-REASON)
END-EXEC


*
*       If the FETCH of the CMASPLEX worked, store the
*       CICSPlex NAME in the CPLEXNAME array.
*
ADD 1 TO WS-CICSPLEX-NAME-CNT

MOVE PLEXNAME OF CMASPLEX TO
   WS-CICSPLEX-NAME-STORE(WS-CICSPLEX-NAME-CNT)

END-PERFORM.

Step 4: Determine the CICSplex your CICS region resides within
Given that an APPLID must be unique within a CICSplex, you can now query each CICSplex in the array to determine which contains the region your program is executing within. This can be done through the use of the EXEC CPSM QUALIFY command – with the CONTEXT and SCOPE set to each array entry (each CICSplex identified earlier) – followed by an EXEC CPSM GET against the CICSRGN table with a CRITERIA of the APPLID.

MOVE 'N' TO WS-CICSPLEX-KNOWN.

PERFORM VARYING WS-TEMP-RECORDS-1
FROM 1 BY 1
UNTIL WS-TEMP-RECORDS-1 > WS-CICSPLEX-NAME-CNT OR
WS-CICSPLEX-KNOWN = 'Y'

   MOVE 'CICSRGN'         TO WS-CPSM-TEMPORARY-OBJECT
   MOVE CICSRGN-TBL-LEN   TO WS-CPSM-TEMPORARY-LENGTH
   MOVE 0                 TO WS-CPSM-TEMPORARY-COUNT

*
*       Set up a CRITERIA string containing the APPLID
*
STRING 'APPLID=' DELIMITED BY SIZE,
        WS-APPLID DELIMITED BY SPACE,
        '.' DELIMITED BY SIZE
        INTO WS-CPSM-TEMPORARY-CRITERIA

        MOVE SPACES             TO WS-CPSM-TEMPORARY-PARM
        MOVE WS-THREAD-CICSPLEX TO WS-CPSM-TEMPORARY-THREAD

        MOVE SPACES TO WS-CPSM-TEMPORARY-SCOPE

        STRING WS-CICSPLEX-NAME-STORE (WS-TEMP-RECORDS-1)
           DELIMITED BY SPACE INTO WS-CPSM-TEMPORARY-SCOPE

        EXEC CPSM QUALIFY
           CONTEXT(WS-CPSM-TEMPORARY-SCOPE)
           SCOPE(WS-CPSM-TEMPORARY-SCOPE)
           THREAD(WS-THREAD-CICSPLEX)
           RESPONSE(WS-RESPONSE)
           REASON(WS-REASON)
        END-EXEC

        EXEC CPSM GET OBJECT(WS-CPSM-TEMPORARY-OBJECT)
                  COUNT(WS-CPSM-TEMPORARY-COUNT)
                  CRITERIA(WS-CPSM-TEMPORARY-CRITERIA)
                  LENGTH(WS-CPSM-TEMP-LEN)
                  RESULT(WS-CPSM-TEMPORARY-RESULT-SET)
                  THREAD(WS-CPSM-TEMPORARY-THREAD)
                  RESPONSE(WS-RESPONSE)
                  REASON(WS-REASON)
        END-EXEC

        IF WS-RESPONSE EQUAL EYUVALUE(OK)
           MOVE WS-CICSPLEX-NAME-STORE (WS-TEMP-RECORDS-1) TO
                WS-SAVED-CICSPLEXNAME
           MOVE 'Y' TO WS-CICSPLEX-KNOWN
        END-IF

END-PERFORM.

If the GET response code is 1024 (OK) then you have found the CICSplex where the CICS region that your program is executing within resides.

Conclusion
Most sites take a dim view of hardcoding, unless absolutely necessary. A no hardcoded CICSplex application is much more flexible and this in turn removes the cost and time involved in updating applications which move between environments. The sample program can be used as a standalone program with the CICSplex name returned in variable WS-SAVED-CICSPLEXNAME or alternatively the sample prgram can be extended to incorporate your own application code.

Join The Discussion

Your email address will not be published. Required fields are marked *