abap-exercises-codejam icon indicating copy to clipboard operation
abap-exercises-codejam copied to clipboard

Extend Exercise 2 to use OAuth

Open ceedee666 opened this issue 5 years ago • 0 comments

Hi all, I would like to suggest to extend exercise two with a part to invoke a service running on the individual CF trial account using OAuth. Instead of "only" doing a get using the service key form the API sandbox it would be good to show how to invoke a ral service on CF.

I tried this last week for the SAP Online track and it took me quite some time to figure it out. This could be an optional part of the exercise.

What I came up with is the following (I'll also blog about it as soon as I find the time):

CLASS zcl_cd_start_zombie_wf DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.
  PROTECTED SECTION.
  PRIVATE SECTION.
    DATA oauth_token TYPE string.

    METHODS start_wf_instance
      IMPORTING
        out TYPE REF TO if_oo_adt_classrun_out
      RAISING
        cx_web_http_client_error
        cx_web_message_error
        cx_http_dest_provider_error.

    METHODS request_oauth_token
      RAISING
        cx_http_dest_provider_error
        cx_web_http_client_error.

    CONSTANTS clientid TYPE string VALUE 'the-client-id'.
    CONSTANTS clientsecret TYPE string VALUE 'the-client.secret'.
ENDCLASS.



CLASS zcl_cd_start_zombie_wf IMPLEMENTATION.

  METHOD if_oo_adt_classrun~main.
    TRY.
        me->request_oauth_token(  ).
        me->start_wf_instance( out ).

      CATCH cx_web_http_client_error cx_web_message_error cx_http_dest_provider_error INTO DATA(exp).
        out->write( exp->get_text( ) ).
    ENDTRY.
  ENDMETHOD.

  METHOD start_wf_instance.
    DATA(wf_service_http_dest) =
            cl_http_destination_provider=>create_by_url( |https://api.workflow-sap.cfapps.eu10.hana.ondemand.com/workflow-service/rest/v1/workflow-instances| ).

    DATA(wf_service) = cl_web_http_client_manager=>create_by_http_destination( wf_service_http_dest ) .

    wf_service->get_http_request( )->set_header_field(
        i_name  = |Authorization|
        i_value = |Bearer | && me->oauth_token ).

    wf_service->get_http_request( )->set_header_field( i_name = |Content-Type| i_value = |application/json| ).

    wf_service->get_http_request( )->set_text(
        i_text =
            |\{| &&
            |   "definitionId": "zombiehuntingwf",                      | &&
            |   "context":                                              | &&
            |       \{                                                  | &&
            |           "zombieData": \{                                | &&
            |               "type": "ABAP-Zombie",                      | &&
            |               "description": "Mighty ABAP Zombie",        | &&
            |               "dangerLevel": 44100                        | &&
            |       \}                                                  | &&
            |    \}                                                     | &&
            |\}                                                         | ).

    DATA(wf_service_response) = wf_service->execute( i_method = if_web_http_client=>post ).
    DATA(status) = wf_service_response->get_status(  ).

    out->write( |Response is: { status-code } { status-reason }.| ).
  ENDMETHOD.


  METHOD request_oauth_token.
    DATA: json_data_ref         TYPE REF TO data,
          access_token_data_ref TYPE REF TO data.


    FIELD-SYMBOLS:
      <json_data>    TYPE data,
      <field>        TYPE data,
      <access_token> TYPE data.

    DATA(http_destination) =
             cl_http_destination_provider=>create_by_url( |https://<account>trial.authentication.eu10.hana.ondemand.com/oauth/token| ).

    DATA(http_client) = cl_web_http_client_manager=>create_by_http_destination( http_destination ) .
    http_client->get_http_request( )->set_authorization_basic(
        i_username = clientid
        i_password = clientsecret ).

    http_client->get_http_request( )->set_header_field( i_name = |Content-Type| i_value = |application/x-www-form-urlencoded| ).
    http_client->get_http_request( )->set_text( |grant_type=client_credentials&response_type=token| ).

    DATA(response) = http_client->execute( if_web_http_client=>post ).

    json_data_ref = /ui2/cl_json=>generate( json =  response->get_text(  ) ).

    ASSIGN json_data_ref->* TO <json_data>.
    ASSIGN COMPONENT |ACCESS_TOKEN| OF STRUCTURE <json_data> TO <field>.
    access_token_data_ref = <field>.
    ASSIGN  access_token_data_ref->* TO <access_token>.

    me->oauth_token = <access_token>.
  ENDMETHOD.

ENDCLASS.

Christian

ceedee666 avatar Jun 02 '20 09:06 ceedee666