SAP BTP Small Talk: Calling an iFlow from an ABAP Environment on Cloud Foundry

Have you heard of the ABAP Environment available on Cloud Foundry, and therefore also available on SAP BTP? If not, I highly recommend exploring this topic—it's both technically fascinating and promising in terms of future development potential.

See ABAP Environment

In this SAP BTP Small Talk, I’ll walk you through a simple example of how to call an integration flow from within an ABAP class hosted on an SAP BTP ABAP environment.

BTP iFLow

We’ll use a simple iFlow that returns the following response to the sender:

Which type of authorization should be used to trigger the iFlow?

For this scenario, to trigger the iFlow, the ABAP code must first retrieve an OAuth2 token. This is done using the token generation endpoint, along with the client ID and client secret for your iFlow service instance.

0:00
/0:12

What about ABAP Environment?

For demonstration purposes—as well as my own development experiments—I use a Trial SAP BTP account.

See Create an SAP BTP ABAP Environment Trial User

You’ll also need the Eclipse IDE with the ABAP Development Tools (ADT) plugin installed to develop in this environment.

See ABAP Development Tools for Eclipse
See SAP Development Tools

Create a New ABAP Class in the SAP BTP ABAP Environment

Define a Method to Retrieve an OAuth2 Token

Below is a method that obtains an OAuth2 token. Be sure to replace placeholders with your actual token endpoint, client ID, and client secret.

💡
Don't forget to secure and manage credentials appropriately—storing them in plain text is not recommended for production use!
CLASS ycl_20250404 DEFINITION  PUBLIC   FINAL   CREATE PUBLIC .

  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.

    TYPES:
      BEGIN OF oauth_token,
        access_token  TYPE string,
        token_type    TYPE string,
        id_token      TYPE string,
        refresh_token TYPE string,
        expires_in    TYPE i,
        scope         TYPE string,
        jti           TYPE string,
      END OF oauth_token.
  PROTECTED SECTION.
  PRIVATE SECTION.
    CLASS-DATA:
        out TYPE REF TO if_oo_adt_classrun_out.
    CLASS-METHODS:
      get_oauth_token IMPORTING VALUE(client_id)     TYPE string
                                VALUE(client_secret) TYPE string
                                VALUE(destination)   TYPE string
                      RETURNING VALUE(oauth_token)   TYPE  oauth_token.
ENDCLASS.



CLASS ycl_20250404 IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    TRY.
        DATA(client_id) = ``.
        DATA(client_secret) = ``.
        DATA(destination) = `https://..../oauth/token`.
        DATA(oauth_token) = get_oauth_token(  client_id = client_id
                                              client_secret = client_secret
                                              destination = destination
                                           ).
      CATCH cx_web_http_client_error
                   cx_http_dest_provider_error INTO DATA(exception).
        out->write( exception->get_text( ) ).
    ENDTRY.
  ENDMETHOD.

  METHOD get_oauth_token.
    DATA(dest) = cl_http_destination_provider=>create_by_url( destination ).
    DATA(http_client) = cl_web_http_client_manager=>create_by_http_destination( dest ).
    DATA(request) = http_client->get_http_request( ).

    DATA(body_request) = `grant_type=client_credentials`.

    request->set_header_fields( VALUE #(
      ( name = 'Content-Type'
        value = 'application/x-www-form-urlencoded' )
      ( name = 'Accept'  value = 'application/json' ) ) ).

    request->set_authorization_basic(
                  i_username = client_id
                  i_password = client_secret
                  ).
    request->append_text( body_request ).
    DATA(token) = http_client->execute( if_web_http_client=>post ).

    /ui2/cl_json=>deserialize(
     EXPORTING
       json = token->get_text( )
     CHANGING
       data = oauth_token
      ).
  ENDMETHOD.
ENDCLASS.

These values can be found in the Instances section of your BTP subaccount.

Define a Method to Trigger the iFlow

