MainframeMaster

COBOL Tutorial

COBOL in Distributed Environments

Progress0 of 0 lessons

COBOL on UNIX/Linux

While COBOL has its roots in mainframe computing, it has successfully transitioned to UNIX and Linux environments, offering organizations flexibility in deploying their COBOL applications. This evolution has allowed businesses to leverage the cost advantages and open ecosystems of these platforms while preserving their investment in COBOL business logic.

COBOL Compilers for UNIX/Linux

Several vendors provide COBOL compilers that generate native code for UNIX and Linux systems:

  • Micro Focus: Offering products like Visual COBOL and COBOL Server that support a wide range of UNIX variants (AIX, HP-UX, Solaris) and Linux distributions
  • GnuCOBOL (formerly OpenCOBOL): An open-source COBOL compiler that translates COBOL into C and then compiles it to native code
  • Fujitsu: NetCOBOL for Linux and UNIX platforms
  • Veryant: isCOBOL Evolve, a Java-based implementation supporting UNIX/Linux

These compilers typically implement most of the ANSI/ISO COBOL standards (COBOL 85, COBOL 2002, COBOL 2014) with various extensions to facilitate migration from mainframe environments.

Differences from Mainframe COBOL

When moving COBOL applications from mainframes to UNIX/Linux, several differences become apparent:

  • File Systems: UNIX/Linux uses hierarchical file systems rather than dataset-based systems like MVS on mainframes
  • File Handling: VSAM files on mainframes need to be replaced with equivalent mechanisms
  • Transaction Processing: Mainframe TP monitors like CICS or IMS need alternatives on UNIX/Linux
  • JCL Replacement: Job Control Language scripts must be replaced with shell scripts or other job scheduling tools
  • Character Sets: Handling of EBCDIC vs. ASCII character encoding differences
  • Binary Data Representation: Endianness and alignment differences between platforms

COBOL Program Structure for UNIX/Linux

COBOL programs for UNIX/Linux follow the same basic structure as mainframe COBOL, but typically include platform-specific adaptations for file handling and environment interaction:

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
IDENTIFICATION DIVISION. PROGRAM-ID. UNIX-SAMPLE. AUTHOR. MAINFRAME-MASTER. * A simple COBOL program for UNIX/Linux environments ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. LINUX. OBJECT-COMPUTER. LINUX. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT CUSTOMER-FILE ASSIGN TO EXTERNAL CUSTOMER-PATH ORGANIZATION IS INDEXED ACCESS MODE IS DYNAMIC RECORD KEY IS CUST-ID FILE STATUS IS FILE-STATUS. DATA DIVISION. FILE SECTION. FD CUSTOMER-FILE. 01 CUSTOMER-RECORD. 05 CUST-ID PIC X(6). 05 CUST-NAME PIC X(30). 05 CUST-ADDRESS PIC X(50). 05 CUST-PHONE PIC X(15). WORKING-STORAGE SECTION. 01 FILE-STATUS PIC XX. 01 CUSTOMER-PATH PIC X(128). 01 ENV-VARS. 05 HOME-DIR PIC X(128). 01 UNIX-COMMAND PIC X(256). 01 CMD-RESULT PIC S9(9) COMP. PROCEDURE DIVISION. MAIN-LOGIC. DISPLAY "COBOL for UNIX/Linux Example". * Get environment variables using standard COBOL intrinsic ACCEPT HOME-DIR FROM ENVIRONMENT "HOME". DISPLAY "Home directory: " HOME-DIR. * Setting the file path using environment variables and concatenation STRING HOME-DIR DELIMITED BY SPACE "/data/customers.idx" DELIMITED BY SIZE INTO CUSTOMER-PATH END-STRING. DISPLAY "Customer file path: " CUSTOMER-PATH. * Using CALL to execute a UNIX command (implementation dependent) MOVE "ls -l $HOME/data" TO UNIX-COMMAND. CALL "SYSTEM" USING UNIX-COMMAND RETURNING CMD-RESULT. IF CMD-RESULT NOT = 0 DISPLAY "Error executing UNIX command. Status: " CMD-RESULT END-IF. OPEN I-O CUSTOMER-FILE. IF FILE-STATUS = "00" PERFORM PROCESS-CUSTOMERS CLOSE CUSTOMER-FILE ELSE DISPLAY "Error opening customer file. Status: " FILE-STATUS END-IF. STOP RUN. PROCESS-CUSTOMERS. DISPLAY "Processing customer records...". * Process customer records here DISPLAY "Processing complete.".

Note the UNIX-specific features: external file assignment that can be set at runtime, calls to system functions, and interaction with environment variables.

Migration and Interoperability Strategies

  • Emulation: Products like Micro Focus Enterprise Server provide emulation of mainframe subsystems (CICS, JCL, VSAM) on UNIX/Linux
  • Middleware: Using database middleware to replace direct file access
  • Recompilation: Directly recompiling source code with platform-specific adjustments
  • Hybrid Approaches: Keeping some components on the mainframe while moving others to UNIX/Linux
  • Containerization: Packaging COBOL applications in containers for easier deployment and scalability

Development Tools in UNIX/Linux Environments

Modern COBOL development on UNIX/Linux can leverage:

  • Integrated Development Environments: Micro Focus Visual COBOL Development Hub, Eclipse-based IDEs with COBOL plugins
  • Source Control: Git, Subversion, and other standard SCM tools
  • Build Automation: Make, Ant, Maven, or Jenkins for continuous integration
  • Text Editors: Vim, Emacs, or Visual Studio Code with COBOL extensions
  • Debuggers: GDB and vendor-specific COBOL debuggers

