Improve the performance of an SAP FIORI application by implementing “Delta Token” mode in SAP Netweaver Gateway Odata
In a mobility context, it is often necessary to develop an application that will be used online and offline.
To avoid performance problems, it is necessary to implement the various features offered by the components of the application architecture.
The large amount of data to be processed is often the first area of improvement. In this article, we offer a guide to implementing Delta Token mode at the webservice level on the SAP Gateway platform.
SAP Gateway & Delta Token
When the app is initially login, for a given user, to the ECC backend, it is necessary to load all the useful data to work offline.
One of the main problems in the field of mobility is to limit the amount of data that migrates from the backend to the final medium.
The network is not necessarily accessible (white zone), speed may not be up to the needs, significantly slowing down data recovery or transfer, and then blocking the application for a time that can sometimes take several minutes.
To overcome these constraints, the use of “Delta mode”is recommended for all web services.
How “Delta” Mode Works
During a call to a webservice, supporting the “Delta” mode, a “token” is generated by the latter and returned, along with the expected data collection, to the frontend.
This token, if used in successive calls, allows the backend to calculate a delta of the data and return only the data from the collection that has undergone changes since the previous call (creation, modification, deletion of values or data). This limits the amount of data that passes through the network and contributes to improved performance.
The “Delta” mode is interesting about methods returning a collection, as are the so-called “Query” methods.
In practical terms, these are the methods (visible via the SEGW transaction) known as “GetEntitySet”; Their principle is to return a list of objects that meet certain criteria (e.g. all “materials” available within the plant); it is this list that is called “collection.”
Delta Mode Implementation
Creating a list-generating RFC module
The ZRFC_READ_ALL function
Our RFC contains only two parameters: two tables
ALL –> contains all the results compatible with the query
SEL_ALL_USER –> allows you to submit one or more filtering values
The structure of the function tables
ALL : This table contains all the fields you want to transmit via webservice
SEL_ALL_USER : This table contains the filter values, its structure is always the same (the length of the “low” and “high” components can vary to adapt to the filter’s needs
The function algorithm
In the function code, we take into account the filter table if informed, otherwise we make a simple query.
Creation of an Odata project
On the SAP Gateway server, execute the SEGW transaction
The structure of the “ZGCG11_DEMO” project
The “Data model” was generated based on the composition of the RFC (without considering the filter table), as well as:
Name of “Data Model” –> “All_Delta”
Associated “Entity Set” name –> “All_Delta_Set”
Implementation of the “Query” method
Mapping is simply done between the areas of the results table and those of the Odata project entityset.
Webservice will return all results associated with this RFC module code (if no filter is provided):
It is thus possible to recover the result via the “IWFND/GW_CLIENT” transaction with this query:
Redefining the “Query” method via ABAP
The redefinition of a method of your Odata project is achieved via a right click on the name of this method and then:
The screen we access can also be found via the SE80 transaction.
The tree of “methods” must then be unfolded until the “Query” method associated with the Entity Set is found, which always ends with an “ENTITYSET” and:
This “Query” method is the one that will be called by default if you don’t specify a token, i.e. when the application is initialized or when you need a complete refresh, for example.
All you have to do is right click on it and choose to “redefine.”
You will then need to report the following data elements:
DATA : lo_dp_facade TYPE REF TO /IWBEP/IF_MGW_DP_FACADE, lv_delta_token TYPE string.
* Appel de la RFC CALL FUNCTION 'ZRFC_READ_ALL' TABLES ALL = et_entityset. CHECK sy-subrc EQ 0. * Get the data provider facade TRY. lo_dp_facade = /iwbep/if_mgw_conv_srv_runtime~get_dp_facade( ). CATCH /iwbep/cx_mgw_tech_exception. RAISE EXCEPTION TYPE /iwbep/cx_mgw_tech_exception. ENDTRY. * Call the delta token functionality TRY. CALL METHOD /iwbep/cl_query_result_log=>create_update_log_entry_hash EXPORTING io_tech_request_context = io_tech_request_context io_dp_facade = lo_dp_facade ir_service_document_name = mr_service_document_name ir_service_version = mr_service_version it_entityset = et_entityset CHANGING ev_delta_token = lv_delta_token. CATCH /iwbep/cx_qrl_locked. RAISE EXCEPTION TYPE /iwbep/cx_qrl_locked. CATCH /iwbep/cx_qrl_delta_unavailabl. RAISE EXCEPTION TYPE /iwbep/cx_qrl_delta_unavailabl. ENDTRY. * export the delta token es_response_context-deltatoken = lv_delta_token.
The method starts by calling the RFC in a standard way, it returns all the results.
Two objects are then required:
- The data provider facade allows data to be stored in a hashed table based on the structure of the associated model
- The “delta token”
After recovering the data from our RFC, a data provider facade is created; then the two are combined in the call of the method allowing data storage and token generation.
The Webservice call then returns all the values as well as the token that will be used in successive calls in order to only trace the difference in results.
Redefining the “Query Delta” method via ABAP
A second method must now be redefined to allow the use of the “delta” mode.
This is the method:
This method is used by all the “Entities” in your Odata project.
You will need to report the following data elements ….
DATA : lv_entity_set_name TYPE string, lv_delta_token TYPE string, lo_dp_facade TYPE REF TO /iwbep/if_mgw_dp_facade.
….As well ase tables, based on the structure of those powered by your RFC,to collect the “created/modified” and “deleted” data identified by the “delta” token method.
TYPES : BEGIN OF wlst_users, ZUSER Type XUBNAME, ZMAIL Type AD_SMTPADR, END OF wlst_users. DATA : lt_users TYPE STANDARD TABLE OF wlst_users WITH NON-UNIQUE DEFAULT KEY INITIAL SIZE 0. DATA : lt_deleted_users TYPE STANDARD TABLE OF wlst_users WITH NON-UNIQUE DEFAULT KEY INITIAL SIZE 0.
We are only interested here in one “EntitySet”, so we have to identify it:
* get the EntitySet name in progress lv_entity_set_name = io_tech_request_context->get_entity_set_name( ). * If it's an EntitySet that we manage in delta mode CASE lv_entity_set_name. WHEN 'All_Delta_Set'. * Appel de la RFC CALL FUNCTION 'ZRFC_READ_ALL' TABLES all = lt_users. * get the data provider facade TRY. lo_dp_facade = /iwbep/if_mgw_conv_srv_runtime~get_dp_facade( ). CATCH /iwbep/cx_mgw_tech_exception. RAISE EXCEPTION TYPE /iwbep/cx_mgw_tech_exception. ENDTRY. * Calculation of differences between delta tokens and updating of information TRY. CALL METHOD /iwbep/cl_query_result_log=>create_update_log_entry_hash EXPORTING io_tech_request_context = io_tech_request_context io_dp_facade = lo_dp_facade ir_service_document_name = mr_service_document_name ir_service_version = mr_service_version it_entityset = lt_users IMPORTING et_deleted_entityset = lt_deleted_users et_entityset = lt_users CHANGING ev_delta_token = lv_delta_token. CATCH /iwbep/cx_qrl_locked. RAISE EXCEPTION TYPE /iwbep/cx_qrl_locked. CATCH /iwbep/cx_qrl_delta_unavailabl. RAISE EXCEPTION TYPE /iwbep/cx_qrl_delta_unavailabl. ENDTRY. * Export of new delta token es_response_context-deltatoken = lv_delta_token. * Export of deleted datas copy_data_to_ref( EXPORTING is_data = lt_deleted_users CHANGING cr_data = er_deleted_entityset ). * Export of modified or created datas copy_data_to_ref( EXPORTING is_data = lt_users CHANGING cr_data = er_entityset ). WHEN OTHERS. * Do nothing ENDCASE. ENDMETHOD.
There is a constraint to the use of the “Delta” mode: the weight of the data!
Each call using this mode generates logs in SAP, only if the result of that call differs from the previous one. These logs are like a snapshot of the result of the query. They are therefore fundamental to the operation of the “Delta” mode because they are the elements on which SAP relies to determine the existence of differences.
These logs are stored in two tables:
The first, contains the head data, while the second contains the detail, the signature, of each line returned.
These records are specific to the user generating the call of the webservice.
Thus, over time, these tables will contain more and more “unnecessary” data since obsolete. To avoid losing performance as a result of this data, it will be necessary to carry out a regular purge.
There is a standard tool, provided by SAP:
Report « /IWBEP/R_CLEAN_UP_QRL”
If this table no longer contains the data you want to access (via the Delta Token), then the webservice will have to make a new call from the webservice but in “full” mode, i.e. without referring to the Delta Token (which will involve a longer processing time than in delta mode).
That said, this full mode will trigger new logs that will be used in subsequent delta mode calls.
Find more informations here about SAP GATEWAY and OData : https://help.sap.com/doc/saphelp_nw74/7.4.16/en-US/ec/aeea50ca692309e10000000a445394/content.htm?no_cache=true
Thanks for the great blog. Really helped us in implementing the delta feature on oData side. While consuming the response via SAP Offline SDK for Android, the response is in XML format and what we expect is the JSON format. In such scenario, how do we consume the delta token? Can you please suggest?