As mentioned in the blog post for configuration of service group in SOAMANAGER, we need to prepare and upload the WSDL. In SAP NetWeaver PI/PO systems, it can be obtained from the Sender Agreement or Integrated Configuration object. For CPI one needs to enrich the WSDL by adding the binding information manually, as the deign time WSDL does not have this information.
In this blog let’s look at a way to enrich the design time WSDL for a consumer proxy in SAP Business system that can be uploaded to SOAMANAGER , using a transformation and a report program.
Step 1- XSL transformation
WSDL binding consists of
-
- Binding element -: Uses the portType available in the design time WSDL and a operation child element which uses the operation of the consumer proxy.
-
- Service Element -: Uses the binding information created above inside the child element port and location where the service is running.
Another consideration is for synchronous interface, the operation should have both input and output message (request and response) and optionally fault message if available.
For simplicity the code below uses hard coded values for SOAP address, which can be parameterized if needed.
The XSL transformation (ZZENRICH_CONSUMER_WSDL) source code is:
<xsl:stylesheet xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:sap="http://www.sap.com/sapxsl" version="1.0">
<!--
Consumer WSDL are generated wihtout binding information.
This transformation adds the binding and service nodes to make the WSDL, WS-I Compliant.
-->
<xsl:output encoding="UTF-8" indent="yes" method="xml"/>
<xsl:strip-space elements="*"/>
<!-- Declare Params, attribute paramter name should be in UPPERCASE-->
<xsl:param name="OPERTAION"/>
<xsl:param name="BINDTYPE"/>
<xsl:param name="MODE"/>
<!-- Declare Params-->
<xsl:template match="wsdl:definitions">
<xsl:copy>
<!-- Copy everything -->
<xsl:copy-of select="*|@*|comment()|processing-instruction()|text()"/>
<!-- AT the end add binding and service information with opertaion name and binding type being passed as external parameter -->
<wsdl:binding name="binding" type="{$BINDTYPE}">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="{$OPERTAION}">
<soap:operation soapAction="" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<xsl:choose>
<xsl:when test="$MODE = 'X'">
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
<!-- <wsdl:fault name="StandardFaultMessage">
<soap:fault name="StandardFaultMessage" use="literal"/>
</wsdl:fault> -->
</xsl:when>
</xsl:choose>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="service">
<wsdl:port binding="tns:binding" name="HTTPS_Port">
<soap:address location="https://myhost.com/"/>
</wsdl:port>
</wsdl:service>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
The above transformation uses 3 parameters.
-
- OPERTAION : Used to populate the operation name
-
- BINDTYPE : Used to populate the type for binding element and is constructed by concatenating target namespace (in this example tns) and the consumer proxy name
-
- MODE : Indicator to specify if the interface is synchronous
Step 2- Report program
For the consumer proxy design time WSDL can be fetched using the class CL_PROXY_PUBLIC_UTILS and also fetch and prepare the input parameters for the transformation as explained above
TRY.
DATA(lv_wsdl) = cl_proxy_public_utils=>get_consumer_dt_wsdl( obj_name = CONV #( api_name ) ).
CATCH cx_proxy_fault.
ENDTRY.
cl_proxy_public_utils=>get_interface_data(
EXPORTING
abap_keys = VALUE #( ( obj_name = api_name ) )
IMPORTING
intf_data = lt_intf_detail
).
READ TABLE lt_intf_detail ASSIGNING FIELD-SYMBOL(<ls_intf_detail>) INDEX 1.
CHECK sy-subrc = 0.
CONCATENATE 'tns:' <ls_intf_detail>-name INTO DATA(lv_binding_name).
TRY.
CALL TRANSFORMATION zzenrich_consumer_wsdl PARAMETERS opertaion = <ls_intf_detail>-operation
bindtype = lv_binding_name
mode = <ls_intf_detail>-synchron
SOURCE XML lv_wsdl
RESULT XML lv_wsdl.
CATCH cx_transformation_error.
ENDTRY.
Verifying the output:
On executing the report we can see the enriched WSDL as shown below. This example uses interface CO_MDM_PRD_BULK_REPL_REQ_OUT and screenshot from the debugger is provided, but the output can also be downloaded to a file.
Optionally you can validate the WSDL for WS-I Compliance using any external tool (SOAP UI as an example)