This is a part of the implementation details of How To... Implement End-to-End Push Notifications with HCPms and SAP Gateway.
Tips & Tricks - Implementing Subscribable OData services & Notification API in ABAP
You have a complete e2e landscape for push. Let's talk about how to implement "Subscribable" OData services with SAP Gateway and trigger the notification from ABAP application.
Building Subscribable OData services
If you don't have any OData services nor ever have coding experiences with SAP Gateway, here's a beginner level crash course of how to build your OData CRUD services. From now on let's assume you have done the CRUD implementation with TravelAgency data.
#1 - OData CRUD Crash Course - Getting ready with offline store
Now that you have functional OData services, go to the transaction code SEGW - Open "Data Model" > "Entity Sets", find your collection you want to make subscribable. You'll see the checkbox "Subscribable". Tick it in.
Click on the project and select "Generate Runtime".
Find "Runtime Artifacts" and select "...DPC_EXT" and "Go to ABAP Workbench".
In the ABAP Workbench, you should be able to find "CHECK_SUBSCRIPTION_AUTHORITY" in the "Methods" > "Inherited Methods". Select it and "Redefine". Simply you save it - this is the place for extra authorization check to access "/IWBEP/D_MGW_SUB" table. But for this case you can leave it empty implementation. (= anyone can subscribe)
In the "Runtime Artifacts", select "...MPC_EXT" and "Go to ABAP Workbench".
Find "DEFINE" in the "Methods" > "Inherited Methods". Select it and "Redefine". And type in a single line of "super->define( )." Save it.
Time to check if you made it subscribable. In the transaction code SEGW, start a Gateway Client via the system in the "Service Maintenance".
Execute it and you should be able to confirm two new collections of "SubscriptionCollection" and "NotificationCollection".
Tip - if you still don't see them, most likely your client is seeing cached metadata. Please try following:
- Clear the cache in Gateway Hub: tx code /IWFND/CACHE_CLEANUP
- Clear in Backend: tx code /IWBEP/CACHE_CLEANUP
- (Recommended during the development) Deactivate caching: tx code SPRO "SAP NetWeaver" > "Gateway" > "OData Channel" > Administration > Cache Settings > Metadata
Now your favorite OData services became subscribable!
Using Notification API to trigger Push event
SAP Gateway provides a notification API that facilitates sending notifications from the back end when a back-end event is triggered. The necessary set of API calls to send an appropriate notification once a back-end business object event is triggered are listed below. Integrate the appropriate code for these calls into the standard processing of your ABAP logic - such as during OData CUD methods or in the SAP business object via an appropriate user exit or BADI.
- Call static method /IWBEP/CL_MGW_SUB_REGISTRY=>GET_SUBSCRIPTION_REGISTRY( ) to get the instance of the subscription registry.
- Call method GET_SUBSCRIPTIONS( ) of the subscription registry, and provide the model group name and the collection for the notifications of the current business application.
- Call static method /IWBEP/CL_MGW_NOTIF_PUBLISHER=>GET_NOTIFICATION_PUBLISHER() to get the instance of the notification publisher.
- Call method CREATE_NOTIFICATION_ENDPOINTS() of the publisher instance, and provide the data structure you want to send and the list of subscriptions returned by the registry. (Note - formal help document: /IWBEP/IF_MGW_NOTIF_PUBLISHER - SAP NetWeaver Gateway - SAP Library)
- Call method SEND_NOTIFICATIONS() of the publisher for each notification endpoint.
Tip - Some remarks with CREATE_NOTIFICATION_ENDPOINTS(). This is specific with /Notification/ Push URL of HCPms:
- IS_DATA - Mandatory, but you could set any data (this data is originally meant for a HTTP body - but HCPms only sends the header data).
- IV_TYPE - Mandatory, but it doesn't matter if it is "ID" or "DATA". This value is used to send the HTTP Body payload that is ignored by HCPms.
- IR_POKE_DATA - If you want to send any additional data (such as OData Entity, email address), use this param - it will be alive in the header.
- IV_ENTRIES_OF_INTEREST - This is a "Badge" value for push client API.
Please have a look at the complete code in the Appendix to go through those steps with push information (the push will send "Created!" text and its OData entity data), it is intended for embedding in the OData's "Create" method, so that when Create occurs, it sends the notification to the subscribers.
As another sample, ABAP report “/IWBEP/R_MGW_PUSH_TEST” demonstrates the notification transmission with FLIGHT sample data.
The notification format can be ATOM XML or JSON, which you must specify when you send the subscription request. For example, to receive notifications in the JSON format, send the value of the “Accept” HTTP header to “application/json”. By default, ATOM XML-formatted notifications are used. If your OData client creates a subscription via JSON, here's how it looks in the subscription table (NOTIF FORMAT field):
Note - XML format is preferred with /Notification/ Push URL. (JSON would not work)
Official help doc: SAP Gateway Notification Support
Appendix: Sample Code to Trigger Push
* Fixed values for /IWBEP/D_MGW_SUB table CONSTANTS: lc_technical_group_name TYPE /iwbep/med_grp_technical_name VALUE 'Z_TRAVELAGENCY_SRV', lc_group_version TYPE /iwbep/med_grp_version VALUE 0001, lc_collection TYPE /iwbep/mgw_sub_collection VALUE 'TravelAgencySet', * The push text message lc_text TYPE string VALUE 'Created!'. * Vars for Subscriptions DATA: lo_sub_registry TYPE REF TO /iwbep/if_mgw_sub_registry, lt_subscriptions TYPE /iwbep/t_mgw_sub_data, * Vars for Notifications lo_notification_publisher TYPE REF TO /iwbep/if_mgw_notif_publisher, ls_notification_endpoint TYPE /iwbep/if_mgw_notif_publisher=>ty_s_notification_endpoint, lt_notification_endpoints TYPE /iwbep/if_mgw_notif_publisher=>ty_t_notification_endpoint, lr_data TYPE REF TO data, lv_notification_type TYPE char1, lx_mgw_tech_exception TYPE REF TO /iwbep/cx_mgw_tech_exception. FIELD-SYMBOLS: <ls_subscription> TYPE /iwbep/s_mgw_sub_data. * Permission for access to /IWBEP/D_MGW_SUB table AUTHORITY-CHECK OBJECT 'S_TABU_DIS' ID 'ACTVT' FIELD '02' " Activity: 02: Create, change, or delete ID 'DICBERCLS' FIELD 'IWAD'. " Authorization Group: IW Admin IF sy-subrc NE 0. RAISE EXCEPTION TYPE /iwbep/cx_mgw_tech_exception EXPORTING textid = /iwbep/cx_mgw_tech_exception=>missing_authorization. ENDIF. * Type is either ID or Data (Full Payload) - for HCPms, it doesn't matter if it is "ID" or "DATA", * as HTTP body will be ignored by /Notification/ Push URL of HCPms lv_notification_type = /iwbep/if_mgw_notif_publisher=>gcs_notification_types-id. * Obtain /IWBEP/D_MGW_SUB table lo_sub_registry = /iwbep/cl_mgw_sub_registry=>get_subscription_registry( ). * Obtain a list of subscribers lt_subscriptions = lo_sub_registry->get_subscriptions( iv_internal_service_name = lc_technical_group_name iv_internal_service_version = lc_group_version iv_collection = lc_collection ). * Object to push lo_notification_publisher = /iwbep/cl_mgw_notif_publisher=>get_notification_publisher( ). LOOP AT lt_subscriptions ASSIGNING <ls_subscription>. IF <ls_subscription>-language IS INITIAL. <ls_subscription>-language = sy-langu. ENDIF. ENDLOOP. * For this case ls_entity set is already declared as "ls_entityset TYPE stravelag" * entity data will be sent to the push client GET REFERENCE OF ls_entityset INTO lr_data. * Set the required params for push lo_notification_publisher->create_notification_endpoints( EXPORTING * those two value are mandatory but ignored is_data = lr_data iv_type = lv_notification_type * type "create" iv_operation_type = /iwbep/if_mgw_notif_publisher=>gcs_operation_types-create * push text iv_text = lc_text * additional info (this example is entity data) ir_poke_data = lr_data * "Badge" value * iv_entries_of_interest = it_subscriptions = lt_subscriptions IMPORTING et_notification_endpoints = lt_notification_endpoints ). * Push the text message to relevant subscribers - this will create a bgRFC queue LOOP AT lt_notification_endpoints INTO ls_notification_endpoint. TRY. lo_notification_publisher->send_notifications( is_notification_endpoint = ls_notification_endpoint ). CATCH /iwbep/cx_mgw_tech_exception INTO lx_mgw_tech_exception. ENDTRY. ENDLOOP.