Skip to Content
Technical Articles
Author's profile photo Andre Fischer

How to redefine RDS based OData services?

Updates

  • 07.10.2022 – Added the information that the code of MPC_EXT and DPC_EXT MUST use the name of the original service

Introduction

Extenstions of OData Services that have been created using the Reference Data Source (RDS) approach do not work out of the box. When you try to add additional entities to the SEGW project that redefines an RDS based OData service these entities are not part of the $metadata document.

This is quite unfortunate since most of the OData services hat have been delivered with SAP S/4HANA are based on RDS.

It is however possible to redefine a reference data source based OData service and perform certain adjustments in the MPC_EXT and DPC_EXT class to achieve this goal.

In the following I will describe the steps that are needed in order to redefine a reference datasource based OData service and how you can use the reference datasource approach in order to add additional entities that are handled by the SADL framework as well.

To make the live of the ABAP developer easier I have provided a report that lets you select the source and the extended SEGW project that will generate the aforementioned boiler plate coding.

The source code of the report can be found on GitHub

There I have also posted a code sample that has been generated by this report for the simple extension example described in this blog post.

Example of generated MPC_EXT and DPC_EXT code

Summary

In the following I will use a simple example of an RDS based source SEGW project Z_SRC_RDS that uses two CDS views: SEPM_I_SALESORDER_E and SEPM_I_SALESORDERITEM_E.

This project is redefined in a second SEGW project called Z_REDEF_RDS where two additional CDS views ZI_Currency and I_CurrencyText have beend added.

Adjust the MPC_EXT class

IF_SADL_GW_MODEL_EXPOSURE_DATA~GET_MODEL_EXPOSURE

In the method IF_SADL_GW_MODEL_EXPOSURE_DATA~GET_MODEL_EXPOSURE, the SADL framework generates the SADL definition, an XML file that contains the structure and the datasources that have been added to your SEGW project using RDS.

The following code snippet shows the sadl definition of the source SEGW project.

method IF_SADL_GW_MODEL_EXPOSURE_DATA~GET_MODEL_EXPOSURE.
    CONSTANTS: co_gen_timestamp TYPE timestamp VALUE '20211208161947'.
    DATA(lv_sadl_xml) =
               |<?xml version="1.0" encoding="utf-16"?>|  &
               |<sadl:definition xmlns:sadl="http://sap.com/sap.nw.f.sadl" syntaxVersion="" >|  &
               | <sadl:dataSource type="CDS" name="SEPM_I_SALESORDERITEM_E" binding="SEPM_I_SALESORDERITEM_E" />|  &
               | <sadl:dataSource type="CDS" name="SEPM_I_SALESORDER_E" binding="SEPM_I_SALESORDER_E" />|  &
               |<sadl:resultSet>|  &
               |<sadl:structure name="SEPM_I_SalesOrderItem_E" dataSource="SEPM_I_SALESORDERITEM_E" maxEditMode="RO" exposure="TRUE" >|  &
               | <sadl:query name="SADL_QUERY">|  &
               | </sadl:query>|  &
               |</sadl:structure>|  &
               |<sadl:structure name="SEPM_I_SalesOrder_E" dataSource="SEPM_I_SALESORDER_E" maxEditMode="RO" exposure="TRUE" >|  &
               | <sadl:query name="SADL_QUERY">|  &
               | </sadl:query>|  &
               | <sadl:association name="TO_ITEM" binding="_ITEM" target="SEPM_I_SalesOrderItem_E" cardinality="zeroToMany" />|  &
               |</sadl:structure>|  &
               |</sadl:resultSet>|  &
               |</sadl:definition>| .

   ro_model_exposure = cl_sadl_gw_model_exposure=>get_exposure_xml( iv_uuid      = CONV #( 'Z_SRC_RDS' )
                                                                    iv_timestamp = co_gen_timestamp
                                                                    iv_sadl_xml  = lv_sadl_xml ).
  endmethod.
ENDCLASS.

When you create the extension project Z_REDEF_RDS via redefinition and then add two additional CDS views using the reference data source approach you will find that the MPC class also contains a SADL definition. But this SADL definition only contains the newly added entities.

