Thursday, 24 January 2019

How To Use eCATT Script via HTTP Request

eCATT is a very powerful tool for test automation in the context of SAP. In this blog I describe how to call eCATT scripts via HTTP request. This approach is very similar to another with PowerShell, which I described in another blog. The difference is here that you don’t need an additional library and therewith is it possible to call eCATT scripts nearly from every tool.

Let us start with a tiny ABAP class. It uses IF_HTTP_EXTENSION interface and contains one public method called execution as well as a method called handle_request. The handle_request methode catches a get request and a few arguments. Then it calls the method execute and delivers a response status with text. The method execute call the eCATT test data container and delivers the content of the protocol. As communication interface to the eCATT script we have the header field input, from the http request, and the parameter ep_output, from the eCATT script.

"-Begin-----------------------------------------------------------------

class Z_CL_ECATT_ETCT definition
  public
  final
  create public .

PUBLIC SECTION.

  INTERFACES if_http_extension .

  "! Call of an eCATT test data container
  "!
  "! @parameter IV_ECTC_NAME            | Name of the test data container
  "! @parameter IV_ECSCR_NAME           | Name of the test script (optional, otherwise it is set to the name of the TDC)
  "! @parameter IV_INPUT                | Input parameters
  "! @parameter IV_TARGETSYTEM          | Target system on which the script is executed
  "!
  "! @parameter EV_LOGID                | LogID
  "! @parameter ET_EXPORT_VALUES        | Return value of the test script
  "!
  "! @exception NOTHING_TO_DO           |
  "! @exception TOO_MANY_SCRIPTS_CALLED |
  "! @exception NOT_AUTHORIZED          |
  "! @exception LOG_NOT_FOUND           |
  "! @exception OTHER_ERROR             |
  METHODS execute
    IMPORTING
      VALUE(iv_ectc_name)     TYPE etobj_name
      VALUE(iv_ecscr_name)    TYPE etobj_name OPTIONAL
      VALUE(iv_input)         TYPE string OPTIONAL
      VALUE(iv_targetsystem)  TYPE etcmp_cmp
    EXPORTING
      VALUE(ev_logid)         TYPE etlog_id
      VALUE(et_export_values) TYPE etlog_expo_tabtype
    EXCEPTIONS
      nothing_to_do
      too_many_scripts_called
      not_authorized
      log_not_found
      other_error .

  PROTECTED SECTION.

  PRIVATE SECTION.

ENDCLASS.

CLASS Z_CL_ECATT_ETCT IMPLEMENTATION.

  METHOD if_http_extension~handle_request."-----------------------------

    DATA:
      lv_verb          TYPE string,
      lv_ectc_name     TYPE etobj_name,
      lv_ecscr_name    TYPE etobj_name,
      lv_input         TYPE string,
      lv_targetsystem  TYPE etcmp_cmp,
      lt_export_values TYPE etlog_expo_tabtype,
      lv_logid         TYPE etlog_id,
      lv_str_logid     TYPE string,
      ls_export_value  TYPE etlog_expo,
      lv_search_string TYPE string,
      ls_eclog_data    TYPE eclog_data,
      ls_eclog_xdat    TYPE eclog_xdat
      .

    lv_verb = server->request->get_header_field( name = '~request_method' ).
    CHECK lv_verb = 'GET'.

    lv_ectc_name = server->request->get_header_field( name = 'ectc_name' ).
    lv_ecscr_name = server->request->get_header_field( name = 'ecscr_name' ).
    lv_targetsystem = server->request->get_header_field( name = 'targetsystem' ).
    lv_input = server->request->get_header_field( name = 'input' ).

    me->execute(
      EXPORTING
        iv_ectc_name            = lv_ectc_name
        iv_ecscr_name           = lv_ecscr_name
        iv_input                = lv_input
        iv_targetsystem         = lv_targetsystem
      IMPORTING
        ev_logid                = lv_logid
        et_export_values        = lt_export_values
      EXCEPTIONS
        nothing_to_do           = 1
        too_many_scripts_called = 2
        not_authorized          = 3
        log_not_found           = 4
        other_error             = 5
        OTHERS                  = 6
    ).

    lv_str_logid = lv_logid.
    server->response->set_header_field(
      EXPORTING
      name  = 'logid'
      value = lv_str_logid
    ).

    CASE sy-subrc.
      WHEN 0.
        LOOP AT lt_export_values INTO ls_export_value.
          CHECK ls_export_value-pname CS 'EP_OUTPUT'.
          "-If result value contains a string > 100 characters...-------
          IF ls_export_value-value CS 'STR-DATA-'.
            "-...it is necessary to get the data from eCATT tables------
            lv_search_string = '%' && ls_export_value-pname && '%'.
            SELECT SINGLE * FROM ECLOG_DATA INTO ls_eclog_data
              WHERE xml_line LIKE lv_search_string.
            CHECK sy-subrc = 0.
            SELECT SINGLE * FROM ECLOG_XDAT INTO ls_eclog_xdat
              WHERE logid = lv_logid AND obj_lnr = ls_eclog_data-obj_lnr AND
              script_lnr = ls_eclog_data-script_lnr.
            CHECK sy-subrc = 0.
            IF ls_eclog_xdat-comprim = abap_true.
              CL_APL_ECATT_LOG=>decompress_xdat(
                CHANGING
                  cs_eclog_xdat = ls_eclog_xdat
              ).
            ENDIF.
            CALL METHOD server->response->set_cdata(
              data = ls_eclog_xdat-xml_string
            ).
          ELSE.
            CALL METHOD server->response->set_cdata(
              data = ls_export_value-value
            ).
          ENDIF.
          EXIT.
        ENDLOOP.
        CALL METHOD server->response->set_status( code = 200 reason = 'Ok' ).
      WHEN OTHERS.
        CALL METHOD server->response->set_status( code = 500 reason = 'Error' ).
    ENDCASE.

  ENDMETHOD.

  METHOD execute."------------------------------------------------------

    DATA:
      lt_exe       TYPE etexe_obj_tabtype,
      lt_startopt  TYPE etname_value_tabtype,
      lt_param     TYPE etexec_par_vals_tabtype,
      lt_exe_param TYPE etexec_params_tabtype,
      ls_log       TYPE etlog_key,
      lv_script    TYPE etobj_name
      .

    AUTHORITY-CHECK OBJECT 'S_DEVELOP'
      ID 'ACTVT'  FIELD '16'.
    IF sy-subrc  0.
      RAISE not_authorized.
    ENDIF.

    lt_exe = VALUE #(
      ( obj_type = 'ECTC' obj_name = iv_ectc_name )
    ).

    lt_startopt = VALUE #(
      ( name = 'start_type'         value = 'S'             )
      ( name = 'startmode'          value = 'A'             )
      ( name = 'mode_sapgui_close'  value = 'N'             )
      ( name = 'interrupt'          value = 'X'             )
      ( name = 'display_log'        value = ''              )
      ( name = 'targetsystem'       value = iv_targetsystem )
    ).

    lt_param = VALUE #(
      ( pname = 'IP_INPUT' pvalue = iv_input pvalue_type = space )
    ).

    lt_exe_param = VALUE #(
      ( paramtab = lt_param )
    ).

    CALL FUNCTION 'ECATT_EXECUTE'
      EXPORTING
        to_execute              = lt_exe
        display_log             = ''
        it_startoptions         = lt_startopt
        it_to_execute_params    = lt_exe_param
      IMPORTING
        logid                   = ls_log
      EXCEPTIONS
        nothing_to_do           = 1
        too_many_scripts_called = 2
        OTHERS                  = 3.
    CASE sy-subrc.
      WHEN 0.
        "Nothing to do
      WHEN 1.
        RAISE nothing_to_do.
      WHEN 2.
        RAISE too_many_scripts_called.
      WHEN OTHERS.
        RAISE other_error.
    ENDCASE.

    CHECK ls_log-logid IS NOT INITIAL.
    ev_logid = ls_log-logid.

    IF iv_ecscr_name IS INITIAL.
      lv_script = iv_ectc_name.
    ELSE.
      lv_script = iv_ecscr_name.
    ENDIF.

    CALL FUNCTION 'ECATT_LOG_GET_EXPORT'
      EXPORTING
        im_script     = lv_script
        im_logid      = ev_logid
      IMPORTING
        export_values = et_export_values
      EXCEPTIONS
        log_not_found = 1
        OTHERS        = 2.

    IF sy-subrc  0.
      RAISE log_not_found.
    ENDIF.

  ENDMETHOD.

ENDCLASS.

"-End-------------------------------------------------------------------

This class can be used directly by the SAP Internet Connection Framework, TAC SICF. Define a service, insert the handler class and activate the service.

SAP ABAP Tutorial and Materials, SAP ABAP Study Material, SAP ABAP Guides

In the next steps we define some eCATT modules – TAC SECATT. We define a system data container, a very simple test script and a test configuration.

SAP ABAP Tutorial and Materials, SAP ABAP Study Material, SAP ABAP Guides

System Data Container

SAP ABAP Tutorial and Materials, SAP ABAP Study Material, SAP ABAP Guides

The Test Script with the input parameter IP_INPUT and the export parameter EP_OUTPUT. The input parameter is in this example not necessary, we use only the output parameter. The script delivers here a tiny string ‘Hello World from eCATT’.

SAP ABAP Tutorial and Materials, SAP ABAP Study Material, SAP ABAP Guides

Start Configuration

SAP ABAP Tutorial and Materials, SAP ABAP Study Material, SAP ABAP Guides

That is all we have to do, the preparations are ready now. When we call this test data container we get the following protocol.

SAP ABAP Tutorial and Materials, SAP ABAP Study Material, SAP ABAP Guides

All looks well so far and it should be possible now to call this script from any other tool which can send an http request. In our case we use Postman to do it.

SAP ABAP Tutorial and Materials, SAP ABAP Study Material, SAP ABAP Guides

I can only repeat now what I wrote in my other blog: The parameter IV_TARGETSYSTEM allows you to execute your script on any SAP system in your system landscape directory resp. which are customized in your SM59. On this way you have now the possibility to use SAP eCATT with via HTTP request and to realize a bidirectional communication between the calling tool and eCATT script and visa versa. This offers us amazing possibilities.

1 comment:

  1. Hi ,
    Im getting the below error while executing the test configuration with the above logic.

    error during method call in scripting host

    can you please suggest.

    Thanks,
    Lokeswar.

    ReplyDelete