Skip to Content
Author's profile photo Vamsi Krishna C V

Consume Odata Service in ABAP CL_HTTP_CLIENT->CREATE_BY_DESTINATION

This blog would have not been possible, but for the awesome community that is SCN. I would like to thank every contributor ever for helping me out in my hours of need!.

I had tremendous help in navigating through my current requirement thanks to the below blog posts.

How to consume an OData service using OData Services Consumption and Integration (OSCI)

Thank you. Andre Fischer

Consuming an External RESTful Web Service with ABAP in Gateway

And Paul J. Modderman

both these blogs helped me understand the intricacies of the functionality that is Consuming an OData Service.

this Blog can be considered as an extension of the Blog by Paul J. Modderman.

we can consume a data service by using the method CREATE_BY_URL of the class CL_HTTP_CLIENT, but when authentication is involved this method was ill suited for it.

The CREATE_BY_DESTINATION method however enables us to store the Credentials in a more standard and secured fashion.

The Requirement:-

I needed to access an OData service that was exposed by HANA . It is required that we trigger this service from the ECC system and process the result.

The user would be logging in to ECC directly and not via portal, thus it would require the use of an RFC destination Login Credentials.

The Process:-

Step 1.

we have to create the RFC connection in SM59 as below.

  1. Go to TCode SM59
  2. Click on the create new connection button.
  3. Provide the description
  4. Choose the connection type as G.
  5. enter the Host name/port number(an Odata Service generally has a URL containing “.COM” followed by “:” Port Number)
    1. The  part until the “.com” without the HTTP:// is the host name
    2. The part after the “:” is the port number
  6. Enter any proxy details if a proxy is being used(we were not in my case)
  7. go to the Logon & Security tab
    1. CHoose the Basic Authentication Radio Button.
    2. Enter the logon credentials
  8. Save and click on connection test.
  9. If all setting are proper you should be able to see a webapage that is relevant to the Host you entered, in the Response Body/Response Text tabs.

Step2.

Now that we have created the RFC connection we proceed to the creation of the HTTP client .

to create the client we use the attached  code. CL_HTTP_CLIENT.txt.

DATA:   lo_http_client TYPE REF TO if_http_client,

        lv_service TYPE string,

        lv_result TYPE string.

“xml variables

DATA:    lo_ixml TYPE REF TO if_ixml,

        lo_streamfactory TYPE REF TO if_ixml_stream_factory,

        lo_istream TYPE REF TO if_ixml_istream,

        lo_document TYPE REF TO if_ixml_document,

        lo_parser TYPE REF TO if_ixml_parser,

        lo_weather_element TYPE REF TO if_ixml_element,

        lo_weather_nodes TYPE REF TO if_ixml_node_list,

        lo_curr_node TYPE REF TO if_ixml_node,

        lv_value TYPE string,

        lv_node_length TYPE i,

        lv_node_index TYPE i,

        lv_node_name TYPE string,

        lv_node_value TYPE string.

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

* lv_ destination will be name of the RFC destination we created in SM59

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

CALL METHOD cl_http_client=>create_by_destination

  EXPORTING

    destination              = lv_destination

  IMPORTING

    client                   = lo_http_client

  EXCEPTIONS

    argument_not_found       = 1

    destination_not_found    = 2

    destination_no_authority = 3

    plugin_not_active        = 4

    internal_error           = 5

    OTHERS                   = 6.

IF sy-subrc <> 0.

* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

*            WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

ENDIF.

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

* we need to build the URI, this is the part in the OData Service that comes after the port number

* This includes the Path and Query string for the service that is being called on the host.

* lv_uri holds the path and query string

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

CALL METHOD cl_http_utility=>set_request_uri

  EXPORTING

    request = lo_http_client->request

    uri     = lv_uri.

lo_http_client->receive(

  EXCEPTIONS

    http_communication_failure = 1

    http_invalid_state         = 2

    http_processing_failed     = 3 ).

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

* Making sense of the result parsing the XML

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

lv_result = lo_http_client->response->get_cdata( ).

lo_ixml = cl_ixml=>create( ).

lo_streamfactory = lo_ixml->create_stream_factory( ).

lo_istream = lo_streamfactory->create_istream_string(

                                 lv_result ).

