savonrb / wasabi

A simple WSDL parser
MIT License
90 stars 84 forks source link

Get input from message element or portType input. #5

Closed hoverlover closed 12 years ago

hoverlover commented 12 years ago

This PR will enable wasabi to automatically include the proper input message by inspecting the WSDL document. Sometimes, the operation name in the binding isn't the exact input message that is expected. The real input message is usually specified in a message element. This is best shown by example:

<?xml version='1.0' encoding='UTF-8'?>
<wsdl:definitions 
    name="AuthenticationWebServiceImplService"
    targetNamespace="http://v1_0.ws.auth.order.example.com/"
    xmlns:ns1="http://cxf.apache.org/bindings/xformat"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:tns="http://v1_0.ws.auth.order.example.com/"
    xmlns:tns1="http://v1_0.ws.auth.order.example.com/request"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <wsdl:types>
        <xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://v1_0.ws.auth.order.example.com/" xmlns:tns="http://v1_0.ws.auth.order.example.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
            ...
        </xs:schema>
    </wsdl:types>
    <wsdl:message name="authenticate">
        <wsdl:part element="tns1:AuthenticateUser" name="parameters" />
    </wsdl:message>
    <wsdl:message name="authenticateResponse">
        <wsdl:part element="tns:AuthenticateResponse" name="parameters" />
    </wsdl:message>
    <wsdl:portType name="AuthenticationWebService">
        <wsdl:operation name="authenticate">
            <wsdl:input message="tns:authenticate" name="authenticate" />
            <wsdl:output message="tns:authenticateResponse" name="authenticateResponse" />
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="AuthenticationWebServiceImplServiceSoapBinding" type="tns:AuthenticationWebService">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
        <wsdl:operation name="authenticate">
            <soap:operation soapAction="" style="document" />
            <wsdl:input name="authenticate">
                <soap:body use="literal" />
            </wsdl:input>
            <wsdl:output name="authenticateResponse">
                <soap:body use="literal" />
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="AuthenticationWebServiceImplService">
        <wsdl:port binding="tns:AuthenticationWebServiceImplServiceSoapBinding" name="AuthenticationWebServiceImplPort">
            <soap:address location="http://example.com/validation/1.0/AuthenticationService" />
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

In this example, the operation's input name is authenticate, and the message attribute is tns:authenticate. Neither of these are the proper, expected input message of AuthenticateUser. For this, we need to walk up the portType, then to the matching message to get the actual input message of AuthenticateUser. See Savon PR #277 to get the full picture on how this all works together, and enables you to pass a single symbol into the Savon::Client#request method and get automatic namespace mapping, as well as the proper operation name -> input message mapping.

rubiii commented 12 years ago

thanks again :) released as v2.2.0.