Vous devez réagir à des événements externes (retours SMS, notifications, fichiers, etc.) sur votre IBM i, mais vous ne voulez pas :
❌ Modifier vos programmes RPG existants ?
❌ Développer une API REST pour un besoin ponctuel ?
❌ Gérer des mécanismes complexes comme les data queues ?
Voici comment nous avons résolu ce problème avec un trigger RPG qui :
🔹 Surveille les insertions dans une table de contrôle (EVENT_QUEUE).
🔹 Filtre les enregistrements selon des critères métiers (ex: statut = erreur).
🔹 Délègue le traitement à un programme existant (PROCESS_EVENT) via SBMJOB.
🔹 Gère les erreurs avec un logging centralisé.
🔧 Implémentation technique (extrait du code réel)
1. Configuration du trigger RPG
Le trigger est attaché à la table EVENT_QUEUE et se déclenche après chaque insertion :
ADDPFTRG FILE(MYLIB/EVENT_QUEUE) TRGTIME(*AFTER) TRGEVENT(*INSERT)
PGM(MYLIB/TRG_EVENT_HDL) 2. Analyse du buffer trigger RPG
Le programme RPG (TRG_EVENT_HDL) analyse le buffer reçu pour :
- Extraire les métadonnées (fichier, bibliothèque, type d'événement).
- Récupérer l'image de l'enregistrement inséré (AfterImage).
// Mapping du buffer trigger pHeader = %Addr(pTriggerBuffer); If (TriggerHeader.OffsetAfter > 0); pAfter = %Addr(pTriggerBuffer) + TriggerHeader.OffsetAfter; EndIf;
3. Logique métier conditionnelle
Seuls les événements avec un statut spécifique (ex: EVENT_STATUS = 'ERR') sont traités :
If %Subst(AfterImage.EVENT_STATUS:1:1) = STATUS_ERROR;
// Soumettre un job pour exécuter le programme métier
cmdStr = 'SBMJOB CMD(CALL PGM(MYLIB/PROCESS_EVENT) PARM(' +
'''' + %Trim(AfterImage.EVENT_ID) + '''' +
')) JOB(EVENT_PROC) JOBQ(*LIBL/EVENT_JOBQ)';
Monitor;
GoCmd(CmdStr:%Len(CmdStr)); // Exécution via QCMDEXC
On-Error;
LogError('Erreur lors du traitement de l''événement ID: ' + AfterImage.EVENT_ID);
EndMon;
EndIf; 4. Gestion des erreurs
Une procédure dédiée (LogError) utilise QMHSNDPM pour tracer les problèmes :
Dcl-Proc LogError;
Dcl-Pi *N;
pErrorMessage Varchar(512) Const;
End-Pi;
SndPgmMsg(
*Blanks: // Message générique
*Blanks: // Fichier par défaut
pErrorMessage: // Texte de l'erreur
%Len(%Trim(pErrorMessage)):
'*INFO': // Type d'information
'*': // Pile d'appel actuelle
1: // Niveau 1
MsgKey: // Clé du message
ApiError // Structure d'erreur
);
End-Proc; ✅ Pourquoi cette approche ?
| Avantage | Détail |
|---|---|
| Non-invasif | Acueune modification des programmes métiers existants (PROCESS_EVENT) |
| Découplage | Le système externe n'a qu'à insérer un enregistrement via ODBC |
| Robustesse | Traitement en job séparé (SMJOB) pour éviter les blocages |
| Traçabilité | Logging centralisé via QMHSNDPM et table d'audit |
| Flexibilité | Ajout/suppression de règles en modifiant uniquement le trigger |
⚠️ Points de vigilance
- Volume d'insertions :
- Table d'audit recommandée :
- Sécurité :
🔄 Comparatif des solutions
| Solution | Complexité | Maintenance | Découplage | Cas d'usage idéal |
|---|---|---|---|---|
| Trigger RPG | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | Traitements légers, besoin de réactivité |
| Data Queues | ⭐⭐⭐ | ⭐⭐ | ⭐⭐ | Haut volume, besoin de FIFO |
| Web Services (REST) | ⭐⭐⭐⭐ | ⭐ | ⭐⭐⭐ | Intégration avec des systèmes modernes |
| Appels DRDA | ⭐⭐ | ⭐ | ⭐ | Besoins ponctuels et simples |
💡 Retour d'expérience
Dans un projet récent, cette solution a permis de :
- Automatiser le traitement d'événements externes (ex: échecs de transactions) sans modifier le code métier.
- Réduire les coûts de maintenance de 60% (pas de modifications en cascade).
- Centraliser la logique de déclenchement dans un seul point (le trigger).
Exemple de flux :
Système Externe → ODBC → INSERT INTO EVENT_QUEUE → Trigger TRG_EVENT_HDL → SBMJOB(PROCESS_EVENT) → Traitement métier



0 commentaire