Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WSDL Response decoding does not seem to work #74

Open
leth opened this issue Jan 2, 2019 · 7 comments
Open

WSDL Response decoding does not seem to work #74

leth opened this issue Jan 2, 2019 · 7 comments

Comments

@leth
Copy link
Contributor

leth commented Jan 2, 2019

I cannot, despite my best efforts, find a way to decode the response body.
The envelope is processed fine, just the contents of the Body is not decoded.

I think we need a test case for the generated code, as #25 calls for

@droyo
Copy link
Owner

droyo commented Jan 3, 2019

I admit I haven't even manually tested this part of the generated code very thoroughly. Would you happen to have a WSDL endpoint in mind that we can use as an example?

@leth
Copy link
Contributor Author

leth commented Jan 3, 2019

I'm new to the world of WSDL, so don't have any examples to test against.
It's fairly striaghtforward to catch: if you marshal and serialise a request struct to bytes, then try to deserialise and marshal it back to structs then it will just be empty.

IIUC it's because the Envelope Body is an interface{}; go can marshal it since it has a instance to reflect on, but it can't unmarshal it because it's not sure what type they should be.

@droyo
Copy link
Owner

droyo commented Jan 3, 2019

Ah, it looks like the tests I have in wsdlgen/examples/* only test marshalling.

I think the gentests/_testgen can be easily extended to generate tests for wsdlgen if there is a *.wsdl file, and mock responses if there is a *.sample file in the relevant directory, with some inspiration from the links you gave me in #25.

@droyo
Copy link
Owner

droyo commented Jan 5, 2019

Ok, I 've got some rudimentary tests pushed in the issue-25 branch and I think I might see the problem. It looks like I may have added an unnecessary layer of encapsulation in the temporary types used to marshal/unmarshal requests and responses. Example:

WSDL:

<message name="GetLastTradePriceOutput">
    <part name="body" element="xsd1:TradePrice"/>
</message>

<portType name="StockQuotePortType">
    <operation name="GetLastTradePrice">
       <input message="tns:GetLastTradePriceInput"/>
       <output message="tns:GetLastTradePriceOutput"/>
    </operation>
</portType>

Go:

var output struct {
	XMLName struct{} `xml:"http://example.com/stockquote.wsdl GetLastTradePrice"`
	Args    struct {
		Body TradePrice `xml:"http://example.com/stockquote.wsdl body"`
	} `xml:"http://example.com/stockquote.wsdl GetLastTradePriceOutput"`
}

I'll need to check the soap spec again to see what the correct behavior is here.

@droyo
Copy link
Owner

droyo commented Jan 6, 2019

Ok, the relevant portion of the WSDL spec is https://www.w3.org/TR/2001/NOTE-wsdl-20010315#_porttypes and it does seem like I have a few too many layers here.

@droyo
Copy link
Owner

droyo commented Jan 9, 2019

OK, reading the specs a bit more I'm beginning to understand.

https://www.w3.org/TR/2001/NOTE-wsdl-20010315#_soap:operation

The value of this attribute also affects the way in which the Body of the SOAP message is constructed [...] If the attribute is not specified, it defaults to the value specified in the soap:binding element. If the soap:binding element does not specify a style, it is assumed to be "document".

https://www.w3.org/TR/2001/NOTE-wsdl-20010315#_soap:body

If the operation style is rpc each part is a parameter or a return value and appears inside a wrapper element within the body (following Section 7.1 of the SOAP specification). [...]
If the operation style is document there are no additional wrappers, and the message parts appear directly under the SOAP Body element.

Relevant portions of the SOAP spec:

rpc style: https://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383533
doc style: https://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383503

So next steps would be:

  • extend wsdl package to parse the soap:binding element (it was ignored prior)
  • extend wsdl package to classify operations as "One-way", "Request-response", "Solicit-response", or "Notification".
  • when using rpc style for an operation or binding, parameters should be members of a wrapper struct.
    • If the relevant part for the parameter is not named, its name is that of the operation, plus ""/"Request"/"Response"/"Solicit", depending on the type of operation.
  • when using document style for an operation or binding, parameters are dropped right into the soap envelope's Body element.

I opened #76 for the related goal of generating error types for soap faults.

@leth
Copy link
Contributor Author

leth commented Jan 9, 2019

Thanks for looking into this in such detail! In the interim I've switched to xsdgen, and manually built the soap envelope handling for my service.

I'm working with an operation which binds input and output to the SOAP body:

      <wsdl:input>
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
      </wsdl:output>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants