1. はじめに
イベント駆動アーキテクチャ(EDA)は、ビジネスにおける重要な“イベント”を検出し、リアルタイムで対応する統合モデルです。現代の企業がリアルタイム運用と柔軟で応答性の高いシステムを求める中で、EDAは不可欠な技術となっています。
SAP S/4HANAにおけるイベント駆動アーキテクチャの実装において、標準RAPイベントが多数提供されていますが、標準イベントのペイロードでは、業務要件に対応できず、カスタマイズが必要となる場合があります。特に、イベントデータによるフィルタリングや標準イベントのペイロード補完を目的として、SAP標準イベントをDerived Eventにより拡張するユースケースがございます。
Derived Eventは、S/4HANA Cloud, private edition & S/4HANA 2023 / S/4HANA Cloud, public edition 2308リリースで導入された機能で、既存のSAP標準イベントをベースに、カスタムペイロードを持つ新しいイベントを定義できる機能です。これにより、標準イベントの実装を再利用しながら、業務に必要な追加フィールドやフィルタリング条件を適用したイベントを作成することが可能になります。
SAP Community Blog: Derived Events- How to Trigger Custom Event from an SAP Standard Event
一方、Derived Eventは、拡張対象のSAP標準オブジェクトが以下の条件を満たしている必要があります。
参照元イベントを含むビジネスオブジェクトが拡張可能(extensible)であること参照されるイベントがC0およびC1リリースされたRAP BOインターフェースで公開されている必要があることDerived Eventのペイロードのデータソースとして使用されるCDSビューエンティティがC1リリースされている必要があること
そのため、SAP標準RAP BOでは、Derived Eventによる拡張に対応していないオブジェクトも存在します。この場合、本来であればDerived Eventで解決できるはずの要件が実現できないケースが発生します。
そこで本ブログでは、Derived Eventによる拡張が不可能なSAP標準イベントに対して、カスタムRAP BOによるペイロードの拡張を実現するワークアラウンドアプローチについて紹介します。
2. ワークアラウンドソリューション
Derived Eventが使用できない場合、Local Event ConsumptionとカスタムRAPイベントを組み合わせたワークアラウンドアプローチが有効な手段となります。このアプローチは、SAP標準イベントをローカル(カスタムABAPクラス)で消費し、それをトリガーとしてカスタムRAPイベントを発生させる手法です。カスタムイベントのペイロードを業務要件に合わせたペイロードとすることで、イベントフィルタの利用等が可能となります。
3. 実装サンプル
本ブログでは、拡張不可なr_purchaseordertpを対象オブジェクトとし、購買発注伝票のデータ変更に対するイベントペイロードの拡張を実現します。SAP標準イベントでは、購買発注伝票番号のみのペイロードあるのに対し、カスタムイベントでは、購買発注伝票番号と購買発注伝票タイプをペイロードとします。Event BindingおよびEvent Meshとのチャンネル設定等は、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 をご確認ください。本ブログの実装サンプルでのRAP BOでは、イベント以外のCRUDや保存等の処理は、実装していない点にご注意ください。
(1) Local Consumer (ローカルイベントハンドリングのためのカスタムABAPクラス)
グローバルクラス: zcl_event_consump
グローバルクラスでは、FOR EVENTS OF r_purchaseordertpの定義により、消費する標準イベントを設定します。
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.
ローカルクラス: zcl_event_consump
ローカルクラスでは、消費した標準イベントのペイロードのデータをもとに追加のデータ取得を行い、カスタムRAPイベントをトリガーします。イベントのトリガーは、RAPフレームワークにおいて、Save Sequenceでのみ可能なため、cl_abap_tx=>save( ). により、明示的にSave Sequenceに変更する必要がある点に注意が必要です。
*”* 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
CDS Viewでは、購買発注伝票番号のみ定義しています。
@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
イベントトリガのためのカスタムRAP BOでは、create / update / delete 機能を定義していません。
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
グローバルクラスでは、イベントトリガー用のメソッドを定義します。
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
ローカルクラスでは、保存処理等は実装せず、イベントトリガー用のメソッドのみ実装しています。
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により、購買発注伝票タイプを追加しています。これにより、カスタムRAPイベントのペイロードは、購買発注伝票番号と購買発注伝票タイプとなります。
@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. 実装結果
Manage Purchase Orders (F0842A) アプリから既存の購買発注伝票を変更して、保存します。
SAP Event MeshでS/4HANAからトリガされたカスタムイベントを受け取ることができます。
5. まとめ
イベント駆動アーキテクチャの実現において、Derived Eventによる拡張が不可能な場合、Local Event ConsumptionとカスタムRAPイベントを組み合わせたワークアラウンドアプローチが有効な手段となります。
こちらのアプローチにより、業務要件に応じたカスタムペイロードとフィルタリング機能を実現することで、必要なデータをイベントコンシューマに提供し、システム間連携の最適化を図ることが可能です。
参考情報
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. はじめにイベント駆動アーキテクチャ(EDA)は、ビジネスにおける重要な“イベント”を検出し、リアルタイムで対応する統合モデルです。現代の企業がリアルタイム運用と柔軟で応答性の高いシステムを求める中で、EDAは不可欠な技術となっています。SAP S/4HANAにおけるイベント駆動アーキテクチャの実装において、標準RAPイベントが多数提供されていますが、標準イベントのペイロードでは、業務要件に対応できず、カスタマイズが必要となる場合があります。特に、イベントデータによるフィルタリングや標準イベントのペイロード補完を目的として、SAP標準イベントをDerived Eventにより拡張するユースケースがございます。Derived Eventは、S/4HANA Cloud, private edition & S/4HANA 2023 / S/4HANA Cloud, public edition 2308リリースで導入された機能で、既存のSAP標準イベントをベースに、カスタムペイロードを持つ新しいイベントを定義できる機能です。これにより、標準イベントの実装を再利用しながら、業務に必要な追加フィールドやフィルタリング条件を適用したイベントを作成することが可能になります。SAP Community Blog: Derived Events- How to Trigger Custom Event from an SAP Standard Event一方、Derived Eventは、拡張対象のSAP標準オブジェクトが以下の条件を満たしている必要があります。参照元イベントを含むビジネスオブジェクトが拡張可能(extensible)であること参照されるイベントがC0およびC1リリースされたRAP BOインターフェースで公開されている必要があることDerived Eventのペイロードのデータソースとして使用されるCDSビューエンティティがC1リリースされている必要があることそのため、SAP標準RAP BOでは、Derived Eventによる拡張に対応していないオブジェクトも存在します。この場合、本来であればDerived Eventで解決できるはずの要件が実現できないケースが発生します。そこで本ブログでは、Derived Eventによる拡張が不可能なSAP標準イベントに対して、カスタムRAP BOによるペイロードの拡張を実現するワークアラウンドアプローチについて紹介します。 2. ワークアラウンドソリューションDerived Eventが使用できない場合、Local Event ConsumptionとカスタムRAPイベントを組み合わせたワークアラウンドアプローチが有効な手段となります。このアプローチは、SAP標準イベントをローカル(カスタムABAPクラス)で消費し、それをトリガーとしてカスタムRAPイベントを発生させる手法です。カスタムイベントのペイロードを業務要件に合わせたペイロードとすることで、イベントフィルタの利用等が可能となります。 3. 実装サンプル本ブログでは、拡張不可なr_purchaseordertpを対象オブジェクトとし、購買発注伝票のデータ変更に対するイベントペイロードの拡張を実現します。SAP標準イベントでは、購買発注伝票番号のみのペイロードあるのに対し、カスタムイベントでは、購買発注伝票番号と購買発注伝票タイプをペイロードとします。Event BindingおよびEvent Meshとのチャンネル設定等は、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 をご確認ください。本ブログの実装サンプルでのRAP BOでは、イベント以外のCRUDや保存等の処理は、実装していない点にご注意ください。 (1) Local Consumer (ローカルイベントハンドリングのためのカスタムABAPクラス)グローバルクラス: zcl_event_consumpグローバルクラスでは、FOR EVENTS OF r_purchaseordertpの定義により、消費する標準イベントを設定します。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. ローカルクラス: zcl_event_consumpローカルクラスでは、消費した標準イベントのペイロードのデータをもとに追加のデータ取得を行い、カスタムRAPイベントをトリガーします。イベントのトリガーは、RAPフレームワークにおいて、Save Sequenceでのみ可能なため、cl_abap_tx=>save( ). により、明示的にSave Sequenceに変更する必要がある点に注意が必要です。*”* 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_eventCDS Viewでは、購買発注伝票番号のみ定義しています。@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イベントトリガのためのカスタムRAP BOでは、create / update / delete 機能を定義していません。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グローバルクラスでは、イベントトリガー用のメソッドを定義します。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ローカルクラスでは、保存処理等は実装せず、イベントトリガー用のメソッドのみ実装しています。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により、購買発注伝票タイプを追加しています。これにより、カスタムRAPイベントのペイロードは、購買発注伝票番号と購買発注伝票タイプとなります。@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. 実装結果Manage Purchase Orders (F0842A) アプリから既存の購買発注伝票を変更して、保存します。 SAP Event MeshでS/4HANAからトリガされたカスタムイベントを受け取ることができます。 5. まとめイベント駆動アーキテクチャの実現において、Derived Eventによる拡張が不可能な場合、Local Event ConsumptionとカスタムRAPイベントを組み合わせたワークアラウンドアプローチが有効な手段となります。こちらのアプローチにより、業務要件に応じたカスタムペイロードとフィルタリング機能を実現することで、必要なデータをイベントコンシューマに提供し、システム間連携の最適化を図ることが可能です。 参考情報SAP 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