method IF_SADL_GW_MODEL_EXPOSURE_DATA~GET_MODEL_EXPOSURE.
    CONSTANTS: co_gen_timestamp TYPE timestamp VALUE '20211208162527'.
    DATA(lv_sadl_xml) =
               |<?xml version="1.0" encoding="utf-16"?>|  &
               |<sadl:definition xmlns:sadl="http://sap.com/sap.nw.f.sadl" syntaxVersion="V2" >|  &
               | <sadl:dataSource type="CDS" name="I_CURRENCYTEXT" binding="I_CURRENCYTEXT" />|  &
               | <sadl:dataSource type="CDS" name="ZI_CURRENCY" binding="ZI_CURRENCY" />|  &
               |<sadl:resultSet>|  &
               |<sadl:structure name="I_CurrencyText" dataSource="I_CURRENCYTEXT" maxEditMode="RO" exposure="TRUE" >|  &
               | <sadl:query name="SADL_QUERY">|  &
               | </sadl:query>|  &
               |</sadl:structure>|  &
               |<sadl:structure name="zI_currency" dataSource="ZI_CURRENCY" maxEditMode="RO" exposure="TRUE" >|  &
               | <sadl:query name="SADL_QUERY">|  &
               | </sadl:query>|  &
               | <sadl:association name="TO_TEXT" binding="_TEXT" target="I_CurrencyText" cardinality="zeroToMany" />|  &
               |</sadl:structure>|  &
               |</sadl:resultSet>|  &
               |</sadl:definition>| .

   ro_model_exposure = cl_sadl_gw_model_exposure=>get_exposure_xml( iv_uuid      = CONV #( 'Z_REDEF_RDS' )
                                                                    iv_timestamp = co_gen_timestamp
                                                                    iv_sadl_xml  = lv_sadl_xml ).
  endmethod.

In order to leverag all reference data source based entities one has to merge both SADL definitions. The merged SADL xml file has than to be provided in the redefined method IF_SADL_GW_MODEL_EXPOSURE_DATA~GET_MODEL_EXPOSURE of the MPC_EXT class of the project Z_REDEF_RDS.

In addition we have to redefine the DEFINE method so that it calls the DEFINE method of its parent class. So will have to create the following:

CLASS ZCL_Z_REDEF_RDS_MPC_EXT IMPLEMENTATION.
  METHOD define.
    super->define( ).
  ENDMETHOD.
  METHOD if_sadl_gw_model_exposure_data~get_model_exposure.
    CONSTANTS: co_gen_timestamp TYPE timestamp VALUE '20211208180352'.
    DATA(lv_sadl_xml) =
               |<?xml version="1.0" encoding="utf-16"?>|  &
               |<sadl:definition xmlns:sadl="http://sap.com/sap.nw.f.sadl" syntaxVersion="V2" >|  &
               | <sadl:dataSource type="CDS" name="SEPM_I_SALESORDERITEM_E" binding="SEPM_I_SALESORDERITEM_E" />|  &
               | <sadl:dataSource type="CDS" name="SEPM_I_SALESORDER_E" binding="SEPM_I_SALESORDER_E" />|  &
               |<sadl:dataSource type="CDS" name="I_CURRENCYTEXT" binding="I_CURRENCYTEXT" />|  &
               | <sadl:dataSource type="CDS" name="ZI_CURRENCY" binding="ZI_CURRENCY" />|  &
               |<sadl:resultSet>|  &
               |<sadl:structure name="SEPM_I_SalesOrderItem_E" dataSource="SEPM_I_SALESORDERITEM_E" maxEditMode="RO" exposure="TRUE" >|  &
               | <sadl:query name="SADL_QUERY">|  &
               | </sadl:query>|  &
               |</sadl:structure>|  &
               |<sadl:structure name="SEPM_I_SalesOrder_E" dataSource="SEPM_I_SALESORDER_E" maxEditMode="RO" exposure="TRUE" >|  &
               | <sadl:query name="SADL_QUERY">|  &
               | </sadl:query>|  &
               | <sadl:association name="TO_ITEM" binding="_ITEM" target="SEPM_I_SalesOrderItem_E" cardinality="zeroToMany" />|  &
               |</sadl:structure>|  &
               |<sadl:structure name="I_CurrencyText" dataSource="I_CURRENCYTEXT" maxEditMode="RO" exposure="TRUE" >|  &
               | <sadl:query name="SADL_QUERY">|  &
               | </sadl:query>|  &
               |</sadl:structure>|  &
               |<sadl:structure name="zI_currency" dataSource="ZI_CURRENCY" maxEditMode="RO" exposure="TRUE" >|  &
               | <sadl:query name="SADL_QUERY">|  &
               | </sadl:query>|  &
               | <sadl:association name="TO_TEXT" binding="_TEXT" target="I_CurrencyText" cardinality="zeroToMany" />|  &
               |</sadl:structure>|  &
               |</sadl:resultSet>|  &
               |</sadl:definition>| .
    ro_model_exposure = cl_sadl_gw_model_exposure=>get_exposure_xml( iv_uuid      = CONV #( 'Z_SRC_RDS' )
                                                                     iv_timestamp = co_gen_timestamp
                                                                     iv_sadl_xml  = lv_sadl_xml ).
  ENDMETHOD.
ENDCLASS.

This process can become cumbersome and error prone when dealing with large SEGW source projects. That’s why I have created a report that automates this process.

Adjust DPC_EXT class

IF_SADL_GW_DPC_UTIL~GET_DPC

The method IF_SADL_GW_DPC_UTIL~GET_DPC contains (for historical) reasons the same sadl definition. We have hence to provide the merged SADL xml file in the redefined method in the DPC_EXT class of the extended SEGW project as well.

 METHOD if_sadl_gw_dpc_util~get_dpc.
    CONSTANTS: co_gen_timestamp TYPE timestamp VALUE '20211208223150'.
    DATA(lv_sadl_xml) =
               |<?xml version="1.0" encoding="utf-16"?>|  &
               |<sadl:definition xmlns:sadl="http://sap.com/sap.nw.f.sadl" syntaxVersion="V2" >|  &
               | <sadl:dataSource type="CDS" name="SEPM_I_SALESORDERITEM_E" binding="SEPM_I_SALESORDERITEM_E" />|  &
               | <sadl:dataSource type="CDS" name="SEPM_I_SALESORDER_E" binding="SEPM_I_SALESORDER_E" />|  &
               |<sadl:dataSource type="CDS" name="I_CURRENCYTEXT" binding="I_CURRENCYTEXT" />|  &
               | <sadl:dataSource type="CDS" name="ZI_CURRENCY" binding="ZI_CURRENCY" />|  &
               |<sadl:resultSet>|  &
               |<sadl:structure name="SEPM_I_SalesOrderItem_E" dataSource="SEPM_I_SALESORDERITEM_E" maxEditMode="RO" exposure="TRUE" >|  &
               | <sadl:query name="SADL_QUERY">|  &
               | </sadl:query>|  &
               |</sadl:structure>|  &
               |<sadl:structure name="SEPM_I_SalesOrder_E" dataSource="SEPM_I_SALESORDER_E" maxEditMode="RO" exposure="TRUE" >|  &
               | <sadl:query name="SADL_QUERY">|  &
               | </sadl:query>|  &
               | <sadl:association name="TO_ITEM" binding="_ITEM" target="SEPM_I_SalesOrderItem_E" cardinality="zeroToMany" />|  &
               |</sadl:structure>|  &
               |<sadl:structure name="I_CurrencyText" dataSource="I_CURRENCYTEXT" maxEditMode="RO" exposure="TRUE" >|  &
               | <sadl:query name="SADL_QUERY">|  &
               | </sadl:query>|  &
               |</sadl:structure>|  &
               |<sadl:structure name="zI_currency" dataSource="ZI_CURRENCY" maxEditMode="RO" exposure="TRUE" >|  &
               | <sadl:query name="SADL_QUERY">|  &
               | </sadl:query>|  &
               | <sadl:association name="TO_TEXT" binding="_TEXT" target="I_CurrencyText" cardinality="zeroToMany" />|  &
               |</sadl:structure>|  &
               |</sadl:resultSet>|  &
               |</sadl:definition>| .
    ro_dpc = cl_sadl_gw_dpc_factory=>create_for_sadl( iv_sadl_xml   = lv_sadl_xml
           iv_timestamp         = co_gen_timestamp
           iv_uuid              = CONV #( 'Z_SRC_RDS' )
           io_context           = me->mo_context ).
  ENDMETHOD.

*************************************************************

!!! CAUTION – IV_UUID !!!

It is important that in both classes, the MPC_EXT and the DPC_EXT class the value for the unique ID of the SADL model is the name of the original model.

iv_uuid = CONV #( 'Z_SRC_RDS' )

(If you use the name of the redefined model instead the newly added entities will not show up).

In addition it is important that the time stamp has been set to a value near “now” so that it is newer than the time stamps used in the rest of the coding generated by SEGW and delivered by SAP.

The report that I wrote takes care of this, so I would strongly recommend to use this report to create the sample code for MPC_EXT and DPC_EXT.

=> RESTRICTION

In addition it is important to note that by using the original model name also the original RDS based model now would show the newly added entities.

So the orginal service would not be accessible in its original version.

But since you are interested to extend the original RDS based service delivered by SAP I assume that this restriction is not a problem.

*************************************************************

Add entity specific _get_entity, _get_entityset methods.

When adding additional CDS views to your redefined RDS based SEGW project Z_RDS_SRC you will find that no entity specifc methods are generated in your extended SEGW project Z_REDEF_RDS.

It is thus necessary to add manually entity specific methods such as:

i_currencytex_get_entityi_currencytex_get_entitysetzi_currency_get_entity and zi_currency_get_entityset.

Please note that we only use one importing parameter io_tech_request_context since the rest of the importing parameters have been deprecated and are thus not used by the SADL framework.

CLASS zcl_z_redef_rds_dpc_ext DEFINITION
 PUBLIC
 INHERITING FROM zcl_z_redef_rds_dpc
 CREATE PUBLIC .
  PUBLIC SECTION.
    METHODS if_sadl_gw_dpc_util~get_dpc REDEFINITION .
    METHODS /iwbep/if_mgw_appl_srv_runtime~get_entityset REDEFINITION .
    METHODS /iwbep/if_mgw_appl_srv_runtime~get_entity REDEFINITION .
  PROTECTED SECTION.
    METHODS i_currencytex_get_entity
      IMPORTING
        !io_tech_request_context TYPE REF TO /iwbep/if_mgw_req_entity OPTIONAL
      EXPORTING
        !er_entity               TYPE zcl_z_redef_rds_mpc=>ts_i_currencytexttype  "use code completion to select correct type from MPC .
        !es_response_context     TYPE /iwbep/if_mgw_appl_srv_runtime=>ty_s_mgw_response_entity_cntxt
      RAISING
        /iwbep/cx_mgw_busi_exception
        /iwbep/cx_mgw_tech_exception .
    METHODS i_currencytex_get_entityset
      IMPORTING
        !io_tech_request_context TYPE REF TO /iwbep/if_mgw_req_entityset OPTIONAL
      EXPORTING
        !et_entityset            TYPE  zcl_z_redef_rds_mpc=>tt_i_currencytexttype  "use code completion to select correct type from MPC .
        !es_response_context     TYPE /iwbep/if_mgw_appl_srv_runtime=>ty_s_mgw_response_context
      RAISING
        /iwbep/cx_mgw_busi_exception
        /iwbep/cx_mgw_tech_exception .
    METHODS zi_currency_get_entity
      IMPORTING
        !io_tech_request_context TYPE REF TO /iwbep/if_mgw_req_entity OPTIONAL
      EXPORTING
        !er_entity               TYPE zcl_z_redef_rds_mpc=>ts_zi_currencytype  "use code completion to select correct type from MPC .
        !es_response_context     TYPE /iwbep/if_mgw_appl_srv_runtime=>ty_s_mgw_response_entity_cntxt
      RAISING
        /iwbep/cx_mgw_busi_exception
        /iwbep/cx_mgw_tech_exception .
    METHODS zi_currency_get_entityset
      IMPORTING
        !io_tech_request_context TYPE REF TO /iwbep/if_mgw_req_entityset OPTIONAL
      EXPORTING
        !et_entityset            TYPE  zcl_z_redef_rds_mpc=>tt_zi_currencytype  "use code completion to select correct type from MPC .
        !es_response_context     TYPE /iwbep/if_mgw_appl_srv_runtime=>ty_s_mgw_response_context
      RAISING
        /iwbep/cx_mgw_busi_exception
        /iwbep/cx_mgw_tech_exception .
