Skip to Content
Technical Articles

How to redefine a CDS based Odata Service with Annotations ?

This blog will give you details on how to link the annotations of the Odata Service created  based on CDS  with the redefined service.

Problem:

Whenever you redefine a Odata service which  was created based on CDS reference, the annotations of the redefined service will not be linked with the new Odata service .

We will now see how to eliminate this problem with one configuration technique.

Solution:

  1. First of  all lets have a look at how the SEGW project  which was created based on CDS .

This Odata service has annotation model linked to this service.

The highlighted one is the Annotation model created and associated with the service in         transaction /IWBEP/REG_VOCAN.

The above mapping in /IWBEP/REG_VOCAN is an automated process.

2. What will happen if there is an service assignment in transaction /IWBEP.REG_VOCAN ?

When you register the Odata  service, it will check for the entry in transaction  /IWBEP/REG_VOCAN if the service is mapped with any Vocabulary model.

If entry exists, an entry will be created in DB table Vocabulary Annotation File -/IWFND/I_MED_VAA

3. The annotation will be retrieved in WebIDE only if the entry exists in /IWFND/I_MED_VAA.

 

Now Let’s have a look , how the  new SEGW project  in which the above service is redefined.

4.Create a SEGW project -> Redefine->Odata Service(GW).

5. Select the required entities and generate the project.

Do not register the service.

Configuration – Important step – In Back end system  where the SEGW project exists.

6.  Before registering the service,

  • Go to transaction /IWBEP/REG_VOCAN .
  • Select the annotation model of the Original Service (which you have redefined in point 1)

7. Click Add assignment – Give the service name generated (in point 1) and click “Enter”.

8. An entry will be created as below.

9. Now register the service

10. Now in WebIDE – Lets select redefined service

11. You will get the annotations of the original service – This is because of Configuration in  point 6 and point 7.

 

Now what could be done if you are already facing the problem for a registered Odata service ?

 

1. De-register the service in transaction  /IWFND/MAINT_SERVICE.

2. Perform the configuration in /IWBEP/REG_VOCAN (Point 6 & 9).

In Back end system  where the SEGW project exists.

3. Register the service again in transaction /IWFND/MAINT_SERVICE.

 

Road Map:

We are planning to automate this configuration steps for CDS based Odata service when redefined.

Stay tuned for updates.

 

5 Comments
You must be Logged on to comment or reply to a post.
  • Hi Manikandan,

    Thanks for sharing this blog!!!

    It was really helpful.

    I have one query on same scenario where we are redefining  ODATA service having CDS as data source reference. When I add CDS to new service I don't see that CDS entity in metadata. Don't know why it's like this. Do you have any idea about it.

    Thanks,

    Dhiraj M

    • I think it's only possible with a workaround as adding a CDS data source reference to a redefinition will not lead to a " combined model exposure" . The result of method "GET_MODEL_EXPOSURE" from the MPC class of your extension project is not combined/merged with the result of the method "GET_MODEL_EXPOSURE" from the base MPC class.

      Furtherore in an extension project the get_entity and get_entityset nethods are not generated automically.

      The trick is to add a new entity to your model based on the DDIC structure which is assigned to your CDS view.
      In your DPC_EXT class you have to implement:

      • Interface IF_SADL_GW_DPC_UTIL
      • Implement method IF_SADL_GW_DPC_UTIL~GET_DPC
        The implementation of this method could be copied from a temporary SEGW project where  you include the same CDS view as a data source reference. Just change the value of the UUID.
        For example:

          TYPES ty_zc_product_plant TYPE zc_product_plant ##NEEDED. " reference for where-used list
        
            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="ProductPlantSet" binding="ZC_PRODUCT_PLANT" />| &
                                      |<sadl:resultSet>| &
                       |<sadl:structure name="ProductPlantSet" dataSource="ProductPlantSet" maxEditMode="RO" >| &
                       | <sadl:query name="EntitySetDefault">| &
                       | </sadl:query>| &
                       | <sadl:attribute name="PRODUCTID" binding="PRODUCTID" isKey="TRUE" />| &
                       | <sadl:attribute name="PLANTID" binding="PLANTID" isKey="TRUE" />| &
                       | <sadl:attribute name="MAINTENANCESTATUS" binding="MAINTENANCESTATUS" isKey="FALSE" />| &
                       |</sadl:structure>| &
                       |</sadl:resultSet>| &
                       |</sadl:definition>| .
        
            ro_dpc = cl_sadl_gw_dpc_factory=>create_for_sadl( iv_sadl_xml   = lv_sadl_xml
                       iv_timestamp         = 20210324121940
                       iv_uuid              = 'ZMYABAP_SEGW_EXTEN'
        *               io_query_control     = me
        *               io_extension_control = me
                       io_context           = me->mo_context ).​
      • Create 2 private or protected method to implement logic for the get_entity and get_entityset of your newly created entity.
        In the get entityset method you have to put:
      •     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 ).

        In the get_entity method:

            if_sadl_gw_dpc_util~get_dpc( )->get_entity( EXPORTING io_tech_request_context = io_tech_request_context
                                                        IMPORTING es_data                 = er_entity ).
      • Override methods /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_ENTITY and /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_ENTITYSET to call the created methods in previous steps for your custom entity. For all other entities call the super implementation.
          METHOD /iwbep/if_mgw_appl_srv_runtime~get_entity.
        
            DATA lr_entity TYPE REF TO data.
        
            CASE io_tech_request_context->get_entity_type_name( ).
              WHEN zcl_zmyabap_segw_exten_mpc=>gc_productplant.
        
        *     Call the entity set generated method
                zc_product_plant_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               = DATA(zc_product_plant_get_entity)
                                                   es_response_context     = es_response_context ).
        
                IF zc_product_plant_get_entity IS NOT INITIAL.
        *     Send specific entity data to the caller interface
                  copy_data_to_ref( EXPORTING is_data = zc_product_plant_get_entity
                                    CHANGING  cr_data = er_entity ).
                ELSE.
        *         In case of initial values - unbind the entity reference
                  er_entity = lr_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.​
          METHOD /iwbep/if_mgw_appl_srv_runtime~get_entityset.
            DATA lr_entity TYPE REF TO data.
        
            CASE io_tech_request_context->get_entity_type_name( ).
              WHEN zcl_zmyabap_segw_exten_mpc=>gc_productplant.
        * call the entity set generated method
                zc_product_plant_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 et_entityset             = DATA(zproductplant_set)
                                                      es_response_context      = es_response_context ).
        
                IF zproductplant_set IS NOT INITIAL.
                  me->copy_data_to_ref( EXPORTING is_data = zproductplant_set
                                         CHANGING cr_data = er_entityset ).
                ELSE.
        * in case of initial values
                  er_entityset = lr_entity.
                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.

       

  • Hi,

    if for any reason some of you take the miserable path like me and keep refreshing only the anno call, which fails with HTTP 400, then make sure to reload the whole app instead. Due to caching only that way will there be a reload of model metadata and the changes of reg_vocan be visible. Even if you keep editing your model and cleaning up the model cache!

    I have already tried addin the redefinition service to reg_vocan but due to caching thought that it does not help. After hours spent debugging I have realized that the above listed way which I have taken too is the right way - just the stupid caching-and-generating-table-entry-based-on-another-entry situation tricked me.

  • Hi Manikandan Rajasekaran

     

    I just followed the same steps as described in your blog, when creating the WebIDE project the annotitaion model of the original service was found, but wen opening the annotation file in my app the external annotations are not shown.

    Do you have any idea?

     

    Thanks!