Architecture des Programmes CICS : Transaction Processing
Introduction à CICS
CICS (Customer Information Control System) est un gestionnaire de transactions middleware qui s'exécute sur les mainframes IBM z/OS. Il fournit un environnement d'exécution pour les applications transactionnelles en ligne, gérant automatiquement l'accès aux ressources système et la coordination des transactions. Dans les architectures modernes d'entreprise, CICS reste le pilier central pour les applications critiques traitant des millions de transactions par jour avec des exigences de disponibilité de 99.99%.
Architecture et Organisation CICS
Topologies CICSplex : TOR, AOR, FOR
L'architecture CICS moderne repose sur une distribution des responsabilités entre plusieurs types de régions spécialisées. Cette approche permet une scalabilité horizontale et une séparation claire des préoccupations :
Architecture CICSplex distribuée
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ TOR (Terminal │ │ AOR (Applica- │ │ FOR (File │
│ Owning Region) │<-->│ tion Owning │<-->│ Owning Region) │
│ │ │ Region) │ │ │
│ • Terminaux │ │ • Programmes │ │ • Fichiers VSAM │
│ • Web Services │ │ • Logique │ │ • Bases DB2 │
│ • API Gateway │ │ • Traitement │ │ • Journalisation│
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└─────────── MRO/IRC ───┴───────────────────────┘
TOR - Gestion des points d'entrée (3270, HTTP, TCP/IP)
AOR - Exécution des programmes applicatifs et logique métier
FOR - Accès centralisé aux données (VSAM, DB2, journaux)
Terminal Owning Region (TOR) :
La TOR agit comme la passerelle d'entrée du système. Elle gère tous les points d'accès : terminaux 3270 traditionnels, services web REST/SOAP, et API modernes. Dans ma pratique, j'ai souvent configuré plusieurs TOR en load-balancing pour distribuer la charge d'entrée.
Application Owning Region (AOR) :
C'est le cœur de traitement où résident les programmes COBOL/PL1 et la logique métier. Les AOR peuvent être spécialisées par domaine fonctionnel (bancaire, assurance, etc.) permettant un scaling indépendant selon les besoins.
File Owning Region (FOR) :
Cette région centralise l'accès aux données, qu'il s'agisse de fichiers VSAM, bases DB2 ou systèmes de journalisation. Cette architecture évite les contentions et permet une optimisation fine des accès.
CICSplex System Manager (CPSM)
Le CPSM représente l'évolution naturelle vers une administration centralisée des environnements CICS complexes. Après 25 ans dans ce domaine, je considère CPSM comme indispensable pour toute installation sérieuse :
* Configuration CPSM pour administration centralisée
DEFINE CICSPLEX(PRODPLEX) DESCRIPTION('Production Environment')
* Définition des régions membres
DEFINE CICSRGN(TOR1) CICSPLEX(PRODPLEX) JOBNAME(CICSTOR1)
DEFINE CICSRGN(AOR1) CICSPLEX(PRODPLEX) JOBNAME(CICSAOR1)
DEFINE CICSRGN(AOR2) CICSPLEX(PRODPLEX) JOBNAME(CICSAOR2)
DEFINE CICSRGN(FOR1) CICSPLEX(PRODPLEX) JOBNAME(CICSFOR1)
* Workload balancing automatique
DEFINE WLMSPEC(BANKING_WLM)
ALGORITHM(OPTIMAL_GOAL)
HEALTH_MONITORING(YES)
REDISTRIBUTION_FREQUENCY(30)
* Règles de routage intelligent
DEFINE ROUTINGBN(BANK_ROUTE)
PROGRAM_PATTERN(BANK*)
TARGET_SCOPE(AOR1,AOR2)
LOADING_ALGORITHM(ROUND_ROBIN)
Le CPSM apporte trois avantages majeurs que j'ai pu mesurer concrètement :
• Administration centralisée : Fini les connexions sur chaque région, tout se pilote depuis une console unique
• Workload balancing intelligent : Distribution automatique basée sur la charge CPU, mémoire et temps de réponse
• Résilience automatique : Bascule transparente en cas de panne d'une région, invisible pour l'utilisateur final
Performance & Scalabilité
Threadsafe & OPEN API : La Clé des Performances
La programmation threadsafe est devenue un impératif absolu dans les environnements CICS modernes. J'ai vu trop d'installations souffrir de basculements TCB coûteux par méconnaissance de ce principe :
* Programme THREADSAFE - Bonne pratique
IDENTIFICATION DIVISION.
PROGRAM-ID. TSAFEPROG.
* Déclaration THREADSAFE obligatoire
CBL THREADSAFE
DATA DIVISION.
WORKING-STORAGE SECTION.
* ATTENTION: Pas de variables partagées entre executions !
01 WS-LOCAL-COUNTER PIC S9(9) COMP VALUE ZERO.
01 WS-THREAD-TIMESTAMP PIC S9(15) COMP-3.
LINKAGE SECTION.
01 COMMAREA-DATA PIC X(1000).
PROCEDURE DIVISION USING COMMAREA-DATA.
MAIN-PROCESSING.
* Chaque exécution obtient sa propre copie des variables WS
EXEC CICS ASKTIME ABSTIME(WS-THREAD-TIMESTAMP) END-EXEC
* Traitement thread-safe : pas d'état global
PERFORM BUSINESS-LOGIC-ISOLATED
EXEC CICS RETURN END-EXEC.
* Exemple de ce qu'il faut ÉVITER :
* 01 GLOBAL-COUNTER PIC S9(9) COMP VALUE ZERO. <- DANGER !
* ADD 1 TO GLOBAL-COUNTER <- Race condition !
Sans programmation threadsafe, CICS bascule du TCB QR (quasi-reentrant, haute performance) vers les TCB L8/Q8 (mode sérialisé, beaucoup plus lent). J'ai observé des dégradations de performances de 300% lors de ces basculements non maîtrisés.
Tuning : Les Paramètres Critiques
Après des années de tuning, voici les paramètres qui font vraiment la différence :
* Paramètres SIT critiques pour les performances
DFHSIT TYPE=FINAL,
MAXTASKS=500, * Nombre max de tâches concurrentes
MXT=200, * Tâches concurrentes par région
AMXT=50, * Tâches concurrentes par APPLID
* Configuration DB2 optimisée
DB2CONN=YES, * Connexion DB2 activée
DB2ID=DB2P, * Sous-système DB2
DROLLBACK=86400, * Rollback timeout (24h)
* Optimisation mémoire
DSA=32768, * Dynamic Storage Area (32MB)
EDSA=16384, * Extended DSA (16MB)
UDSA=512, * User DSA (512KB)
CDSA=65536, * Common DSA (64MB)
* Configuration des fichiers critique
FCQRMAX=999, * Max File Control requests queued
AKPFREQ=10000, * Fréquence monitoring auto (10s)
RUNAWAY=20000 * Détection tâches en boucle (20s)
* Définitions de fichiers optimisées
DEFINE FILE(CUSTOMER) GROUP(PRODGRP)
DSNAME(PROD.CUSTOMER.VSAM)
STATUS(ENABLED)
OPENTIME(FIRSTREF) * Ouverture différée
DISPOSITION(SHR) * Partage entre régions
RECORDSIZE(500,1000) * Taille variable optimisée
KEYLENGTH(10) * Clé primaire
STRINGS(20) * Buffers de chaîne
LSR=YES * Local Shared Resources
BUFFERS(100) * Cache buffers
Instrumentation : SMF, CMF et Performance Analyzer
Le monitoring proactif est essentiel. Voici comment j'instrumente mes environnements CICS :
* Configuration SMF pour CICS (Records 110)
//SMFPRM01 DD *
INTERVAL(15) * Intervalle de collecte 15min
DETAIL(YES) * Données détaillées
SYS(STC,CICS01,CICS02,CICS03) * Systèmes monitorés
REC(110,111,112) * Records CICS
* Activation CMF (CICS Monitoring Facility)
CEMT SET MONITOR STATUS(ON) EXCEPTION(ON)
CEMT SET REQUESTMODEL STATUS(ON)
CEMT SET PERFORMANCECLASS(1) STATUS(ON)
* Exemple d'analyse SMF - Rapport TPS
SELECT
SMF110_APPLID,
COUNT(*) / 900 AS TPS_15MIN, * Transactions par seconde
AVG(SMF110_ELAPSED_TIME) AS AVG_RESPONSE,
MAX(SMF110_ELAPSED_TIME) AS PEAK_RESPONSE,
SUM(SMF110_CPU_TIME) AS TOTAL_CPU
FROM SMF110_RECORDS
WHERE SMF110_TIME BETWEEN '14:00:00' AND '14:15:00'
GROUP BY SMF110_APPLID
ORDER BY TPS_15MIN DESC
Sécurité & Gouvernance
Intégration RACF/SAF : Délégation Sécuritaire
CICS s'appuie intelligemment sur RACF pour toute la sécurité. Cette architecture de délégation assure cohérence et centralisation :
* Protection d'une transaction critique
RDEFINE TCICSTRN CICSPROD.PAYM UACC(NONE) OWNER(BANKSEC)
PERMIT CICSPROD.PAYM CLASS(TCICSTRN) ACCESS(READ) ID(CASHIER)
PERMIT CICSPROD.PAYM CLASS(TCICSTRN) ACCESS(UPDATE) ID(MANAGER)
* Protection des programmes sensibles
RDEFINE PCICSPGM CICSPROD.PAYLOGIC UACC(NONE)
PERMIT CICSPROD.PAYLOGIC CLASS(PCICSPGM) ACCESS(EXECUTE) ID(PAYGROUP)
* Protection des ressources fichiers
RDEFINE FCICSFIL CICSPROD.ACCOUNTS UACC(NONE)
PERMIT CICSPROD.ACCOUNTS CLASS(FCICSFIL) ACCESS(READ) ID(READGRP)
PERMIT CICSPROD.ACCOUNTS CLASS(FCICSFIL) ACCESS(UPDATE) ID(UPDTGRP)
* Vérification programmatique des droits
EXEC CICS QUERY SECURITY
RESCLASS('TCICSTRN')
RESID('PAYM')
USERID(EIBUSERID)
READ(WS-READ-AUTH)
UPDATE(WS-UPDATE-AUTH)
END-EXEC
IF WS-UPDATE-AUTH = 'Y'
PERFORM AUTHORIZED-PAYMENT-PROCESSING
ELSE
MOVE 'Insufficient privileges' TO ERROR-MSG
PERFORM SEND-SECURITY-VIOLATION-ALERT
END-IF
Journalisation & Audit avec System Logger
La traçabilité est cruciale pour la gouvernance. CICS offre plusieurs mécanismes complémentaires :
* Configuration journalisation CICS
DFHJCADS TYPE=JOURNAL,
JOURNALNAME=DFHJ01,
TYPE=SMF, * SMF ou BSAM
STATUS=ENABLED,
DISPOSITION=KEEP,
PROTECT=YES * Protection écriture
* Écriture manuelle au journal depuis le programme
EXEC CICS WRITE JOURNALNAME('AUDITLOG')
FROM(AUDIT-RECORD)
FLENGTH(LENGTH OF AUDIT-RECORD)
JTYPEID('AU')
END-EXEC
* Structure d'audit complète
01 AUDIT-RECORD.
05 AUDIT-HEADER.
10 AUDIT-TIMESTAMP PIC X(26).
10 AUDIT-USERID PIC X(8).
10 AUDIT-TERMID PIC X(4).
10 AUDIT-TRANSID PIC X(4).
05 AUDIT-BUSINESS-DATA.
10 CUSTOMER-ID PIC X(10).
10 OPERATION-TYPE PIC X(8).
10 AMOUNT-BEFORE PIC S9(9)V99 COMP-3.
10 AMOUNT-AFTER PIC S9(9)V99 COMP-3.
10 AUTHORIZATION-CODE PIC X(12).
TLS & API Gateway pour l'Ère Moderne
L'intégration aux architectures modernes nécessite une sécurisation des flux. Voici comment j'aborde cette problématique :
* Configuration TCPIPSERVICE avec TLS
DEFINE TCPIPSERVICE(WEBSVC) GROUP(WEBGROUP)
PORT(8443)
PROTOCOL(HTTP)
SSL(YES)
CERTIFICATE('CICSCERT')
CIPHERS('TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256')
AUTHENTICATE(REQUIRED)
CLIENTCERTIFICATE(REQUIRED)
* Programme CICS exposé en REST/JSON
IDENTIFICATION DIVISION.
PROGRAM-ID. RESTAPI.
PROCEDURE DIVISION.
MAIN-PROCESSING.
* Parsing de la requête HTTP JSON
EXEC CICS WEB READ
HTTPHEADER(WS-HTTP-HEADERS)
NAMELENGTH(WS-NAME-LEN)
CHARACTERSET(1208) * UTF-8
END-EXEC
* Validation token JWT
PERFORM VALIDATE-JWT-TOKEN
* Traitement métier
IF JWT-VALID
PERFORM PROCESS-REST-REQUEST
PERFORM BUILD-JSON-RESPONSE
ELSE
MOVE 401 TO HTTP-STATUS-CODE
MOVE '{"error":"Unauthorized"}' TO JSON-RESPONSE
END-IF
* Envoi réponse sécurisée
EXEC CICS WEB SEND
FROM(JSON-RESPONSE)
MEDIATYPE('application/json')
STATUSCODE(HTTP-STATUS-CODE)
STATUSTEXT('OK')
END-EXEC
Structure fondamentale d'un programme CICS
Un programme CICS typique suit une structure bien définie avec des sections spécifiques pour la gestion des données et des transactions.
IDENTIFICATION DIVISION.
PROGRAM-ID. CICSPROG.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-COMMAREA-LEN PIC S9(4) COMP VALUE 100.
01 WS-RESPONSE PIC S9(8) COMP.
01 WS-MESSAGE PIC X(80).
LINKAGE SECTION.
01 DFHCOMMAREA PIC X(100).
PROCEDURE DIVISION.
MAIN-PARA.
EXEC CICS HANDLE CONDITION
ERROR(ERROR-PARA)
END-EXEC.
PERFORM PROCESS-TRANSACTION
EXEC CICS RETURN
END-EXEC.
PROCESS-TRANSACTION.
EXEC CICS RECEIVE MAP('MAINMAP')
MAPSET('MAINSET')
INTO(WS-MESSAGE)
RESP(WS-RESPONSE)
END-EXEC.
IF WS-RESPONSE = DFHRESP(NORMAL)
PERFORM BUSINESS-LOGIC
ELSE
PERFORM HANDLE-ERROR
END-IF.
Gestion des transactions et pseudo-conversationnel
CICS utilise un modèle pseudo-conversationnel pour optimiser l'utilisation des ressources. Chaque interaction utilisateur est traitée comme une transaction distincte.
EXEC CICS SEND MAP('INPUTMAP')
MAPSET('MAINSET')
ERASE
CURSOR
END-EXEC.
EXEC CICS RETURN
TRANSID('TRAN')
COMMAREA(WS-COMMAREA)
LENGTH(WS-COMMAREA-LEN)
END-EXEC.
Communication Areas (COMMAREA)
Les COMMAREA permettent de passer des données entre les transactions pseudo-conversationnelles, maintenant l'état de l'application.
01 COMMUNICATION-AREA.
05 CA-FUNCTION-CODE PIC X(2).
05 CA-USER-ID PIC X(8).
05 CA-LAST-MAP PIC X(8).
05 CA-ERROR-FLAG PIC X(1).
05 CA-DATA-AREA PIC X(80).
Gestion des écrans et BMS (Basic Mapping Support)
Le BMS permet la gestion des écrans 3270 avec des mapsets prédéfinis pour l'interface utilisateur.
* Définition d'un mapset BMS
DFHMSD TYPE=&SYSPARM,MODE=INOUT,LANG=COBOL,STORAGE=AUTO
CUSTMAP DFHMDI SIZE=(24,80),LINE=1,COLUMN=1
DFHMDF POS=(1,25),LENGTH=20,ATTRB=BRT,
INITIAL='CUSTOMER MANAGEMENT'
CUSTNO DFHMDF POS=(5,10),LENGTH=8,ATTRB=UNPROT
CUSTNAME DFHMDF POS=(7,10),LENGTH=30,ATTRB=UNPROT
BALANCE DFHMDF POS=(9,10),LENGTH=10,ATTRB=UNPROT
MSG DFHMDF POS=(22,1),LENGTH=79,ATTRB=BRT
DFHMSD TYPE=FINAL
Gestion des exceptions et HANDLE CONDITION
CICS fournit un mécanisme sophistiqué de gestion d'exceptions pour traiter les erreurs de manière centralisée.
EXCEPTION-HANDLING.
EXEC CICS HANDLE CONDITION
NOTFND(NOT-FOUND-PARA)
DUPREC(DUPLICATE-RECORD-PARA)
NOSPACE(NO-SPACE-PARA)
IOERR(IO-ERROR-PARA)
PGMIDERR(PROGRAM-ERROR-PARA)
MAPFAIL(MAP-ERROR-PARA)
END-EXEC.
NOT-FOUND-PARA.
MOVE 'Record not found in database' TO MSG-TEXT
PERFORM SEND-ERROR-MESSAGE
EXEC CICS RETURN END-EXEC.
DUPLICATE-RECORD-PARA.
MOVE 'Duplicate key violation' TO MSG-TEXT
PERFORM SEND-ERROR-MESSAGE
EXEC CICS RETURN END-EXEC.
IO-ERROR-PARA.
MOVE 'I/O error occurred' TO MSG-TEXT
PERFORM LOG-SYSTEM-ERROR
EXEC CICS ABEND ABCODE('IOER') END-EXEC.
Transactions multi-threadées et Task Control
CICS gère automatiquement le multithreading avec des mécanismes de contrôle de tâches sophistiqués.
TASK-CONTROL-MANAGEMENT.
* Démarrage d'une tâche enfant
EXEC CICS START
TRANSID('CHLD')
FROM(CHILD-DATA)
LENGTH(LENGTH OF CHILD-DATA)
TERMID(TERMINAL-ID)
END-EXEC.
* Attente de signalisation
EXEC CICS WAIT EVENT
ECADDR(EVENT-CONTROL-BLOCK)
END-EXEC.
* Signalisation d'événement
EXEC CICS POST
ECADDR(EVENT-CONTROL-BLOCK)
END-EXEC.
* Suspension temporaire
EXEC CICS DELAY
INTERVAL(10)
END-EXEC.
Intégration avec DB2 et SQL dynamique
L'intégration CICS-DB2 permet l'exécution de requêtes SQL dans un contexte transactionnel.
DB2-INTEGRATION.
* Préparation d'une requête dynamique
MOVE 'SELECT CUST_ID, CUST_NAME, BALANCE FROM CUSTOMER
- 'WHERE STATUS = ? AND REGION = ?' TO SQL-STATEMENT.
EXEC SQL
PREPARE STMT1 FROM :SQL-STATEMENT
END-EXEC.
* Exécution avec paramètres
MOVE 'ACTIVE' TO HOST-STATUS
MOVE 'EUROPE' TO HOST-REGION
EXEC SQL
EXECUTE STMT1 USING :HOST-STATUS, :HOST-REGION
END-EXEC.
* Traitement des cursors
EXEC SQL
DECLARE CUST_CURSOR CURSOR FOR STMT1
END-EXEC.
EXEC SQL OPEN CUST_CURSOR END-EXEC.
PERFORM UNTIL SQLCODE = 100
EXEC SQL
FETCH CUST_CURSOR
INTO :WS-CUST-ID, :WS-CUST-NAME, :WS-BALANCE
END-EXEC
IF SQLCODE = 0
PERFORM PROCESS-CUSTOMER-ROW
END-IF
END-PERFORM.
Disponibilité & Résilience
Recovery Manager : La Gestion des Points de Synchronisation
Le CICS Recovery Manager (DFHRMxx) orchestre la cohérence transactionnelle avec une sophistication remarquable. Après avoir géré de nombreux incidents de production, je peux témoigner de l'efficacité de ces mécanismes :
* Configuration Recovery Manager dans DFHSIT
DFHSIT TYPE=FINAL,
RLS=YES, * Recovery Log Stream activation
JOURNAL=AUTO, * Journalisation automatique
LOGDEFER=NO, * Écriture immédiate des logs
OFFLOAD=YES, * Déchargement automatique
* Points de synchronisation optimisés
AKPFREQ=5000, * Checkpoints toutes les 5000 tâches
AKPTIME=300, * Ou toutes les 5 minutes
TRTABSZ=5000, * Table recovery 5000 entrées
TRTRANSZ=64000 * Taille max transaction recovery
* Coordination avec DB2 - Two Phase Commit
EXEC CICS SYNCPOINT END-EXEC * Phase 1: Préparation
* CICS coordonne avec DB2 Resource Manager
* Phase 2: Validation ou Rollback selon réponses
* Exemple de gestion manuelle des UOW (Unit of Work)
WORKING-STORAGE SECTION.
01 SAVEPOINT-OPTIONS.
05 SP-ID PIC X(8) VALUE 'SP000001'.
05 SP-LEVEL PIC S9(4) COMP VALUE 1.
PROCEDURE DIVISION.
COMPLEX-TRANSACTION-PROCESSING.
* Établissement d'un point de sauvegarde
EXEC CICS SAVEPOINT
ID(SP-ID)
LEVEL(SP-LEVEL)
END-EXEC
* Traitement complexe avec validation progressive
PERFORM UPDATE-CUSTOMER-DATA
IF UPDATE-SUCCESSFUL
PERFORM UPDATE-ACCOUNT-BALANCE
IF BALANCE-UPDATE-OK
EXEC CICS SYNCPOINT END-EXEC * Commit définitif
ELSE
EXEC CICS ROLLBACK
TO(SP-ID)
END-EXEC * Retour au savepoint
END-IF
ELSE
EXEC CICS SYNCPOINT ROLLBACK END-EXEC * Rollback complet
END-IF
Parallel Sysplex : Haute Disponibilité à l'Échelle z/OS
L'intégration CICS au Parallel Sysplex transforme votre environnement transactionnel en forteresse de disponibilité. Dans les installations que j'ai architecturées, nous atteignons systématiquement 99.99% de disponibilité :
* Configuration CICS dans un Sysplex
//CICS01 JOB CLASS=A,MSGCLASS=H,MSGLEVEL=(1,1)
//IEFBR14 EXEC PGM=IEFBR14
//SYSPLEX DD DSN=SYS1.SYSPLEX.CONFIG,DISP=SHR
* Définition groupe XCF pour CICS
SETXCF START,GROUP,GROUPNAME=CICSPLEX
SETXCF DEFINE,STRUCTURE,STRNAME=CICS_LOCK_STRUCTURE,
SIZE=32768,INITSIZE=16384
* Sharing de données via Coupling Facility
DEFINE LOCK_STRUCTURE(CICS_SHARED_LOCKS)
TYPE(LOCK)
SIZE(32M)
INITSIZE(16M)
MAXENTRIES(1000000)
* Configuration VSAM RLS (Record Level Sharing)
DEFINE CLUSTER -
(NAME(PROD.CUSTOMER.KSDS) -
RLS(CR,NRI) - * Cross-Region, Non-Recovery
SHAREOPTIONS(4,3) - * RLS compatible
RECORDSIZE(500,2000) -
FREESPACE(20,10))
* Automatic restart en cas de panne
//DFHSIT DD *
AIEXIT=YES, * Automatic Initialize Exit
START=AUTO, * Démarrage automatique
CLSDST=TRANSACTION, * Fermeture propre transactions
DTRTABSZ=4000, * Dynamic Transaction Routing
GRPLIST=(GRP1,GRP2,GRP3)
Queues Transientes et Temporaires : Piliers de Résilience
Les TDQ (Transient Data Queues) et TSQ (Temporary Storage Queues) jouent un rôle crucial dans la résilience applicative que beaucoup sous-estiment :
* Utilisation TDQ pour audit et recovery
WORKING-STORAGE SECTION.
01 TDQ-AUDIT-RECORD.
05 TDQ-TIMESTAMP PIC X(26).
05 TDQ-TRANSACTION-DATA PIC X(500).
05 TDQ-STATUS PIC X(8).
PROCEDURE DIVISION.
RESILIENT-TRANSACTION-PROCESSING.
* Sauvegarde état avant traitement critique
MOVE FUNCTION CURRENT-DATE TO TDQ-TIMESTAMP
MOVE 'IN_PROGRESS' TO TDQ-STATUS
EXEC CICS WRITEQ TD
QUEUE('AUDT') * Queue audit prédéfinie
FROM(TDQ-AUDIT-RECORD)
LENGTH(LENGTH OF TDQ-AUDIT-RECORD)
END-EXEC
* Traitement métier avec protection
PERFORM CRITICAL-BUSINESS-LOGIC
* Confirmation succès
MOVE 'COMPLETED' TO TDQ-STATUS
EXEC CICS WRITEQ TD
QUEUE('AUDT')
FROM(TDQ-AUDIT-RECORD)
END-EXEC
* TSQ pour données de session complexes
EXEC CICS WRITEQ TS
QUEUE('USERSESSION')
FROM(COMPLEX-USER-STATE)
LENGTH(2000)
MAIN * Stockage en mémoire principale
ITEM(SESSION-ITEM-NUMBER)
REWRITE * Écrasement autorisé
END-EXEC
* Recovery automatique depuis TSQ
EXEC CICS READQ TS
QUEUE('USERSESSION')
INTO(RECOVERED-STATE)
ITEM(LAST-ITEM)
NEXT * Navigation séquentielle
END-EXEC
Modernisation & Intégration
CICS Transaction Gateway (CTG) : Pont vers Java/EAI
Le CTG représente l'évolution naturelle pour exposer la puissance transactionnelle CICS aux architectures Java modernes. J'ai mis en œuvre de nombreuses intégrations CTG pour des clients cherchant à moderniser sans perdre leurs investissements mainframe :
* Configuration CTG côté CICS
DEFINE CONNECTION(CTGCONN) GROUP(WEBGROUP)
CONNECTIONNAME('CTG_GATEWAY')
NETNAME('TCP:192.168.1.100:2006') * Adresse CTG server
PROTOCOL(HTTP)
TRANSACTION(CWXN)
ATTACHSEC(LOCAL)
* Programme CICS compatible CTG
IDENTIFICATION DIVISION.
PROGRAM-ID. CTGPROG.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 CTG-REQUEST-DATA.
05 CTG-FUNCTION-CODE PIC X(4).
05 CTG-CUSTOMER-ID PIC X(10).
05 CTG-AMOUNT PIC S9(9)V99 COMP-3.
05 CTG-CURRENCY PIC X(3).
01 CTG-RESPONSE-DATA.
05 CTG-RETURN-CODE PIC S9(4) COMP.
05 CTG-BALANCE PIC S9(11)V99 COMP-3.
05 CTG-MESSAGE PIC X(80).
LINKAGE SECTION.
01 DFHCOMMAREA PIC X(200).
PROCEDURE DIVISION.
MAIN-PROCESSING.
* Parsing des données depuis Java
MOVE DFHCOMMAREA(1:4) TO CTG-FUNCTION-CODE
MOVE DFHCOMMAREA(5:10) TO CTG-CUSTOMER-ID
MOVE DFHCOMMAREA(15:8) TO CTG-AMOUNT
* Traitement métier CICS classique
EVALUATE CTG-FUNCTION-CODE
WHEN 'INQY'
PERFORM INQUIRY-PROCESSING
WHEN 'UPDT'
PERFORM UPDATE-PROCESSING
WHEN OTHER
MOVE 9999 TO CTG-RETURN-CODE
MOVE 'Invalid function code' TO CTG-MESSAGE
END-EVALUATE
* Formatage réponse pour Java
MOVE CTG-RESPONSE-DATA TO DFHCOMMAREA
EXEC CICS RETURN END-EXEC
* Code Java correspondant (côté client)
// Connexion via CTG
CTGConnection ctgConn = new CTGConnection();
ctgConn.setConnectionURL("tcp://mainframe:2006");
ctgConn.setUserName("CICSUSER");
ctgConn.setPassword("PASSWORD");
// Invocation programme CICS
JavaGateway gateway = new JavaGateway(ctgConn);
CommAreaHolder commArea = new CommAreaHolder();
commArea.setValue("INQYCUST12345 ".getBytes());
gateway.flow("CICSRGN", "CTGPROG", commArea);
String response = new String(commArea.getValue());
Web Services & RESTful APIs : CICS à l'Ère du JSON
L'exposition des services CICS en REST/JSON transforme votre mainframe en API moderne. Voici une implémentation complète que j'ai déployée en production :
* Service REST complet pour gestion client
IDENTIFICATION DIVISION.
PROGRAM-ID. CUSTREST.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 JSON-REQUEST.
05 JSON-CUSTOMER-ID PIC X(10).
05 JSON-OPERATION PIC X(10).
05 JSON-AMOUNT PIC X(15).
01 JSON-RESPONSE.
05 JSON-STATUS PIC X(10) VALUE '"success"'.
05 JSON-CUSTOMER-DATA PIC X(200).
05 JSON-BALANCE PIC X(20).
05 JSON-TIMESTAMP PIC X(30).
PROCEDURE DIVISION.
REST-SERVICE-MAIN.
* Parsing de la requête HTTP JSON entrante
EXEC CICS WEB READ
HTTPHEADER(WS-HTTP-HEADERS)
NAMELENGTH(WS-HEADER-LEN)
VALUE(WS-HEADER-VALUE)
VALUELENGTH(WS-VALUE-LEN)
END-EXEC
* Extraction des données JSON
EXEC CICS WEB EXTRACT
PATH('/customer/id')
VALUE(JSON-CUSTOMER-ID)
TYPE(CHAR)
LENGTH(10)
END-EXEC
EXEC CICS WEB EXTRACT
PATH('/operation/type')
VALUE(JSON-OPERATION)
END-EXEC
* Traitement métier selon l'opération
EVALUATE JSON-OPERATION
WHEN 'GET'
PERFORM GET-CUSTOMER-INFO
WHEN 'POST'
PERFORM CREATE-CUSTOMER
WHEN 'PUT'
PERFORM UPDATE-CUSTOMER
WHEN 'DELETE'
PERFORM DELETE-CUSTOMER
END-EVALUATE
* Construction réponse JSON
STRING
'{"status":' JSON-STATUS ','
'"customer":{"id":"' JSON-CUSTOMER-ID '",'
'"balance":' JSON-BALANCE ','
'"timestamp":"' JSON-TIMESTAMP '"}'
'}'
DELIMITED BY SIZE INTO WS-JSON-RESPONSE
* Envoi réponse HTTP
EXEC CICS WEB SEND
FROM(WS-JSON-RESPONSE)
MEDIATYPE('application/json')
STATUSCODE(200)
STATUSTEXT('OK')
CHARACTERSET(1208) * UTF-8
END-EXEC
EXEC CICS RETURN END-EXEC
GET-CUSTOMER-INFO.
* Lecture fichier VSAM client
EXEC CICS READ FILE('CUSTOMER')
RIDFLD(JSON-CUSTOMER-ID)
INTO(CUSTOMER-RECORD)
RESP(WS-RESPONSE)
END-EXEC
IF WS-RESPONSE = DFHRESP(NORMAL)
MOVE CUSTOMER-BALANCE TO JSON-BALANCE
MOVE FUNCTION CURRENT-DATE TO JSON-TIMESTAMP
ELSE
MOVE '"error"' TO JSON-STATUS
MOVE '0.00' TO JSON-BALANCE
END-IF
MQ & Event Streaming : Intégration Kafka Moderne
L'intégration événementielle modern nécessite une approche hybride MQ/Kafka que j'ai implémentée dans plusieurs environnements critiques :
* Publishing d'événements vers Kafka via MQ Bridge
WORKING-STORAGE SECTION.
01 EVENT-MESSAGE.
05 EVENT-HEADER.
10 EVENT-TYPE PIC X(20) VALUE 'CUSTOMER_UPDATE'.
10 EVENT-TIMESTAMP PIC X(26).
10 EVENT-SOURCE PIC X(8) VALUE 'CICSPROD'.
10 EVENT-VERSION PIC X(5) VALUE '1.0.0'.
05 EVENT-PAYLOAD.
10 CUSTOMER-ID PIC X(10).
10 OPERATION-TYPE PIC X(10).
10 PREVIOUS-STATE PIC X(100).
10 NEW-STATE PIC X(100).
PROCEDURE DIVISION.
PUBLISH-CUSTOMER-EVENT.
* Construction événement CloudEvents compliant
MOVE FUNCTION CURRENT-DATE TO EVENT-TIMESTAMP
MOVE 'UPDATE' TO OPERATION-TYPE
MOVE OLD-CUSTOMER-DATA TO PREVIOUS-STATE
MOVE NEW-CUSTOMER-DATA TO NEW-STATE
* Publication via MQ vers Kafka Connect
EXEC CICS PUT QUEUE('KAFKA.EVENTS.CUSTOMER')
FROM(EVENT-MESSAGE)
LENGTH(LENGTH OF EVENT-MESSAGE)
CORRELID(CUSTOMER-ID)
END-EXEC
* Configuration MQ-Kafka Bridge (côté MQ)
DEFINE CHANNEL(KAFKA.BRIDGE) CHLTYPE(SVRCONN)
TRPTYPE(TCP)
MCAUSER('KAFKAUSER')
DESCR('Channel for Kafka Connect')
DEFINE QLOCAL(KAFKA.EVENTS.CUSTOMER)
DESCR('Customer events for Kafka streaming')
MAXDEPTH(100000)
MSGDLVSQ(PRIORITY)
DEFPRTY(5)
* Exemple consumer Kafka (côté applicatif moderne)
// Configuration Kafka Consumer pour événements CICS
Properties props = new Properties();
props.put("bootstrap.servers", "kafka-cluster:9092");
props.put("group.id", "cics-event-processor");
props.put("key.deserializer", StringDeserializer.class);
props.put("value.deserializer", "CICSEventDeserializer");
KafkaConsumer consumer = new KafkaConsumer<>(props);
consumer.subscribe(Arrays.asList("cics-customer-events"));
while (true) {
ConsumerRecords records = consumer.poll(100);
for (ConsumerRecord record : records) {
processCICSEvent(record.value()); // Traitement événement
}
}
Diagramme d'Architecture Globale
Voici une représentation complète de l'architecture CICS moderne que j'ai implémentée dans plusieurs grandes organisations :
. ┌─────────────────────────────────────────────┐
│ ARCHITECTURE CICS MODERNE │
└─────────────────────────────────────────────┘
┌──────────────┐ ┌─────────────────────────────────────────────────┐
│ Utilisateurs│ │ COUCHE ACCÈS │
│ │ │ ┌──────────┐ ┌──────────┐ ┌─────────────────┐ │
│ • 3270 │───→│ │ TOR1 │ │ TOR2 │ │ API Gateway │ │
│ • Web │ │ │ Terminal │ │ Terminal │ │ (z/OS Connect)│ │
│ • Mobile │ │ │ Region │ │ Region │ │ │ │
│ • APIs │ │ └────┬─────┘ └─────┬────┘ └────────┬────────┘ │
└──────────────┘ └───────┼─────────────┼───────────────┼──────────┘
│ │ │
│ ┌────────┴─────────┐ │
│ │ Load Balancer │ │
│ │ (CPSM/WLM) │ │
│ └────────┬─────────┘ │
└─────────────┼──────────────┘
│
┌─────────────────────┼─────────────────────┐
│ COUCHE TRAITEMENT │
│ ┌──────────┐ ┌────┴─────┐ ┌──────────┐ │
│ │ AOR1 │ │ AOR2 │ │ AOR3 │ │
│ │ Banking │ │Insurance │ │ Web │ │
│ │Programs │ │Programs │ │Services │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
└───────┼────────────┼────────────┼────────┘
│ │ │
┌───────┼────────────┼────────────┼────────┐
│ COUCHE DONNÉES │
│ ┌────┴─────┐ ┌────┴─────┐ ┌────┴─────┐ │
│ │ FOR1 │ │ DB2 │ │ MQ │ │
│ │ VSAM │ │SubSystem │ │ Messaging │ │
│ │ Files │ │ │ │ Queues │ │
│ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────┘
│
┌──────────┼──────────┐
│ INTÉGRATIONS │
│ │
│ ┌──────────────┐ │ ┌─────────────────┐
│ │ Kafka │ │ │ External │
│ │ Streaming │──┼─→│ Systems │
│ │ Events │ │ │ • CRM/ERP │
│ └──────────────┘ │ │ • Cloud APIs │
│ │ │ • Partners │
└───────────────────┘ └─────────────────┘
Points clés de l'architecture CICS moderne
• Séparation des préoccupations : TOR (accès), AOR (traitement), FOR (données) pour une scalabilité optimale
• Haute disponibilité : Parallel Sysplex, recovery automatique, réplication multi-sites
• Performance prédictive : Monitoring SMF/CMF, auto-tuning, workload balancing intelligent
• Sécurité en profondeur : RACF/SAF, TLS, audit forensique, détection d'intrusion
• Modernisation progressive : APIs REST/JSON, intégration Kafka, exposition microservices
• Gouvernance complète : Journalisation System Logger, traçabilité, conformité réglementaire