Sending Data from SAP to the Local Database Data Source (Data Push from SAP)

In this article:

Preparing Project in Foresight Mobile Platform

Step 1. Add the Local Database Data Source

Step 2. Add a Group of Users

Step 3. Add an API User

Executing Procedures in SAP Data Source

It is required to quickly send data from SAP to Foresight Mobile Platform, use ABAP procedures that allow for incremental data loading via API servers of mobile platform:

NOTE. The second procedure can be executed only if the user token obtained after the first procedure execution is used.

To send data from SAP to Foresight Mobile Platform:

  1. Prepare a project in Foresight Mobile Platform. When the project is prepared, a resource is created for the Local Database data source and the new API user is added. After being authenticated on a mobile platform server, the user can address the created resource via server API.

  2. Execute procedures in SAP data source. When procedures are executed, data is sent incrementally from SAP to Foresight Mobile Platform.

NOTE. By default, the SOAP/XML protocol is used to send data from SAP, but the JSON data sending format is used on executing procedures. Data is converted to the required format in ABAP procedures and does not require additional actions.

After executing the operation the project is prepared in Foresight Mobile Platform and procedures are executed in the SAP system. The Local Database data source of the prepared project contains the data sent from SAP.

Preparing Project in Foresight Mobile Platform

Before project preparation:

  1. Go to the Environments section and add a new environment.

  2. Add a project in the new environment.

After executing the operations a new project is added for further preparation.

Step 1. Add the Local Database Data Source

To add the Local Database data source:

  1. Open the new project.

  2. Add the Local Database data source using the drop-down menu of the Add Data Source button.

After adding the data source click the Create Resource button. The resource import options open:

Set the parameters:

NOTE. On resource import, the value in the Mobile Client Name field must match with the repository identifier.

IMPORTANT. When setting resource name it is forbidden to use some PostgreSQL keywords. For details about forbidden keywords see the PostgreSQL documentation. On an attempt to use forbidden keywords in the resource name, the error message is displayed.

NOTE. Caching settings are available only for scalar input parameters of resource.

  1. Click the Import button.

After executing the operations the Local Database data source is added to the project data sources list.

Step 2. Add a Group of Users

To add a group of users:

  1. Go to the Groups of Users subsection and add a new group:

Set the parameters:

  1. Click the Add button.

After executing the operations the new group of users is added to the project groups list.

Step 3. Add an API User

To add an API user:

  1. Go to the API Users section and add a new user:

Set the parameters:

  1. Click the Save button.

After executing the operations the new API user is added who is included in the added group.

Executing Procedures in SAP Data Source

Data is sent from SAP by means of procedures in the SAP system:

  1. Execute the first procedure to authenticate on a mobile platform server and get user token:

