RAP Event: consume SAP standard event and trigger custom RAP event

Estimated read time 13 min read

1. Introduction

Event-driven architecture (EDA) is an integrated model that detects critical business “events” and responds to them in real time. As modern businesses seek real-time operations and flexible, responsive systems, EDA has become an essential technology.
Many standard RAP events are provided for the implementation of the event-driven architecture in SAP S/4HANA, but the standard event payload may not meet business requirements and require customization. In particular, there is a use case where SAP standard events are extended with Derived Events for the purpose of filtering by event data and payload completion of standard events.
Derived Event is available in S/4HANA Cloud, private edition & S/4HANA 2023 / S/4HANA Cloud, public edition Introduced in the 2308 release, this feature allows you to define new events with custom payloads based on existing SAP standard events. This allows you to reuse standard event implementations while creating events with additional fields and filtering criteria that you need for your business.
SAP Community Blog: Derived Events- How to Trigger Custom Event from an SAP Standard Event
On the other hand, a Derived Event requires that the SAP Standard object to be extended meets the following conditions:

The business object containing the referring event must be extensible.The referenced event must be published on the C0 and C1 released RAP BO interfacesThe CDS view entity used as the data source for the Derived Event payload must have been released in C1

Therefore, some objects do not support extensibility with Derived Events in SAP Standard RAP BO. In this case, there may be cases where the requirements that should be solved by Derived Events cannot be realized.
So, in this blog, we will introduce a workaround approach that enables payload expansion with custom RAP BO for SAP standard events that cannot be extended with Derived Events.

 

2. Workaround Solutions

If Derived Events are not available, a workaround approach that combines Local Event Consumption with custom RAP events can be an effective approach. This approach involves consuming SAP standard events locally (custom ABAP classes) and using them as triggers to raise custom RAP events. By setting the payload of a custom event to meet your business requirements, you can use event filters.

 

3. Implementation Sample

In this blog, we will use a non-extensible r_purchaseordertp as the target object to extend the event payload for data changes in a PO document. SAP standard events have a payload of only the purchase order document number, whereas custom events have a purchase order document number and purchase order type as the payload. For more information on Event Binding and channel configuration with Event Mesh, please visit the SAP Community Blog: https://community.sap.com/t5/technology-blog-posts-by-sap/how-to-create-rap-business-events-in-sap-s-4hana-on-premise-2022/ba-p/13553312 . Please note that the RAP BO in the implementation sample in this blog does not implement CRUD or save processing other than events.

 

(1) Local Consumer (Custom ABAP Class for Local Event Consumption)

Global class: zcl_event_consump

In the Global class, the definition FOR EVENTS OF r_purchaseordertp sets the standard events to be consumed.

CLASS zcl_event_consump DEFINITION
PUBLIC
ABSTRACT
FINAL
FOR EVENTS OF r_purchaseordertp.

PUBLIC SECTION.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.

CLASS zcl_event_consump IMPLEMENTATION.
ENDCLASS.

 

Local class: zcl_event_consump

The Local class performs additional data retrieval based on the data from the standard event payload consumed to trigger a custom RAP event.
It is important to note that triggering events is only possible in the RAP framework with a Save Sequence, so you must explicitly change it to Save Sequence by cl_abap_tx=>save( ).

*”* use this source file for the definition and implementation of
*”* local helper classes, interface definitions and type
*”* declarations
CLASS lcl_event_consump DEFINITION INHERITING FROM cl_abap_behavior_event_handler.
PRIVATE SECTION.
METHODS:
consume_changed FOR ENTITY EVENT changed_instances FOR purchaseorder~changed.
ENDCLASS.

CLASS lcl_event_consump IMPLEMENTATION.

METHOD consume_changed.
cl_abap_tx=>save( ).

DATA lv_potype TYPE mm_purchaseordertype.

CHECK changed_instances IS NOT INITIAL.

LOOP AT changed_instances INTO DATA(changed_instance).

SELECT SINGLE purchaseordertype
FROM c_purchaseordertp
INTO _potype
WHERE purchaseorder = @changed_instance-purchaseorder.

DATA(et_events) = VALUE zbp_i_purchseorder_test=>tt_events(
(
purchaseorder = changed_instance-purchaseorder
purchaseordertype = lv_potype
)
).

zbp_i_purchseorder_event=>raise_po_changed_event( it_events = et_events ).

