SAP Event Mesh permet une communication faiblement couplée et basée sur les événements entre les systèmes ABAP et d’autres applications sur la SAP Business Technology Platform. Avec les RAP Business Events, vous pouvez définir des événements métier et les propager en temps réel vers des systèmes externes.
Qu’est-ce que l’architecture event-driven ?
L’architecture event-driven (EDA) est un modèle d’architecture dans lequel les systèmes communiquent via des événements plutôt que par des appels API directs :
| Aspect | Intégration directe | Event-driven |
|---|---|---|
| Couplage | Étroit (synchrone) | Faible (asynchrone) |
| Disponibilité | Dépendant du système cible | Indépendant |
| Évolutivité | Limitée | Élevée |
| Tolérance aux pannes | Faible | Élevée (Retry/Replay) |
| Latence | Synchrone | Asynchrone |
| Cas d’utilisation | Cohérence transactionnelle | Notifications, réplication |
Concept SAP Event Mesh
SAP Event Mesh est un service de messagerie entièrement géré sur BTP :
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐│ ABAP Cloud │ │ SAP Event Mesh │ │ Subscriber ││ (Publisher) │─────>│ (Message Broker)│─────>│ (Consumer) ││ │ │ │ │ ││ RAP Business │ │ - Queues │ │ - ABAP Cloud ││ Events │ │ - Topics │ │ - CAP App ││ │ │ - Subscriptions │ │ - 3rd Party │└─────────────────┘ └──────────────────┘ └─────────────────┘Concepts clés :
- Event : Message concernant un événement métier (par ex. “Commande créée”)
- Topic : Canal logique pour les événements (par ex. “sap/sales/order/created”)
- Queue : Stockage persistant pour les événements par abonné
- Subscription : Connexion entre le Topic et la Queue
Définir un RAP Business Event
Les Business Events sont déclarés dans la Behavior Definition et déclenchés lors des changements d’état.
Behavior Definition avec Events
managed implementation in class zbp_i_salesorder unique;strict ( 2 );
define behavior for ZI_SalesOrder alias SalesOrderpersistent table zsalesorderlock masterauthorization master ( instance )etag master LastChangedAtwith additional save{ create; update; delete;
// Définir les Business Events event created; event updated; event deleted; event statusChanged parameter ZA_StatusChangeInfo;}Event avec structure de paramètres
Pour les événements complexes, vous définissez une Abstract Entity comme paramètre :
@EndUserText.label: 'Status Change Info"define abstract entity ZA_StatusChangeInfo{ SalesOrderId : abap.char(10); OldStatus : abap.char(2); NewStatus : abap.char(2); ChangedBy : abap.uname; ChangedAt : timestampl;}Publication d’événements
Les événements sont déclenchés dans l’implémentation du Behavior - généralement dans des Determinations ou Actions.
Déclencher un événement lors du Create
CLASS lhc_salesorder DEFINITION INHERITING FROM cl_abap_behavior_handler. PRIVATE SECTION. METHODS raise_created_event FOR DETERMINE ON SAVE IMPORTING keys FOR SalesOrder~raiseCreatedEvent.ENDCLASS.
CLASS lhc_salesorder IMPLEMENTATION. METHOD raise_created_event. " Déclencher l'événement pour les nouvelles instances RAISE ENTITY EVENT zi_salesorder~created FROM VALUE #( FOR key IN keys ( %key = key-%key ) ). ENDMETHOD.ENDCLASS.Event lors d’un changement de statut avec paramètres
CLASS lhc_salesorder DEFINITION INHERITING FROM cl_abap_behavior_handler. PRIVATE SECTION. METHODS on_status_change FOR DETERMINE ON SAVE IMPORTING keys FOR SalesOrder~onStatusChange.ENDCLASS.
CLASS lhc_salesorder IMPLEMENTATION. METHOD on_status_change. " Lire les anciennes et nouvelles valeurs READ ENTITIES OF zi_salesorder IN LOCAL MODE ENTITY SalesOrder ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(orders).
" Déclencher l'événement avec paramètres RAISE ENTITY EVENT zi_salesorder~statusChanged FROM VALUE #( FOR order IN orders ( %key = order-%key %param = VALUE #( salesorderid = order-SalesOrderId oldstatus = order-OldStatus newstatus = order-Status changedby = sy-uname changedat = utclong_current( ) ) ) ). ENDMETHOD.ENDCLASS.Determination pour le déclenchement d’événements
managed implementation in class zbp_i_salesorder unique;strict ( 2 );
define behavior for ZI_SalesOrder alias SalesOrderpersistent table zsalesorderlock masterauthorization master ( instance )with additional save{ create; update; delete;
// Events event created; event statusChanged parameter ZA_StatusChangeInfo;
// Determinations pour le déclenchement d'événements determination raiseCreatedEvent on save { create; } determination onStatusChange on save { field Status; }}Consommation d’événements
Les événements peuvent être consommés dans d’autres systèmes ABAP ou applications externes.
Event Handler dans ABAP Cloud
CLASS zcl_salesorder_event_handler DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. INTERFACES if_rap_event_handler.ENDCLASS.
CLASS zcl_salesorder_event_handler IMPLEMENTATION. METHOD if_rap_event_handler~handle. " Vérifier le type d'événement CASE io_event->get_event_name( ). WHEN 'CREATED'. handle_created( io_event ). WHEN 'STATUSCHANGED'. handle_status_changed( io_event ). ENDCASE. ENDMETHOD.
METHOD handle_created. DATA: lt_keys TYPE TABLE OF zi_salesorder.
" Lire les données de l'événement io_event->get_business_data( IMPORTING et_business_data = lt_keys ).
" Traitement : par ex. envoyer un message, écrire un log LOOP AT lt_keys INTO DATA(ls_key). " Logique métier ENDLOOP. ENDMETHOD.
METHOD handle_status_changed. DATA: lt_params TYPE TABLE OF za_statuschangeinfo.
" Lire les données des paramètres io_event->get_business_data( IMPORTING et_business_data = lt_params ).
LOOP AT lt_params INTO DATA(ls_param). " Par ex. envoyer un e-mail lors du changement de statut IF ls_param-newstatus = 'AP'. " Approved send_approval_notification( ls_param ). ENDIF. ENDLOOP. ENDMETHOD.ENDCLASS.Enregistrer un Event Handler
L’enregistrement se fait via le Business Event Handling Framework :
" Enregistrement dans une table de customizing ou par APIDATA(lo_registration) = cl_beh_event_registration=>get_instance( ).
lo_registration->register_handler( iv_event_name = 'CREATED" iv_handler_class = 'ZCL_SALESORDER_EVENT_HANDLER" iv_source_entity = 'ZI_SALESORDER' ).Configuration dans le cockpit BTP
1. Créer le service Event Mesh
- Dans le cockpit BTP, naviguez vers votre Subaccount
- Allez dans Service Marketplace → SAP Event Mesh
- Créez une instance de service avec le plan
default - Créez une Service Key pour l’authentification
2. Configurer le Message Client
Les données de la Service Key contiennent tous les paramètres de connexion nécessaires :
{ "management": [ { "oa2": { "clientid": "sb-event-mesh-client!...", "clientsecret": "...", "tokenendpoint": "https://.../oauth/token" }, "uri": "https://enterprise-messaging-hub-backend..." } ], "messaging": [ { "oa2": { "clientid": "...", "clientsecret": "...", "tokenendpoint": "..." }, "protocol": ["amqp10ws"], "broker": { "type": "sapmgw" }, "uri": "wss://enterprise-messaging-pubsub.cfapps..." } ], "namespace": "default/sap.s4/salesorder"}3. Communication Arrangement dans le système ABAP
┌──────────────────────────────────────────────────────────────┐│ Communication Arrangement │├──────────────────────────────────────────────────────────────┤│ Scenario: SAP_COM_0092 (Enterprise Eventing Integration) ││ ││ Communication System: EVENT_MESH_SYSTEM ││ ├── Host: enterprise-messaging-pubsub.cfapps... ││ ├── Port: 443 ││ └── Auth: OAuth 2.0 Client Credentials ││ ││ Outbound Services: ││ └── Enterprise Event Enablement: Active │└──────────────────────────────────────────────────────────────┘4. Configurer le Channel
Dans le système ABAP sous Enterprise Event Enablement :
" Créer un Event ChannelDATA(lo_channel) = cl_eee_channel_factory=>create_channel( iv_channel_id = 'Z_SALESORDER_EVENTS" iv_description = 'Sales Order Events" iv_topic_space = 'default/sap.s4/salesorder" iv_destination = 'EVENT_MESH_DESTINATION' ).
" Topic-Bindinglo_channel->add_topic_binding( iv_event_type = 'ZI_SALESORDER.CREATED" iv_topic = 'sap/salesorder/created/v1' ).
lo_channel->add_topic_binding( iv_event_type = 'ZI_SALESORDER.STATUSCHANGED" iv_topic = 'sap/salesorder/statuschanged/v1' ).Consommation d’événements dans des systèmes externes
Application CAP (Node.js)
const cds = require('@sap/cds');
module.exports = async (srv) => { // Connexion Event Mesh const messaging = await cds.connect.to('messaging');
// Enregistrer les Event Handlers messaging.on('sap/salesorder/created/v1', async (msg) => { const { SalesOrderId } = msg.data; console.log(`New sales order created: ${SalesOrderId}`);
// Logique métier await processSalesOrder(SalesOrderId); });
messaging.on('sap/salesorder/statuschanged/v1', async (msg) => { const { SalesOrderId, OldStatus, NewStatus } = msg.data; console.log(`Status changed: ${SalesOrderId} from ${OldStatus} to ${NewStatus}`); });};Consumer Python
from sap_event_mesh_client import EventMeshClient
# Initialiser le clientclient = EventMeshClient( service_key_path='event-mesh-service-key.json")
# S'abonner à une queue@client.subscribe('queue:salesorder-events')def handle_salesorder_event(message): event_type = message.headers.get('type')
if event_type == 'sap/salesorder/created/v1': order_id = message.body['SalesOrderId'] print(f'Processing new order: {order_id}') # Logique métier
message.ack() # Confirmer le message
# Démarrer le consumerclient.start()Exemple complet : Pipeline de traitement des commandes
Business Object avec Events
managed implementation in class zbp_i_purchaseorder unique;strict ( 2 );
define behavior for ZI_PurchaseOrder alias PurchaseOrderpersistent table zpurchaseorderlock masterauthorization master ( instance )etag master LastChangedAtwith additional save{ create; update; delete;
// Actions action ( features : instance ) approve result [1] $self; action ( features : instance ) reject result [1] $self;
// Events pour chaque changement d'état important event created; event approved parameter ZA_ApprovalInfo; event rejected parameter ZA_RejectionInfo; event amountChanged parameter ZA_AmountChangeInfo;
// Triggers determination triggerCreated on save { create; } determination triggerAmountChange on save { field TotalAmount; }}Paramètres d’événements
@EndUserText.label: 'Approval Info"define abstract entity ZA_ApprovalInfo{ PurchaseOrderId : abap.char(10); ApprovedBy : abap.uname; ApprovedAt : timestampl; TotalAmount : abap.dec(15,2);}
@EndUserText.label: 'Rejection Info"define abstract entity ZA_RejectionInfo{ PurchaseOrderId : abap.char(10); RejectedBy : abap.uname; RejectedAt : timestampl; RejectionReason : abap.char(255);}Implémentation d’Action avec Event
CLASS lhc_purchaseorder IMPLEMENTATION. METHOD approve. " Mettre à jour le statut MODIFY ENTITIES OF zi_purchaseorder IN LOCAL MODE ENTITY PurchaseOrder UPDATE FIELDS ( Status ApprovedBy ApprovedAt ) WITH VALUE #( FOR key IN keys ( %tky = key-%tky Status = 'AP" ApprovedBy = sy-uname ApprovedAt = utclong_current( ) ) ) FAILED failed REPORTED reported.
" Lire le résultat READ ENTITIES OF zi_purchaseorder IN LOCAL MODE ENTITY PurchaseOrder ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(orders).
" Déclencher l'événement RAISE ENTITY EVENT zi_purchaseorder~approved FROM VALUE #( FOR order IN orders ( %key = order-%key %param = VALUE #( purchaseorderid = order-PurchaseOrderId approvedby = order-ApprovedBy approvedat = order-ApprovedAt totalamount = order-TotalAmount ) ) ).
" Retourner le résultat result = VALUE #( FOR order IN orders ( %tky = order-%tky %param = order ) ). ENDMETHOD.ENDCLASS.Bonnes pratiques
| Sujet | Recommandation |
|---|---|
| Granularité des événements | Un événement par événement métier, pas trop granulaire |
| Idempotence | Les consumers doivent pouvoir traiter les événements en double |
| Schéma d’événements | Respecter le versionnement (v1, v2), éviter les breaking changes |
| Paramètres | Uniquement les données nécessaires dans l’événement, pas l’entité entière |
| Gestion des erreurs | Configurer une Dead-Letter-Queue pour les événements échoués |
| Monitoring | Utiliser le dashboard SAP Event Mesh pour les métriques |
| Tests | Tester les événements localement avant l’intégration en production |
| Sécurité | Service Keys séparées pour le développement et la production |
Sujets connexes
- Actions et Functions RAP - Actions qui déclenchent des événements
- Destination Service - Connecter des systèmes externes
- Bases de RAP - Fondamentaux du développement RAP