COBOL on Windows

COBOL on Windows represents a significant evolution of the language, bringing mainframe business logic to the most widely used desktop and server operating system in the world. This migration has transformed how organizations deploy and interact with their COBOL applications, often modernizing the user interface and integration capabilities while preserving critical business rules.

Windows COBOL Development Environment

Windows-based COBOL development offers several advantages over traditional mainframe development:

  • Modern IDEs: GUI-based development environments with productivity features like code completion, syntax highlighting, and integrated debugging
  • Visual Studio Integration: Products like Micro Focus Visual COBOL integrate directly with Visual Studio, providing a familiar environment for development teams
  • Integration with .NET: COBOL can compile to .NET assemblies, allowing seamless integration with C#, VB.NET, and other .NET languages
  • Windows-Native GUI: The ability to create Windows forms and controls directly from COBOL
  • Windows Services: COBOL applications can run as background Windows services

COBOL Compilers for Windows

Several commercial and open-source COBOL compilers are available for Windows:

  • Micro Focus Visual COBOL: A comprehensive suite for developing and deploying COBOL applications on Windows, with extensive Visual Studio integration
  • NetCOBOL for Windows: Fujitsu's offering for Windows development
  • GnuCOBOL: Free and open-source COBOL compiler available for Windows
  • COBOL-IT: COBOL compiler with Windows support
  • AcuCOBOL-GT: Micro Focus product supporting Windows environments

GUI Development with COBOL

One of the most significant advancements in Windows COBOL is the ability to create modern graphical user interfaces:

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
IDENTIFICATION DIVISION. PROGRAM-ID. WINDOWS-GUI-EXAMPLE. CLASS-CONTROL. MyForm IS CLASS "MyForm" System.Windows.Forms.Form IS CLASS "System.Windows.Forms.Form" System.Windows.Forms.Button IS CLASS "System.Windows.Forms.Button" System.Windows.Forms.TextBox IS CLASS "System.Windows.Forms.TextBox" System.Windows.Forms.Label IS CLASS "System.Windows.Forms.Label". OBJECT SECTION. CLASS-OBJECT. CLASS MyForm INHERITS FROM System.Windows.Forms.Form. 01 myForm OBJECT REFERENCE. 01 calculateButton OBJECT REFERENCE. 01 amountTextBox OBJECT REFERENCE. 01 rateTextBox OBJECT REFERENCE. 01 resultLabel OBJECT REFERENCE. PROCEDURE DIVISION. MAIN-LOGIC. PERFORM INITIALIZE-FORM INVOKE System.Windows.Forms.Application::Run(myForm) STOP RUN. INITIALIZE-FORM. INVOKE MyForm NEW RETURNING myForm INVOKE myForm::set_Text("COBOL Interest Calculator") INVOKE myForm::set_Width(450) INVOKE myForm::set_Height(250) INVOKE System.Windows.Forms.Label NEW RETURNING resultLabel INVOKE resultLabel::set_Text("Result will appear here") INVOKE resultLabel::set_Width(300) INVOKE resultLabel::set_Location(NEW System.Drawing.Point(20, 150)) INVOKE myForm::Controls::Add(resultLabel) INVOKE System.Windows.Forms.TextBox NEW RETURNING amountTextBox INVOKE amountTextBox::set_Width(100) INVOKE amountTextBox::set_Location(NEW System.Drawing.Point(120, 20)) INVOKE myForm::Controls::Add(amountTextBox) INVOKE System.Windows.Forms.Label NEW RETURNING tempLabel INVOKE tempLabel::set_Text("Loan Amount:") INVOKE tempLabel::set_Width(100) INVOKE tempLabel::set_Location(NEW System.Drawing.Point(20, 23)) INVOKE myForm::Controls::Add(tempLabel) INVOKE System.Windows.Forms.TextBox NEW RETURNING rateTextBox INVOKE rateTextBox::set_Width(100) INVOKE rateTextBox::set_Location(NEW System.Drawing.Point(120, 50)) INVOKE myForm::Controls::Add(rateTextBox) INVOKE System.Windows.Forms.Label NEW RETURNING tempLabel INVOKE tempLabel::set_Text("Interest Rate:") INVOKE tempLabel::set_Width(100) INVOKE tempLabel::set_Location(NEW System.Drawing.Point(20, 53)) INVOKE myForm::Controls::Add(tempLabel) INVOKE System.Windows.Forms.Button NEW RETURNING calculateButton INVOKE calculateButton::set_Text("Calculate") INVOKE calculateButton::set_Location(NEW System.Drawing.Point(120, 90)) INVOKE myForm::Controls::Add(calculateButton) INVOKE calculateButton::add_Click(NEW System.EventHandler(CALCULATE-BUTTON-CLICK)) . CALCULATE-BUTTON-CLICK. LINKAGE SECTION. 01 sender OBJECT REFERENCE. 01 e OBJECT REFERENCE. PROCEDURE DIVISION USING BY VALUE sender e. DECLARE amount DECIMAL DECLARE rate DECIMAL DECLARE result DECIMAL INVOKE amountTextBox::get_Text RETURNING temp-string MOVE FUNCTION NUMVAL(temp-string) TO amount INVOKE rateTextBox::get_Text RETURNING temp-string MOVE FUNCTION NUMVAL(temp-string) TO rate COMPUTE result = amount * (1 + rate / 100) INVOKE resultLabel::set_Text("Future Value: $" & result) EXIT PROGRAM. END PROGRAM WINDOWS-GUI-EXAMPLE.

This example shows COBOL integration with .NET Windows Forms to create a simple interest calculator application. Note the object-oriented syntax and event handling, which are extensions to standard COBOL.

Integration with Windows Services and Technologies

Windows COBOL applications can leverage various Windows-specific technologies:

  • COM/DCOM: Component Object Model for interprocess communication and object creation
  • ODBC/ADO.NET: Data access technologies for connecting to various database systems
  • Windows Registry: For storing configuration and application settings
  • DLLs: Creating and consuming Dynamic Link Libraries
  • Event Logs: Writing to Windows Event Logs for application monitoring
  • Windows Authentication: Leveraging Windows user account infrastructure
cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
IDENTIFICATION DIVISION. PROGRAM-ID. REGISTRY-EXAMPLE. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. * Variables for Windows Registry Access 01 REG-KEY-HANDLE PIC S9(9) COMP-5. 01 REG-VALUE-NAME PIC X(50). 01 REG-VALUE-TYPE PIC S9(9) COMP-5. 01 REG-DATA-BUFFER PIC X(1024). 01 REG-DATA-SIZE PIC S9(9) COMP-5. 01 REG-RESULT PIC S9(9) COMP-5. 01 HKEY-CONSTANTS. 05 HKEY-CURRENT-USER PIC S9(9) COMP-5 VALUE 2147483649. 05 REG-SZ PIC S9(9) COMP-5 VALUE 1. 05 KEY-READ PIC S9(9) COMP-5 VALUE 131097. PROCEDURE DIVISION. MAIN-LOGIC. DISPLAY "Windows Registry Access Example". * Read a value from the Windows Registry * (Note: specific registry API calls are implementation-dependent) MOVE "Software\MyCompany\MyCobolApp\Settings" TO REG-VALUE-NAME. MOVE 1024 TO REG-DATA-SIZE. CALL "RegOpenKeyEx" USING BY VALUE HKEY-CURRENT-USER BY REFERENCE REG-VALUE-NAME BY VALUE 0 BY VALUE KEY-READ BY REFERENCE REG-KEY-HANDLE RETURNING REG-RESULT. IF REG-RESULT = 0 MOVE "InstallPath" TO REG-VALUE-NAME CALL "RegQueryValueEx" USING BY VALUE REG-KEY-HANDLE BY REFERENCE REG-VALUE-NAME BY VALUE 0 BY REFERENCE REG-VALUE-TYPE BY REFERENCE REG-DATA-BUFFER BY REFERENCE REG-DATA-SIZE RETURNING REG-RESULT IF REG-RESULT = 0 DISPLAY "Install Path from Registry: " REG-DATA-BUFFER(1:REG-DATA-SIZE) ELSE DISPLAY "Error reading registry value. Error: " REG-RESULT END-IF CALL "RegCloseKey" USING BY VALUE REG-KEY-HANDLE ELSE DISPLAY "Error opening registry key. Error: " REG-RESULT END-IF. STOP RUN.

Migrating Mainframe COBOL to Windows

Migrating mainframe COBOL applications to Windows involves several considerations:

  • Runtime Environment: Windows-specific COBOL runtime environments typically provide emulation for mainframe features like CICS, JCL, and VSAM
  • Automated Migration Tools: Vendors offer tools to analyze, convert, and test mainframe COBOL code for Windows platforms
  • Database Migration: Moving from mainframe databases (DB2, IMS, IDMS) to Windows-compatible databases (SQL Server, Oracle)
  • Transaction Processing: Implementing equivalents for mainframe transaction monitors (for example, Micro Focus Enterprise Server on Windows)
  • File and Encoding Conversion: Converting EBCDIC data files to ASCII and handling record format differences
  • Batch Processing: Converting JCL batch jobs to Windows-compatible scheduling

Web-enabled COBOL

Web-enabling COBOL applications represents a significant modernization strategy that extends the reach of traditional COBOL programs to web browsers and mobile devices. This approach allows organizations to preserve their valuable business logic while providing modern user interfaces and integration points.

Approaches to Web-enabling COBOL

Several strategies exist for connecting COBOL applications to the web:

  • Screen Transformation: Converting traditional 3270 terminal screens to HTML/CSS/JavaScript interfaces
  • Web Services: Exposing COBOL programs as web services (SOAP, REST) that can be consumed by web applications
  • Direct Web Support: Using COBOL compilers or extensions that support web technologies directly
  • Middleware Integration: Using middleware products that bridge COBOL applications with web servers
  • Application Servers: Deploying COBOL components within Java EE or .NET application servers

COBOL as a Web Service

One of the most common approaches is exposing COBOL business logic as web services. This can be implemented in several ways:

  • CICS Web Services: For mainframe COBOL, IBM's CICS provides direct support for exposing transactions as web services
  • z/OS Connect: IBM's offering to create REST APIs from mainframe applications
  • Enterprise Server: Micro Focus products provide web service capabilities for distributed COBOL
  • Custom Integration: Using wrapper programs that handle HTTP communication and invoke COBOL programs
cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
IDENTIFICATION DIVISION. PROGRAM-ID. CUSTOMER-SERVICE. AUTHOR. MAINFRAME-MASTER. DATA DIVISION. WORKING-STORAGE SECTION. 01 WS-CUSTOMER-RECORD. 05 WS-CUST-ID PIC X(6). 05 WS-CUST-NAME PIC X(30). 05 WS-CUST-EMAIL PIC X(50). 05 WS-CUST-PHONE PIC X(15). 05 WS-CUST-STATUS PIC X(1). 88 WS-CUST-ACTIVE VALUE "A". 88 WS-CUST-INACTIVE VALUE "I". 05 WS-CUST-BALANCE PIC S9(7)V99. 01 WS-RESPONSE. 05 WS-STATUS-CODE PIC 9(3). 05 WS-RESPONSE-MESSAGE PIC X(100). LINKAGE SECTION. 01 DFHCOMMAREA. 05 LS-REQUEST-TYPE PIC X(4). 88 LS-GET-CUSTOMER VALUE "GET ". 88 LS-ADD-CUSTOMER VALUE "ADD ". 88 LS-UPD-CUSTOMER VALUE "UPD ". 05 LS-CUSTOMER-ID PIC X(6). 05 LS-CUSTOMER-DATA PIC X(250). 05 LS-RESPONSE-DATA PIC X(500). PROCEDURE DIVISION. MAIN-LOGIC. EVALUATE TRUE WHEN LS-GET-CUSTOMER PERFORM GET-CUSTOMER-DETAILS WHEN LS-ADD-CUSTOMER PERFORM ADD-CUSTOMER WHEN LS-UPD-CUSTOMER PERFORM UPDATE-CUSTOMER WHEN OTHER MOVE 400 TO WS-STATUS-CODE MOVE "Invalid request type" TO WS-RESPONSE-MESSAGE END-EVALUATE MOVE WS-RESPONSE TO LS-RESPONSE-DATA EXEC CICS RETURN END-EXEC. GET-CUSTOMER-DETAILS. * Logic to retrieve customer from database EXEC CICS READ DATASET('CUSTFILE') INTO(WS-CUSTOMER-RECORD) RIDFLD(LS-CUSTOMER-ID) RESP(WS-RESPONSE-CODE) END-EXEC IF WS-RESPONSE-CODE = DFHRESP(NORMAL) MOVE 200 TO WS-STATUS-CODE STRING '{"customerId":"' DELIMITED BY SIZE WS-CUST-ID DELIMITED BY SIZE '","name":"' DELIMITED BY SIZE WS-CUST-NAME DELIMITED BY SIZE '","email":"' DELIMITED BY SIZE WS-CUST-EMAIL DELIMITED BY SIZE '","status":"' DELIMITED BY SIZE WS-CUST-STATUS DELIMITED BY SIZE '","balance":' DELIMITED BY SIZE WS-CUST-BALANCE DELIMITED BY SIZE '}' DELIMITED BY SIZE INTO WS-RESPONSE-MESSAGE ELSE MOVE 404 TO WS-STATUS-CODE MOVE "Customer not found" TO WS-RESPONSE-MESSAGE END-IF. ADD-CUSTOMER. * Logic to parse JSON from LS-CUSTOMER-DATA and add customer * ... UPDATE-CUSTOMER. * Logic to update existing customer * ...

This example demonstrates a CICS COBOL program structured to act as a web service. It processes requests based on a request type and returns JSON-formatted data. A web service framework (like CICS Web Services) would handle the HTTP protocol details and marshaling/unmarshaling of data.

Modern Web Interfaces for COBOL Applications

Creating modern web interfaces for COBOL applications typically involves:

  • Frontend Technologies: HTML5, CSS3, JavaScript frameworks (React, Angular, Vue.js)
  • API Layer: RESTful services that communicate with COBOL programs
  • Security: Authentication, authorization, and secure communication
  • Session Management: Maintaining user context across web requests

The architecture typically looks like this:

Web Browser -> Web Server -> API Gateway -> COBOL Application
                     (HTML/JS)     (Node.js/   (REST/SOAP)   (Mainframe/
                                  Java/.NET)                Distributed)

Direct Web Generation from COBOL

Some modern COBOL environments support direct web enablement:

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
IDENTIFICATION DIVISION. PROGRAM-ID. WEB-CUSTOMER-FORM. * Example using hypothetical COBOL web extensions ENVIRONMENT DIVISION. CONFIGURATION SECTION. SPECIAL-NAMES. WEB-CONTEXT IS CUSTOMER-WEB. DATA DIVISION. WORKING-STORAGE SECTION. 01 CUSTOMER-DATA. 05 CUST-ID PIC X(6). 05 CUST-NAME PIC X(30). 05 CUST-EMAIL PIC X(50). 05 CUST-PHONE PIC X(15). WEB SECTION. * This is a conceptual example of how a COBOL web * extension might define UI components 01 CUSTOMER-FORM. 05 FORM-TITLE VALUE "Customer Information". 05 ID-FIELD LABEL "Customer ID" SOURCE CUST-ID MAXLENGTH 6 READONLY. 05 NAME-FIELD LABEL "Customer Name" SOURCE CUST-NAME REQUIRED. 05 EMAIL-FIELD LABEL "Email" SOURCE CUST-EMAIL TYPE "email". 05 PHONE-FIELD LABEL "Phone Number" SOURCE CUST-PHONE. 05 SUBMIT-BUTTON LABEL "Save Customer" ACTION ON-SUBMIT. PROCEDURE DIVISION. MAIN-LOGIC. INITIALIZE CUSTOMER-DATA ACCEPT CUST-ID FROM HTTP-REQUEST-PARAM "id" IF CUST-ID NOT = SPACES PERFORM GET-CUSTOMER-DATA END-IF DISPLAY CUSTOMER-FORM STOP RUN. GET-CUSTOMER-DATA. * Logic to retrieve customer data from database * ... ON-SUBMIT. ACCEPT CUSTOMER-DATA FROM CUSTOMER-FORM * Logic to save customer data * ... RESPOND HTTP-STATUS 200 CONTENT-TYPE "application/json" BODY '{"status":"success","message":"Customer saved"}' STOP RUN.