Implement another method that uses the retrieved token to call the iFlow. This method requires the full endpoint URL of the iFlow you want to call.

CLASS ycl_20250404 DEFINITION  PUBLIC   FINAL   CREATE PUBLIC .

  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.

    TYPES:
      BEGIN OF oauth_token,
        access_token  TYPE string,
        token_type    TYPE string,
        id_token      TYPE string,
        refresh_token TYPE string,
        expires_in    TYPE i,
        scope         TYPE string,
        jti           TYPE string,
      END OF oauth_token.
  PROTECTED SECTION.
  PRIVATE SECTION.
    CLASS-DATA:
        out TYPE REF TO if_oo_adt_classrun_out.
    CLASS-METHODS:
      get_oauth_token IMPORTING VALUE(client_id)     TYPE string
                                VALUE(client_secret) TYPE string
                                VALUE(destination)   TYPE string
                      RETURNING VALUE(oauth_token)   TYPE  oauth_token,

      trigger_iflow  IMPORTING VALUE(iflow_endpoint) TYPE string
                               VALUE(oauth_token)    TYPE oauth_token
                     RETURNING VALUE(response)       TYPE string.

ENDCLASS.



CLASS ycl_20250404 IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    TRY.
        DATA(client_id) = ``.
        DATA(client_secret) = ``.
        DATA(destination) = `https://.../oauth/token`.
        DATA(iflow_endpoint) = `https://.../http/test`.

        DATA(oauth_token) = get_oauth_token(  client_id = client_id
                                              client_secret = client_secret
                                              destination = destination
                                           ).

        IF oauth_token IS NOT INITIAL.
          DATA(iflow_response) =   trigger_iflow( oauth_token = oauth_token
                                                  iflow_endpoint = iflow_endpoint
                                                ).
          out->write( iflow_response )   .
        ENDIF.
      CATCH cx_web_http_client_error
                   cx_http_dest_provider_error INTO DATA(exception).
        out->write( exception->get_text( ) ).
    ENDTRY.
  ENDMETHOD.

  METHOD get_oauth_token.
    DATA(dest) = cl_http_destination_provider=>create_by_url( destination ).
    DATA(http_client) = cl_web_http_client_manager=>create_by_http_destination( dest ).
    DATA(request) = http_client->get_http_request( ).

    DATA(body_request) = `grant_type=client_credentials`.

    request->set_header_fields( VALUE #(
      ( name = 'Content-Type'
        value = 'application/x-www-form-urlencoded' )
      ( name = 'Accept'  value = 'application/json' ) ) ).

    request->set_authorization_basic(
                  i_username = client_id
                  i_password = client_secret
                  ).
    request->append_text( body_request ).
    DATA(token) = http_client->execute( if_web_http_client=>post ).

    /ui2/cl_json=>deserialize(
     EXPORTING
       json = token->get_text( )
     CHANGING
       data = oauth_token
      ).
  ENDMETHOD.

  METHOD trigger_iflow.

    DATA(dest) = cl_http_destination_provider=>create_by_url( iflow_endpoint ).
    DATA(http_client) = cl_web_http_client_manager=>create_by_http_destination( dest ).
    DATA(request) = http_client->get_http_request( ).

    DATA(bearer) = |Bearer { oauth_token-access_token }|.
    request->set_header_field(
          i_name  = 'Authorization'
          i_value = bearer ).

    DATA(resp) = http_client->execute( if_web_http_client=>get ).
    response = resp->get_text(   ).

  ENDMETHOD.
ENDCLASS.

Testing

Let’s now run the newly created ABAP class. After execution, you can check the Monitor Message Processing dashboard to confirm the call was successful.

0:00
/0:32

Isn't it beautiful?

Thanks for reading! I hope this example helps you get started with integrating BTP iFlows into your ABAP development on SAP BTP.

👨‍💻
The SAP BTP Small Talk category consists of short posts that briefly describe solutions or approaches to resolving common issues.