ENDLOOP.

ENDMETHOD.

ENDCLASS.

 

(2) Custom RAP BO (Custom Event)

CDS View: ZI_purchseorder_event

In the CDS View, I define only the purchase order.

@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Consume purchase order event’
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define root view entity ZI_purchseorder_event as select from I_PurchaseOrder
{
key PurchaseOrder
}

 
Behavior Definition: ZI_purchseorder_event

Custom RAP BO for event triggers does not define the create/update/delete function.

managed with unmanaged save implementation in class zbp_i_purchseorder_event unique;
strict ( 2 );

define behavior for ZI_purchseorder_event //alias <alias_name>
//persistent table ekko
lock master
authorization master ( instance )
//etag master <field_name>
{
// create;
// update;
// delete;
event purchaseorder_changed parameter ZAB_PO_changed_event;

field ( readonly ) PurchaseOrder;
}

Behavior Implementation (Global class) : zbp_i_purchseorder_event

In the Global class, I define a method for triggering events.

CLASS zbp_i_purchseorder_event DEFINITION PUBLIC ABSTRACT FINAL FOR BEHAVIOR OF zi_purchseorder_event.

TYPES tt_events TYPE TABLE FOR EVENT zi_purchseorder_event~purchaseorder_changed.

PUBLIC SECTION.
CLASS-METHODS raise_po_changed_event
IMPORTING it_events TYPE tt_events.

ENDCLASS.

CLASS zbp_i_purchseorder_event IMPLEMENTATION.
METHOD raise_po_changed_event.
lcl_event_handler=>on_po_changed_event( it_events ).
endmethod.
ENDCLASS.

 
Behavior Implementation (Local class) : lhc_zi_purchseorder_event

The Local class does not implement save processing, etc., but only implements methods for triggering events.

CLASS lhc_zi_purchseorder_event DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.

METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION
IMPORTING keys REQUEST requested_authorizations FOR zi_purchseorder_event RESULT result.

ENDCLASS.

CLASS lhc_zi_purchseorder_event IMPLEMENTATION.

METHOD get_instance_authorizations.
ENDMETHOD.

ENDCLASS.

CLASS lsc_zi_purchseorder_event DEFINITION INHERITING FROM cl_abap_behavior_saver.
PROTECTED SECTION.

METHODS save_modified REDEFINITION.

METHODS cleanup_finalize REDEFINITION.

ENDCLASS.

CLASS lsc_zi_purchseorder_event IMPLEMENTATION.

METHOD save_modified.
ENDMETHOD.

METHOD cleanup_finalize.
ENDMETHOD.

ENDCLASS.

CLASS lcl_event_handler DEFINITION FRIENDS zbp_i_purchseorder_event.
PUBLIC SECTION.
CLASS-METHODS on_po_changed_event IMPORTING it_events TYPE zbp_i_purchseorder_event=>tt_events.
ENDCLASS.

CLASS lcl_event_handler IMPLEMENTATION.
METHOD on_po_changed_event.

RAISE ENTITY EVENT ZI_purchseorder_event~purchaseorder_changed FROM it_events.

ENDMETHOD.
ENDCLASS.

 
Abstract Entity: ZAB_PO_changed_event

Abstract entity adds a purchase order document type. This results in the payload of the custom RAP event being the purchase order document number and the purchase order document type.

@EndUserText.label: ‘Abastract entity for po changed event’
define abstract entity ZAB_PO_changed_event
// with parameters parameter_name : parameter_type
{
PurchaseOrderType : mm_purchaseordertype;
}

 

4. Implementation Results

Modify and save an existing purchase order document from the Manage Purchase Orders (F0842A) app.

 

You can receive custom events triggered from S/4HANA in SAP Event Mesh.

 

5. Summary

When it is not possible to scale with Derived Events in implementing an event-driven architecture, a workaround approach that combines Local Event Consumption with custom RAP events is an effective approach.
This approach enables custom payloads and filtering capabilities based on business requirements, providing event consumers with the data they need to optimize cross-system integration.

 

References

SAP Learning:Explaining Event-Driven Architecture
SAP Help: Event-driven Architecture
SAP Community Blog: RAP Business Events with Advanced Event Mesh [2]: Creating custom business events
SAP Community Blog: RAP Business Events with Advanced Event Mesh [5]: Consuming a local business event

 

 

