Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
vadimklimov
Active Contributor

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:

  <gfs_file_data> TYPE gty_file_data.

TRY.

    CALL FUNCTION 'GUI_UPLOAD'

      EXPORTING
filename =
'D:\Temp\TestDoc.pdf'
filetype = 'BIN'
TABLES
data_tab = gt_file_data.


    IF sy-subrc NE 0.

        " Error handling logic

      ENDIF.

    LOOP AT gt_file_data ASSIGNING <gfs_file_data>.
CONCATENATE gv_attachment_xstring


                  <gfs_file_data>-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):
<?xml version="1.0" encoding="UTF-8"?>

<!-- Inbound Message -->

<SAP:ReliableMessaging xmlns:SAP=http://sap.com/xi/XI/Message/30 xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" SOAP:mustUnderstand="1">

   <SAP:QualityOfService>ExactlyOnceInOrder</SAP:QualityOfService>

   <SAP:QueueId>TEST_QUEUE</SAP:QueueId>

</SAP:ReliableMessaging>

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):
<?xml version="1.0" encoding="UTF-8"?>

<!-- Receiver Determination -->

<SAP:Error xmlns:SAP="http://sap.com/xi/XI/Message/30" xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" SOAP:mustUnderstand="1">

   <SAP:Category>XIServer</SAP:Category>

   <SAP:Code area="RCVR_DETERMINATION">NO_RECEIVER_CASE_BE</SAP:Code>

   <SAP:P1 />

   <SAP:P2 />

   <SAP:P3 />

   <SAP:P4 />

   <SAP:AdditionalText />

   <SAP:Stack>No receiver could be determined</SAP:Stack>

   <SAP:Retry>M</SAP:Retry>

</SAP:Error>

With usage of protocol, receiver determination object is still missing in Integration Directory (extract of Trace of XI message):
<Trace level="1" type="B" name="PLSRV_RECEIVER_DETERMINATION">

<Trace level="1" type="Timestamp">2012-10-18T06:46:22Z CET Start of pipeline service processing PLSRVID= PLSRV_RECEIVER_DETERMINATION</Trace>

<Trace level="1" type="B" name="CL_XMS_MAIN-CALL_PLSRV">

<Trace level="1" type="B" name="CL_XMS_MAIN-CALL_PLSRV_LOCAL">

<Trace level="1" type="B" name="CL_RD_PLSRV-ENTER_PLSRV">

<Trace level="1" type="T">R E C E I V E R - D E T E R M I N A T I O N </Trace>

<Trace level="1" type="T"> Cache content is up to date </Trace>

<Trace level="2" type="T">Start with given receiver  - PIUCLNT105 </Trace>

<Trace level="2" type="T">Using Receiver Determination 00000000000000000000000000000000 </Trace>

<Trace level="1" type="T">No Relation found - accept given Receivers. </Trace>

<Trace level="2" type="T">...extracting Receiver from Header:  PIUCLNT105 </Trace>

<Trace level="2" type="T">Classic Receiver Determination via Rules. </Trace>

<Trace level="2" type="T">No Receiver found behaviour: 0  </Trace>

<Trace level="2" type="T">Number of Receivers:1  </Trace>

</Trace>

</Trace>

</Trace>

<Trace level="1" type="Timestamp">2012-10-18T06:46:22Z CET End of pipeline service processing PLSRVID= PLSRV_RECEIVER_DETERMINATION</Trace>

</Trace>

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: http://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:

19 Comments
Labels in this area