Skip to Content

Create a Remote Client Proxy

test
0 %
Create a Remote Client Proxy
Details

Create a Remote Client Proxy

Requires Customer/Partner License
September 15, 2020
Created by
February 25, 2020
In the SAP Cloud Platform, ABAP Environment, create a local class that instantiates a proxy, which passes an OData request to a remote service.

You will learn

  • How to create an HTTP client in an ABAP class
  • How to instantiate a client proxy in this class
  • How to handle errors by creating an exception class and message class

Prerequisites

  • IMPORTANT: This tutorial cannot be completed on a trial account

To retrieve data from a remote service, you must:

  1. Connect to the provisioning system

  2. Instantiate a proxy in the client system that passes an OData request to the remote service

This tutorial is based on: Creating a Remote Client Proxy.

Therefore, this tutorial will only cover in detail those aspects that are different - in particular, handling exceptions.


Step 1: Create auxiliary class

First, you create the class that instantiates the client proxy.

  1. In ADT, open your package Z_A4C_TO_A4C_XXX and choose New > Class.

  2. Enter a name and description:

    • ZCL_PROXY_TRAVELS_XXX
    • Create client proxy for Travels
  3. Choose the transport request, then choose Finish.

Log on to answer question
Step 2: Copy code

Copy the following code.

IMPORTANT: Always specify the authentication mode using the interface if_a4c_cp_service. Never hard-code your password in the class.


CLASS zcl_proxy_travels_xxx DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. CLASS-METHODS get_client_proxy RETURNING VALUE(ro_client_proxy) TYPE REF TO /iwbep/if_cp_client_proxy * RAISING /dmo/cx_travel_service_xxx . PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. CLASS zcl_proxy_travels_xxx IMPLEMENTATION. METHOD get_client_proxy. TRY. " 1. Get the destination of foreign system " 2. Create http client " i_name = name of destination in S.C.Cockpit; URL = base URL of T08 " i_service_instance_name = "Service Instance Name" property in FLP, in Comm. Arr. SAP_COM_0276_XXX, DATA(lo_http_client) = cl_web_http_client_manager=>create_by_http_destination( cl_http_destination_provider=>create_by_cloud_destination( i_name = 'XXX' i_service_instance_name = 'Xxx' i_authn_mode = if_a4c_cp_service=>service_specific ) ). "LATER: Handle Exceptions CATCH cx_http_dest_provider_error INTO DATA(lx_http_dest_provider_error). CATCH cx_web_http_client_error INTO DATA(lx_web_http_client_error). ENDTRY. TRY. "iv_service_definition_name = the service definition generated with Service Consumption Model (EDMX file) " iv_relative_service_root = ro_client_proxy = cl_web_odata_client_factory=>create_v2_remote_proxy( EXPORTING iv_service_definition_name = 'XXX' io_http_client = lo_http_client iv_relative_service_root = '/sap/opu/odata/sap/XXX' ). "LATER: Handle Exceptions CATCH cx_web_http_client_error INTO DATA(lx_http_client_error). CATCH /iwbep/cx_cp_remote INTO DATA(lx_cp_remote). CATCH /iwbep/cx_gateway INTO DATA(lx_gateway). ENDTRY. ENDMETHOD. ENDCLASS.
Log on to answer question
Step 3: Adapt code
  1. Specify your provisioning system as the destination, by replacing the defaults:

    • i_name = name of destination in SAP Cloud Cockpit, where URL = base URL of provisioning system
    • i_service_instance_name = Service Instance Name property in Communication Arrangement SAP_COM_0276_XXX in the client system Dashboard: points to OAuth Client ID, System ID etc (generated from Service Key for provisioning system). See tutorial Create an Outbound Communication Arrangement

    i_name = 'A4C_ACCESS_XXX_HTTP' i_service_instance_name = 'Outbound-For-Tutorials_XXX'
    step3c-dest-namestep3d-service-instance-name-outbound-2
  2. Specify your service definition and the relative path of your inbound service, by replacing the defaults:


    EXPORTING iv_service_definition_name = 'Z_MODEL_TRAVELS_XXX' io_http_client = lo_http_client iv_relative_service_root = '/sap/opu/odata/sap/Z_BIND_TRAVELS_XXX' ).
    step3a-abap-artifactsstep3b-relative-path-inbound-service
Log on to answer question
Step 4: Create message class
  1. Select your package and choose New > Other ABAP Repository Object from the context menu.

  2. Enter the filter text message and choose ABAP > … Message Class, then choose Next.

    step4a-message-class-wizard
  3. Enter a name, ZCM_TRAVELS_XXX, and description, then choose Next. Your message class should have the prefix ZCM.

  4. Accept the proposed transport request and choose Finish.

The new message class appears in a new editor.

step4b-new-message-class
Log on to answer question
Step 5: Add messages

In your code, there are five CATCH statements. Enter a number and short text for each one. Enter the five numbers using the Create icon.

step5-create-message-icon
Number Short Text
001 Access to remote system cannot be established.
002 HTTP Client could not be instantiated.
003 Client Proxy could not be instantiated.
004 Remote HTTP service consumption error.
005 SAP Gateway error.
Log on to answer question
Step 6: Create exception class

You will now handle exceptions that may be raised if, for example, your code points at the wrong HTTP destination.
To do this, you need to create an exception class, which catches the exception and a message class, which contains all the appropriate messages.

All exception classes inherit from an exception superclass, which in turn inherits from one of three exception classes, CX_STATIC_CHECK, CX_DYNAMIC_CHECK, or CX_NO_CHECK.
In this case, your exception class must inherit from the superclass CX_RAP_QUERY_PROVIDER.

  1. Start with the exception class: From your package, choose Source Code Library > Classes > New ABAP Class.

  2. Enter a name, ZCX_TRAVELS_CONS_XXX, a description, and the superclass CX_RAP_QUERY_PROVIDER, then choose Next. Your exception class should have the prefix ZCX.

  3. Accept the proposed transport request and choose Finish.

The new exception class appears with some pre-defined code in a new editor.

Log on to answer question
Step 7: Define constants

For each exception, the exception class defines one or more constant structures, which specifies the message class, message number, and attributes. (There should be four attributes for each constant structure, whether or not they are used.)

Define these using a code template:

  1. In the private section of your exception class, type textID, then trigger code completion using Ctrl+Space, then choose textIdExceptionClass...

    step7a-code-complete-textid
  2. Replace the default texts:

    • begin of <ExceptionClass> = begin of destination_provider_fail
    • msgid = your message class, that is, ZCM_TRAVELS_XXX
    • msgno = 001
    • attr1 - attr4= leave as default.

    destination_provider_fail is displayed when the exception cx_http_dest_provider_error is caught and corresponds to the short text of message 001, “Access to remote system cannot be established.”

    Your code should look like this:

    constants:
      begin of destination_provider_fail,
        msgid type symsgid value 'ZCM_TRAVELS_XXX',
        msgno type symsgno value '001',
        attr1 type scx_attrname value 'attr1',
        attr2 type scx_attrname value 'attr2',
        attr3 type scx_attrname value 'attr3',
        attr4 type scx_attrname value 'attr4',
      end of destination_provider_fail.
    
    
  3. Repeat steps 1-2 for messages 002-005, naming the constants as follows. (End CONSTANTS 1-4 with a comma; end CONSTANT 5 with a period.)

    Number Name of constant
    002 http_client_fail
    003 client_proxy_fail
    004 remote_access_fail
    005 gateway_fail
Log on to answer question
Step 8: Handle exceptions
  1. Add a RAISING clause to the method get_client_proxy, pointing to your exception class.

    The addition RAISING is used to declare one or more class-based exceptions that can be propagated from the method to the caller.

    CLASS-METHODS
    get_client_proxy
      RETURNING VALUE(ro_client_proxy) TYPE REF TO /iwbep/if_cp_client_proxy
      RAISING /dmo/cx_travel_service_003.
    
  2. Replace the first two CATCH statements with the following code.

    That is, replace:

    CATCH cx_http_dest_provider_error INTO DATA(lx_http_dest_provider_error).             
    CATCH cx_web_http_client_error INTO DATA(lx_web_http_client_error).
    

    with:

    CATCH cx_http_dest_provider_error INTO DATA(lx_http_dest_provider_error).
            "Handle exceptions
            RAISE EXCEPTION TYPE /dmo/cx_travel_service_003
              EXPORTING
        textid   = /dmo/cx_travel_service_003=>destination_provider_fail
        previous = lx_http_dest_provider_error
        .
    
    CATCH cx_web_http_client_error INTO DATA(lx_web_http_client_error).
            RAISE EXCEPTION TYPE /dmo/cx_travel_service_003
              EXPORTING
        textid   = /dmo/cx_travel_service_003=>http_client_fail
        previous = lx_web_http_client_error.
    
  3. Similarly, replace:

    CATCH cx_web_http_client_error INTO DATA(lx_http_client_error).    
    CATCH /iwbep/cx_cp_remote INTO DATA(lx_cp_remote).
    CATCH /iwbep/cx_gateway INTO DATA(lx_gateway).
    

    with:

    CATCH cx_web_http_client_error INTO DATA(lx_http_client_error).
      RAISE EXCEPTION TYPE /dmo/cx_travel_service_003
        EXPORTING
            textid   = /dmo/cx_travel_service_003=>client_proxy_fail
            previous = lx_web_http_client_error.
    
    CATCH /iwbep/cx_cp_remote INTO DATA(lx_cp_remote).
        RAISE EXCEPTION TYPE /dmo/cx_travel_service_003
            EXPORTING
                " Handle remote Exception
                " It contains details about the problems of your http(s) connection
             textid   = /dmo/cx_travel_service_003=>remote_access_fail
             previous = lx_cp_remote.
    
    CATCH /iwbep/cx_gateway INTO DATA(lx_gateway).
        RAISE EXCEPTION TYPE /dmo/cx_travel_service_003
            EXPORTING
      textid   = /dmo/cx_travel_service_003=>gateway_fail
      previous = lx_gateway.    
    
Log on to answer question
Step 9: Check code for proxy class

The code for your proxy class should look like this:

CLASS zcl_proxy_travels_xxx DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
        CLASS-METHODS
    get_client_proxy
      RETURNING VALUE(ro_client_proxy) TYPE REF TO /iwbep/if_cp_client_proxy
     RAISING zcx_travels_cons_xxx
.

  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.



CLASS zcl_proxy_travels_xxx IMPLEMENTATION.
  METHOD get_client_proxy.
    TRY.
        " 1. Get the destination of foreign system
        " 2. Create http client

        " i_name = name of destination in S.C.Cockpit; URL = base URL of T08
        " i_service_instance_name = "Service Instance Name" property in FLP, in Comm. Arr. SAP_COM_0276_XXX,

        DATA(lo_http_client) = cl_web_http_client_manager=>create_by_http_destination(
                cl_http_destination_provider=>create_by_cloud_destination(

                    i_name                  = 'T08_ACCESS_HTTP_2'
                    i_service_instance_name = 'OutboundForTutorial-2'

                    i_authn_mode            = if_a4c_cp_service=>service_specific
                )
               ).

        "Handle Exceptions
        CATCH cx_http_dest_provider_error INTO DATA(lx_http_dest_provider_error).

                RAISE EXCEPTION TYPE ZCX_TRAVELS_CONS_XXX
                  EXPORTING
            textid   = ZCX_TRAVELS_CONS_XXX=>destination_provider_fail
            previous = lx_http_dest_provider_error.


        CATCH cx_web_http_client_error INTO DATA(lx_web_http_client_error).
                RAISE EXCEPTION TYPE ZCX_TRAVELS_CONS_XXX
                  EXPORTING
            textid   = ZCX_TRAVELS_CONS_XXX=>http_client_fail
            previous = lx_web_http_client_error.

     ENDTRY.

    TRY.

          "iv_service_definition_name = the service definition generated with Service Consumption Model (EDMX file)
          " iv_relative_service_root =

          ro_client_proxy = cl_web_odata_client_factory=>create_v2_remote_proxy(
            EXPORTING
                iv_service_definition_name = 'XXX'
                io_http_client             = lo_http_client
                iv_relative_service_root   = '/sap/opu/odata/sap/XXX'
          ).

        "Handle Exceptions
          CATCH cx_web_http_client_error INTO DATA(lx_http_client_error).
            RAISE EXCEPTION TYPE ZCX_TRAVELS_CONS_XXX
              EXPORTING
                  textid   = ZCX_TRAVELS_CONS_XXX=>client_proxy_fail
                  previous = lx_web_http_client_error.

          CATCH /iwbep/cx_cp_remote INTO DATA(lx_cp_remote).
              RAISE EXCEPTION TYPE ZCX_TRAVELS_CONS_XXX
                  EXPORTING
                      " Handle remote Exception
                      " It contains details about the problems of your http(s) connection
                   textid   = ZCX_TRAVELS_CONS_XXX=>remote_access_fail
                   previous = lx_cp_remote.

          CATCH /iwbep/cx_gateway INTO DATA(lx_gateway).
              RAISE EXCEPTION TYPE ZCX_TRAVELS_CONS_XXX
                  EXPORTING
            textid   = ZCX_TRAVELS_CONS_XXX=>gateway_fail
            previous = lx_gateway.

      ENDTRY.
    ENDMETHOD.

ENDCLASS.

Log on to answer question
Step 10: Check code for exception class

The code for your exception class should look like this:

CLASS zcx_travels_cons_xxx DEFINITION
  PUBLIC
  INHERITING FROM cx_rap_query_provider
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    METHODS constructor
      IMPORTING
        !textid   LIKE if_t100_message=>t100key OPTIONAL
        !previous LIKE previous OPTIONAL .

        constants:
          begin of destination_provider_fail,
            msgid type symsgid value 'ZCM_TRAVELS_XXX',
            msgno type symsgno value '001',
            attr1 type scx_attrname value 'attr1',
            attr2 type scx_attrname value 'attr2',
            attr3 type scx_attrname value 'attr3',
            attr4 type scx_attrname value 'attr4',
          end of destination_provider_fail,

        begin of http_client_fail,
            msgid type symsgid value '/DMO/CM_SERVICE_003',
            msgno type symsgno value '002',
            attr1 type scx_attrname value 'attr1',
            attr2 type scx_attrname value 'attr2',
            attr3 type scx_attrname value 'attr3',
            attr4 type scx_attrname value 'attr4',
        end of http_client_fail,

        begin of client_proxy_fail,
          msgid type symsgid value '/DMO/CM_SERVICE_003',
          msgno type symsgno value '003',
          attr1 type scx_attrname value 'attr1',
          attr2 type scx_attrname value 'attr2',
          attr3 type scx_attrname value 'attr3',
          attr4 type scx_attrname value 'attr4',
        end of client_proxy_fail,

        begin of remote_access_fail,
          msgid type symsgid value '/DMO/CM_SERVICE_003',
          msgno type symsgno value '004',
          attr1 type scx_attrname value 'attr1',
          attr2 type scx_attrname value 'attr2',
          attr3 type scx_attrname value 'attr3',
          attr4 type scx_attrname value 'attr4',
        end of remote_access_fail,

        begin of gateway_fail,
          msgid type symsgid value '/DMO/CM_SERVICE_003',
          msgno type symsgno value '005',
          attr1 type scx_attrname value 'attr1',
          attr2 type scx_attrname value 'attr2',
          attr3 type scx_attrname value 'attr3',
          attr4 type scx_attrname value 'attr4',
        end of gateway_fail,

        begin of query_fail,
          msgid type symsgid value '/DMO/CM_SERVICE_003',
          msgno type symsgno value '006',
          attr1 type scx_attrname value 'attr1',
          attr2 type scx_attrname value 'attr2',
          attr3 type scx_attrname value 'attr3',
          attr4 type scx_attrname value 'attr4',
        end of query_fail

          .

  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS zcx_travels_cons_xxx IMPLEMENTATION.
  METHOD constructor ##ADT_SUPPRESS_GENERATION.
    CALL METHOD super->constructor
      EXPORTING
        previous = previous.
    CLEAR me->textid.
    IF textid IS INITIAL.
      if_t100_message~t100key = if_t100_message=>default_textid.
    ELSE.
      if_t100_message~t100key = textid.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

Log on to answer question
Step 11: Test yourself

Create a CONSTANT structure named agency_unkown for an exception class, specifying the message class /DMO/CM_FLIGHTS, message number 010, and four attributes. The first attribute should have the value MV_AGENCY_ID. Enter your code in the space below and choose Submit Answer.

×

More Information

For more information on ABAP class-based exceptions, see:


Next Steps

Back to top