​ 1. IntroductionEvent-driven architecture (EDA) is an integrated model that detects critical business “events” and responds to them in real time. As modern businesses seek real-time operations and flexible, responsive systems, EDA has become an essential technology.Many standard RAP events are provided for the implementation of the event-driven architecture in SAP S/4HANA, but the standard event payload may not meet business requirements and require customization. In particular, there is a use case where SAP standard events are extended with Derived Events for the purpose of filtering by event data and payload completion of standard events.Derived Event is available in S/4HANA Cloud, private edition & S/4HANA 2023 / S/4HANA Cloud, public edition Introduced in the 2308 release, this feature allows you to define new events with custom payloads based on existing SAP standard events. This allows you to reuse standard event implementations while creating events with additional fields and filtering criteria that you need for your business.SAP Community Blog: Derived Events- How to Trigger Custom Event from an SAP Standard EventOn the other hand, a Derived Event requires that the SAP Standard object to be extended meets the following conditions:The business object containing the referring event must be extensible.The referenced event must be published on the C0 and C1 released RAP BO interfacesThe CDS view entity used as the data source for the Derived Event payload must have been released in C1Therefore, some objects do not support extensibility with Derived Events in SAP Standard RAP BO. In this case, there may be cases where the requirements that should be solved by Derived Events cannot be realized.So, in this blog, we will introduce a workaround approach that enables payload expansion with custom RAP BO for SAP standard events that cannot be extended with Derived Events. 2. Workaround SolutionsIf Derived Events are not available, a workaround approach that combines Local Event Consumption with custom RAP events can be an effective approach. This approach involves consuming SAP standard events locally (custom ABAP classes) and using them as triggers to raise custom RAP events. By setting the payload of a custom event to meet your business requirements, you can use event filters. 3. Implementation SampleIn this blog, we will use a non-extensible r_purchaseordertp as the target object to extend the event payload for data changes in a PO document. SAP standard events have a payload of only the purchase order document number, whereas custom events have a purchase order document number and purchase order type as the payload. For more information on Event Binding and channel configuration with Event Mesh, please visit the SAP Community Blog: https://community.sap.com/t5/technology-blog-posts-by-sap/how-to-create-rap-business-events-in-sap-s-4hana-on-premise-2022/ba-p/13553312 . Please note that the RAP BO in the implementation sample in this blog does not implement CRUD or save processing other than events. (1) Local Consumer (Custom ABAP Class for Local Event Consumption)Global class: zcl_event_consumpIn the Global class, the definition FOR EVENTS OF r_purchaseordertp sets the standard events to be consumed.CLASS zcl_event_consump DEFINITION
PUBLIC
ABSTRACT
FINAL
FOR EVENTS OF r_purchaseordertp.

PUBLIC SECTION.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.

CLASS zcl_event_consump IMPLEMENTATION.
ENDCLASS. Local class: zcl_event_consumpThe Local class performs additional data retrieval based on the data from the standard event payload consumed to trigger a custom RAP event.It is important to note that triggering events is only possible in the RAP framework with a Save Sequence, so you must explicitly change it to Save Sequence by cl_abap_tx=>save( ).*”* use this source file for the definition and implementation of
*”* local helper classes, interface definitions and type
*”* declarations
CLASS lcl_event_consump DEFINITION INHERITING FROM cl_abap_behavior_event_handler.
PRIVATE SECTION.
METHODS:
consume_changed FOR ENTITY EVENT changed_instances FOR purchaseorder~changed.
ENDCLASS.

CLASS lcl_event_consump IMPLEMENTATION.

METHOD consume_changed.
cl_abap_tx=>save( ).

DATA lv_potype TYPE mm_purchaseordertype.

CHECK changed_instances IS NOT INITIAL.

LOOP AT changed_instances INTO DATA(changed_instance).

SELECT SINGLE purchaseordertype
FROM c_purchaseordertp
INTO _potype
WHERE purchaseorder = @changed_instance-purchaseorder.

DATA(et_events) = VALUE zbp_i_purchseorder_test=>tt_events(
(
purchaseorder = changed_instance-purchaseorder
purchaseordertype = lv_potype
)
).

zbp_i_purchseorder_event=>raise_po_changed_event( it_events = et_events ).

ENDLOOP.

ENDMETHOD.

