From e090cc5bd98c287161d929895e77306e97eac555 Mon Sep 17 00:00:00 2001 From: Celso Fernandes Date: Thu, 3 Mar 2016 11:52:26 -0300 Subject: [PATCH] Add support for rpc encoded wsdl After Wasabi add support for multi part on messages, now it's returning a hash with parts, and Savon needs to handle correctly. So on builder, instead of just add a single message to body, now handle if it's a hash and build the body containing the respective parts, with its type and arguments passed via `locals` variable. This way we add support for builder create a message that contains multi parts. --- lib/savon/builder.rb | 30 +- spec/fixtures/wsdl/brand.xml | 624 ++++++++++++++++++++ spec/integration/stockquote_example_spec.rb | 6 + spec/savon/softlayer_spec.rb | 27 + 4 files changed, 685 insertions(+), 2 deletions(-) create mode 100644 spec/fixtures/wsdl/brand.xml create mode 100644 spec/savon/softlayer_spec.rb diff --git a/lib/savon/builder.rb b/lib/savon/builder.rb index 88be9af4..f7334624 100644 --- a/lib/savon/builder.rb +++ b/lib/savon/builder.rb @@ -41,7 +41,7 @@ def build_document if @globals[:no_message_tag] tag(xml, :Body, body_attributes) { xml << message.to_s } else - tag(xml, :Body, body_attributes) { xml.tag!(*namespaced_message_tag) { xml << message.to_s } } + tag(xml, :Body, body_attributes) { xml.tag!(*namespaced_message_tag) { xml << body_message } } end end @@ -141,6 +141,7 @@ def header def namespaced_message_tag tag_name = message_tag + return [tag_name] if @wsdl.document? and @wsdl.soap_input(@operation_name.to_sym).is_a?(Hash) if namespace_identifier == nil [tag_name, message_attributes] elsif @used_namespaces[[tag_name.to_s]] @@ -150,8 +151,25 @@ def namespaced_message_tag end end + def serialized_message_tag + [:wsdl, @wsdl.soap_input(@operation_name.to_sym).keys.first, {}] + end + + def serialized_messages + messages = "" + message_tag = serialized_message_tag[1] + @wsdl.soap_input(@operation_name.to_sym)[message_tag].each_pair do |message, type| + break if @locals[:message].nil? + message_locals = @locals[:message][message.snakecase.to_sym] + message_content = Message.new(message_tag, namespace_identifier, @types, @used_namespaces, message_locals, :unqualified, @globals[:convert_request_keys_to], @globals[:unwrap]).to_s + messages << "<#{message} xsi:type=\"#{type.join(':')}\">#{message_content}" + end + messages + end + def message_tag - message_tag = @locals[:message_tag] + message_tag = @wsdl.soap_input(@operation_name.to_sym).keys.first if @wsdl.document? and @wsdl.soap_input(@operation_name.to_sym).is_a?(Hash) + message_tag ||= @locals[:message_tag] message_tag ||= @wsdl.soap_input(@operation_name.to_sym) if @wsdl.document? message_tag ||= Gyoku.xml_tag(@operation_name, :key_converter => @globals[:convert_request_keys_to]) @@ -162,6 +180,14 @@ def message_attributes @locals[:attributes] || {} end + def body_message + if @wsdl.document? and @wsdl.soap_input(@operation_name.to_sym).is_a?(Hash) + serialized_messages + else + message.to_s + end + end + def message element_form_default = @globals[:element_form_default] || @wsdl.element_form_default # TODO: clean this up! [dh, 2012-12-17] diff --git a/spec/fixtures/wsdl/brand.xml b/spec/fixtures/wsdl/brand.xml new file mode 100644 index 00000000..ce6180f1 --- /dev/null +++ b/spec/fixtures/wsdl/brand.xml @@ -0,0 +1,624 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Every SoftLayer customer account is associated to a brand + +SoftLayer customers are unable to change their brand information in the portal or the API. + + Create a new customer account record. + + + + + Create a new brand record. + + + + + + + + + + Retrieve all accounts owned by the brand. + + + + + + + + + + Retrieve this flag indicates if creation of accounts is allowed. + + + + + Retrieve the Product Catalog for the Brand + + + + + Retrieve the contact information for the brand such as the corporate or support contact. This will include the contact name, telephone number, fax number, email address, and mailing address of the contact. + + + + + Retrieve the contacts for the brand. + + + + + Retrieve this references relationship between brands, locations and countries associated with a user's account that are ineligible when ordering products. For example, the India datacenter may not be available on this brand for customers that live in Great Britain. + + + + + + + + + + + + + + + + + + + + Retrieve an account's associated hardware objects. + + + + + + + + + + Get the payment processor merchant name. + + + + + + + + + + + + + + + Retrieve active accounts owned by the brand. + + + + + + + + + + + + + + + + + + + + + + + + + Retrieve an account's associated virtual guest objects. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spec/integration/stockquote_example_spec.rb b/spec/integration/stockquote_example_spec.rb index 83a59508..fd010105 100644 --- a/spec/integration/stockquote_example_spec.rb +++ b/spec/integration/stockquote_example_spec.rb @@ -19,6 +19,12 @@ cdata = response.body[:get_quote_response][:get_quote_result] + if cdata == "exception" + # Fallback to not fail the specs when the service's API limit is reached, + # but to mark the spec as pending instead. + pending "Exception on API" + end + nori_options = { :convert_tags_to => lambda { |tag| tag.snakecase.to_sym } } result = Nori.new(nori_options).parse(cdata) diff --git a/spec/savon/softlayer_spec.rb b/spec/savon/softlayer_spec.rb new file mode 100644 index 00000000..21037416 --- /dev/null +++ b/spec/savon/softlayer_spec.rb @@ -0,0 +1,27 @@ +require "spec_helper" + +describe Savon::Builder do + + subject(:builder) { Savon::Builder.new(:create_object, wsdl, globals, locals) } + + let(:globals) { Savon::GlobalOptions.new } + # let(:locals) { Savon::LocalOptions.new } + let(:wsdl) { Wasabi::Document.new Fixture.wsdl(:brand) } + let(:no_wsdl) { Wasabi::Document.new } + + describe "#to_s" do + it "defaults to include the default envelope namespace of :env" do + message = { + :message=>{ + :template_object=>{ + :longName=>"Zertico LLC Reseller" + } + } + } + + locals = Savon::LocalOptions.new(message) + builder = Savon::Builder.new(:create_object, wsdl, globals, locals) + expect(builder.to_s).to eq('Zertico LLC Reseller') + end + end +end