Search code examples
rubyxmlsoapwsdlsavon

invalid SOAP request needs experienced eye


TLDR: the solution can be found here

I'm using savon to make requests against a SOAP service. I know... Gross.

Regardless, I'm having trouble making Savon behave. The SOAP provider has this validator, which takes the following inputs:

Web Service: ProductData
Version: 1.0.0
Operation: getProductSellable
Endpoint: https://psproductdata100-stg.pcna.online

When I use the validator, I enter this xml:

<GetProductSellableRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/">
  <wsVersion xmlns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/">1.0.0</wsVersion>
</GetProductSellableRequest>

And I get this response body

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header />
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <GetProductSellableResponse xmlns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/">
      <ErrorMessage xmlns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/">
        <code>110</code>
        <description>Authentication Credentials Required</description>
      </ErrorMessage>
    </GetProductSellableResponse>
  </s:Body>
</s:Envelope>

That response is valid because I did not provide my un/pw. If I do provide credentials, I get a full response. Below is a screenshot of that happening in my browser.

image

However, when I use Savon to make the same request

#!/usr/bin/env ruby

require 'savon'
require 'awesome_print'
require 'byebug'
require 'pry'

endpoint = 'https://psproductdata100-stg.pcna.online'
path = 'psProductData.svc?singleWsdl'
wsdl = "#{endpoint}/#{path}"

args = {
  wsdl: wsdl,
  log: true,
  log_level: :debug,
  pretty_print_xml: true,
  element_form_default: :qualified
}

client = Savon.client(args) do
  convert_request_keys_to :lower_camelcase
end

message = { ws_version: '1.0.0' }
response = client.call(:get_product_sellable) do
  message(message)
end

ap response

The response does not come back as expected. The XML looks close to what was sent by the validator, but not exact.

Heres the request

D, [2018-04-26T18:01:00.471662 #89854] DEBUG -- : HTTPI /peer GET request to psproductdata100-stg.pcna.online (net_http)
I, [2018-04-26T18:01:00.979809 #89854]  INFO -- : SOAP request: https://psproductdata100-stg.pcna.online/psProductData.svc
I, [2018-04-26T18:01:00.979886 #89854]  INFO -- : SOAPAction: "getProductSellable", Content-Type: text/xml;charset=UTF-8, Content-Length: 501
D, [2018-04-26T18:01:00.980107 #89854] DEBUG -- : <?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ins0="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/">
  <env:Body>
    <tns:GetProductSellableRequest>
      <tns:wsVersion>1.0.0</tns:wsVersion>
    </tns:GetProductSellableRequest>
  </env:Body>
</env:Envelope>

And the response

D, [2018-04-26T18:01:00.980224 #89854] DEBUG -- : HTTPI /peer POST request to psproductdata100-stg.pcna.online (net_http)
I, [2018-04-26T18:01:01.650449 #89854]  INFO -- : SOAP response (status 200)
D, [2018-04-26T18:01:01.650731 #89854] DEBUG -- : <?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <GetProductSellableResponse xmlns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/">
      <ErrorMessage xmlns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/">
        <code>110</code>
        <description>Version mismatch.</description>
      </ErrorMessage>
    </GetProductSellableResponse>
  </s:Body>
</s:Envelope>

and the output from Savon

{
    :get_product_sellable_response => {
        :error_message => {
                   :code => "110",
            :description => "Version mismatch.",
                 :@xmlns => "http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/"
        },
               :@xmlns => "http://www.promostandards.org/WSDL/ProductDataService/1.0.0/"
    },
                     :"@xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
                     :"@xmlns:xsd" => "http://www.w3.org/2001/XMLSchema"
}

Solution

  • Similar problem with namespaces ruby savon and wsdl namespacing. I believe you have the same problem.

    Additional Note: Try to use SOAP UI to debug, the generated XML from the WSDL and see the difference. Also change the XML to the XML generated from the code and validate the XML in SOAP UI. It will show the errors if any in SOAP UI, will make debugging faster and errors more understandable.