ENDCLASS. (2) Custom RAP BO (Custom Event)CDS View: ZI_purchseorder_eventIn the CDS View, I define only the purchase order.@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Consume purchase order event’
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define root view entity ZI_purchseorder_event as select from I_PurchaseOrder
{
key PurchaseOrder
} Behavior Definition: ZI_purchseorder_eventCustom RAP BO for event triggers does not define the create/update/delete function.managed with unmanaged save implementation in class zbp_i_purchseorder_event unique;
strict ( 2 );

define behavior for ZI_purchseorder_event //alias <alias_name>
//persistent table ekko
lock master
authorization master ( instance )
//etag master <field_name>
{
// create;
// update;
// delete;
event purchaseorder_changed parameter ZAB_PO_changed_event;

field ( readonly ) PurchaseOrder;
}Behavior Implementation (Global class) : zbp_i_purchseorder_eventIn the Global class, I define a method for triggering events.CLASS zbp_i_purchseorder_event DEFINITION PUBLIC ABSTRACT FINAL FOR BEHAVIOR OF zi_purchseorder_event.

TYPES tt_events TYPE TABLE FOR EVENT zi_purchseorder_event~purchaseorder_changed.

PUBLIC SECTION.
CLASS-METHODS raise_po_changed_event
IMPORTING it_events TYPE tt_events.

ENDCLASS.

CLASS zbp_i_purchseorder_event IMPLEMENTATION.
METHOD raise_po_changed_event.
lcl_event_handler=>on_po_changed_event( it_events ).
endmethod.
ENDCLASS. Behavior Implementation (Local class) : lhc_zi_purchseorder_eventThe Local class does not implement save processing, etc., but only implements methods for triggering events.CLASS lhc_zi_purchseorder_event DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.

METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION
IMPORTING keys REQUEST requested_authorizations FOR zi_purchseorder_event RESULT result.

ENDCLASS.

CLASS lhc_zi_purchseorder_event IMPLEMENTATION.

METHOD get_instance_authorizations.
ENDMETHOD.

ENDCLASS.

CLASS lsc_zi_purchseorder_event DEFINITION INHERITING FROM cl_abap_behavior_saver.
PROTECTED SECTION.

METHODS save_modified REDEFINITION.

METHODS cleanup_finalize REDEFINITION.

ENDCLASS.

CLASS lsc_zi_purchseorder_event IMPLEMENTATION.

METHOD save_modified.
ENDMETHOD.

METHOD cleanup_finalize.
ENDMETHOD.

ENDCLASS.

CLASS lcl_event_handler DEFINITION FRIENDS zbp_i_purchseorder_event.
PUBLIC SECTION.
CLASS-METHODS on_po_changed_event IMPORTING it_events TYPE zbp_i_purchseorder_event=>tt_events.
ENDCLASS.

CLASS lcl_event_handler IMPLEMENTATION.
METHOD on_po_changed_event.

RAISE ENTITY EVENT ZI_purchseorder_event~purchaseorder_changed FROM it_events.

ENDMETHOD.
ENDCLASS. Abstract Entity: ZAB_PO_changed_eventAbstract entity adds a purchase order document type. This results in the payload of the custom RAP event being the purchase order document number and the purchase order document type.@EndUserText.label: ‘Abastract entity for po changed event’
define abstract entity ZAB_PO_changed_event
// with parameters parameter_name : parameter_type
{
PurchaseOrderType : mm_purchaseordertype;
} 4. Implementation ResultsModify and save an existing purchase order document from the Manage Purchase Orders (F0842A) app. You can receive custom events triggered from S/4HANA in SAP Event Mesh. 5. SummaryWhen it is not possible to scale with Derived Events in implementing an event-driven architecture, a workaround approach that combines Local Event Consumption with custom RAP events is an effective approach.This approach enables custom payloads and filtering capabilities based on business requirements, providing event consumers with the data they need to optimize cross-system integration. ReferencesSAP Learning:Explaining Event-Driven ArchitectureSAP Help: Event-driven ArchitectureSAP Community Blog: RAP Business Events with Advanced Event Mesh [2]: Creating custom business eventsSAP Community Blog: RAP Business Events with Advanced Event Mesh [5]: Consuming a local business event    Read More Technology Blog Posts by SAP articles 

#SAP

#SAPTechnologyblog

You May Also Like

More From Author