This conceptual example demonstrates how a hypothetical web-enabled COBOL extension might define UI components directly in COBOL code. While not standard COBOL, some vendors provide similar capabilities through their own extensions.

Challenges and Considerations

  • Performance: Ensuring acceptable response times for web interactions
  • Scalability: Handling variable web traffic loads
  • State Management: Managing user sessions and application state
  • Security: Protecting applications from web-specific threats
  • Skills Gap: Bridging the knowledge gap between COBOL developers and web technologies
  • Data Transformation: Converting between COBOL data structures and web formats (JSON, XML)

Microservices with COBOL

Microservices architecture represents a modern approach to building distributed systems, where applications are composed of loosely coupled, independently deployable services. While microservices are often associated with newer languages and platforms, COBOL applications can successfully participate in and benefit from this architectural style.

COBOL in a Microservices Context

Integrating COBOL into a microservices architecture typically involves:

  • Service Decomposition: Breaking down monolithic COBOL applications into smaller, focused services that can be developed, deployed, and scaled independently
  • API-First Design: Defining clear, well-documented interfaces between services using standards like OpenAPI (Swagger)
  • Containerization: Packaging COBOL services in containers (e.g., Docker) for consistent deployment across environments
  • Orchestration: Using platforms like Kubernetes to manage deployment, scaling, and resilience
  • Service Mesh: Implementing service discovery, load balancing, and communication patterns

Refactoring COBOL Programs for Microservices

Traditional COBOL applications often follow monolithic design patterns. Transforming them into microservices requires careful analysis and refactoring:

  1. Identify Service Boundaries: Analyze the COBOL codebase to identify components that represent cohesive business functions
  2. Extract Shared Data Structures: Move common copybooks, definitions, and types to shared libraries
  3. Define Service Interfaces: Create well-defined entry points with clear input/output parameters
  4. Manage Dependencies: Reduce tight coupling between components
  5. Implement Service Communication: Use HTTP/REST, message queues, or other appropriate communication protocols
cobol
1
IDENTIFICATION DIVISION.PROGRAM-ID. CUSTOMER-MICROSERVICE.AUTHOR. MAINFRAME-MASTER.DATA DIVISION.WORKING-STORAGE SECTION.01 WS-HTTP-STATUS PIC 9(3).01 WS-REQUEST-METHOD PIC X(10).01 WS-REQUEST-PATH PIC X(256).01 WS-REQUEST-BODY PIC X(4096).01 WS-RESPONSE-BODY PIC X(4096).01 WS-CUSTOMER-RECORD. 05 WS-CUST-ID PIC X(6). 05 WS-CUST-NAME PIC X(30). 05 WS-CUST-EMAIL PIC X(50). 05 WS-ACCOUNT-INFO. 10 WS-ACCOUNT-TYPE PIC X(1). 88 WS-ACCOUNT-STANDARD VALUE "S". 88 WS-ACCOUNT-PREMIUM VALUE "P". 10 WS-ACCOUNT-BALANCE PIC S9(7)V99. 10 WS-ACCOUNT-OPEN-DATE PIC X(10). 01 WS-DB-STATUS PIC X(2).01 WS-SERVICE-CONFIG. 05 WS-SERVICE-PORT PIC 9(5) VALUE 8080. 05 WS-DB-CONNECTION PIC X(100). 05 WS-LOG-LEVEL PIC X(10) VALUE "INFO".PROCEDURE DIVISION.MAIN-LOGIC. PERFORM INITIALIZE-SERVICE PERFORM UNTIL FOREVER PERFORM WAIT-FOR-REQUEST PERFORM PROCESS-REQUEST PERFORM SEND-RESPONSE END-PERFORM STOP RUN.INITIALIZE-SERVICE. DISPLAY "Starting Customer Microservice on port " WS-SERVICE-PORT PERFORM LOAD-CONFIGURATION PERFORM INITIALIZE-DB-CONNECTION PERFORM REGISTER-WITH-SERVICE-REGISTRY.PROCESS-REQUEST. EVALUATE WS-REQUEST-METHOD ALSO WS-REQUEST-PATH WHEN "GET" ALSO "/api/customers" PERFORM GET-ALL-CUSTOMERS WHEN "GET" ALSO MATCHING("/api/customers/*") PERFORM GET-CUSTOMER-BY-ID WHEN "POST" ALSO "/api/customers" PERFORM CREATE-CUSTOMER WHEN "PUT" ALSO MATCHING("/api/customers/*") PERFORM UPDATE-CUSTOMER WHEN "DELETE" ALSO MATCHING("/api/customers/*") PERFORM DELETE-CUSTOMER WHEN OTHER MOVE 404 TO WS-HTTP-STATUS MOVE '{"error":"Resource not found"}' TO WS-RESPONSE-BODY END-EVALUATE.GET-ALL-CUSTOMERS. * Retrieves all customers with pagination * Query implementation would go here * ... MOVE 200 TO WS-HTTP-STATUS.GET-CUSTOMER-BY-ID. * Extract ID from path * Lookup customer in database * Return JSON representation * ... MOVE 200 TO WS-HTTP-STATUS.CREATE-CUSTOMER. * Parse customer data from request body (JSON) * Validate fields * Insert into database * ... MOVE 201 TO WS-HTTP-STATUS.* Additional procedures for other endpoints* ...REGISTER-WITH-SERVICE-REGISTRY. * Logic to register this service with service discovery system * For example, connecting to Eureka, Consul, or etcd * ...

This simplified example shows how a COBOL program could be structured as a microservice with RESTful endpoints. In practice, this would be implemented using platform-specific extensions or frameworks to handle the HTTP communication and interact with the service mesh.

Microservice Architecture Patterns for COBOL

Several patterns are particularly relevant when integrating COBOL into a microservices architecture:

  • API Gateway: A dedicated service that provides a unified entry point for external clients and handles cross-cutting concerns like authentication, rate limiting, and routing
  • Strangler Pattern: Gradually replacing parts of a monolithic COBOL application with microservices while keeping the system operational
  • Sidecar Pattern: Deploying helper containers alongside COBOL service containers to handle cross-cutting concerns (logging, monitoring, etc.)
  • Circuit Breaker: Preventing cascading failures when dependent services are unavailable
  • Event Sourcing: Capturing state changes as a sequence of events for improved resilience and audit capability

Applying the Strangler Pattern to COBOL applications:

Phase 1: Original Monolithic COBOL Application┌───────────────────────────────────────────────┐│                                               ││  COBOL Monolith                               ││  - Customer Management                        ││  - Account Processing                         ││  - Reporting                                  ││  - Transaction Handling                       ││                                               │└───────────────────────────────────────────────┘Phase 2: API Gateway + First Microservice┌─────────────────┐     ┌───────────────────────┐│                 │     │                       ││  API Gateway    │─────│  COBOL Monolith       ││                 │     │  (Legacy Components)  │└─────┬───────────┘     │                       │      │                 └───────────────────────┘      │      │                 ┌───────────────────────┐      │                 │                       │      └─────────────────│  Customer Service     │                        │  (New Microservice)   │                        │                       │                        └───────────────────────┘Phase 3: Multiple Microservices┌─────────────────┐      │                 │        │  API Gateway    │        │                 │      └─────┬───────────┘            │                        ├─────────────────┐            │                 │            │                 ▼            │        ┌───────────────────────┐      │        │                       │      │        │  Customer Service     │      │        │  (COBOL or New Lang)  │      │        │                       │      │        └───────────────────────┘      │      │                 ┌───────────────────────┐      │                 │                       │      ├─────────────────│  Account Service      │      │                 │  (COBOL)              │      │                 │                       │      │                 └───────────────────────┘      │      │                 ┌───────────────────────┐      │                 │                       │      └─────────────────│  Transaction Service  │                        │  (New Language)       │                        │                       │                        └───────────────────────┘

Deployment and Containerization

Containerizing COBOL services allows them to be deployed and managed using modern DevOps practices:

dockerfile
1
# Example Dockerfile for a COBOL microserviceFROM microfocus/enterprise-developer:latest# Set environment variablesENV COBDIR=/opt/microfocus/EnterpriseDeveloperENV TERM=xtermENV PATH=$COBDIR/bin:$PATHENV COBPATH=/app/copybooks# Create application directoryWORKDIR /app# Copy source code, copybooks, and configurationCOPY src/ ./src/COPY copybooks/ ./copybooks/COPY config/ ./config/# Compile the COBOL programRUN cobol -x src/customer-service.cbl -o bin/customer-service# Expose the service portEXPOSE 8080# Run the service when container startsCMD ["bin/customer-service"]

This Dockerfile example shows how a COBOL microservice could be containerized using the Micro Focus Enterprise Developer product. The container includes the COBOL runtime, compiled application, and necessary configuration.

For orchestration, a Kubernetes manifest could be used to deploy and manage the service:

yaml
1
apiVersion: apps/v1kind: Deploymentmetadata: name: customer-service labels: app: customer-service spec: replicas: 3 selector: matchLabels: app: customer-service template: metadata: labels: app: customer-service spec: containers: - name: customer-service image: mycompany/customer-service:1.0.0 ports: - containerPort: 8080 env: - name: DB_CONNECTION_STRING valueFrom: secretKeyRef: name: customer-service-secrets key: db-connection - name: LOG_LEVEL value: "INFO" resources: limits: memory: "512Mi" cpu: "500m" requests: memory: "256Mi" cpu: "250m" readinessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 5 periodSeconds: 10---apiVersion: v1kind: Servicemetadata: name: customer-servicespec: selector: app: customer-service ports: - port: 80 targetPort: 8080 type: ClusterIP

Challenges and Considerations

  • Statelessness: Traditional COBOL applications often maintain state between transactions. Microservices typically prefer statelessness, which may require redesign.
  • Data Ownership: Microservices should ideally own their own data, which might require rethinking shared database designs common in COBOL.
  • Transaction Management: Moving from single-transaction monoliths to distributed transactions across services.
  • Performance: Handling the network overhead introduced by inter-service communication.
  • Monitoring and Observability: Adapting COBOL applications for modern monitoring tools and practices.
  • Deployment Complexity: Managing the increased operational complexity of multiple services.

COBOL and REST APIs

REST (Representational State Transfer) has become the predominant architectural style for modern APIs. Integrating COBOL applications with REST APIs enables them to participate in contemporary digital ecosystems, allowing for greater interoperability and extended functionality. This section explores how COBOL programs can both consume and provide REST services.

Consuming REST APIs from COBOL

COBOL programs can call external REST APIs, though implementation details vary based on the environment:

  • On Mainframes: Specialized facilities like z/OS Connect, IBM HTTP Client APIs, or CICS Web Support
  • On Distributed Platforms: Native HTTP client libraries, language integration, or third-party tools
  • Processing JSON/XML: Using built-in or external parsers to handle API responses
cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
IDENTIFICATION DIVISION. PROGRAM-ID. REST-API-CLIENT. AUTHOR. MAINFRAME-MASTER. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. 01 WS-HTTP-REQUEST. 05 WS-REQUEST-URL PIC X(255). 05 WS-REQUEST-METHOD PIC X(10). 05 WS-REQUEST-HEADERS. 10 WS-CONTENT-TYPE PIC X(50). 10 WS-AUTHORIZATION PIC X(100). 05 WS-REQUEST-BODY PIC X(1000). 01 WS-HTTP-RESPONSE. 05 WS-RESPONSE-CODE PIC 9(3). 05 WS-RESPONSE-BODY PIC X(10000). 05 WS-RESPONSE-LENGTH PIC 9(8) COMP. 05 WS-ERROR-MESSAGE PIC X(100). 01 WS-WEATHER-DATA. 05 WS-TEMPERATURE PIC S9(3)V9. 05 WS-CONDITION PIC X(30). 05 WS-HUMIDITY PIC 9(3). 05 WS-WIND-SPEED PIC 9(3)V9. 01 WS-JSON-PARSER USAGE IS POINTER. 01 WS-HTTP-CLIENT USAGE IS POINTER. 01 WS-RESULT PIC 9(9) COMP. PROCEDURE DIVISION. MAIN-LOGIC. DISPLAY "COBOL REST API Client Example" * Initialize HTTP client library CALL "HTTP_INITIALIZE" RETURNING WS-HTTP-CLIENT * Set up the request MOVE "https://api.weather.example.com/forecast?city=NewYork" TO WS-REQUEST-URL MOVE "GET" TO WS-REQUEST-METHOD MOVE "application/json" TO WS-CONTENT-TYPE MOVE "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." TO WS-AUTHORIZATION * Make the API call CALL "HTTP_SEND_REQUEST" USING BY VALUE WS-HTTP-CLIENT BY REFERENCE WS-HTTP-REQUEST BY REFERENCE WS-HTTP-RESPONSE RETURNING WS-RESULT * Check response IF WS-RESULT NOT = 0 DISPLAY "Error calling API: " WS-ERROR-MESSAGE STOP RUN END-IF DISPLAY "Response code: " WS-RESPONSE-CODE IF WS-RESPONSE-CODE = 200 * Parse JSON response CALL "JSON_PARSER_INIT" RETURNING WS-JSON-PARSER CALL "JSON_PARSE" USING BY VALUE WS-JSON-PARSER BY REFERENCE WS-RESPONSE-BODY RETURNING WS-RESULT IF WS-RESULT = 0 * Extract data from JSON CALL "JSON_GET_NUMBER" USING BY VALUE WS-JSON-PARSER BY CONTENT "temperature" BY REFERENCE WS-TEMPERATURE CALL "JSON_GET_STRING" USING BY VALUE WS-JSON-PARSER BY CONTENT "condition" BY REFERENCE WS-CONDITION * Display the weather information DISPLAY "Current weather in New York:" DISPLAY "Temperature: " WS-TEMPERATURE " °C" DISPLAY "Condition: " WS-CONDITION ELSE DISPLAY "Error parsing JSON response" END-IF * Clean up CALL "JSON_PARSER_FREE" USING BY VALUE WS-JSON-PARSER ELSE DISPLAY "API call failed with status: " WS-RESPONSE-CODE END-IF CALL "HTTP_CLEANUP" USING BY VALUE WS-HTTP-CLIENT STOP RUN.

This example demonstrates a COBOL program that calls a hypothetical weather API. It uses generic HTTP client and JSON parser functions that would be provided by environment-specific libraries. In reality, the exact implementation would vary based on the COBOL compiler and platform.

Exposing COBOL Programs as REST APIs

To expose COBOL functionality as REST APIs, several approaches can be used:

  • API Gateways: Products like z/OS Connect EE, CICS Web Services, or API Connect that expose COBOL as RESTful endpoints
  • Middleware Wrappers: Java/Node.js/.NET services that call COBOL programs and expose REST interfaces
  • Direct Implementation: Modern COBOL platforms that support HTTP servers and REST processing

Architecture for exposing COBOL as REST:

┌───────────────┐  HTTP/REST  ┌────────────────┐  Service Call  ┌─────────────────┐
│ REST Clients  │◄─────────────►│ API Gateway/  │◄──────────────►│ COBOL Program   │
│ (Web/Mobile) │              │ Middleware     │                │ (Business Logic)│
└───────────────┘              └────────────────┘                └─────────────────┘
                                      │                                 │
                                      │                                 │
                                      ▼                                 ▼
                               ┌────────────────┐                ┌─────────────────┐
                               │ API Definition │                │ Database Access │
                               │ (OpenAPI/YAML) │                │ (DB2, VSAM, etc)│
                               └────────────────┘                └─────────────────┘

Example OpenAPI (Swagger) definition for a COBOL-backed API:

yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
openapi: 3.0.0 info: title: Customer Management API description: REST API for customer data backed by COBOL business logic version: 1.0.0 paths: /customers: get: summary: Get all customers parameters: - name: page in: query schema: type: integer - name: limit in: query schema: type: integer responses: '200': description: Successfully retrieved customers content: application/json: schema: type: array items: $ref: '#/components/schemas/Customer' post: summary: Create a customer requestBody: content: application/json: schema: $ref: '#/components/schemas/NewCustomer' responses: '201': description: Customer created successfully /customers/{id}: get: summary: Get customer by ID parameters: - name: id in: path required: true schema: type: string responses: '200': description: Customer found content: application/json: schema: $ref: '#/components/schemas/Customer' '404': description: Customer not found components: schemas: Customer: type: object properties: id: type: string name: type: string email: type: string status: type: string enum: [active, inactive] balance: type: number NewCustomer: type: object required: - name - email properties: name: type: string email: type: string status: type: string default: active

Handling JSON in COBOL

JSON has become the standard data format for REST APIs. Modern COBOL compilers offer various mechanisms for JSON processing:

  • IBM Enterprise COBOL 6.3+: Built-in JSON PARSE and JSON GENERATE statements
  • Micro Focus COBOL: JSON handling through supplied libraries
  • Manual Parsing: Using STRING/UNSTRING for simpler JSON structures
  • Third-party Libraries: External modules or callable services for JSON processing
cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
IDENTIFICATION DIVISION. PROGRAM-ID. JSON-HANDLING-SAMPLE. AUTHOR. MAINFRAME-MASTER. DATA DIVISION. WORKING-STORAGE SECTION. * Customer data structure 01 CUSTOMER-DATA. 05 CUSTOMER-ID PIC X(6). 05 CUSTOMER-NAME PIC X(30). 05 CUSTOMER-EMAIL PIC X(50). 05 CUSTOMER-STATUS PIC X(1). 88 CUSTOMER-ACTIVE VALUE "A". 88 CUSTOMER-INACTIVE VALUE "I". 05 CUSTOMER-BALANCE PIC S9(7)V99. * JSON document 01 JSON-DOC PIC X(1000). 01 JSON-LENGTH PIC 9(4) COMP. * Work fields 01 WS-RESULT PIC S9(9) COMP. PROCEDURE DIVISION. MAIN-LOGIC. * Example 1: Generate JSON from COBOL data structure MOVE "CUS123" TO CUSTOMER-ID MOVE "John Doe" TO CUSTOMER-NAME MOVE "john.doe@example.com" TO CUSTOMER-EMAIL MOVE "A" TO CUSTOMER-STATUS MOVE 1250.75 TO CUSTOMER-BALANCE * Using IBM Enterprise COBOL JSON GENERATE DISPLAY "Generating JSON from COBOL data..." JSON GENERATE JSON-DOC FROM CUSTOMER-DATA COUNT IN JSON-LENGTH DISPLAY JSON-DOC(1:JSON-LENGTH) * Example 2: Parse JSON into COBOL data structure DISPLAY "Parsing JSON to COBOL data..." MOVE '{ "customerId": "CUS456", "customerName": "Jane Smith", "customerEmail": "jane.smith@example.com", "customerStatus": "I", "customerBalance": -125.50 }' TO JSON-DOC INITIALIZE CUSTOMER-DATA * Using IBM Enterprise COBOL JSON PARSE JSON PARSE JSON-DOC INTO CUSTOMER-DATA DISPLAY "Parsed customer data:" DISPLAY "ID: " CUSTOMER-ID DISPLAY "Name: " CUSTOMER-NAME DISPLAY "Email: " CUSTOMER-EMAIL DISPLAY "Status: " CUSTOMER-STATUS DISPLAY "Balance: " CUSTOMER-BALANCE STOP RUN.

This example demonstrates the JSON PARSE and JSON GENERATE statements available in IBM Enterprise COBOL. These built-in features significantly simplify working with JSON in COBOL applications.

Security Considerations

When integrating COBOL with REST APIs, several security considerations are essential:

  • Authentication: Implementing OAuth 2.0, API keys, JWT tokens, or other standard authentication mechanisms
  • Authorization: Controlling access to specific API endpoints based on user roles/permissions
  • Data Validation: Validating all inputs to prevent injection attacks or buffer overflows
  • Transport Security: Using TLS/HTTPS for all API communications
  • API Rate Limiting: Preventing denial-of-service through excessive requests
  • Sensitive Data Handling: Proper encryption and masking of PII or confidential information

Best Practices

  • API Design: Follow REST principles (resource-oriented design, proper HTTP methods, statelessness)
  • Error Handling: Implement comprehensive error handling with meaningful HTTP status codes and error messages
  • Documentation: Create clear API documentation using industry standards like OpenAPI/Swagger
  • Versioning: Implement API versioning to manage changes without breaking existing clients
  • Testing: Thoroughly test APIs with automated test suites covering various scenarios
  • Monitoring: Implement API metrics and monitoring to track usage, performance, and errors
  • Caching: Use appropriate caching strategies to improve performance and reduce load on backend systems

Test Your Knowledge

Test Your Knowledge

1. Which COBOL compiler vendor is well-known for providing solutions for UNIX/Linux and Windows?

  • IBM (for z/OS only)
  • Micro Focus
  • Fujitsu
  • Both Micro Focus and Fujitsu

2. What technology commonly allowed COBOL programs to be exposed as web services in earlier web enablement efforts?

  • Direct HTTP listeners in COBOL
  • SOAP and WSDL
  • AJAX
  • PHP wrappers

3. When integrating COBOL with REST APIs, what data format is most commonly used for message payloads?

  • XML
  • JSON
  • Raw text files
  • COBOL copybooks

4. Which of these is a key challenge when deploying COBOL applications in a microservices architecture?

  • COBOL's inability to perform calculations
  • Lack of COBOL compilers for modern platforms
  • State management and data consistency across services
  • COBOL programs being too fast for network communication

5. What is a common approach to allow a COBOL program on a mainframe to call an external REST API?

  • Rewriting the COBOL program in Java
  • Using a mainframe-based HTTP client tool or a wrapper module (e.g., CICS web services, z/OS Connect EE)
  • Directly opening TCP/IP sockets from COBOL and implementing HTTP from scratch
  • It is not possible for mainframe COBOL to call external REST APIs

Frequently Asked Questions