ENDCLASS .

Please note that the implementation of the entity specific methods ultimatively only contains generic calls of the underlying SADL framework.

  METHOD i_currencytex_get_entity.
    if_sadl_gw_dpc_util~get_dpc( )->get_entity( EXPORTING io_tech_request_context = io_tech_request_context
                                                IMPORTING es_data                 = er_entity ).
  ENDMETHOD.
  METHOD i_currencytex_get_entityset.
    if_sadl_gw_dpc_util~get_dpc( )->get_entityset( EXPORTING io_tech_request_context = io_tech_request_context
                                                   IMPORTING et_data                 = et_entityset
                                                             es_response_context     = es_response_context ).
  ENDMETHOD.
  METHOD zi_currency_get_entity.
    if_sadl_gw_dpc_util~get_dpc( )->get_entity( EXPORTING io_tech_request_context = io_tech_request_context
                                                IMPORTING es_data                 = er_entity ).
  ENDMETHOD.
  METHOD zi_currency_get_entityset.
    if_sadl_gw_dpc_util~get_dpc( )->get_entityset( EXPORTING io_tech_request_context = io_tech_request_context
                                                   IMPORTING et_data                 = et_entityset
                                                             es_response_context     = es_response_context ).
  ENDMETHOD.

/IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_ENTITYSET

The generic method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_ENTITYSET controls which entities can be reached in the service at runtime. It contains a CASE statement that will call the entity specific methods if an OData request for ths same has reached the SAP Gateway OData framework.

Please note that the entity specific methods ultimately only contain a delegation to the SADL runtime. In the generic methods.

If none of the newly added entity sets is called the generic GET_ENTITYSET of the parent class and thus the DPC_EXT implementation of the source service is called.

 METHOD /iwbep/if_mgw_appl_srv_runtime~get_entityset.
    DATA(my_entity_name) = io_tech_request_context->get_entity_set_name( ).
    CASE io_tech_request_context->get_entity_set_name( ).
      WHEN 'I_CurrencyText'.
        i_currencytex_get_entityset( EXPORTING io_tech_request_context = io_tech_request_context
                                       IMPORTING et_entityset               = DATA(i_currencytex_entityset)
                                         es_response_context     = es_response_context ).
        IF i_currencytex_entityset IS NOT INITIAL.
          copy_data_to_ref( EXPORTING is_data = i_currencytex_entityset
                           CHANGING  cr_data = er_entityset ).
        ENDIF.
      WHEN 'zI_currency'.
        zi_currency_get_entityset( EXPORTING io_tech_request_context = io_tech_request_context
                                       IMPORTING et_entityset               = DATA(zi_currency_entityset)
                                         es_response_context     = es_response_context ).
        IF zi_currency_entityset IS NOT INITIAL.
          copy_data_to_ref( EXPORTING is_data = zi_currency_entityset
                           CHANGING  cr_data = er_entityset ).
        ENDIF.
      WHEN OTHERS.
        super->/iwbep/if_mgw_appl_srv_runtime~get_entityset( EXPORTING iv_entity_name           = iv_entity_name
                                                                  iv_entity_set_name       = iv_entity_set_name
                                                                  iv_source_name           = iv_source_name
                                                                  it_filter_select_options = it_filter_select_options
                                                                  it_order                 = it_order
                                                                  is_paging                = is_paging
                                                                  it_key_tab               = it_key_tab
                                                                  it_navigation_path       = it_navigation_path
                                                                  iv_filter_string         = iv_filter_string
                                                                  iv_search_string         = iv_search_string
                                                                  io_tech_request_context  = io_tech_request_context
                                                        IMPORTING er_entityset             = er_entityset
                                                                  es_response_context      = es_response_context ).
    ENDCASE.
  ENDMETHOD.

/IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_ENTITY

Also for the GET_ENTITY requests we have to provide appropriate code in the generic GET_ENTITY method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_ENTITY.

 METHOD /iwbep/if_mgw_appl_srv_runtime~get_entity.
    DATA(my_entity_name) = io_tech_request_context->get_entity_set_name( ).
    CASE io_tech_request_context->get_entity_set_name( ).
      WHEN 'I_CurrencyText'.
        i_currencytex_get_entity( EXPORTING io_tech_request_context = io_tech_request_context
                                       IMPORTING er_entity               = DATA(i_currencytex_entity)
                                         es_response_context     = es_response_context ).
        IF i_currencytex_entity IS NOT INITIAL.
          copy_data_to_ref( EXPORTING is_data = i_currencytex_entity
                           CHANGING  cr_data = er_entity ).
        ENDIF.
      WHEN 'zI_currency'.
        zi_currency_get_entity( EXPORTING io_tech_request_context = io_tech_request_context
                                       IMPORTING er_entity               = DATA(zi_currency_entity)
                                         es_response_context     = es_response_context ).
        IF zi_currency_entity IS NOT INITIAL.
          copy_data_to_ref( EXPORTING is_data = zi_currency_entity
                           CHANGING  cr_data = er_entity ).
        ENDIF.
      WHEN OTHERS.
        super->/iwbep/if_mgw_appl_srv_runtime~get_entity( EXPORTING iv_entity_name          = iv_entity_name
                                                                   iv_entity_set_name      = iv_entity_set_name
                                                                   iv_source_name          = iv_source_name
                                                                   it_key_tab              = it_key_tab
                                                                   it_navigation_path      = it_navigation_path
                                                                   io_tech_request_context = io_tech_request_context
                                                          IMPORTING er_entity              = er_entity
                                                                    es_response_context    = es_response_context ).
    ENDCASE.
  ENDMETHOD.

Add missing annotations

The following blog post of my colleague Manikandan Rajasekaran will give you details on how to link the annotations of the Odata Service created  based on CDS  with the redefined service.

How to redefine a CDS based Odata Service with Annotations ? | SAP Blogs

See also SAP Note:

3091281 – Extended OData Service throws error :No Service found for Annotation File ‘XXXXXXXXXXXXXXXX’ version ‘0001’ on SAP GW Server – SAP ONE Support Launchpad

Result

When having performed the aforementioned adjustments the OData service of the redefined SEGW project now contains four CDS based entities.

Problems when redefining large OData Services

While the described process works find for our simple example you might encounter problems when dealing with large RDS based OData services as they have been delivered as part of SAP S/4HANA.

Failures during consistency checks

When redefining an SAP Gateway based OData service SEGW nevertheless performs consistency checks. It has been observed that some of these consistency checks fail though the underlying service works fine.

To overcome this issue the following notes have been created that are also part of the latest deliveries of the SAP Gateway framework.

2853065 – SEGW Tool update – Association & Referential Constraints

3115221 – SEGW Tool – Covert Error Messages to Warnings during check

Time out problems

Redefinition of large OData service might take several minutes so that the maximum runtime of a workprocess is exceeded. The profile parameter rdisp/scheduler/prio_high/max_runtime is used to configure the dialog request run-time limit, i.e., the time that a request is allowed to run in a dialog work process without interruption.

Fortunately it is possible to change the setting of this profile parameter online using transaction RZ11. So you can adapt this setting without the need to reboot your development system.

 

Tool support

Since merging XML files and creating additional methods in the DPC_EXT class is a time consuming and errorprone task I have developed a report that lets you select two SEGW projects. A source project and an extension project.

