Configuration-less Shortcut and Generic Consumer Proxy
Both features (configuration-less shortcut and generic consumer proxy) are offered starting with
- NGAP 1.0
- NetWeaver Release 7.31
and were downported to
- NetWeaver Release 7.02 SP8
- NetWeaver Release 7.30 SP3
An ABAP Consumer Proxy on an SAP Netweaver system exposes the interface of a Provider Service (Web Service) to a consuming application (or framework).
To make a Provider Service consumable, an Endpoint must be created on provider side. On consumer side, a configuration step is needed that stores all relevant information to open the connection and meet the requirements of the Provider Endpoint. Such requirements are specified in the binding part of a WSDL and include e.g. security and logon settings, optimization of transfer format, usage of WS-RM or WS-A. The complete set of relevant information on consumer side is stored in a so-called Logical Port. At runtime, the Logical Port name is typically determined in a Receiver Determination step, and the Logical Port name is then used to create an instance of a Consumer Proxy
In case the Consumer Proxy and the Provider Service are located on the same system, the Provider Service call can be executed much simpler and faster via a shortened processing (called shortcut), without the necessity for logon, for security processing (like e.g. encryption), for remote communication processing and others. However, it used to be necessary to create a separate Endpoint for local communication on the provider side, and to create a Logical Port for local communication on the consumer side.
The new feature of a configuration-less shortcut simplifies the local usage of a Provider Service. It is no longer necessary to create an Endpoint and a Logical Port for local communication in a separate configuration step. Instead, a generic endpoint for all Provider Services is generated during technical setup of the web service runtime (within report SRT_ADMIN), and a Logical Port name for shortcut processing can be retrieved at runtime via API.
Typical use cases
Typical use cases for the local call of a Provider Service by a Consumer Proxy are:
- Business functionality is offered as Provider Services (e.g. eSOAP Services) and consumed by Consumer Proxies, no matter if the functionality is used remotely or locally. This allows for a unified programming model and flexibility concerning the deployment of software components.
- A programs wants to make use of the web service programming model, even when calling Provider Services only locally (see also chapter 1.2.2).
- Test programs
The following pseudo source code snippet shows how to get the name for a configuration-less shortcut, use this name to instantiate a consumer proxy and make a request-response call. The service definition name is required to define the design time information (like operation names, input, output and fault data types, session handling, ...) of the service that shall be called.
CONSTANTS: lc_service_def_name TYPE srt_wsp_dt_obj_name VALUE 'MY_SERVICE_DEFINITION'. DATA: lo_local_shortcut_handler TYPE REF TO if_srt_public_local_shortcut, lv_lp_name TYPE srt_lp_name, lo_my_proxy TYPE REF TO <co_my_proxy>, ls_request_data TYPE <my_request_data>, ls_response_data TYPE <my_response_data>. TRY. lo_local_shortcut_handler = cl_srt_public_factory=>get_local_shortcut_handler( ). lv_lp_name = lo_local_shortcut_handler->get_lp_name_by_sdef_name( lc_service_def_name ). " Create proxy CREATE OBJECT lo_proxy EXPORTING logical_port_name = lv_lp_name. " execute call ls_request_data = ... lo_proxy->my_method( EXPORTING ls_request_data IMPORTING ls_response_data ). CATCH cx_srt_public_config. ... CATCH cx_ai_system_fault. ... ENDTRY.
Generic Consumer Proxy
When a Provider Service shall be called locally, the question comes up why a Consumer Proxy shall be called, instead of calling directly the ABAP provider interface of the Provider Service.
Reasons for calling the Provider Service through a Consumer Proxy are:
- Identical programming model on consumer side for local and remote call
- The identical programming model does not only cover the method call itself, but also the usage of the various WS protocols on consumer side (see interface IF_WSPROTOCOL), including sequencing, update task handling, message ID handling, session handling, attachment handling, etc.
- If a Consumer Proxy is used, the consuming application program is independent from local or remote execution of the service. This allows more flexibility of the deployment of software components and offers more chances for reuse of software modules.
- Identical programming model on provider side for local and remote call
- A direct call of the provider interface would fail, if the web service implementation makes use of the WS protocols on provider side, including sequencing data retrieval, message ID handling, attachment handling, etc.
- Process separation of consumer and provider
- Separation of consumer and provider process is relevant if the consuming application program and the Provider Service share common data like global variables, that must not be affected by the other program.
- Decoupling the application from errors and ExactlyOnce (EO) for one-way messages:
- In case of an application error during service execution, the message that represents the call is stored and can be restarted after error resolution.
- ExactlyOnce execution is guaranteed by the web service runtime, no application logic is needed for EO.
- Unified Support Tools
- Usage of a Consumer Proxy and thus the web service runtime allows for a unified Monitoring, Tracing and Logging, and Alerting by Health Checks.
So a local call through a Consumer Proxy has many advantages. But in case a Consumer Proxy is only required for local calls, the generation of such a proxy may be seen as redundant, as the Provider Service interface, which is locally available, includes all the design time information that is required for a local call.
The new feature of a Generic Consumer Proxy offers an API to call a Provider Service locally through the Generic Consumer Proxy without the need to generate a specific Consumer Proxy for each locally called Provider Service.
Internally, the Generic Consumer Proxy makes use of the Configuration-less Shortcut Logical Port. This allows for a *very simplified way to set up the local usage of Provider Services.
Typical use case
A typical use cases for the usage of the Generic Consumer Proxy is the adaptation of an existing Provider Service (e.g. an eSOA Service) to a modified service interface according to the needs of a communication partner. The communication partner could e.g. be a mobile application with a strongly reduced parameter set.
A generic consumer proxy can be used in different flavours:
- Instantiation by (provider) service interface name or by consumer proxy class name
- Provide a logical port name or use configuration-less shortcut LP as default
- Pass request (and response) data as ABAP data or XML xstring.
- Call (synchronous) request-response operation or (asynchronous) one-way operation
For the main use case from chapter 220.127.116.11, the generic consumer proxy will typically be instantiated by service interface (as a specific consumer proxy may not exist). It is not necessary to specify a logical port name, as the service shall be called locally. Data will be passed as ABAP data as built by the implementation of the adapted Provider Service.
Instantiation by specific consumer proxy name and passing data as XML xstring may not be important for applications but is used internally in the web service runtime.
As an example, the following pseudo code snippets shows how to instantiate the Generic Consumer Proxy by interface name in a local (shortcut) scenario and make a call based on the ABAP data for request (and response) message.
Request-response operation based on ABAP data
CONSTANTS: lc_interface_name TYPE seoclname VALUE 'MY_INTERFACE'. DATA: lo_generic_consumer TYPE REF TO if_proxy_generic_client, ls_request_data TYPE <my_request_data>, ls_response_data TYPE <my_response_data>. TRY. lo_generic_consumer = cl_proxy_gen_clnt_factory=>create_proxy_for_interface( intf_name = lc_interface_name ). ls_request_data = ... lo_generic_consumer->execute_abap_data( EXPORTING request = ls_request_data IMPORTING response = ls_response_data ). CATCH cx_ai_system_fault. ... CATCH cx_ai_application_fault. ... ENDTRY.
One-way operation based on ABAP data
CONSTANTS: lc_interface_name TYPE seoclname VALUE 'MY_INTERFACE'. DATA: lo_generic_consumer TYPE REF TO if_proxy_generic_client, ls_request_data TYPE <my_request_data>. TRY. lo_generic_consumer = cl_proxy_gen_clnt_factory=>create_proxy_for_interface( intf_name = lc_interface_name ). ls_request_data = ... lr_generic_consumer->execute_abap_data( EXPORTING request = ls_request_data ). CATCH cx_ai_system_fault. ... CATCH cx_ai_application_fault. ... ENDTRY.