Chapter 38 Exercises: Modern COBOL Integrations
These exercises are organized into five tiers of increasing difficulty. Work through them sequentially to build mastery, or jump to the tier that matches your current skill level.
Tier 1: Recall (Exercises 1-7)
These exercises cover the fundamental syntax and concepts of COBOL integration with modern technologies.
Exercise 1: JSON GENERATE Basics
Write a COBOL program that defines a customer record in WORKING-STORAGE and uses JSON GENERATE to convert it into a JSON string. The customer record should contain: - Customer ID (PIC 9(8)) - First name (PIC X(20)) - Last name (PIC X(25)) - Balance (PIC 9(7)V99)
Display the generated JSON string.
Solution:
IDENTIFICATION DIVISION.
PROGRAM-ID. JSONGENA.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-CUSTOMER.
05 CUST-ID PIC 9(8) VALUE 10045382.
05 FIRST-NAME PIC X(20) VALUE "ELENA".
05 LAST-NAME PIC X(25) VALUE "MARTINEZ".
05 BALANCE PIC 9(7)V99 VALUE 15420.75.
01 WS-JSON-OUTPUT PIC X(500) VALUE SPACES.
01 WS-JSON-LENGTH PIC 9(5) VALUE 0.
PROCEDURE DIVISION.
0000-MAIN.
JSON GENERATE WS-JSON-OUTPUT
FROM WS-CUSTOMER
COUNT WS-JSON-LENGTH
END-JSON
DISPLAY "Generated JSON:"
DISPLAY WS-JSON-OUTPUT(1:WS-JSON-LENGTH)
DISPLAY "Length: " WS-JSON-LENGTH
STOP RUN.
Expected output (approximately):
Generated JSON:
{"CUST-ID":10045382,"FIRST-NAME":"ELENA","LAST-NAME":"MARTINEZ","BALANCE":15420.75}
Exercise 2: JSON PARSE Basics
Write a COBOL program that parses the following JSON string into a COBOL data structure and displays the extracted fields:
{"orderId":"ORD-99201","quantity":25,"unitPrice":14.99}
Solution:
IDENTIFICATION DIVISION.
PROGRAM-ID. JSONPARA.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-JSON-INPUT PIC X(200) VALUE
'{"orderId":"ORD-99201","quantity":25,'
& '"unitPrice":14.99}'.
01 WS-ORDER-DATA.
05 ORDERID PIC X(10).
05 QUANTITY PIC 9(5).
05 UNITPRICE PIC 9(5)V99.
01 WS-TOTAL-COST PIC 9(7)V99.
01 WS-FMT-COST PIC $$$,$$$,$$9.99.
PROCEDURE DIVISION.
0000-MAIN.
JSON PARSE WS-JSON-INPUT
INTO WS-ORDER-DATA
END-JSON
DISPLAY "Order ID: " ORDERID
DISPLAY "Quantity: " QUANTITY
DISPLAY "Unit Price: " UNITPRICE
COMPUTE WS-TOTAL-COST =
QUANTITY * UNITPRICE
MOVE WS-TOTAL-COST TO WS-FMT-COST
DISPLAY "Total Cost: " WS-FMT-COST
STOP RUN.
Exercise 3: XML GENERATE Basics
Write a COBOL program that generates an XML document from an employee record containing employee number, name, department, and hire date. Display the generated XML.
Solution:
IDENTIFICATION DIVISION.
PROGRAM-ID. XMLGENA.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-EMPLOYEE.
05 EMP-NUMBER PIC 9(6) VALUE 204518.
05 EMP-NAME PIC X(30) VALUE "JOHNSON, MICHAEL".
05 DEPARTMENT PIC X(15) VALUE "ACCOUNTING".
05 HIRE-DATE PIC 9(8) VALUE 20180315.
01 WS-XML-OUTPUT PIC X(1000) VALUE SPACES.
01 WS-XML-LENGTH PIC 9(5) VALUE 0.
PROCEDURE DIVISION.
0000-MAIN.
XML GENERATE WS-XML-OUTPUT
FROM WS-EMPLOYEE
COUNT WS-XML-LENGTH
END-XML
DISPLAY "Generated XML:"
DISPLAY WS-XML-OUTPUT(1:WS-XML-LENGTH)
STOP RUN.
Exercise 4: Identifying Integration Technologies
For each of the following scenarios, identify the most appropriate integration technology from: JSON PARSE/GENERATE, XML GENERATE, REST API (z/OS Connect), SOAP Web Service, IBM MQ, or direct database call.
- A mobile banking app needs to retrieve account balances from a mainframe COBOL program.
- A COBOL program must send a regulatory report in a structured markup format to a government agency system.
- A real-time fraud detection system must notify a COBOL batch program about suspicious transactions as they occur.
- A COBOL program needs to exchange data with a partner bank's legacy system that uses a formal service contract with WSDL.
- A COBOL program must convert internal data structures to a lightweight format for consumption by a JavaScript front-end.
Solution:
- REST API via z/OS Connect -- Mobile apps typically consume RESTful APIs with JSON payloads. z/OS Connect exposes COBOL programs as REST endpoints.
- XML GENERATE -- Government agencies often require XML-formatted submissions with strict schema compliance.
- IBM MQ -- Message queuing provides asynchronous, guaranteed delivery for real-time event notification between systems.
- SOAP Web Service -- SOAP with WSDL provides the formal contract-based interface expected by legacy partner systems.
- JSON GENERATE -- JSON is the native data format for JavaScript front-ends and is lightweight for web transmission.
Exercise 5: z/OS Connect Concepts
Answer the following questions about z/OS Connect:
- What is a Service Archive (SAR) file?
- What is the role of the API Requester?
- What mapping step converts COBOL copybook layouts to JSON schemas?
- What is the default HTTP method for a z/OS Connect REST API that retrieves data?
Solution:
- A Service Archive (SAR) file is a deployable package that contains the service definition, mapping rules, and metadata needed by z/OS Connect to expose a COBOL program as a RESTful API.
- The API Requester is the z/OS Connect component that allows COBOL programs to call external REST APIs -- it handles outbound HTTP requests, JSON parsing, and response mapping back to COBOL data structures.
- The mapping step uses the z/OS Connect API Toolkit or Mapping Assistant to generate JSON-to-COBOL and COBOL-to-JSON mappings from COBOL copybook layouts (01-level structures with their PIC clauses).
- The default HTTP method for data retrieval is GET. POST is used for creation, PUT for update, and DELETE for removal.
Exercise 6: IBM MQ Terminology
Match each IBM MQ term with its correct definition:
Terms: Queue Manager, Queue, Channel, Message, Connection Handle
Definitions: A. A named destination where messages are stored until consumed. B. The primary MQ administrative unit that manages queues and channels. C. A communication link between two queue managers or between a program and a queue manager. D. A unit of data exchanged between applications through MQ. E. A token returned by MQCONN that identifies a program's connection to a queue manager.
Solution:
- Queue Manager = B -- The primary MQ administrative unit.
- Queue = A -- A named destination for message storage.
- Channel = C -- A communication link between queue managers or between program and queue manager.
- Message = D -- A unit of data exchanged between applications.
- Connection Handle = E -- A token identifying the program's MQ connection.
Exercise 7: JSON NAME Clause
Write the WORKING-STORAGE definition for a record where the COBOL data names differ from the desired JSON field names. The JSON output should use camelCase names:
accountNumber(COBOL:WS-ACCT-NUM)accountType(COBOL:WS-ACCT-TYPE)currentBalance(COBOL:WS-CURR-BAL)isActive(COBOL:WS-ACTIVE-FLAG)
Use the JSON NAME clause to specify the mapping.
Solution:
01 WS-ACCOUNT-DATA.
05 WS-ACCT-NUM PIC 9(10)
JSON NAME "accountNumber".
05 WS-ACCT-TYPE PIC X(8)
JSON NAME "accountType".
05 WS-CURR-BAL PIC 9(9)V99
JSON NAME "currentBalance".
05 WS-ACTIVE-FLAG PIC 9
JSON NAME "isActive".
Tier 2: Understand (Exercises 8-14)
These exercises require explanation, comparison, and tracing through integration code.
Exercise 8: JSON GENERATE with Nested Structures
Trace through the following code and write the expected JSON output:
01 WS-ORDER.
05 ORDER-ID PIC X(10) VALUE "ORD-55102".
05 ORDER-DATE PIC 9(8) VALUE 20250915.
05 CUSTOMER.
10 CUST-NAME PIC X(20) VALUE "CHEN, DAVID".
10 CUST-EMAIL PIC X(30)
VALUE "dchen@example.com".
05 LINE-ITEMS.
10 ITEM-COUNT PIC 9(2) VALUE 2.
01 WS-JSON PIC X(500).
01 WS-JSON-LEN PIC 9(5).
JSON GENERATE WS-JSON FROM WS-ORDER
COUNT WS-JSON-LEN
Solution:
The generated JSON reflects the nested COBOL group structure. Group items become JSON objects:
{
"ORDER-ID": "ORD-55102",
"ORDER-DATE": 20250915,
"CUSTOMER": {
"CUST-NAME": "CHEN, DAVID",
"CUST-EMAIL": "dchen@example.com"
},
"LINE-ITEMS": {
"ITEM-COUNT": 2
}
}
Note: The actual JSON generated by the compiler is not pretty-printed -- it is a single line. Group items (CUSTOMER, LINE-ITEMS) are rendered as nested JSON objects. Alphanumeric fields are quoted strings; numeric fields are unquoted numbers.
Exercise 9: Comparing JSON and XML for COBOL Integration
Compare JSON PARSE/GENERATE with XML PARSE/GENERATE for COBOL integration across the following dimensions. For each, explain which is better suited and why.
- Payload size for large-volume batch transmissions
- Schema validation and formal contracts
- Integration with modern JavaScript/React front-ends
- Compatibility with legacy enterprise service buses
- Ease of mapping to COBOL copybook structures
Solution:
- JSON -- JSON payloads are smaller (no closing tags, less verbose) which matters for high-volume batch transmissions where bandwidth and processing time are critical.
- XML -- XML has robust schema validation (XSD) and formal namespaces. SOAP/WSDL contracts are XML-based, making XML better for systems requiring strict contract enforcement.
- JSON -- JavaScript natively parses JSON (
JSON.parse()). No additional libraries needed. JSON is the de facto standard for REST APIs consumed by modern front-ends. - XML -- Most legacy enterprise service buses (IBM Integration Bus, TIBCO, MuleSoft older versions) were built around XML/SOAP. XML integration is more mature in these environments.
- Both are comparable -- Both map reasonably to COBOL's hierarchical group/elementary item structure. JSON's flat key-value pairs map cleanly to COBOL elementary items. XML's element nesting maps to COBOL group items.
Exercise 10: MQ Message Flow Tracing
Trace the flow of the following COBOL MQ operations and describe what happens at each step:
CALL 'MQCONN' USING WS-QM-NAME
WS-HCONN
WS-COMP-CODE
WS-REASON
MOVE MQOO-OUTPUT TO MQOO-OPTIONS
CALL 'MQOPEN' USING WS-HCONN
WS-OBJDESC
WS-OPEN-OPTIONS
WS-HOBJ
WS-COMP-CODE
WS-REASON
MOVE MQMT-DATAGRAM TO MQMD-MSGTYPE
MOVE MQFMT-STRING TO MQMD-FORMAT
CALL 'MQPUT' USING WS-HCONN
WS-HOBJ
WS-MSGDESC
WS-PMO
WS-MSG-LENGTH
WS-MSG-BUFFER
WS-COMP-CODE
WS-REASON
CALL 'MQCLOSE' USING WS-HCONN
WS-HOBJ
MQCO-NONE
WS-COMP-CODE
WS-REASON
CALL 'MQDISC' USING WS-HCONN
WS-COMP-CODE
WS-REASON
Solution:
- MQCONN -- Establishes a connection to the queue manager named in
WS-QM-NAME. Returns a connection handle (WS-HCONN) used by all subsequent MQ calls. The completion code and reason code indicate success or failure. - MQOPEN -- Opens a specific queue (identified in
WS-OBJDESC) for output (MQOO-OUTPUT). Returns an object handle (WS-HOBJ) for the opened queue. The program can now put messages onto this queue. - MQPUT -- Sends a message to the open queue. The message is in
WS-MSG-BUFFERwith lengthWS-MSG-LENGTH. The message descriptor (WS-MSGDESC) is set to datagram type (one-way, no reply expected) and string format. The put-message options (WS-PMO) control delivery behavior. - MQCLOSE -- Closes the queue handle.
MQCO-NONEindicates no special close options. After this call,WS-HOBJis no longer valid. - MQDISC -- Disconnects from the queue manager, releasing the connection handle. All resources associated with the connection are freed.
Exercise 11: REST API Response Codes
For each HTTP response status code, describe what it means in the context of a COBOL program exposed as a REST API through z/OS Connect, and what COBOL program behavior would trigger it:
- 200 OK
- 400 Bad Request
- 404 Not Found
- 500 Internal Server Error
- 503 Service Unavailable
Solution:
- 200 OK -- The COBOL program executed successfully and returned valid data. Triggered by normal program completion with a valid response structure.
- 400 Bad Request -- The incoming request data failed validation. Triggered when z/OS Connect mapping detects invalid JSON format or when the COBOL program sets an error return code indicating bad input data.
- 404 Not Found -- The requested resource does not exist. Triggered when the COBOL program searches for a record (e.g., by account number) and the record is not found. The program returns a "not found" status that z/OS Connect maps to 404.
- 500 Internal Server Error -- An unexpected error occurred in the COBOL program. Triggered by an unhandled abend, a file I/O error, a DB2 error, or any condition that prevents normal program completion.
- 503 Service Unavailable -- The service is temporarily unable to handle the request. Triggered when the COBOL program's resources are unavailable (e.g., a required VSAM file is closed for batch processing, or the CICS region is at maximum task capacity).
Exercise 12: SOAP vs. REST for COBOL Services
Compare SOAP and REST approaches for exposing COBOL program functionality to external consumers. Address each of the following:
- Message format and protocol
- Service contract definition
- Tool support on z/OS
- Suitability for mobile clients
- Error handling mechanisms
Solution:
- SOAP uses XML messages over HTTP/HTTPS (or other protocols like MQ). REST uses JSON (typically) over HTTP/HTTPS. SOAP messages are larger due to XML envelope overhead.
- SOAP uses WSDL (Web Services Description Language) for formal, machine-readable contracts. REST uses OpenAPI/Swagger specifications, which are simpler but less formal. SOAP's strict contract is better for B2B integrations.
- SOAP on z/OS uses CICS Web Services or IMS SOAP Gateway. REST on z/OS uses z/OS Connect EE, which provides a modern API management layer. Both have mature tooling.
- REST is far better for mobile clients due to lighter payloads (JSON), simpler parsing, and alignment with modern mobile development frameworks. SOAP's XML overhead is burdensome on mobile networks.
- SOAP uses standardized fault elements within the SOAP envelope. REST relies on HTTP status codes (400, 404, 500, etc.) and JSON error bodies. SOAP's fault handling is more structured; REST's is simpler.
Exercise 13: JSON PARSE Error Handling
Explain what happens when JSON PARSE encounters each of the following error conditions. What should the COBOL program do in each case?
- The JSON input string is not valid JSON (missing closing brace).
- A JSON field name does not match any field in the COBOL target structure.
- A JSON numeric value exceeds the capacity of the COBOL PIC clause.
- The JSON input contains a nested array, but the COBOL structure does not define a table.
Solution:
- Invalid JSON: The JSON PARSE raises an exception (condition EXCEPTION/ERROR). The COBOL program should include
ON EXCEPTIONhandling to detect parse failures and return an appropriate error response. - Unmatched field name: By default, unmatched JSON fields are ignored (the COBOL field retains its previous value). Using the
SUPPRESSphrase orNAMEclauses can control this behavior. The program should validate that required fields were populated after parsing. - Numeric overflow: The value is truncated to fit the PIC clause, potentially losing significant digits. The program should validate parsed numeric values against business rules after parsing.
- Array without table: If the JSON contains an array but the COBOL target is not an OCCURS structure, the parse may fail or only capture the first element. The program should define appropriate OCCURS clauses for expected arrays.
Exercise 14: Microservices Architecture with COBOL
Describe how a COBOL program running on z/OS can participate in a microservices architecture. Address:
- How z/OS Connect enables COBOL to act as a microservice provider.
- How a COBOL program can consume external microservices using the API Requester.
- What role API management (like IBM API Connect) plays in the architecture.
- How data format translation between COBOL copybooks and JSON/XML is handled.
Solution:
- Service provider: z/OS Connect wraps a COBOL CICS transaction or IMS transaction as a RESTful API. It generates an OpenAPI specification, maps JSON request/response to COBOL copybook layouts, and handles HTTP protocol concerns. The COBOL program processes the request as a normal CICS or IMS transaction, unaware it was invoked via REST.
- Service consumer: The API Requester component in z/OS Connect allows COBOL to call external REST APIs. It converts COBOL data to JSON for the outbound request, makes the HTTP call, and maps the JSON response back to COBOL data structures. The COBOL program sees standard COBOL data items.
- API management: IBM API Connect provides rate limiting, authentication, analytics, and developer portal capabilities on top of z/OS Connect APIs. It acts as the gateway between external consumers and the mainframe services.
- Data format translation: The z/OS Connect API Toolkit or CICS Assistant generates mapping artifacts from COBOL copybooks. These mappings handle type conversion (PIC 9 to JSON number, PIC X to JSON string), name transformation (COBOL hyphens to JSON camelCase), and structure flattening/nesting as needed.
Tier 3: Apply (Exercises 15-22)
These exercises require writing complete or substantial COBOL integration code.
Exercise 15: Customer Record JSON Round-Trip
Write a complete COBOL program that: 1. Defines a customer record with 6 fields including a nested address structure. 2. Populates the record with sample data. 3. Uses JSON GENERATE to produce a JSON string. 4. Clears the original record. 5. Uses JSON PARSE to reload the record from the JSON string. 6. Displays all fields to verify the round-trip.
Solution:
IDENTIFICATION DIVISION.
PROGRAM-ID. JSONRTRP.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-CUSTOMER.
05 CUSTID PIC 9(8) VALUE 0.
05 FIRSTNAME PIC X(20) VALUE SPACES.
05 LASTNAME PIC X(25) VALUE SPACES.
05 CUSTADDRESS.
10 STREET PIC X(30) VALUE SPACES.
10 CITY PIC X(20) VALUE SPACES.
10 STATE PIC X(2) VALUE SPACES.
10 ZIPCODE PIC X(10) VALUE SPACES.
05 PHONE PIC X(15) VALUE SPACES.
05 BALANCE PIC 9(9)V99 VALUE 0.
01 WS-JSON-BUFFER PIC X(2000) VALUE SPACES.
01 WS-JSON-LENGTH PIC 9(5) VALUE 0.
PROCEDURE DIVISION.
0000-MAIN.
PERFORM 1000-POPULATE-DATA
PERFORM 2000-GENERATE-JSON
PERFORM 3000-CLEAR-RECORD
PERFORM 4000-PARSE-JSON
PERFORM 5000-DISPLAY-RESULTS
STOP RUN
.
1000-POPULATE-DATA.
MOVE 30128574 TO CUSTID
MOVE "MARIA" TO FIRSTNAME
MOVE "GONZALEZ" TO LASTNAME
MOVE "742 EVERGREEN TERRACE" TO STREET
MOVE "SPRINGFIELD" TO CITY
MOVE "IL" TO STATE
MOVE "62704" TO ZIPCODE
MOVE "217-555-0143" TO PHONE
MOVE 45872.50 TO BALANCE
DISPLAY "--- Original Data ---"
PERFORM 9000-DISPLAY-CUSTOMER
.
2000-GENERATE-JSON.
JSON GENERATE WS-JSON-BUFFER
FROM WS-CUSTOMER
COUNT WS-JSON-LENGTH
ON EXCEPTION
DISPLAY "JSON GENERATE failed"
STOP RUN
END-JSON
DISPLAY " "
DISPLAY "--- Generated JSON ---"
DISPLAY WS-JSON-BUFFER(1:WS-JSON-LENGTH)
.
3000-CLEAR-RECORD.
INITIALIZE WS-CUSTOMER
DISPLAY " "
DISPLAY "--- After INITIALIZE (cleared) ---"
PERFORM 9000-DISPLAY-CUSTOMER
.
4000-PARSE-JSON.
JSON PARSE WS-JSON-BUFFER(1:WS-JSON-LENGTH)
INTO WS-CUSTOMER
ON EXCEPTION
DISPLAY "JSON PARSE failed"
STOP RUN
END-JSON
.
5000-DISPLAY-RESULTS.
DISPLAY " "
DISPLAY "--- After JSON PARSE (restored) ---"
PERFORM 9000-DISPLAY-CUSTOMER
.
9000-DISPLAY-CUSTOMER.
DISPLAY " Customer ID: " CUSTID
DISPLAY " Name: " FIRSTNAME " " LASTNAME
DISPLAY " Street: " STREET
DISPLAY " City/St/Zip: " CITY " " STATE
" " ZIPCODE
DISPLAY " Phone: " PHONE
DISPLAY " Balance: " BALANCE
.
Exercise 16: XML Generation with Attributes
Write a COBOL program that generates an XML document for a product catalog entry. Use XML GENERATE with namespace support and attributes where appropriate.
Solution:
IDENTIFICATION DIVISION.
PROGRAM-ID. XMLCATLG.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-PRODUCT.
05 PRODUCT-ID PIC X(10) VALUE "PRD-88412".
05 PRODUCT-NAME PIC X(40)
VALUE "Industrial Pressure Gauge".
05 CATEGORY PIC X(15) VALUE "INSTRUMENTATION".
05 SPECIFICATIONS.
10 WEIGHT PIC 9(3)V9 VALUE 2.5.
10 WIDTH-CM PIC 9(3) VALUE 12.
10 HEIGHT-CM PIC 9(3) VALUE 8.
05 PRICING.
10 LIST-PRICE PIC 9(5)V99 VALUE 149.95.
10 COST-PRICE PIC 9(5)V99 VALUE 67.30.
10 CURRENCY PIC X(3) VALUE "USD".
05 IN-STOCK PIC 9(5) VALUE 342.
01 WS-XML-BUFFER PIC X(2000) VALUE SPACES.
01 WS-XML-LENGTH PIC 9(5) VALUE 0.
PROCEDURE DIVISION.
0000-MAIN.
XML GENERATE WS-XML-BUFFER
FROM WS-PRODUCT
COUNT WS-XML-LENGTH
WITH XML-DECLARATION
ON EXCEPTION
DISPLAY "XML GENERATE failed"
STOP RUN
END-XML
DISPLAY "Generated XML (" WS-XML-LENGTH " bytes):"
DISPLAY WS-XML-BUFFER(1:WS-XML-LENGTH)
STOP RUN.
Exercise 17: MQ Message Send Program
Write a COBOL program that sends a transaction notification message to an IBM MQ queue. The program should: 1. Connect to the queue manager. 2. Open the notification queue for output. 3. Build a JSON-formatted message body. 4. Send the message with appropriate message descriptor settings. 5. Close the queue and disconnect. 6. Handle errors at each step.
Solution:
IDENTIFICATION DIVISION.
PROGRAM-ID. MQSENDTX.
DATA DIVISION.
WORKING-STORAGE SECTION.
COPY CMQV.
01 WS-QM-NAME PIC X(48) VALUE "BANKQM01".
01 WS-QUEUE-NAME PIC X(48)
VALUE "TXN.NOTIFY.QUEUE".
01 WS-HCONN PIC S9(9) BINARY VALUE 0.
01 WS-HOBJ PIC S9(9) BINARY VALUE 0.
01 WS-COMP-CODE PIC S9(9) BINARY VALUE 0.
01 WS-REASON PIC S9(9) BINARY VALUE 0.
01 WS-OPEN-OPTIONS PIC S9(9) BINARY VALUE 0.
01 WS-OBJDESC.
COPY CMQODV.
01 WS-MSGDESC.
COPY CMQMDV.
01 WS-PMO.
COPY CMQPMOV.
01 WS-TXN-DATA.
05 TXN-ID PIC X(12) VALUE "TXN-20250401".
05 ACCOUNT-NUM PIC 9(10) VALUE 1000234567.
05 TXN-TYPE PIC X(10) VALUE "WITHDRAWAL".
05 TXN-AMOUNT PIC 9(9)V99 VALUE 2500.00.
05 TXN-TIMESTAMP PIC X(26) VALUE SPACES.
01 WS-MSG-BUFFER PIC X(1000) VALUE SPACES.
01 WS-MSG-LENGTH PIC S9(9) BINARY VALUE 0.
01 WS-JSON-LENGTH PIC 9(5) VALUE 0.
PROCEDURE DIVISION.
0000-MAIN.
PERFORM 1000-CONNECT-QM
PERFORM 2000-OPEN-QUEUE
PERFORM 3000-BUILD-MESSAGE
PERFORM 4000-SEND-MESSAGE
PERFORM 5000-CLOSE-QUEUE
PERFORM 6000-DISCONNECT-QM
DISPLAY "Transaction notification sent successfully"
STOP RUN
.
1000-CONNECT-QM.
CALL 'MQCONN' USING WS-QM-NAME
WS-HCONN
WS-COMP-CODE
WS-REASON
IF WS-COMP-CODE NOT = MQCC-OK
DISPLAY "MQCONN failed. Reason: " WS-REASON
STOP RUN
END-IF
DISPLAY "Connected to queue manager: " WS-QM-NAME
.
2000-OPEN-QUEUE.
MOVE WS-QUEUE-NAME TO MQOD-OBJECTNAME
COMPUTE WS-OPEN-OPTIONS =
MQOO-OUTPUT + MQOO-FAIL-IF-QUIESCING
CALL 'MQOPEN' USING WS-HCONN
WS-OBJDESC
WS-OPEN-OPTIONS
WS-HOBJ
WS-COMP-CODE
WS-REASON
IF WS-COMP-CODE NOT = MQCC-OK
DISPLAY "MQOPEN failed. Reason: " WS-REASON
PERFORM 6000-DISCONNECT-QM
STOP RUN
END-IF
DISPLAY "Opened queue: " WS-QUEUE-NAME
.
3000-BUILD-MESSAGE.
MOVE FUNCTION CURRENT-DATE TO WS-TXN-DATA
TXN-TIMESTAMP
JSON GENERATE WS-MSG-BUFFER
FROM WS-TXN-DATA
COUNT WS-JSON-LENGTH
ON EXCEPTION
DISPLAY "JSON GENERATE failed"
PERFORM 5000-CLOSE-QUEUE
PERFORM 6000-DISCONNECT-QM
STOP RUN
END-JSON
MOVE WS-JSON-LENGTH TO WS-MSG-LENGTH
DISPLAY "Message built: "
WS-MSG-BUFFER(1:WS-JSON-LENGTH)
.
4000-SEND-MESSAGE.
MOVE MQMT-DATAGRAM TO MQMD-MSGTYPE
MOVE MQFMT-STRING TO MQMD-FORMAT
MOVE MQPER-PERSISTENT TO MQMD-PERSISTENCE
CALL 'MQPUT' USING WS-HCONN
WS-HOBJ
WS-MSGDESC
WS-PMO
WS-MSG-LENGTH
WS-MSG-BUFFER
WS-COMP-CODE
WS-REASON
IF WS-COMP-CODE NOT = MQCC-OK
DISPLAY "MQPUT failed. Reason: " WS-REASON
PERFORM 5000-CLOSE-QUEUE
PERFORM 6000-DISCONNECT-QM
STOP RUN
END-IF
DISPLAY "Message sent to queue"
.
5000-CLOSE-QUEUE.
IF WS-HOBJ NOT = MQHO-UNUSABLE-HOBJ
CALL 'MQCLOSE' USING WS-HCONN
WS-HOBJ
MQCO-NONE
WS-COMP-CODE
WS-REASON
IF WS-COMP-CODE NOT = MQCC-OK
DISPLAY "MQCLOSE warning. Reason: "
WS-REASON
END-IF
END-IF
.
6000-DISCONNECT-QM.
IF WS-HCONN NOT = 0
CALL 'MQDISC' USING WS-HCONN
WS-COMP-CODE
WS-REASON
IF WS-COMP-CODE NOT = MQCC-OK
DISPLAY "MQDISC warning. Reason: "
WS-REASON
END-IF
END-IF
.
Exercise 18: MQ Message Receive Program
Write a COBOL program that receives and processes messages from an IBM MQ queue. The program should: 1. Connect and open the queue for input. 2. Receive messages in a loop until the queue is empty. 3. Parse each JSON message into a COBOL structure. 4. Display the parsed data. 5. Properly close and disconnect.
Hint: Use MQGMO-WAIT with a short wait interval and check for MQRC-NO-MSG-AVAILABLE to detect an empty queue.
Exercise 19: Multi-Format Response Generator
Write a COBOL program that takes a single account inquiry result and generates output in three formats: 1. JSON (using JSON GENERATE) 2. XML (using XML GENERATE) 3. Fixed-width text
The program should demonstrate that the same COBOL data structure can serve multiple output formats.
Hint: Define the account data once, then generate each format into a separate output buffer.
Exercise 20: JSON Array Generation
Write a COBOL program that generates a JSON response containing an array of account transactions. Define a table of 5 transactions in WORKING-STORAGE and use JSON GENERATE to produce valid JSON with the array properly represented.
Hint: JSON GENERATE handles OCCURS clauses by producing JSON arrays. The COBOL table automatically maps to a JSON array.
Exercise 21: XML PARSE with Event Processing
Write a COBOL program that uses XML PARSE to process the following XML document and extract specific fields:
<AccountInquiryResponse>
<Status>SUCCESS</Status>
<Account>
<Number>1000234567</Number>
<Type>SAVINGS</Type>
<Balance>25430.75</Balance>
<Currency>USD</Currency>
</Account>
<LastTransaction>
<Date>2025-04-01</Date>
<Amount>500.00</Amount>
<Type>DEPOSIT</Type>
</LastTransaction>
</AccountInquiryResponse>
Hint: Use the XML PARSE processing procedure to handle XML events and extract values into COBOL data items.
Exercise 22: CICS Web Service Call
Write a COBOL CICS program that calls an external REST API to validate a postal address. The program should: 1. Build a JSON request body with street, city, state, and zip. 2. Use EXEC CICS WEB SEND/RECEIVE to make the HTTP call. 3. Parse the JSON response to extract the validated address. 4. Handle HTTP errors and timeouts.
Hint: Use EXEC CICS WEB OPEN, WEB CONVERSE, and WEB CLOSE for the HTTP lifecycle.
Tier 4: Analyze (Exercises 23-28)
These exercises require evaluating designs, debugging, and architectural reasoning.
Exercise 23: Debugging JSON GENERATE Failures
A developer reports that the following JSON GENERATE produces unexpected output. The JSON string contains numeric fields with leading zeros instead of proper JSON numbers. Diagnose the problem and propose a fix.
01 WS-PRODUCT.
05 PROD-CODE PIC X(8) VALUE "WDG-4421".
05 PROD-QUANTITY PIC 9(5) VALUE 42.
05 PROD-PRICE PIC 9(5)V99 VALUE 19.99.
01 WS-JSON PIC X(200).
JSON GENERATE WS-JSON FROM WS-PRODUCT
The output includes "PROD-QUANTITY":"00042" instead of "PROD-QUANTITY":42.
Hint: Check the PIC clause types. JSON GENERATE renders PIC 9 as strings with leading zeros in some compiler implementations. Consider using PIC 9 USAGE BINARY or COMP fields.
Exercise 24: API Design Review
Review the following z/OS Connect API design for an account inquiry service:
URL: POST /api/v1/getAccountBalance
Request Body: { "acctNum": "1234567890" }
Response: { "balance": 15420.75, "status": "active" }
Identify at least four problems with this API design from a REST best-practices perspective. Propose an improved design.
Hint: Consider HTTP method semantics, URL naming conventions, response structure completeness, and error handling.
Exercise 25: MQ vs. REST Trade-off Analysis
A bank needs to integrate its COBOL core banking system with a new cloud-based fraud detection service. The fraud service needs to evaluate every transaction in near-real-time (within 500ms). Analyze the trade-offs between two approaches:
- REST API: The COBOL program calls the fraud service synchronously via z/OS Connect API Requester.
- IBM MQ: The COBOL program puts a message on a queue, and the fraud service consumes it asynchronously.
Evaluate each approach across: latency, reliability, coupling, throughput, and error handling.
Hint: Consider what happens when the fraud service is down, when transaction volume spikes, and when responses need to influence the transaction outcome.
Exercise 26: JSON Schema Mismatch Debugging
A COBOL program receives the following JSON from an external system but fails to parse correctly. The COBOL target structure is shown below. Identify all mismatches and explain how to fix them.
JSON received:
{
"customerId": 10045382,
"name": { "first": "Elena", "last": "Martinez" },
"accounts": [
{ "type": "savings", "balance": 15420.75 },
{ "type": "checking", "balance": 3200.00 }
]
}
COBOL target:
01 WS-CUSTOMER.
05 CUSTOMER-ID PIC 9(8).
05 FIRST-NAME PIC X(20).
05 LAST-NAME PIC X(25).
05 ACCOUNT-TYPE PIC X(10).
05 ACCOUNT-BALANCE PIC 9(7)V99.
Hint: Consider name mismatches, nested structure mapping, and array handling.
Exercise 27: Integration Architecture Evaluation
A company currently has a COBOL mainframe system that handles policy administration for an insurance company. They want to build a customer-facing web portal. Three integration architectures have been proposed:
- Direct CICS Web Services (SOAP) from the web server to the mainframe.
- z/OS Connect REST APIs with an API gateway.
- IBM MQ for all communication, with a middleware layer translating between web requests and MQ messages.
For each architecture, analyze: development effort, operational complexity, performance characteristics, security implications, and scalability limits.
Hint: Consider the team's existing skills, the nature of the web portal's interactions (synchronous vs. asynchronous), and the need for API versioning and management.
Exercise 28: Performance Optimization for High-Volume JSON Processing
A COBOL batch program processes 5 million records nightly, generating a JSON file where each record becomes a JSON object. The current approach uses JSON GENERATE for each record individually, and the batch takes 4 hours. Propose optimizations to reduce processing time.
Hint: Consider buffer management, reducing JSON GENERATE invocations through manual string construction for simple structures, batching output writes, and the overhead of COBOL intrinsic functions.
Tier 5: Create (Exercises 29-33)
These exercises require designing and implementing complete integration solutions.
Exercise 29: Complete REST API Service
Design and implement a complete COBOL program that serves as the backend for a REST API with the following endpoints (all handled through z/OS Connect mapping):
- GET /accounts/{id} -- Returns account details as JSON.
- POST /accounts/{id}/deposit -- Accepts an amount and processes a deposit.
- POST /accounts/{id}/withdraw -- Accepts an amount and processes a withdrawal.
- GET /accounts/{id}/transactions -- Returns recent transaction history as a JSON array.
Write the COBOL program that handles all four request types based on an action code passed from z/OS Connect. Include input validation, error response generation, and JSON output formatting.
Hint: z/OS Connect maps different REST endpoints to different COMMAREA fields or action codes. Your single COBOL program uses EVALUATE on the action code to dispatch to the appropriate processing logic.
Exercise 30: Event-Driven Notification System
Design a COBOL-based event notification system using IBM MQ:
- A transaction processing program sends events to a topic (publish/subscribe).
- Three subscriber programs receive relevant events: - Fraud monitor: receives transactions over $10,000. - Statement generator: receives all transactions for monthly statement compilation. - Regulatory reporter: receives cross-border transactions.
- Each subscriber parses the JSON event message and performs its specific processing.
Write the publisher program and one subscriber program in full.
Hint: Use MQ publish/subscribe with topic-based filtering. Each subscriber opens a subscription to the topic with appropriate selection criteria.
Exercise 31: COBOL-to-Microservice Gateway
Design and implement a COBOL program that acts as a gateway between legacy COBOL batch programs and modern microservices. The gateway should:
- Accept requests from legacy programs via a standard COBOL CALL interface.
- Transform COBOL copybook data to JSON using JSON GENERATE.
- Call external REST APIs using the z/OS Connect API Requester pattern.
- Parse the JSON response and map it back to COBOL data structures.
- Return the results to the calling legacy program through the LINKAGE SECTION.
Write the gateway program and a sample calling program.
Hint: The gateway encapsulates all integration complexity. Legacy programs continue using familiar CALL/USING patterns while the gateway handles JSON, HTTP, and response mapping.
Exercise 32: Multi-Channel Response Formatter
Write a COBOL program that accepts account data and generates responses in four formats based on a channel indicator:
- JSON for mobile apps and web portals.
- XML for enterprise service bus integrations.
- Fixed-width for legacy mainframe-to-mainframe file transfers.
- CSV for data analytics and reporting systems.
Implement the complete program with all four formatters, a channel routing mechanism, and comprehensive error handling.
Hint: Use a strategy-like approach where the channel indicator selects the formatting routine. Each routine produces output in the specified format from the same underlying data structure.
Exercise 33: Real-Time Data Synchronization System
Design and implement a bidirectional data synchronization system between a COBOL mainframe application and a cloud database:
- Outbound sync: When COBOL programs update customer records, generate change events as JSON messages and send them to an MQ queue for cloud consumption.
- Inbound sync: Receive change events from the cloud system via a separate MQ queue, parse the JSON, validate the data, and apply updates to the mainframe data store.
- Conflict resolution: Handle cases where both systems update the same record. Use timestamp-based last-writer-wins strategy.
Write the outbound publisher and inbound consumer programs in full. Include error handling, logging, and a dead-letter queue for unprocessable messages.
Hint: Each message includes a record key, timestamp, change type (insert/update/delete), and the data payload. The consumer compares timestamps before applying changes.
General Guidelines
- All programs should compile and run without errors.
- Include proper error handling for all integration operations (JSON PARSE/GENERATE, MQ calls, HTTP operations).
- Use the COPY statement for MQ data structures (CMQV, CMQODV, CMQMDV, etc.) where applicable.
- Use JSON NAME clauses when COBOL data names differ from desired JSON field names.
- Test programs should demonstrate both success and failure paths.
- For MQ exercises, include proper resource cleanup (close queues, disconnect) even in error paths.