savonrb / wasabi

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

[3.3.0] Invalid namespace while parsing WS-N wsdl #56

Open keltia opened 9 years ago

keltia commented 9 years ago

I'm trying to send a request for a WebService Notification service (WS-N).

Using the following WSDL (which import various OASIS-based WSDL/XSD) — https://gist.github.com/keltia/8e6cb6da0521c0290cd8, an invalid namespace is used to generate the request.

Error: 500 (soap:Client) Unexpected element {http://docs.oasis-open.org/wsn/brw-2}Subscribe found.   Expected {http://docs.oasis-open.org/wsn/b-2}Subscribe.

The code is very basic:

# Main module
module Surv
  class Client
    attr_accessor :topics
    attr_reader :client, :config

    def initialize(config)
      @topics = Hash.new
      @out = config.feed_one

      #$stderr.puts("Entry point is #{config.proto}://#{config.site}:#{config.port}/#{config.entry}.")

      client = Savon.client(wsdl: config.wsdl,
                            strip_namespaces: false,
                            log_level: :info,
                            convert_request_keys_to: :camelcase,
                            #pretty_print_xml: true,
      )

      #$stderr.puts("Entry point: #{client.wsdl.endpoint}")
      $stderr.puts("Init done.")
      $stderr.puts("Available methods: #{client.operations}")
      @client = client
      @config = config
    end

    def subscribe(topic, callback)
      my_topic = "#{@config.base}/#{callback}"
      message = {
          ConsumerReference: {
            Address: my_topic,
          },
          Filter: {
              TopicExpression: topic,
          },
      }

      $stderr.puts(message)
      $stderr.puts("  Subscribing #{my_topic} for #{topic}")

      @topics[callback] = Topic.new(callback)
      @topics[callback].bytes = 0
      @topics[callback].pkts = 0

      begin
        resp = client.call(:subscribe, message: message)
      rescue Savon::Error => error
        $stderr.puts("Error: #{error.http.code} #{error}")
      end
    end
  end
end

the request generated is:

<?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:wsdl="http://docs.oasis-open.org/wsn/brw-2"
           xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
  <env:Body>
    <wsdl:Subscribe>
      <consumerReference>
        <address>http://localhost/feed_jsongz</address>
      </consumerReference>
      <filter>
        <topicExpression>AsterixJSONGzipped</topicExpression>
      </filter>
    </wsdl:Subscribe>
  </env:Body>
</env:Envelope>

wsdl should be using b-2 and not brw-2. SoapUI get it right see the following screenshot: https://www.dropbox.com/s/ntyxz44se481eu1/Screenshot%202015-03-10%2015.05.31.png?dl=0

Any idea?

tjarratt commented 9 years ago

This is a tricky issue @keltia. I haven't read the spec fully on this, but my best guess is that the br-2 namespace is brought in from the imported WSDL on line 9 of your gist.

Wasabi has never had support for importing other xsd or wsdls, mainly because of the numerous challenges involved. This makes me really sad, because it's one of the most common problems people have with Savon and Wasabi, and it generates a lot of support requests.

My best guess at a workaround would be to take all of the imports from your WSDL and combine them into a single WSDL, and take the combined document and feed that to Savon.

tjarratt commented 9 years ago

I also tried to take your example and pare it down a bit, so it was actually runnable. Seems like the remote server is unresponsive, because all of my attempts to run this code timed out while opening a socket.

https://gist.github.com/tjarratt/f9c9de9c23e96d957ca6

Anyway, hope this helps!

keltia commented 9 years ago

To my experience, it is pretty seldom that you have a self-contained wsdl file. All the standard ones, be it OASIS or W3C, do have includes for types definitions and other stuff so supporting both XSD and WSDL inclusion is just a must otherwise we end up in that very situation.

The main problem is that there are no so many SOAP client libraries out there (in fact, I only know of Savon & Wasabi) so we do not have any choice...

I do not know how to fix that (and to be honest, if I could do w/o all that XML stuff I would).

I'll try to see if merging everything is doable although I manage to do everything myself by manually writing the XML code.

tjarratt commented 9 years ago

I think since this is such a common problem with Savon (it's actually issue #1), that I'm going to try to dedicate some time to this later this month. Some of the simple cases (e.g.: absolute URLs) should be straightforward, and adding additional cases can happen on an as-needed basis.

Would love to hear how merging all the XML works, when you get a chance.