ABAP Proxy Protocols: Use Cases and Examples
Intro
Usage of ABAP proxy communication technology is becoming more and more popular when implementing integration involving SAP application system running on ABAP stack mediated via SAP NetWeaver Processing Integration / Process Orchestration with counterpart systems. Unfortunately, not all requirements can be fulfilled using standard means of proxies (for example, retrieval of XI message header / routing data, serialized message processing, manipulation with the generated XI message payload). In such cases, the one may benefit from utilizing so-called proxy protocols – a set of functions that are provided as a part of ABAP proxy framework and enabling usage of additional services of ABAP proxy runtime.
The goal of this blog is to provide summarized overview of available ABAP proxy protocols and depict most common use cases that are relevant for proxy protocols utilization. General steps that are necessary for ABAP proxy implementation as well as common aspects of proxy runtime and monitoring are out of scope of this blog.
Overview
Proxy protocols are provided by ABAP proxy runtime through ABAP classes that implement respective interface. A list of available XI/WS protocols can be found as constants of interface IF_WSPROTOCOL:
Protocols supported by ABAP proxy are listed below:
- XI_HEADER
- MESSAGE_ID
- PAYLOAD
- ATTACHMENTS
- ASYNC_MESSAGING
- ROUTING
- CONNECTIVITY
Each protocol specification (including protocol-specific operations) is defined in the respective interface (interfaces names start from IF_WSPROTOCOL_). Each interface has respective implementing class named by the interface name (e.g. class CL_WSPROTOCOL_XI_HEADER implements interface IF_WSPROTOCOL_XI_HEADER). A list of supported ABAP proxy specific protocols with breakdown per available operations for these protocols is summarized in the table below:
For consumer (outbound) proxy, protocol can be retrieved using method GET_PROTOCOL that is available for the proxy object instantiated using generated proxy interface in the caller program. GET_PROTOCOL method is a generic method that is defined in interface IF_PROXY_BASIS and implemented in class CL_PROXY_BASIS that is inherited by the generated proxy. Here is an example of XI message GUID retrieval (one of the most common use cases of ABAP proxy protocols usage) done on the consumer side:
DATA:
gr_consumer_proxy TYPE REF TO zco_consumer_proxy,
gr_proto_msg_id TYPE REF TO if_wsprotocol_message_id,
gx_system TYPE REF TO cx_ai_system_fault,
gs_msg_id TYPE sxmsmguid.
TRY.
CREATE OBJECT gr_consumer_proxy.
gr_proto_msg_id ?=
gr_consumer_proxy->get_protocol( if_wsprotocol=>message_id ).
gs_msg_id = gr_proto_msg_id->get_message_id( ).
CATCH cx_ai_system_fault INTO gx_system.
” Exception handling logic
ENDTRY.
As it can be seen from the provided example, an instance of the object representing the required protocol is created and then protocol-specific operation is called for that instance. Please note that for some protocols, it can be possible (may be necessary) to call several operations in a sequence.
For provider (inbound) proxy: protocol can be retrieved using method GET_PROTOCOL of the server context instance (server context is obtained via method GET_SERVER_CONTEXT of class CL_PROXY_ACCESS). The example below is again XI message GUID retrieval done on the provider side:
DATA:
gr_srv_context TYPE REF TO if_ws_server_context,
gr_proto_msg_id TYPE REF TO if_wsprotocol_message_id,
gx_system TYPE REF TO cx_ai_system_fault,
gs_msg_id TYPE sxmsmguid.
TRY.
gr_srv_context = cl_proxy_access=>get_server_context( ).
gr_proto_msg_id ?=
gr_server_context->get_protocol( if_wsprotocol=>message_id ).
gs_msg_id = gr_proto_msg_id->get_message_id( ).
CATCH cx_ai_system_fault INTO gx_system.
” Exception handling logic
ENDTRY.
As seen from the coding, firstly server context is retrieved that is followed by instantiation of the object representing the required protocol. Finally, protocol-specific operation is called.
If the requested protocol is not supported, exception of class CX_AI_SYSTEM_FAULT is raised that contains details of the called protocol (error id = PRX_PROTO_NOT_SUPPORTED, error text includes name of the called protocol):
Remaining part of the blog contains some examples of utilization of commonly used protocols.
Protocol XI_HEADER
Sample use case: retrieve some data elements of XI message header level of the processed XI message on the receiver side.
Source code extract (provider proxy):
DATA:
gr_srv_context TYPE REF TO if_ws_server_context,
gr_proto_header TYPE REF TO if_wsprotocol_xi_header,
gx_system TYPE REF TO cx_ai_system_fault,
gv_snd_service TYPE string,
gv_snd_interface TYPE string,
gv_snd_namespace TYPE string,
gv_rcv_service TYPE string.
TRY.
gr_srv_context = cl_proxy_access=>get_server_context( ).
gr_proto_header ?=
gr_srv_context->get_protocol( if_wsprotocol=>xi_header ).
gv_snd_service =
gr_proto_header->get_header_field( if_wsprotocol_xi_header=>sender_service ).
gv_snd_interface =
gr_proto_header->get_header_field( if_wsprotocol_xi_header=>interface ).
gv_snd_namespace =
gr_proto_header->get_header_field( if_wsprotocol_xi_header=>interface_namespace ).
gv_rcv_service =
gr_proto_header->get_header_field( if_wsprotocol_xi_header=>receiver_service ).
CATCH cx_ai_system_fault INTO gx_system.
” Exception handling logic
ENDTRY.
Outcome: information about sender service, interface and interface namespace as well and receiver service are retrieved from XI message header.
Remark: a list of supported attachment types can be found as constants of interface IF_WSPROTOCOL_XI_HEADER:
Protocol MESSAGE_ID
Sample use case: retrieve message GUID of the processed XI message on the receiver side.
Source code extract (provider proxy):
DATA:
gr_srv_context TYPE REF TO if_ws_server_context,
gr_proto_msg_id TYPE REF TO if_wsprotocol_message_id,
gx_system TYPE REF TO cx_ai_system_fault,
gs_msg_id TYPE sxmsmguid.
TRY.
gr_srv_context = cl_proxy_access=>get_server_context( ).
gr_proto_msg_id ?=
gr_server_context->get_protocol( if_wsprotocol=>message_id ).
gs_msg_id = gr_proto_msg_id->get_message_id( ).
CATCH cx_ai_system_fault INTO gx_system.
” Exception handling logic
ENDTRY.
Outcome: XI message GUID is retrieved from XI message header.
Remark: message GUID can be retrieved using protocol XI_HEADER as well, but in order to simplify this task, special protocol MESSAGE_ID was introduced.
Protocol PAYLOAD
Sample use case: suppress the required given payload element in the payload of the processed XI message on the sender side.
Source code extract (consumer proxy):
DATA:
gr_consumer_proxy TYPE REF TO zco_consumer_proxy,
gr_proto_payload TYPE REF TO if_wsprotocol_payload,
gx_system TYPE REF TO cx_ai_system_fault,
gs_msg_request TYPE zmt_proxy_request,
gt_controller TYPE prxctrltab,
gs_controller_line TYPE prxctrl.
TRY.
CREATE OBJECT gr_consumer_proxy.
gr_proto_payload ?=
gr_consumer_proxy->get_protocol( if_wsprotocol=>payload ).
gr_proto_payload->set_extended_xml_handling( abap_true ).
gs_controller_line-field = ‘TEXT’.
gs_controller_line-value = sai_ctrl_none.
APPEND gs_controller_line TO gt_controller.
gs_msg_request-mt_proxy_request-controller = gt_controller.
CATCH cx_ai_system_fault INTO gx_system.
” Exception handling logic
ENDTRY.
Outcome: payload element ‘Text’ is suppressed and will not exist in the payload of the transmitted XI message.
Remark: each complex type of the message type includes the table element CONTROLLER (controller table) generated for it by proxy generator (meaning that the same message type may have several controller tables after proxy generation for the respective service interface). Controller table should contain enumeration of elements with respective payload operation for each of them (initialize value, suppress value, set value xsi:nil) for those elements that should be treated exceptionally. Values that were originally assigned to such payload elements are overwritten by protocol PAYLOAD.
Protocol ATTACHMENTS
Sample use case: supplement XI message payload data with the attached PDF document located on the local host on the sender side.
Source code extract (consumer proxy):
TYPES:
BEGIN OF gty_file_data,
entry TYPE x LENGTH 255,
END OF gty_file_data.DATA:
gr_consumer_proxy TYPE REF TO zco_consumer_proxy,
gr_proto_attachment TYPE REF TO if_wsprotocol_attachments,
gr_attachment TYPE REF TO if_ai_attachment,
gt_attachments TYPE prx_attach,gt_file_data TYPE TABLE OF gty_file_data,
gv_attachment_xstring TYPE xstring.
FIELD-SYMBOLS:
TYPE gty_file_data. TRY.
CALL FUNCTION ‘GUI_UPLOAD’
EXPORTING
filename = ‘D:TempTestDoc.pdf’
filetype = ‘BIN’
TABLES
data_tab = gt_file_data.IF sy-subrc NE 0.
” Error handling logic
ENDIF.
LOOP AT gt_file_data ASSIGNING
.
CONCATENATE gv_attachment_xstring
–entry INTO gv_attachment_xstring
IN BYTE MODE.
ENDLOOP.CREATE OBJECT gr_consumer_proxy.
gr_proto_attachment ?=
gr_consumer_proxy->get_protocol( if_wsprotocol=>attachments ).
gr_attachment =
gr_proto_attachment->get_attachment_from_binary(
data = gv_attachment_xstring
type = if_ai_attachment=>c_mimetype_pdf
name = ‘AttachmentDocument’ ).
APPEND gr_attachment TO gt_attachments.
gr_proto_attachment->set_attachments( gt_attachments ).
CATCH cx_ai_system_fault INTO gx_system.
” Exception handling logic
ENDTRY.
Outcome: XI message is created with PDF document attached to it:
Remark: a list of supported attachment types can be found as constants of interface IF_AI_ATTACHMENT:
Protocol ASYNC_MESSAGING
Sample use case: ensure serialized processing of the XI message on the sender side.
Source code extract (consumer proxy):
DATA:
gr_consumer_proxy TYPE REF TO zco_consumer_proxy,
gr_proto_async TYPE REF TO if_wsprotocol_async_messaging,
gx_system TYPE REF TO cx_ai_system_fault,
gs_msg_request TYPE zmt_proxy_request.
TRY.
CREATE OBJECT gr_consumer_proxy.
gr_proto_async ?=
gr_consumer_proxy->get_protocol( if_wsprotocol=>async_messaging ).
gr_proto_async->set_serialization_context( ‘TEST_QUEUE’ ).
gr_consumer_proxy->o_async_send_sample( gs_msg_request ).
cl_soap_commit_rollback=>commit( ).
CATCH cx_ai_system_fault INTO gx_system.
” Exception handling logic
ENDTRY.
Outcome: XI message is serialized in context TEST_QUEUE in the sender application system (extract of ReliableMessaging of XI message):
https://sap.com/xi/XI/Message/30 xmlns:SOAP=”https://schemas.xmlsoap.org/soap/envelope/” SOAP:mustUnderstand=”1″>
ExactlyOnceInOrder
TEST_QUEUE
Protocol ROUTING
Sample use case: explicitly specify the receiver of the XI message on the sender side.
Source code extract (consumer proxy):
DATA:
gr_consumer_proxy TYPE REF TO zco_consumer_proxy,
gr_proto_routing TYPE REF TO if_wsprotocol_routing,
gx_system TYPE REF TO cx_ai_system_fault,
gt_set_receivers TYPE sxi_addresses,
gs_set_receiver TYPE sxi_address.
TRY.
CREATE OBJECT gr_consumer_proxy.
gr_proto_routing ?=
gr_consumer_proxy->get_protocol( if_wsprotocol=>routing ).
gs_set_receiver-service = ‘PIUCLNT105’.
APPEND gs_set_receiver TO gt_set_receivers.
gr_proto_routing->set_receivers( gt_set_receivers ).
CATCH cx_ai_system_fault INTO gx_system.
” Exception handling logic
ENDTRY.
Outcome: the receiver is explicitly set by the consumer and passed to central Integration Engine. Even if there is an issue with the receiver determination configuration in PI, the message will be successfully processed in case remaining part of logical routing (precisely, interface determination logic) exists and is correct for the specified receiver.
Without usage of protocol, receiver determination object is missing in Integration Directory (Error of XI message):
https://sap.com/xi/XI/Message/30 ” xmlns:SOAP=”https://schemas.xmlsoap.org/soap/envelope/” SOAP:mustUnderstand=”1″>
XIServer
NO_RECEIVER_CASE_BE
No receiver could be determined
M
With usage of protocol, receiver determination object is still missing in Integration Directory (extract of Trace of XI message):
2012-10-18T06:46:22Z CET Start of pipeline service processing PLSRVID= PLSRV_RECEIVER_DETERMINATION
R E C E I V E R – D E T E R M I N A T I O N
Cache content is up to date
Start with given receiver – PIUCLNT105
Using Receiver Determination 00000000000000000000000000000000
No Relation found – accept given Receivers.
…extracting Receiver from Header: PIUCLNT105
Classic Receiver Determination via Rules.
No Receiver found behaviour: 0
Number of Receivers:1
2012-10-18T06:46:22Z CET End of pipeline service processing PLSRVID= PLSRV_RECEIVER_DETERMINATION
Protocol CONNECTIVITY
Sample use case: retrieve information about runtime framework of the processed XI message on the sender side.
Source code extract (consumer proxy):
DATA:
gr_consumer_proxy TYPE REF TO zco_consumer_proxy,
gr_proto_conn TYPE REF TO if_wsprotocol_connectivity,
gx_system TYPE REF TO cx_ai_system_fault,
gv_conn_type TYPE string.
TRY.
CREATE OBJECT gr_consumer_proxy.
gr_proto_conn ?=
gr_proxy_request_time->get_protocol( if_wsprotocol=>connectivity ).
gv_conn_type = gr_proto_conn->get_type( ).
CATCH cx_ai_system_fault INTO gx_system.
” Exception handling logic
ENDTRY.
Outcome: runtime framework type (XI for ABAP proxy) and its version (currently available for XI – 2.0 and 3.0) are retrieved.
Outro
For more information regarding ABAP proxy protocols (inlcuding more examples), refer to SAP Help Portal: https://help.sap.com/saphelp_nw73ehp1/helpdata/en/51/d5cd16235e4643ae8ec92395c4ad97/content.htm .
There are also some other blogs on SCN that discuss ABAP proxy protocols application on real-life examples – here are links to some of them:
- Consumption of protocols in provider proxies, the blog written by Michal Krawczyk: https://scn.sap.com/community/pi-and-soa-middleware/blog/2012/02/06/michals-pi-tips-accessing-protocol-classes-for-provider-abap-proxies–xi-message-header
- Usage of protocol ATTACHMENTS, the blog written by Michal Krawczyk: https://scn.sap.com/community/pi-and-soa-middleware/blog/2006/04/19/xi-rfc-or-abap-proxy-abap-proxies-with-attachments
- Usage of protocol MESSAGE_ID, the blog written by Mickael Huchet: https://scn.sap.com/people/mickael.huchet/blog/2011/11/10/ecc-outbound-abap-proxy-client–get-ecc-messageid-from-protocol
New NetWeaver Information at SAP.com
Very Helpfull