The report will generate the source code in a separate text file that has to be implemented in the MPC_EXT and the DPC_EXT class of your SEGW extension project.

The source code of the report can be found on GitHub:

SAP-samples / abap-platform-code-samples-standard

Simply copy and paste the code from the text file that you have dowloaded into the MPC_EXT and DPC_EXT classes of your extended SEGW project.

The only thing that is left to do for the developer is that he or she has to copy and paste the generated code into the MPC_EXT and the DPC_EXT class.

At the moment it is also necessary to select the TYPES that have been generated in the MPC class via code completion.

Technical restrictions

Since we are merging the SADL xml files at some point in time you have to redo parts of this when

a) the underlying source service changes and

b) if you add additional entities via the reference data source approach

Hopefully we will be able to add (parts) of this functionality into the standard ;-).

Outlook

I am currently testing code snippets that can be added to your MPC_EXT and DPC_EXT class that are calling the so called flex classes. Flex classes are part of SEGW projects where the OData services have been prepared to support the extension by key user tools.

Flex classes are parent classes of the MPC_EXT and DPC_EXT class of an OData service and they are in turn inheriting from the MPC and DPC class of the SEGW project delivered by SAP.

This code is needed so that fields that have been added using the custom fields key user tool are also visible in the SAP FIori application if the underlying OData service has been redefined.

 

 

 

 

Assigned Tags

      16 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Umut Yazici
      Umut Yazici

      Thanks Andre…

      Author's profile photo Mattijs Happé
      Mattijs Happé

      Hi Andre,

       

      Thanks for interesting blog, the program to genereate the exposure XML is was the missing part for me 🙂

       

      Whats the impact during an uprade when SAP made some changes to the extended service? These changes will not be refelected by the extension service (with replacing the main service) ?

       

      Furthermore one addition for the problems part. In case the extended OData contains annotations those annotations are not propogated to your extension service.

      See note "3091281 - Extended OData Service throws error :No Service found for Annotation File ‘XXXXXXXXXXXXXXXX’ version ‘0001’ on SAP GW Server" for the solution

      Author's profile photo Andre Fischer
      Andre Fischer
      Blog Post Author

      Hi Matijs,

      the link to the source code which resides on GitHub is in the blog post.

      abap-platform-code-samples-standard/zaf_r_extend_rds_based_service.prog.abap at main · SAP-samples/abap-platform-code-samples-standard (github.com)

      You are right, changes to the source service will not be reflected in the target service. You will have to regenerate the condensed SADL XML.

      For the missing annotations you are also right. For this issue my colleague Manikandan has posted a blog post. I have added the link to the problems section.

      Kind regards,

      Andre

       

      Author's profile photo Thomas Knobloch
      Thomas Knobloch

      Hi Andre,

      Thanks for the blog. I have a question about adding entities.

      I just added the new entity in my project via this button.

      Everything is generated and data are provided. So what is the difference?

      Add%20CDS-Entity%20Button

      Add CDS-Entity Button

      Thanks and best regards,

      Thomas

      Author's profile photo Karsten Schaser
      Karsten Schaser

      Hi Thomas,

      your screenshot misses the interesting part the project/service name. Normally you cannot add new CDS entities via SEGW to SAP delivered projects/services and regenerate, as this means a modification of SAP classes.

      The difference of redefining a service is that this method is modification free...

      Best regards,

      Karsten

      Author's profile photo Andre Fischer
      Andre Fischer
      Blog Post Author

      As Karsten pointed out.

      The project Z_SRC_RDS would normally reside in the SAP namespace and a customer would not be able to open it via SEGW and add entities without creating a modification.

      I just created a simple project Z_SRC_RDS with two entities so that it easier to follow the differencies of the XML files used in the source RDS based project and the redefined project that gets additional entities via RDS.

       

      Author's profile photo Archer Zhang
      Archer Zhang

      Hello Andre,

      I didn`t figure out, which SEGW project in your example that I can take it as an SAP project?

      Z_SRC_RDS or Z_REDEF_RDS?

       

      BRs,

      Archer

      Author's profile photo Andre Fischer
      Andre Fischer
      Blog Post Author

      Hi Archer,

      please see my comment above.

      The source project that should simulate the project in the SAP namespace is the SEGW project Z_SRC_RDS.  

      Z_REDEF_RDS is the SEGW project that is created via redefinition of the project Z_SRC_RDS. 

      Unfortunately there are no simple RDS based SEGW projects available in the SAP namespace.

      Kind regards,
      Andre

       

      Author's profile photo David Fernandez Castro
      David Fernandez Castro

      Hi Andre,

      I am facing an issue when extending a standard OData service which does not use RDS-based entities (RETAILSTORE_RECEIVE_PRODUCT). I created an OData project/service that extends this standard service and then, when I try to add an entity based on a CDS (using RDS) then I can see the entity added in SEGW transaction and I can regenerate project with no errors. But then, when I test my OData service the new entity added through RDS is not visible.

      Is this also an identified problem or this scenario should work?

       

      Thanks

      Author's profile photo Andre Fischer
      Andre Fischer
      Blog Post Author

      It does not seem to work for standard services. At least I was not able to extend a service that uses a code based implementation as described in my blog above.

      Updated 15.02.2023

      I have to rephrase my comment here. 

      What I was not able to do is to redefine an OData service that used code based implementation using the approach that I have described in this blog.  

      It works for services that are delivered with the SAP standard that are using RDS.

       

      Author's profile photo Archer Zhang
      Archer Zhang

      I was following your Blog to solve one customer incident, which is to extend the SAP standard service.

      Author's profile photo Pedro Oliveira
      Pedro Oliveira

      Hello,

      Great blog. It helps a lot. But i wonder, if you want to extend with an entity and have the CRUD capacity with draft on the new entity. how could this be done?

      Thanks,

      Author's profile photo Priyanka Vana
      Priyanka Vana

      Hi Andre,

      Thanks for the blog.

      According to the xml code of the extended SADL in MPC_EXT , I understood that this extended service has 2 associations. One is between SO header and item and second one is between zI_Currency and I_currencyText. I would like to know what is the mapping/association between the redefined entities and the source entity. When I want to expand the entity from SO header to zI_Currency, there is no association available.

      If I want to run a query as below,  the association between header and zI_currency needs to be created  in zI_currency CDS view or in SEGW project? /sap/opu/odata/sap/Z_REDEF_RDS_SRV/SEPM_I_SALESORDER_E("SO")/to_zI_currency?

      I have a similar requirement to extend API_PRODUCT_SRV with z-attributes in MARA. I used an ABAP code based implementation but it did not work with filter and expand. So, I switched to "RDS" based implementation following your blog. All entities are visible in the service now including my Z-cds entity. How should I create the association between A_Product entity and the new Z-entity?

      Thanks!

      Author's profile photo Upendra Verma
      Upendra Verma

      Hi Andre,

      Thanks for this nice blog.

      What about creating new association from original entity to new entity? How can we create new associations to existing Odata entities. I tried to follow above steps to redefine RDS but when added association to redefined entity I keep getting SADL error that association cannot be found.

      Thanks in advance!

      Upendra

      Author's profile photo Archer Zhang
      Archer Zhang

      Hello Andre,

      Do you have any conclusions about your outlook?

      'This code is needed so that fields that have been added using the custom fields key user tool are also visible in the SAP FIori application if the underlying OData service has been redefined.'

      If it works and how? thank you.

      BRs,
      Archer

      Author's profile photo Momen Allouh
      Momen Allouh

      Hi Andre,

      I used your program to extend RDS based ODATA used in Manage Prices - Sales Fiori App, to add standard fields that are missing in the BOBF CDS views and structures along with their Value Help standard CDS views.

      It worked fine BUT we lost all the ZZ1_ custom fields that was created in Custom Fields App.
      I think the custom fields from the CFL app will be part of the Flex classes, so did you get time to update your SE38 program to consider the Flex custom fields ? or do you know any workaround ?

      Regards,

      Momen