I have heard many things about REST, oauth, JSON and all these things. Finally i have to meet these terms this week. There was a third party tool which is provding a REST service and i have to consume it with ABAP. Interestingly i learnt that there is not any Enterprise Service infrastructure in order to call REST services. Therefore i had to use HTTP service objects within ABAP program library. cl_http_client is the main class for REST services. Calling a REST service is consist of two parts. In this post i will focust on the first part. It is getting access token which is required to successfully make main webservice and this is the second poart of REST service.
There are a few different authentication method to get access token. I have used password as grant type. Below i am sharing my custom functiom module code which i have used to acquire an access token for my REST service. Z_GET_ACCESS_TOKEN function returns the access token acquired from the provider service and gives an exception if the service does not return an 200 (successfull http call).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
function z_get_access_token. *"---------------------------------------------------------------------- *"*"Local Interface: *" EXPORTING *" REFERENCE(E_ACCESS_TOKEN) TYPE LOCALFILE *" EXCEPTIONS *" ERROR *"---------------------------------------------------------------------- data: lo_http_client type ref to if_http_client . data: lv_http_error_descr type string, lv_http_error_descr_long type xstring. data: lv_http_return_code type i. data: lv_access_token_str_found type boole_d, lv_expire_str_found type boole_d. data: lv_url type string, lv_xml_result_str type string. data: lv_cdata type string. data: lv_content_length_value type i. data: lv_strlen type i. data lv_client_id type localfile. data lv_client_secret type localfile. data lv_username type localfile. data lv_password type localfile. data lv_access_token type localfile. data lv_token_expire_seconds type char10. types: begin of ty_result, str(200), end of ty_result. data: lt_itab_result type table of ty_result with header line. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Create the lo_http_client using URL : lv_url = 'http://{provider_server}/{provider_service}/oauth/token'. lv_client_id = '{client_id}'. lv_client_secret = '{client_secret}'. lv_username = '{username}'. lv_password = '{pasword}'. ** Create the HTTP client 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. * Set up the HTTP Post call method lo_http_client->request->set_method exporting method = 'POST'. call method lo_http_client->request->set_version exporting version = if_http_request=>co_protocol_version_1_0. " 1.0 lo_http_client->request->set_header_field( name = 'Content-Type' value = 'application/x-www-form-urlencoded' ). *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Body of POST Request (SET_CDATA) and Content Length: concatenate 'grant_type=password' '&' 'client_id=' lv_client_id '&' 'client_secret=' lv_client_secret '&' 'username=' lv_username '&' 'password=' lv_password into lv_cdata. lv_content_length_value = strlen( lv_cdata ). call method lo_http_client->request->if_http_entity~set_cdata exporting data = lv_cdata length = lv_content_length_value offset = 0. * Send the HTTP Post call method lo_http_client->send exporting timeout = 15 " 15 Seconds exceptions http_communication_failure = 1 http_invalid_state = 2. * Disable SAP's pop-up for user id and password: lo_http_client->propertytype_logon_popup = lo_http_client->co_disabled. " POPUP for user id and pwd *Read the Response call method lo_http_client->receive exceptions http_communication_failure = 1 http_invalid_state = 2 http_processing_failed = 3. * Get the HTTP return code from the HTTP POST: lo_http_client->response->get_status( importing code = lv_http_return_code ). lo_http_client->response->get_status( importing reason = lv_http_error_descr ). lv_http_error_descr_long = lo_http_client->response->get_raw_message( ). * Write the HTTP Return Code / Description to the screen: write:/ 'HTTP return Code/Description:', lv_http_return_code no-gap, '/' no-gap, lv_http_error_descr. skip 1. write:/ 'HTTP return Code/Long Description:', lv_http_return_code no-gap, '/' no-gap, lv_http_error_descr_long. skip 1. * Refresh the Request after each POST: call method lo_http_client->refresh_request( exceptions http_action_failed = 1 others = 2 ). *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Write the data received back from the POST to the screen: clear lv_xml_result_str. lv_xml_result_str = lo_http_client->response->get_cdata( ). split lv_xml_result_str at '"' into table lt_itab_result. clear: lv_access_token_str_found, lv_expire_str_found. loop at lt_itab_result. case lt_itab_result-str. when 'access_token'. lv_access_token_str_found = abap_true. when 'expires_in'. lv_expire_str_found = abap_true. when others. if lv_access_token_str_found eq abap_true and lv_access_token is initial. lv_strlen = strlen( lt_itab_result-str ). if lv_strlen > 30. lv_access_token = lt_itab_result-str. endif. endif. if lv_expire_str_found eq abap_true and lv_token_expire_seconds is initial and lt_itab_result-str cs '0'. replace ':' with space into lt_itab_result-str. replace '#' with space into lt_itab_result-str. replace '}' with space into lt_itab_result-str. shift lt_itab_result-str by 1 places right circular. while lt_itab_result-str(1) eq space. shift lt_itab_result-str by 1 places right circular. endwhile. lt_itab_result-str(1) = ' '. shift lt_itab_result-str left deleting leading space. lv_token_expire_seconds = lt_itab_result-str. endif. endcase. endloop. if lv_http_return_code eq 200. " ok * Close the HTTP connection: lo_http_client->close( ). e_access_token = lv_access_token . else. raise error . endif. endfunction. |