I have been not blogging for quite sometime and I was looking for some interesting use-case related to SAP Gateway which could be of some help to the community. Recently I have worked on SAP & External third party integration about which am going to share the technical know-how’s.
Let’s get started !
This is a step-by-step guide on how to call an external REST service from an SAP system using ABAP code. This documentation can be used as a reference for implementing calls from ABAP to any third party service which supports REST requests & JSON.The examples in this blog series have been implemented with SAP NetWeaver 7.50. However, the used ABAP classes exist with NetWeaver 7.3x onwards. Thus, the code can easily be adopted to suit for older SAP releases.
Before start coding in ABAP, we must execute the following preparation steps.
You need an SSL certificate for the external slack server which hosts REST services. The following steps demonstrate how you can export the appropriate certificate using Google Chrome.
1. Start Google Chrome and go to url https://slack.com/api/conversations.list
2. You will receive http status 403 – Forbidden unless your browser already has installed an appropriate certificate. Ignore the error.
3. Press F12 to start the developer tools.
4. Click on tab Security.
5. Click button View certificate.
6. In popup dialog click on tab Details.
7. Click button Copy to file in your local machine if you are using Windows.
8. Save base-64 encoded X.509 certificate as file extrestsap.cer which will be imported into SAP.
Let’s get started !
Background
This is a step-by-step guide on how to call an external REST service from an SAP system using ABAP code. This documentation can be used as a reference for implementing calls from ABAP to any third party service which supports REST requests & JSON.The examples in this blog series have been implemented with SAP NetWeaver 7.50. However, the used ABAP classes exist with NetWeaver 7.3x onwards. Thus, the code can easily be adopted to suit for older SAP releases.
Preparations
Before start coding in ABAP, we must execute the following preparation steps.
Export the SSL Certificate from the browser
You need an SSL certificate for the external slack server which hosts REST services. The following steps demonstrate how you can export the appropriate certificate using Google Chrome.
1. Start Google Chrome and go to url https://slack.com/api/conversations.list
2. You will receive http status 403 – Forbidden unless your browser already has installed an appropriate certificate. Ignore the error.
3. Press F12 to start the developer tools.
4. Click on tab Security.
5. Click button View certificate.
6. In popup dialog click on tab Details.
7. Click button Copy to file in your local machine if you are using Windows.
8. Save base-64 encoded X.509 certificate as file extrestsap.cer which will be imported into SAP.
Install Certificate in the SAP System
Proceed as follows to install the exported SSL certificate in your SAP system.
1. In SAP, call transaction STRUST.
2. Switch to edit mode (press according tool bar icon).
3. If a local PSE file does not exist already, create it by right-clicking on SSL client SSL Client (Standard) and selecting Create from context menu. Keep all default settings in next popup dialog.
4. In Certificate section, click Import (alternatively select menu item Certificate → Import). Choose file extrestsap.cer and import the certificate.
5. Add to certificate list and click save as shown below.
Maintain RFC Destination in SAP
We have to create a RFC destination of type G with the following technical settings:
Target Host: https://slack.com/api/conversations.list
In our example this RFC destination is called ODATAORG.
Please note that you might have to configure a proxy server if you are in corporate network where access to external sites and web services are restricted by firewall due to security reasons.
Maintain the destination details based on your requirements. Below screenshot is for demo purpose only.
Configuration of TLS / SSL parameters in SAP
TLS (Transport Layer Security) is used to secure communication between your application program in SAP which acts as a consumer proxy and the REST API to which we are interfacing with.
There are scenarios where the hosted REST services in the external server support different version of TLS like 1.0 / 1.1 / 1.2. Ensure the required TLS / SSL configurations are enabled in SAP to connect with the REST api. Unless otherwise you may be not able to hit the api from SAP.
In modern api’s TLS version 1.0 is not supported. API integrations use TLS 1.1 as a minimum, but version 1.2 is recommended.
You can test whether your integration is compatible at any time using the test environment (https://api-testbed.giftbit.com/papi/v1)
If your test calls fail with an SSL handshake failure or similar error in SM59 when testing the connection, refer the F1 documentation or ICM Monitor ( TCode: SMICM ) for you to communicate with rest API. This type of failure may be caused by an outdated language version or library being used that does not have support for newer TLS versions.
Attached OSS message discusses in detail about the SSL configurations to be enabled in the ABAP application server. https://launchpad.support.sap.com/#/notes/510007
Thats all about configurations to be maintained. In the next part of this blog series, we will see how to write the ABAP code solution to consume these REST api’s using the standard handler CL_REST_HTTP_CLIENT and parser class /UI2/CL_JSON.
Technical implementation:
In this section, all steps are described that you must implement for calling an external SLACK based web service from ABAP. First we send a GET request to the external REST api and then receive the response data in JSON format. Afterwards this JSON is converted into native ABAP format.
Following are the ABAP classes are used.
CL_HTTP_CLIENT
CL_REST_HTTP_CLIENT
/UI2/CL_JSON
Step 1:
Create a new REST client object with necessary request headers and authorization key.
Destination details should be maintained and received from SM59.
*Declarations for REST handlers
data: go_http_client type ref to if_http_client,
go_rest_client type ref to cl_rest_http_client.
*Declarations for Data refereces
data:lo_json type ref to /ui2/cl_json.
*Fetch the SLACK destination details from SM59 and create the HTTP client reference
call method me>create_http_client
exporting i_rfc_dest = gc_rfc_dest
importing e_return = l_wa_return .
if l_wa_return is not initial.
* Send the error message
e_return = l_wa_return.
return.
endif.
method create_http_client.
*& This method is used to fetch the destination details about the SLACK Server from SM59*
*—————————————————————————*
* Data Declarations*
—————————————————————————*
data:lv_reason type string,
lv_utc_timestamp type timestampl.
data GV_AUTH_VAL type STRING .
constants GC_AUTH type STRING value ‘Authorization’ ##NO_TEXT.
constants GC_CONTENT_TYPE type STRING value ‘content-type’
constants GC_ACCEPT type STRING value ‘ACCEPT’ ##NO_TEXT.
constants GC_ACCEPT_VALUE type STRING value ‘application/json’
constants GC_RFC_DEST type RFCDEST value ‘SLACK_REST_API_CONV’ ##NO_TEXT
constants gc_tabname type rstable-tabname value ‘Z_SLACK_LOG’.”Table Name
constants: gc_e type dd26e-enqmode value ‘E’,” E
*Create the HTTP client instance
call method cl_http_client=>create_by_destination exporting
destination = i_rfc_dest
importing
client = go_http_client
exceptions
destination_not_found = 1
internal_error = 2
argument_not_found = 3
destination_no_authority = 4
plugin_not_active = 5
others = 5 .
if sy-subrc ne 0.
“Log the Exception
*Ping Destination Failed get time stamp field
lv_utc_timestamp.
lv_reason = sy-msgv1.
return.
endif.
check go_http_client is bound.
*Set the HTTP header fields
call method go_http_client->request->set_header_field
exporting name = gc_auth
value = gv_auth_val.
call method go_http_client->request->set_header_field
exporting name = gc_accept
value = gc_accept_value.
call method go_http_client->request->set_header_field
exporting name = gc_content_type
value = gc_accept_value.
” set http protocol version go_http_client->request->set_version(
if_http_request=>co_protocol_version_1_0 ).
endmethod.
Step 2:
REST call – HTTP GET
We get a string variable that contains the response data in JSON format. To process the data in ABAP, it must be converted into an appropriate ABAP structure or data object for which we use standard parser class
If the request is successful, convert the JSON string into ABAP native internal table format using standard parser class /ui2/cl_json which contains methods to perform serialization and de-serialization.
Catch here is, we need to create a local type or a global type with the attribute names as same as JSON response retrieve from the REST api.
*Declations to store the native format data
types: begin of ts_slack_info,
] user type string,
email type string,
end of ts_slack_info .
data ls_slack_data type ts_slack_info.
data GO_HTTP_CLIENT type ref to IF_HTTP_CLIENT .
data: lr_json type ref to /ui2/cl_json.
CHECK go_http_client IS BOUND.
*Set the User ID
IF c_user_id IS NOT INITIAL.
lv_user_guid = c_user_id-zuser_guid.
cl_http_utility=>set_request_uri(
EXPORTING request = go_http_client->request uri = lv_user_guid ).
*Create REST Client object
CREATE OBJECT lo_rest_client
EXPORTING io_http_client = go_http_client.
TRY.
lo_rest_client->if_rest_client~get( ).
DATA(lo_response) = lo_rest_client->if_rest_client~get_response_entity( ).
DATA(lv_http_status) = lo_response->get_header_field( ‘~status_code’ ).
IF lv_http_status NE 200.
lv_error_status = lv_http_status.
*HTTP Request Failed
DATA(lv_reason) = lo_response->get_header_field( ‘~status_reason’ ).
*STOP Processing
e_return-type = gc_err.
e_return-message = lv_reason.
RETURN.
ENDIF.
*Receive the response data in JSON.
DATA(lv_json_data) = lo_response->get_string_data( ).
“Refresh the SLACK response to clear HTTP memory of previous calls
IF go_http_client IS BOUND.
go_http_client->refresh_response( ).
“Close HTTP session (Exception HTTP_NO_MEMORY)
go_http_client->close( ).
ENDIF.
*Collect into the exception table.
CATCH cx_rest_client_exception INTO DATA(lo_rest_client_exception).
ENDTRY.
IF lv_json_data IS NOT INITIAL.
CREATE OBJECT lr_json.
TRY .
lr_json->deserialize_int( EXPORTING json = lv_json_data CHANGING data = ls_slack_data ).
ENDIF.
CATCH cx_sy_move_cast_error INTO DATA(lo_move_cast_error) .
DATA(lv_msg_desrl_err) = `HTTP GET failed: ` && lo_move_cast_error->get_longtext( ). FREE:l_wa_reason,lo_move_cast_error.
ENDTRY.
ENDIF.
ENDIF.
Step 3: Troubleshooting
GET or POST method throws exception Communication Error
◈ Verify that the specified host name is correct.
◈ Check proxy server settings.
HTTP status is 400 (Bad Request)
◈ Check uri path and parameter string.
HTTP status is 401 (Unauthorized)
◈ Check that user name and password as specified in your program matches those of your service instance in external server.
HTTP status is 403 (Forbidden)
◈ Proceed as follows to check if the SSL certificate for the external server is installed correctly.
1. Call transaction SMICM.
2. Select menu item Goto → Trace File → Display End
3. If you find the following messages, re-install the SSL certificate.
Disclaimer: Above ABAP code snippets are for illustration purposes only and these are untested. Please tailor/validate these codes based on your business requirements for the production purposes.
No comments:
Post a Comment