FUNCTION zfmp_get_token.
  CONSTANTS: BEGIN OF lc_form_field,
               username    TYPE string VALUE 'username',
               environment TYPE string VALUE 'environment',
               password    TYPE string VALUE 'password',
               project     TYPE string VALUE 'project',
             END OF lc_form_field,
             lc_http         TYPE string VALUE '200',
             lv_content_type TYPE string VALUE 'application/x-www-form-urlencoded'.
  DATA:
    lo_client TYPE REF TO if_http_client,
    lv_data   TYPE string,
    ls_data   TYPE zfmp_token,
    lv_mess   TYPE string.
  cl_http_client=>create(
    EXPORTING
      host               = host_server
    IMPORTING
      client             = lo_client
    EXCEPTIONS
      argument_not_found = 1
      internal_error     = 2
      plugin_not_active  = 3
      OTHERS             = 4 ).
  IF sy-subrc <> 0.
    CASE sy-subrc.
      WHEN 1.
        lv_mess = text-002.
      WHEN 2.
        lv_mess = text-003.
      WHEN 3.
        lv_mess = text-004.
      WHEN 4.
        lv_mess = text-005.
    ENDCASE.
    MESSAGE s208(00) WITH lv_mess DISPLAY LIKE rs_c_error.
    EXIT.
  ENDIF.
  cl_http_utility=>set_request_uri( request = lo_client->request uri = api_server ).
  lo_client->request->set_method( if_http_request=>co_request_method_post ).
  lo_client->request->set_content_type( lv_content_type ).
  lo_client->request->set_form_field( name = lc_form_field-environment value = environment ).
  lo_client->request->set_form_field( name = lc_form_field-username    value = username ).
  lo_client->request->set_form_field( name = lc_form_field-password    value = password ).
  lo_client->request->set_form_field( name = lc_form_field-project     value = project ).
  lo_client->send(
      EXCEPTIONS
      http_communication_failure = 1
      http_invalid_state         = 2
      http_processing_failed     = 3
      OTHERS                     = 4 ).
  IF sy-subrc <> 0.
    CASE sy-subrc.
      WHEN 1.
        lv_mess = text-006.
      WHEN 2.
        lv_mess = text-007.
      WHEN 3.
        lv_mess = text-008.
      WHEN 4.
        lv_mess = text-009.
    ENDCASE.
    MESSAGE s208(00) WITH lv_mess DISPLAY LIKE rs_c_error.
    EXIT.
  ENDIF.
  lo_client->receive(
   EXCEPTIONS
      http_communication_failure = 1
      http_invalid_state         = 2
      http_processing_failed     = 3
      OTHERS                     = 4 ).
  IF sy-subrc <> 0.
    CASE sy-subrc.
      WHEN 1.
        lv_mess = text-006.
      WHEN 2.
        lv_mess = text-007.
      WHEN 3.
        lv_mess = text-008.
      WHEN 4.
        lv_mess = text-009.
    ENDCASE.
    MESSAGE s208(00) WITH lv_mess DISPLAY LIKE rs_c_error.
    EXIT.
  ENDIF.
  lv_data = lo_client->response->get_cdata( ).
  lo_client->response->get_status( IMPORTING code = DATA(http_rc) ).
  IF http_rc <> lc_http.
    MESSAGE s368(00) WITH text-001 http_rc DISPLAY LIKE rs_c_error.
    EXIT.
  ELSE.
    /ui2/cl_json=>deserialize(
             EXPORTING
                json        = lv_data
                pretty_name = /ui2/cl_json=>pretty_mode-camel_case
            CHANGING
                data        = ls_data ).
    IF ls_data-token IS NOT INITIAL.
      ls_data-username = username.
      MODIFY zfmp_token FROM ls_data.
    ELSE.
      MESSAGE s208(00) WITH text-010 http_rc DISPLAY LIKE rs_c_error .
      EXIT.
    ENDIF.
  ENDIF.
  lo_client->close( ).
ENDFUNCTION.

When the first procedure is executed, an API authentication request is sent to a mobile platform server. After executing the procedure the user token is obtained and saved.

  1. Separate the obtained user token in two parts to substitute to the second procedure.

NOTE. Separation of user token is required to meet the requirements of SAP graphic editor. The first part of the token must not be longer than 207 characters.

  1. Prepare the second procedure for execution. Set values instead of the following substitutes in the procedure code:

REPORT zmar_test.
PERFORM use_fmp.
FORM use_fmp.
  CONSTANTS:
    *Set IP address or DNS server name of mobile platform and resource name of the Local Database data source
    lc_host       TYPE string VALUE '<IP address or DNS name of a mobile platform server>',
    lc_url        TYPE string VALUE '/api/v1/rpc/<resource name>/',
    *Insert the right part of the token to the lc_token_1 variable after the Bearer value, assign the second part of the token
    *to the lc_token_2 variable
    lc_token_1    TYPE string VALUE 'Bearer <first part of token>',
    lc_token_2    TYPE string VALUE '<second part of token>',
    lc_auth       TYPE string VALUE 'Authorization',
    lc_content    TYPE string VALUE 'Content-Type',
    lc_json       TYPE string VALUE 'application/json',
    lc_data_start TYPE string VALUE '{"delete_ids":null,"upsert_rows":[',
    lc_number     TYPE i      VALUE 100,
    lc_count      TYPE int4   VALUE 10.
  DATA:
    lt_data       TYPE STANDARD TABLE OF string,
    lo_client     TYPE REF TO if_http_client,
    lv_data       TYPE string,
    lv_token      TYPE string,
    lv_value      TYPE string,
    lv_text       TYPE string,
    lv_check      TYPE i,
    lv_number     TYPE i,
    lv_size       TYPE i,
    lv_time_1     TYPE timestampl,
    lv_time_2     TYPE timestampl,
    lv_mess       TYPE string,
    lv_result     TYPE timestampl,
    lv_time_rec_1 TYPE timestampl,
    lv_time_rec_2 TYPE timestampl.
  cl_http_client=>create(
     EXPORTING
       host               = lc_host
     IMPORTING
       client             = lo_client
     EXCEPTIONS
       argument_not_found = 1
       internal_error     = 2
       plugin_not_active  = 3
       OTHERS             = 4 ).
  IF sy-subrc <> 0.
    CASE sy-subrc.
      WHEN 1.
        lv_mess = text-002.
      WHEN 2.
        lv_mess = text-003.
      WHEN 3.
        lv_mess = text-004.
      WHEN 4.
        lv_mess = text-005.
    ENDCASE.
    MESSAGE s208(00) WITH lv_mess DISPLAY LIKE rs_c_error.
    LEAVE LIST-PROCESSING.
  ENDIF.
  WRITE: 'Number of rows: ', lc_count.
  SKIP.
  lv_token = lc_token_1 && lc_token_2.
  cl_http_utility=>set_request_uri( request = lo_client->request uri = lc_url ).
  lo_client->request->set_method( if_http_request=>co_request_method_post ).
  lo_client->request->set_header_field(
      EXPORTING
        name  = lc_auth
        value = lv_token  ).
  lo_client->request->set_header_field(
    EXPORTING
      name  = lc_content
      value = lc_json ).
  GET TIME STAMP FIELD lv_time_1.
  DO lc_count TIMES.
    CALL FUNCTION 'NUMBER_GET_NEXT'
      EXPORTING
        nr_range_nr = '1'
        object      = 'ZRO_PUSH_F'
      IMPORTING
        number      = lv_number.
    CALL FUNCTION 'GENERAL_GET_RANDOM_STRING'
      EXPORTING
        number_chars  = lc_number
      IMPORTING
        random_string = lv_text.
    lv_value = lv_value && '[' && lv_number && ',"' && lv_text && '"]'.
    CHECK sy-index < lc_count.
    lv_value = lv_value && ','.
  ENDDO.
  lv_value = lc_data_start && lv_value && ']}'.
  cl_soap_moni_helper=>convert_string_to_xstring(
    EXPORTING
      i_string = lv_value
    IMPORTING
      e_xstring = DATA(lv_value_new)
      e_length  = lv_size ).
  lo_client->request->set_data( lv_value_new ).
  lo_client->send(
      EXCEPTIONS
      http_communication_failure = 1
      http_invalid_state         = 2
      http_processing_failed     = 3
      OTHERS                     = 4 ).
  IF sy-subrc <> 0.
    CASE sy-subrc.
      WHEN 1.
        lv_mess = text-006.
      WHEN 2.
        lv_mess = text-007.
      WHEN 3.
        lv_mess = text-008.
      WHEN 4.
        lv_mess = text-009.
    ENDCASE.
    MESSAGE s208(00) WITH lv_mess DISPLAY LIKE rs_c_error.
    EXIT.
  ENDIF.
  GET TIME STAMP FIELD lv_time_rec_1.
  lo_client->receive(
   EXCEPTIONS
      http_communication_failure = 1
      http_invalid_state         = 2
      http_processing_failed     = 3
      OTHERS                     = 4 ).
  IF sy-subrc <> 0.
    CASE sy-subrc.
      WHEN 1.
        lv_mess = text-006.
      WHEN 2.
        lv_mess = text-007.
      WHEN 3.
        lv_mess = text-008.
      WHEN 4.
        lv_mess = text-009.
    ENDCASE.
    MESSAGE s208(00) WITH lv_mess DISPLAY LIKE rs_c_error.
    EXIT.
  ENDIF.
  GET TIME STAMP FIELD lv_time_rec_2.
  lv_result = lv_time_rec_1 - lv_time_rec_2.
  SKIP.
  WRITE: 'Execute time of recieve (get response ' ,lc_host , '):', lv_result.
  GET TIME STAMP FIELD lv_time_2.
  lv_result = lv_time_1 - lv_time_2.
  SKIP.
  WRITE: 'Program execution time without outputting txt and displaying result: ' , lv_result.
  CLEAR: lv_result,lv_time_2.
  lv_data = lo_client->response->get_cdata( ).
  WRITE lv_data.                              
  lo_client->response->get_status( IMPORTING code = DATA(http_rc) ).
  SKIP.
  WRITE: http response: ' , http_rc.
  APPEND lv_data TO lt_data.
  GET TIME STAMP FIELD lv_time_2.
  lv_result = lv_time_1 - lv_time_2.
  SKIP.
  WRITE: 'Program execution time without outputting txt: ' , lv_result.
  CLEAR: lv_result,lv_time_2.
  lo_client->close( ).
  GET TIME STAMP FIELD lv_time_2.
  lv_result = lv_time_1 - lv_time_2.
  SKIP.
  WRITE: 'Program execution time: ' , lv_result.
ENDFORM.
  1. Execute the second procedure to send data from SAP to the Local Database data source of the prepared project in Foresight Mobile Platform. When the second procedure is executed, sending of data to a mobile platform server is initiated via API request.

NOTE. The Local Database data source is by default a PostgreSQL database. When the Local Database data source is added, an external API is created on a mobile platform server, which is used to manage data in the source.

After executing the operations the Local Database data source will contain the data sent from SAP.

See also:

Knowledge Base