Oops, one of the CICS data tables in our system filled up, and, unfortunately, the application did not report the NOSPACE condition or even abend when it ran into the problem. So, I guess that makes it the system programmer’s responsibility to detect. (That was a bit of sarcasm.)
Can we detect this condition with a CICS System Event? Or, with CPSM resource monitoring?
No, not really. At least I don’t see it. We can report on a not-OK condition on a EXEC CICS WRITE with a system event, but that not really granular enough. Reporting on the condition requires some development, too (MQ?).
We can detect that a table is full or nearing full with CPSM (CURCOUNT reaches a certain threshold value) which is closer. But I would prefer to have the threshold as a percentage (CURCOUNT nn% of MAXNUMRECS) and I don’t see how to do these caparisons. Also, I don’t see how to coax the resulting message to contain the file name that is having the problem other than setting up a monitor for each table.
Time for another program.
We will start a transaction during startup PLT that will query the CICS region via CPSM, gather the set of data tables, check CURCOUNT against MAXNUMRECS and report various threshold values. And then the transaction will schedule itself to run again in ten minutes. When a table becomes dangerously full, the console message will be issued which can be picked up by an automation product to send text or email alerts or garner the operator’s attention to call someone.
I’m starting with one of the IBM supplied sample COBOL programs that uses the EXEC CPSM API, SEYUSAMP(EYULAPI2). So, apologies in advance for some of the lame field names and a bunch of GO TO statements.
The basic flow of the program is to
- Connect to CPSM using the known CICSPLEX name with a SCOPE of the current CICS region.
- Get the CMDT resource table.
- Loop through fetch each table entry checking CURCOUNT against MAXNUMRECS and reporting as required.
- Disconnect (terminate) from CPSM
Connect
WORKING-STORAGE SECTION. 01 W-SCOPE PIC X(8). 01 W-RESPONSE PIC S9(8) USAGE BINARY. 01 W-REASON PIC S9(8) USAGE BINARY. 01 W-THREAD PIC S9(8) USAGE BINARY. 01 W-RESULT-TOK PIC S9(8) USAGE BINARY. 01 W-RECCNT PIC S9(8) USAGE BINARY. 01 W-INTO-OBJECTLEN PIC S9(8) USAGE BINARY. 01 W-RESULT PIC S9(8) USAGE BINARY. 01 W-COUNT PIC S9(8) USAGE BINARY. 01 W-PCT PIC S9(8) USAGE BINARY. 01 W-TEXT PIC X(80) VALUE SPACES. 01 W-TEXT-PCT PIC ZZ9. 01 W-MSG-TEXT PIC X(80) VALUE SPACES. 01 III PIC S9(8) VALUE ZERO. 01 JJJ PIC S9(8) VALUE ZERO. 01 PICZZZ9A PIC ZZZ9. 01 PICZZZ9B PIC ZZZ9. 01 W-WTO PIC X(64). COPY CMDT. LINKAGE SECTION. PROCEDURE DIVISION. EXEC CICS ASSIGN APPLID(W-SCOPE) END-EXEC EXEC CPSM CONNECT CONTEXT('CICSPLEX') SCOPE(W-SCOPE) VERSION('0510') THREAD(W-THREAD) RESPONSE(W-RESPONSE) REASON(W-REASON) END-EXEC. IF W-RESPONSE NOT = EYUVALUE(OK) GO TO NO-CONNECT.
This call usually fails the first time the transaction runs. I think this is because, during CICS startup, the CPSM environment is not ready.
CMDT Get
EXEC CPSM GET OBJECT('CMDT') COUNT(W-COUNT) RESULT(W-RESULT) THREAD(W-THREAD) RESPONSE(W-RESPONSE) REASON(W-REASON) END-EXEC. IF W-RESPONSE NOT = EYUVALUE(OK) GO TO NO-GET.
CMDT Fetch Loop
MOVE 1 TO III. LOOPTOP. IF III > W-RECCNT GO TO JJJBOT. MOVE CMDT-TBL-LEN TO W-INTO-OBJECTLEN. EXEC CPSM FETCH INTO(CMDT) LENGTH(W-INTO-OBJECTLEN) RESULT(W-RESULT-TOK) THREAD(W-THREAD) RESPONSE(W-RESPONSE) REASON(W-REASON) END-EXEC. IF W-RESPONSE NOT = EYUVALUE(OK) GO TO NO-FETCH.
This is how we determine how full the table is…
COMPUTE W-PCT = (CURCOUNT * 100) / MAXNUMRECS.
If the table is more than 70% full, we put out a message to CESE/CEEMSG using the COBOL DISPLAY verb. At 80 % we will also issue a WTO and at 95% the WTO will be flagged for immediate action.
IF W-PCT >= 70 THEN STRING 'xxxxxxxx ' DELIMITED BY SIZE W-SCOPE DELIMITED BY ' ' ' Warning: CICS Table ' DELIMITED BY SIZE FILE-R DELIMITED BY ' ' ' is now ' DELIMITED BY SIZE W-TEXT-PCT DELIMITED BY SIZE '% full!' DELIMITED BY SIZE INTO W-WTO DISPLAY W-WTO IF W-PCT >= 80 THEN IF W-PCT >= 95 THEN EXEC CICS WRITE OPERATOR TEXT(W-WTO) IMMEDIATE END-EXEC ELSE EXEC CICS WRITE OPERATOR TEXT(W-WTO) EVENTUAL END-EXEC END-IF END-IF END-IF ADD 1 TO III. GO TO LOOPTOP.
Terminate, error handling, restart
And the rest…
JJJBOT. GO TO ENDIT. *-------------------------------------------------------------* * PROCESSING FOR API FAILURES. * *-------------------------------------------------------------* NO-CONNECT. MOVE 'xxxxxxxx ERROR CONNECTING TO API.' TO W-MSG-TEXT. GO TO SCRNLOG. NO-GET. MOVE 'xxxxxxxx ERROR GETTING RESOURCE TABLE.' TO W-MSG-TEXT. GO TO SCRNLOG. NO-FETCH. MOVE 'xxxxxxxx ERROR FETCHING RESULT SET.' TO W-MSG-TEXT. GO TO SCRNLOG. NO-LOCATE. MOVE 'xxxxxxxx ERROR LOCATING TOP OF RESULT SET.' TO W-MSG-TEXT. GO TO SCRNLOG. SCRNLOG. DISPLAY W-MSG-TEXT. MOVE SPACES TO W-MSG-TEXT. MOVE W-RESPONSE TO PICZZZ9A. MOVE W-REASON TO PICZZZ9B. STRING 'xxxxxxxx RESPONSE=' DELIMITED BY SIZE PICZZZ9A DELIMITED BY SIZE ', REASON=' DELIMITED BY SIZE PICZZZ9B DELIMITED BY SIZE INTO W-MSG-TEXT. DISPLAY W-MSG-TEXT. * Try again if not available, * may just not be connected to the CMAS yet after startup IF W-RESPONSE = EYUVALUE(NOTAVAILABLE) THEN GO TO ENDIT END-IF EXEC CICS ABEND ABCODE('XXXX') END-EXEC. ENDIT. *-------------------------------------------------------------* * terminate api connection & restart in 10 minutes * *-------------------------------------------------------------* EXEC CPSM TERMINATE RESPONSE(W-RESPONSE) REASON(W-REASON) END-EXEC. EXEC CICS START TRANSID(EIBTRNID) AFTER MINUTES(10) END-EXEC. GOBACK.