Thursday 28 July 2016

How to Consume HANA XS Odata in ECC

Introduction:


In this blog we will discuss how can we consume HANA XS-Odata services in ECC system. In this scenario we will set up an RFC connection between HANA and ECC system and the XS Odata services can be consumed. The data coming from the XS-Odata services can be populated in an internal table for further processing.

Prerequisites:

  • This scenario has to be implemented in ECC system.
  • An RFC connection should exist between HANA and ECC.

Let’s us discuss the steps in detail in order to consume the HANA XS-Odata services.

Step-1: Create an RFC destination in ECC.


In order to connect to HANA server we have to create an RFC connection of type “G”. We need to maintain the below parameters for setting up the connection.
  1. RFC Destination: Provide RFC destination name.
  2. Connection Type: G (HTTP Connection to External Serv)
  3. Description: Provide the description for the connection.
How to Consume HANA XS Odata in ECC

In the Technical setting tab, provide the below details.
  1. Target Host: IP address of the target system.
  2. Service No.: Port number.
  3. Path Prefix: Provide “/”.
How to Consume HANA XS Odata in ECC

In the Logon & Security tab, provide the below details.
1. Select the Basic authentication option under Logon with user and provide the user id and password.

How to Consume HANA XS Odata in ECC

Step-2: Create Function module to consume HANA XS-Odata service.


In this step we will create a function module to consume the XS-Odata service. First of all we need to setup a connection by using the RFC destination created in the previous step. Next, we have to call the desired service (XS-Odata service) which we want to consume in ECC. The HTTP client will send a request and receive call and if the connection does not work out then it will throw an exception.

  DATA: lo_http_client   TYPE REF TO if_http_client,
lv_service            TYPE string,
lv_result             TYPE string,
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_tkt_status_element TYPE REF TO if_ixml_element,
lo_tkt_status_nodes   TYPE REF TO if_ixml_node_list,
lif_ixml_node_iterator TYPE REF TO if_ixml_node_iterator,
lif_ixml_node_iterator1 TYPE REF TO if_ixml_node_iterator,
lv_value              TYPE string.
  DATA: lif_ixml_node_list TYPE REF TO if_ixml_node_list ,
lif_ixml_node_list2 TYPE REF TO if_ixml_node_list ,
lif_ixml_node_list3 TYPE REF TO if_ixml_node_list ,
lif_ixml_node1 TYPE REF TO if_ixml_node ,
lif_ixml_node2 TYPE REF TO if_ixml_node ,
lif_ixml_node_list1 TYPE REF TO if_ixml_node_list ,
lif_ixml_node TYPE REF TO if_ixml_node,
node          TYPE REF TO if_ixml_node.

cl_http_client=>create_by_destination(
EXPORTING
destination              = '<RFC Destination Name>'       
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 ).

lv_service = 'http://<URL>:<PORT>/<Service Namespace>/<Service Name>/<View Name>'

cl_http_utility=>set_request_uri( request = lo_http_client->request uri = lv_service ).

lo_http_client->send(
EXCEPTIONS
http_communication_failure = 1
http_invalid_state         = 2 ).

lo_http_client->receive(
EXCEPTIONS
http_communication_failure = 1
http_invalid_state         = 2
http_processing_failed     = 3 ).

Next we have to prepare the XML data which is coming from the service output.
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 ).

Now we have the XML output of the XS-Odata. We need to process each “entry” node in the XML document to collect the data. This will be a recursive approach as we will have several “entry” node in the XML document. In this example I have set a pointer to the very first node in the XML document and then followed a recursive approach to process each “entry” node in the document. Inside “entry” node we have “content” node which contains all the properties defined in the service model. Let’s process the XML document to get the values of each properties.

lif_ixml_node = lo_document->find_from_name( name = 'feed' ).
lif_ixml_node_list = lif_ixml_node->get_children( ).
lif_ixml_node_iterator = lif_ixml_node_list->create_iterator( ).

WHILE NOT lif_ixml_node IS INITIAL.
lv_name = lif_ixml_node->get_name( ).
IF lif_ixml_node->get_name( ) = 'entry'.
lif_ixml_node1 = lif_ixml_node->get_first_child( ).
lif_ixml_node_list1 = lif_ixml_node->get_children( ).
lif_ixml_node_iterator1 = lif_ixml_node_list1->create_iterator( ).
"To Process Entry node in the document
      WHILE NOT lif_ixml_node1 IS INITIAL.
           lv_name1 = lif_ixml_node1->get_name( ).
           IF lif_ixml_node1->get_name( ) = 'content'.
           lif_ixml_node2 = lif_ixml_node1->get_first_child( ).
           lif_ixml_node_list2 = lif_ixml_node1->get_children( ).
           lif_ixml_node_iterator2 = lif_ixml_node_list2->create_iterator( ).
           "To Process Properties node in the document
           WHILE NOT lif_ixml_node2 IS INITIAL.
                lv_name2 = lif_ixml_node2->get_name( ).
                IF lif_ixml_node2->get_name( ) = 'properties'.
                node = lif_ixml_node2->get_first_child( ).
                lif_ixml_node_list3 = node->get_children( ).
                "To Process each node under properties node in the document
                WHILE NOT node IS INITIAL.
                     lv_name3 = node->get_name( ).
                     lv_value = node->get_value( ).
                     node = node->get_next( ).
                ENDWHILE.
                lif_ixml_node2 = lif_ixml_node2->get_next( ).
           ENDWHILE.
           ENDIF.
           lif_ixml_node1 = lif_ixml_node_iterator1->get_next( ).
      ENDWHILE. 
      ENDIF.
      lif_ixml_node = lif_ixml_node_iterator->get_next( ).
ENDWHILE.

This code will help to consume HANA XS-Odata services in ECC and we can populate the data in ABAP structure.

Source: scn.sap.com

No comments:

Post a Comment