SAP AIF synchronous

Document overview

This document explains in details how synchronous messages can be handled in AIF framework (including error handling and monitoring). In this example below we describe scenario with WebService deployed on SAP S4/Hana system as a proxy class where inbound request is processed in AIF.

Please bear in mind that you must have at least basic knowledge of ABAP and AIF framework to understand this approach.

Short introduction to synchronous vs asynchronous process

What is actually synchronous messaging and how this fits to our reality?

Synchronous communication is when you send a request and you wait for the response to move to the next operation step, in contrast asynchronous process allows to do it without waiting.

 

AIF synchronous problem overview

SAP AIF from architecture and design point does not allow any logging with synchronous calls. This is affected by SAP WebService configuration where persistence is not executed. Data are not stored in SRT_MMASTER table (please check SAP note 1575707 for this ). This affects a payload where data are not available in AIF error log (in case of error/success you are not able to see the inbound message).

This issue is only related to ABAP Proxy (web service) related interfaces where external application triggers the message. In fact standard functions allow to consume that message by executing AIF framework but data are gone, thus it cannot be extracted. You might use XML enabler class (please look into to next chapter) but this process is setup as background where 1-1 (direct) feedback from the consumer (in this case AIF action) would not be possible.

Please follow directly AIF documentation https://help.sap.com/viewer/p/SAP_APPLICATION_INTERFACE_FRAMEWORK (from SAP) to get more information about AIF tool.

AIF technical solution of the problem

To understand the solution we must know how AIF is designed and what is allowed to change by customizing:

  • application engine – skeleton of AIF framework where most important functions are there, this might be enhanced by populating specific restart/cancel process of the message (for this solution we used default implementation)
  • persistence engine – mostly responsible for setting/getting the data (payload)
    Persistence engine Class name Comments
    XML /AIF/CL_PERSIST_ENGINE_XML Commonly used but not for proxy interfaces
    Web Service /AIF/CL_PERSIST_ENGINE_WEBSERV Only WebService communication
    Proxy /AIF/CL_PERSIST_ENGINE_PROXY Message handled by SAP PI system (e.g. allows to restart messages and control them)
    Abstract class /AIF/CL_PERSIST_ENGINE_BASE Base class (root)
    Others /AIF/CL_PERSIST_ENGINE_FILE
    /AIF/CL_PERSIST_ENGINE_RFC
    /AIF/CL_PERSIST_ENGINE_STRU
    /AIF/CL_PERSIST_ENGINE_IDOC
    /AIF/CL_PERSIST_ENGINE_BDC
    /AIF/CL_PERSIST_ENGINE_TRFCSTA
    /AIF/CL_PERSIST_ENGINE_CIFPP
    /AIF/CL_PERSIST_ENGINE_ODATA

For this solution we used default engines:

Application Engine – new WebService 

Persistence Engine – XML

In the proxy implementation class there must be logic created for enabling the AIF where all mappings, checks and actions are executed. In the example below standard exception class is used CX_MDC_STANDARD_MESSAGE_FAULT with specific properties. Therefore it is possible to catch the error and read all messages returned from the Action or any other AIF checks:

 TRY.

        /aif/cl_enabler_proxy=>process_message(
                 is_input                = ls_input
                 iv_exception_classname  = 'CX_MDC_STANDARD_MESSAGE_FAULT' ).


 CATCH cx_mdc_standard_message_fault INTO DATA(lo_fault).
	
	LOOP AT lo_fault->standard-fault_detail ASSIGNING FIELD-SYMBOL(<fs_fault>).
			
	" error handling

	ENDLOOP.


ENDTRY.

In second step persistence process is implemented where message GUID is taken from the static method call of enabler class ( aif/cl_enabler_proxy=>process_message )  and populated into the standard classes (there is no custom coding implemented). Methods below are taken from /AIF/CL_ENABLER_XML class :

 TRY.

        /aif/cl_enabler_proxy=>msgguid_from_proxy_engine(
          IMPORTING
            ev_msgguid = DATA(lv_msgguid)
        ).

        DATA(lr_enabler_xml) = NEW /aif/cl_enabler_xml(
           iv_msgguid   = CONV #( lv_msgguid )
           iv_direction = 'I'
           iv_ns        = c_ns
           iv_ifname    = c_ifname
           iv_ifversion = c_ifversion ).

        DATA(ls_xmlparse) = VALUE /aif/xmlparse_data(
                 ns      = c_ns
                 ifname  = c_ifname
                 ifver   = c_ifversion
                 msgguid = lv_msgguid ).

        GET REFERENCE OF is_input INTO ls_xmlparse-xi_data.

        GET REFERENCE OF ls_xmlparse INTO lr_xmlparse.

        TRY.

            /aif/cl_aif_engine_factory=>get_engine(
               iv_ns            = c_ns
               iv_ifname        = c_ifname
               iv_ifversion     = c_ifversion )->persist_message_data(
                  EXPORTING
                    iv_use_buffer = abap_false
                  CHANGING
                    cr_xmlparse   = lr_xmlparse ).

          CATCH /aif/cx_error_handling_general INTO DATA(lr_err_general).

				
        ENDTRY.

      CATCH /aif/cx_enabler_base
            /aif/cx_aif_engine_not_found
            cx_ai_system_fault
            /aif/cx_error_handling_general.

        " todo

    ENDTRY.



Leave a Reply