- 27 October 2018
- Posted by: Mateusz Kwasniewski
- Category: SAP AIF
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
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.