lo_document = lo_ixml->create_document( ).

lo_parser = lo_ixml->create_parser(

                       stream_factory = lo_streamfactory

                       istream        = lo_istream

                       document       = lo_document ).

“This actually makes the XML document navigable

lo_parser->parse( ).

DATA: lv_name TYPE string.

“Navigate XML to nodes we want to process

*lo_weather_element = lo_document->get_root_element( ).

lv_name = ‘content’.

lo_weather_element = lo_document->find_from_name( lv_name ).

lo_weather_nodes = lo_weather_element->get_children( ).

“Move through the nodes and assign appropriate values to export

lv_node_length = lo_weather_nodes->get_length( ).

lv_node_index = 0.

WHILE lv_node_index < lv_node_length.

  lo_curr_node = lo_weather_nodes->get_item( lv_node_index ).

  lv_node_name = lo_curr_node->get_name( ).

  lv_node_value = lo_curr_node->get_value( ).

  ADD 1 TO lv_node_index.

ENDWHILE.



Hope this Helps!, let me know if i can clarify further.


Peace!!!!

Assigned Tags

      30 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Tudor Riscutia
      Tudor Riscutia

      Hi Vamsi,

      Why not use the existing Gateway classes for OSCI integration?

      You can call:

      /iwfnd/cl_sutil_client_proxy=>get_instance( )->web_request(

               EXPORTING

                 it_request_header = VALUE /iwfnd/sutil_property_t(

                   (

                     name  = if_http_header_fields_sap=>request_method

                     value = if_http_entity=>co_request_method_get

                   ) (

                     name  = if_http_header_fields_sap=>request_uri

                     value = |{ mv_service_url }/{ iv_query }|

                   )

                 )

               IMPORTING

                 ev_status_code    = DATA(lv_status_code)

                 ev_response_body  = rv_xbody

                 ev_error_text     = DATA(lv_error_text)

             ).


      To get the content, and then:


      /iwfnd/cl_sutil_odata_mapper=>get_instance( )->convert_to_abap(

             EXPORTING

               iv_xdoc       = http_get( |{ iv_entityset_name }| )

             IMPORTING

               ed_data       = et_data

               ev_error_text = DATA(lv_error_text) ).


      To convert directly to the appropriate ABAP type (this also works with ComplexTypes).

      But why do you want to consume an OData service in ABAP?

      BR,

      Tudor

      Author's profile photo Vamsi Krishna C V
      Vamsi Krishna C V
      Blog Post Author

      Hi Tudor,

      i am calling the HANA service from ECC.

      In our landscape, the Gateway and ECC are different systems.

      and the Class that you mentioned is only available in the gateway system.

      that is why I am using the CL_HTTP_CLIENT class.

      Many thanks,

      Vamsi

      Author's profile photo Amol Samte
      Amol Samte

      Hi Vamsi,

      Quick question and clarification required.

      You mean i can consume odata service URL generated from HANA DB in ECC or BI System ?

      -Amol S

      Author's profile photo Vamsi Krishna C V
      Vamsi Krishna C V
      Blog Post Author

      Hi Amol,

      Yes, it is possible. I am not sure if we can do it from BI, because i have no experience in that area. but from ECC ABAP definitely yes.

      We are basically instantiating an HTTP Client  and triggering the services.

      Kind Regards,

      Vamsi

      Author's profile photo Vladimir Lutsas
      Vladimir Lutsas

      Hi Tudor. Is web_request should be used only to simulate request? If no - how propertytype_logon_popup can be avoided?

      Author's profile photo Manoj Mohanty
      Manoj Mohanty

      Hi Tudor

      How can token details be passed along with other client info at the time of the call, using the /iwfnd/cl_sutil_client_proxy=>get_instance( )->web_request.

      Author's profile photo Tudor Riscutia
      Tudor Riscutia

      Hi Manoj,

      I haven't worked with this in a while, but as far as I can see in the method signtuare, you could use parameter IT_REQUEST_HEADER. Which kind of token are you using? I image something like

      ( name =  if_http_header_fields=>authorization value = |Bearer { <your_token> }| )

      Hope this helps!

      Author's profile photo Manoj Mohanty
      Manoj Mohanty

      Hi Tudor

      The details used below need to be passed when the service is requested in ABAP.

      Author's profile photo Tudor Riscutia
      Tudor Riscutia

      Hi Manoj,

      Yes, and each one of them corresponds to a header parameter. If you switch to the Headers tab in Postman you will see the technical names of the header fields as well.

      Author's profile photo Harikrishnan Panakkal
      Harikrishnan Panakkal

      I got an error when I use to access the way mentioned above(I tried both from Tudor and Vamsi). I have both Gateway and ECC in same system.

      HTTP Receive failed: SSL handshake with iotmmsXXXXXXtrial.hanatrial.ondemand.com:443 failed: SSSLERR_PEER_CERT_UNTRUSTED (-102)#The peer's X.509 Certificate (chain) is untrusted##SapSSLSessionStart()==SSSLERR_PEER_CERT_UNTRUSTED#  SSL:SSL_connnect() fail...

      -------------------

      Any idea what I am missing?

      Author's profile photo Vamsi Krishna C V
      Vamsi Krishna C V
      Blog Post Author

      Hi Harikrishnan,

      Your HTTP request is being rejected by the server you want to access. My basis team was able to help me out with this issue. a security certificate has to be downloaded from your target system and installed on the system from which you are trying to access the service using the transaction code STRUST

      Since the error message mentions x.509 certificates, i am assuming that you are not using a user Id based authentication.

      Try configuring your RFC connection using a User ID based authentication.

      I shall try to look into the certificate based error and get back to you in the meanwhile.

      Kind Regards,

      Vamsi

      Author's profile photo Harikrishnan Panakkal
      Harikrishnan Panakkal

      Getting same error even after changing to Basic Authentication with user/password 😐 .

      I am getting HTTP_INVALID_STATE exception while lo_http_client->receive().

      Author's profile photo Vamsi Krishna C V
      Vamsi Krishna C V
      Blog Post Author

      have you tested your RFC connection? is the connection test succesful from SM59?

      Author's profile photo Krishan Raheja
      Krishan Raheja

      Hi Vamsi,

      I am getting the same error as Invalid State with sy-subrc = 2 during call lo_http_client->receive .

      I checked my RFC connection and  it's status is OK.

       

      My requirement is to consume one OData service from one ERP system to another ERP system through ABAP.

       

      Author's profile photo Balbino Soares Ferreira Filho
      Balbino Soares Ferreira Filho

      Very good post. Congratulations!

      Author's profile photo Nigel James
      Nigel James

      Matt Harding I think you will like this blog 😉

      Author's profile photo Sudip Kumar Das
      Sudip Kumar Das

      Hello Vamsi

      Its really a nice post. I am trying the same with HCP. In HCP I have exposed a OData and trying to consume the OData from ABAP program.

      I was getting http_invalid_state exception from receive method.

      I have resolved it by adding Send method before the receive method call.

      Now I'm not getting any error , but not receiving any XML also.

      For the configuration part -

      My SM59 config is working fine and im getting the connection successful .

      Not sure about ICM configuration but our network team confirmed that there no block from firewall side.

      Could you please help me out to identify the probable problem.

      Thanks

      Sudip

      Author's profile photo Vamsi Krishna C V
      Vamsi Krishna C V
      Blog Post Author

      HI Sudip not sure if you are still facing the issue, but please let me know, if you can share your code here, i could help out.

      Kind Regards

      Vamsi

      Author's profile photo Former Member
      Former Member

      Hi Vamsi,

      While trying to create the RFC Destination I am getting below error. I want to create Destination for my OData created in HCP for Iot services. Please suggest how to create successful connection.

      Error - HTTPIO_PLG_CANCELED

      O Data service - 

      https://iotmmsXXXXXXXXtrial.hanatrial.ondemand.com/com.sap.iotservices.mms/v1/api/http/app.svc/

      Author's profile photo Vamsi Krishna C V
      Vamsi Krishna C V
      Blog Post Author

      Hi Yogendra,

      i am not sure how HCP is configured, my experience is limited to ABAP. do check with your BASIS team they might be able to help.

      Kind Regards,

      Vamsi

      Author's profile photo Phanipoorna Avula
      Phanipoorna Avula

      Hi Vamsi,

      Regarding connection type G, does the destination can be any Non-SAP system?

      Or it can be any SAP system?

      Any limitations for this destination?

      Regards

      Phani Poorna

      Author's profile photo Vamsi Krishna C V
      Vamsi Krishna C V
      Blog Post Author

      Hi Phani,

      In my case it as an SAP System. I created an RFC destination as we were required to access it from HANA.

      you can create an RFC destination to your external system. or rather you can use the "Create_by_url" method also.

      as shown here

      Consuming an External RESTful Web Service with ABAP in Gateway

      Kind Regards,

      Vamsi

      Author's profile photo Phanipoorna Avula
      Phanipoorna Avula

      Hi Vamsi,

      Thank you for the Info.

      I am not familiar with that method. But if we use create_by_url method, how to authenticate the service?

      Going forward if Single sign on is enabled then how it can help?

      Kindly help me out

      Regards

      Phani Poorna

      Author's profile photo Vamsi Krishna C V
      Vamsi Krishna C V
      Blog Post Author

      Hi Phani,

      Even with create_by_url you can pass the requisite username and password as parameters in the method.

      There are several methods in the class CL_HTTP_CLIENT that you can use for implementing "single sign on",  "X-CSRF token" handling etc.

      If you are implementing this  on the Gateway Hub System Directly, there are other classes that are more easier to use.

      These are referred to as OSCI.

      this blog by Andre Fischer details the approach using OSCI.

      How to consume an OData service using OData Services Consumption and Integration (OSCI)

      By  Andre Fischer

      Kind Regards,

      Vamsi

      Author's profile photo Sharif Gool
      Sharif Gool

      Good day Vamsi,

       

      I thank you for this informative post. Please keep em coming 🙂

       

      Will this blog still be relevant if I would like to POST data to the webservice?

       

      With kind regards,

      Sharif

      Author's profile photo Sankara Bhatta
      Sankara Bhatta

      HI,

       

      Thanks for the blog

      I am trying to use class CL_HTTP_CLIENT to trigger SAP cloud workflow from ABAP. I am able to get the CSRF token part successfully but the second POST call fails with HTTP 403 Forbidden error. where I am going wrong? I have posted the question already.

      https://answers.sap.com/questions/615947/trigger-scp-from-abap-program.html

      Author's profile photo ashish chanekar
      ashish chanekar

      Dear Vamsi,

       

      was referring to your link to call external Restful API in ABAP.

      1. if we call the API directly from an ABAP program with out the gateway service then is it possible to trace the logging of request and response parameters as we get it when we create an API in ABAP and call it via SICF service without the gateway.

      would appreciate your reply.

       

      Thanks,

      Ashish.

      Author's profile photo Vamsi Krishna C V
      Vamsi Krishna C V
      Blog Post Author

      All outgoing and incoming requests are always tracked through the ICM.

      You can use the SMICM transaction to check all traffic.

      there is no SICF involved here. we are doing it dynamically in our class.

      do correct me if you think otherwise.

      Author's profile photo Rachit Khanna
      Rachit Khanna

      HI Vamsi Krishna C V

      I referred the code in the blog , but for me when I am calling the HANA service in the result it returning error Service exception: [258] insufficient privilege , I checked the RFC connection and its fine , from the browser also I am able to see the metadata of the service but not via ABAP , request your help.

      (**--Get the response data
      DATA(l_result) = lo_http_client->response->get_cdata( ).

       

      I always get error below error

      <?xml version="1.0" encoding="utf-8" standalone="yes"?><error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><code/><message xml:lang="en-US">Service exception: [258] insufficient privilege</message></error>

      Author's profile photo Vamsi Krishna C V
      Vamsi Krishna C V
      Blog Post Author

      HI Rachit,

       

      Apologies for the late reply, but have you checked if you are actually able to see the response from your service, when you do all the settings mentioned in Step 1?

      If you are able to see the response in STEP1 then there should not be a problem when you are calling the service from your code.

       

      try checking to check the authorisations/credentials implemented on the service, i have used the basic authentication protocol here, that might not be the same protocol that is being used by your service.

      Insufficient privilege, just speculating here, it could be due to some security protocols that are implemented in the system.

      Kind regards,

      Vamsi