Introduction

With the introduction of Blockchain in SAP Cloud Platform, the important questions for SAP developers was its implementation in SAP ABAP. All the client information of SAP is mainly on premise based. The major amount of data is already stored in backend system and if we cannot push this data on blockchain then the Blockchain on SAP Cloud Platform is of no use. In this article we will explain the Blockchain Implementation in ABAP.

Blockchain on SAP Cloud Platform

In our previous articles we have already explained the blockchain services (mainly Hyperledger, Multichain and Quorum) on SAP Cloud Platform. These instances are connected with SAP Blockchain enablement services, which acts as an interface between these blockchain services and other SAP services.

Blockchain Implementation in ABAP

We can easily understand the blockchain implementation in ABAP using the given block diagram:

Blockchain Implementation in ABAP

In the diagram above, you can see that the SAP ABAP interacts with Blockchain Enablement services and the HANA Database. This application can be either displayed using Classical ABAP Report or using Fiori Application which will then use OData to interact with SAP ABAP methods.

To call any service in SAP Cloud platform, we need to do the following:

  1. Get Token from the service using a read call.
  2. Perform CRUD operation on the service using the token received above.

Let us understand these steps with respect to the blockchain services.

Get Token from the Blockchain Service

In this step we will call the service to get the token and store that token in a global variable for later use.

METHOD get_token.
    DATA: lo_http_client TYPE REF TO if_http_client.
    DATA: response TYPE string,
          lv_url   TYPE string.
    CONSTANTS: lv_initial_url TYPE string VALUE '<Blockchain Service Link>',
               lv_auth        TYPE string VALUE 'Basic <your login credentials>'.


    "create HTTP client by url
    CALL METHOD cl_http_client=>create_by_url
      EXPORTING
        url                = lv_initial_url
      IMPORTING
        client             = lo_http_client
      EXCEPTIONS
        argument_not_found = 1
        plugin_not_active  = 2
        internal_error     = 3
        OTHERS             = 4.

    "Available API Endpoints
    "https://blockchain-service.cfapps.sap.hana.ondemand.com/blockchain/proofOfHistory/api/v1
    "https://blockchain-service.cfapps.eu10.hana.ondemand.com/blockchain/proofOfHistory/api/v1
    "https://blockchain-service.cfapps.us10.hana.ondemand.com/blockchain/proofOfHistory/api/v1

    IF sy-subrc <> 0.
      "error handling
    ENDIF.

    "setting request method
    lo_http_client->request->set_method('GET').

    "adding headers
    lo_http_client->request->set_header_field( name = 'Authorization' value = lv_auth ).


    "Available Security Schemes for productive API Endpoints
    "OAuth 2.0

    CALL METHOD lo_http_client->send
      EXCEPTIONS
        http_communication_failure = 1
        http_invalid_state         = 2
        http_processing_failed     = 3
        http_invalid_timeout       = 4
        OTHERS                     = 5.

    IF sy-subrc = 0.
      CALL METHOD lo_http_client->receive
        EXCEPTIONS
          http_communication_failure = 1
          http_invalid_state         = 2
          http_processing_failed     = 3
          OTHERS                     = 5.
    ENDIF.

    IF sy-subrc <> 0.
      "error handling
    ENDIF.

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

   GV_TOKEN = response. "Global Variable
  ENDMETHOD.

 

Get Proof history from the Blockchain Service

In this step we will call the blockchain service again using the token that we have stored in above step. And then we will receive the history of transactions from blockchain.

METHOD get_proof_history.
    DATA: lo_http_client TYPE REF TO if_http_client.
    DATA: response TYPE string,
          lv_url   TYPE string,
          lv_auth  TYPE string,
          lv_auth2 TYPE string.

    CONSTANTS : lv_initial_url TYPE string VALUE '<Your Service>'.

    IF iv_object_id IS NOT INITIAL.

*** Getting Token
      TYPES:
        BEGIN OF t_entry,
          access_token TYPE string,
          token_type   TYPE string,
          expires_in   TYPE n LENGTH 8,
          scope        TYPE string,
          jti          TYPE string,
        END OF t_entry .
      TYPES:
        t_entry_map TYPE SORTED TABLE OF t_entry WITH UNIQUE KEY access_token.
      DATA: m_entries TYPE t_entry.

      DATA: lr_instance  TYPE REF TO  /ui5/cl_json_parser.
      CREATE OBJECT lr_instance.
      CALL METHOD me->get_token.
      IF gv_token IS NOT INITIAL.

*        data: itab TYPE TABLE OF string.
*        data: access_tok type string.
*        SPLIT gv_token at '"' INTO TABLE itab.
*        try.
*            lv_auth2 = itab[ 4 ].
*          catch cx_sy_itab_line_not_found.
*        ENDTRY.

        /ui2/cl_json=>deserialize(
        EXPORTING json = gv_token pretty_name = /ui2/cl_json=>pretty_mode-camel_case CHANGING data = m_entries ).
        lv_auth2 = m_entries-access_token.
        gv_token = gv_token+17.

        CONCATENATE 'Bearer' lv_auth2 INTO lv_auth SEPARATED BY space.

      ENDIF.
      DATA lv_object_id TYPE string.
      lv_object_id = iv_object_id.
      TRANSLATE lv_object_id TO LOWER CASE.

      CONCATENATE lv_initial_url lv_object_id INTO lv_url. "Appending Fix URL and the Object ID to get the Request URL

      "create HTTP client by url
      CALL METHOD cl_http_client=>create_by_url
        EXPORTING
          url                = lv_url
        IMPORTING
          client             = lo_http_client
        EXCEPTIONS
          argument_not_found = 1
          plugin_not_active  = 2
          internal_error     = 3
          OTHERS             = 4.

      "Available API Endpoints
      "https://blockchain-service.cfapps.sap.hana.ondemand.com/blockchain/proofOfHistory/api/v1
      "https://blockchain-service.cfapps.eu10.hana.ondemand.com/blockchain/proofOfHistory/api/v1
      "https://blockchain-service.cfapps.us10.hana.ondemand.com/blockchain/proofOfHistory/api/v1

      IF sy-subrc <> 0.
        "error handling
      ENDIF.

      "setting request method
      lo_http_client->request->set_method('GET').

      "creatung Auth value
*       lv_auth2 = 'Basic <Your Login Credentials>'.

      "adding headers
*      lo_http_client->request->set_header_field( name = 'Content-Type' value = 'application/x-www-form-urlencoded' ).
      lo_http_client->request->set_header_field( name = 'Accept' value = 'application/json' ).
      lo_http_client->request->set_header_field( name = 'Authorization' value = lv_auth ).
*      lo_http_client->request->set_header_field( name = 'APIKey' value = 'zBoCpDtkaT9jexRjtMk0J98Rs8izmQi1' ).


      "Available Security Schemes for productive API Endpoints
      "OAuth 2.0

      CALL METHOD lo_http_client->send
        EXCEPTIONS
          http_communication_failure = 1
          http_invalid_state         = 2
          http_processing_failed     = 3
          http_invalid_timeout       = 4
          OTHERS                     = 5.

      IF sy-subrc = 0.
        CALL METHOD lo_http_client->receive
          EXCEPTIONS
            http_communication_failure = 1
            http_invalid_state         = 2
            http_processing_failed     = 3
            OTHERS                     = 5.
      ENDIF.

      IF sy-subrc = 1.
        "error handling
        ev_response = 'http_communication_failure'.
      ELSEIF sy-subrc = 2.
        ev_response = 'http_invalid_state'.
      ELSEIF sy-subrc = 3.
        ev_response = 'http_processing_failed'.
      ELSEIF sy-subrc = 0.
        response = lo_http_client->response->get_cdata( ).
*WRITE: 'response: ', response.
        ev_response = response.
      ELSE.
        ev_response = 'Unknown Error'.
      ENDIF.
    ENDIF.
  ENDMETHOD.

 

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Translate »