diff options
author | Leon Breedt <bitserf@gmail.com> | 2005-02-25 23:39:39 +0000 |
---|---|---|
committer | Leon Breedt <bitserf@gmail.com> | 2005-02-25 23:39:39 +0000 |
commit | 6f5a7b200443baf209d2f33c428ed4a4059782f7 (patch) | |
tree | 9c3942fe27be69c102873d9fdaa13f66dc12853d /actionwebservice/lib/action_web_service/client | |
parent | 10faf204b712763f05a2b3155a4fd9c5338f1fb2 (diff) | |
download | rails-6f5a7b200443baf209d2f33c428ed4a4059782f7.tar.gz rails-6f5a7b200443baf209d2f33c428ed4a4059782f7.tar.bz2 rails-6f5a7b200443baf209d2f33c428ed4a4059782f7.zip |
merged the changes for the upcoming 0.6.0:
seperate out protocol marshaling into a small 'ws' library in vendor, so that
AWS itself only does integration with ActionPack, and so we can keep protocol
specific code in AWS proper to a minimum. refactor unit tests to get 95%
code coverage (for a baseline).
be far more relaxed about the types given to us by the remote side, don't do
any poor man's type checking, just try to cast and marshal to the correct types if
possible, and if not, return what they gave us anyway. this should make interoperating
with fuzzy XML-RPC clients easier.
if exception reporting is turned on, do best-effort error responses, so that
we can avoid "Internal protocol error" with no details if there is a bug in
AWS itself.
also perform extensive cleanups on AWS proper.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@800 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionwebservice/lib/action_web_service/client')
3 files changed, 48 insertions, 41 deletions
diff --git a/actionwebservice/lib/action_web_service/client/base.rb b/actionwebservice/lib/action_web_service/client/base.rb index 431b78c748..9dada7bf98 100644 --- a/actionwebservice/lib/action_web_service/client/base.rb +++ b/actionwebservice/lib/action_web_service/client/base.rb @@ -12,28 +12,17 @@ module ActionWebService # :nodoc: def method_missing(name, *args) # :nodoc: call_name = method_name(name) return super(name, *args) if call_name.nil? - perform_invocation(call_name, args) + self.perform_invocation(call_name, args) end - protected - def perform_invocation(method_name, args) # :nodoc: - raise NotImplementedError, "use a protocol-specific client" - end - private def method_name(name) if @api.has_api_method?(name.to_sym) name.to_s elsif @api.has_public_api_method?(name.to_s) @api.api_method_name(name.to_s).to_s - else - nil end end - - def lookup_class(klass) - klass.is_a?(Hash) ? klass.values[0] : klass - end end end end diff --git a/actionwebservice/lib/action_web_service/client/soap_client.rb b/actionwebservice/lib/action_web_service/client/soap_client.rb index dfabfd86ee..b93f6475d9 100644 --- a/actionwebservice/lib/action_web_service/client/soap_client.rb +++ b/actionwebservice/lib/action_web_service/client/soap_client.rb @@ -28,10 +28,10 @@ module ActionWebService # :nodoc: # option, you must specify it here def initialize(api, endpoint_uri, options={}) super(api, endpoint_uri) - @service_name = options[:service_name] || 'ActionWebService' - @namespace = "urn:#{@service_name}" - @mapper = ActionWebService::Protocol::Soap::SoapMapper.new(@namespace) - @protocol = ActionWebService::Protocol::Soap::SoapProtocol.new(@mapper) + @service_name = options[:service_name] + @namespace = @service_name ? '' : "urn:#{@service_name}" + @marshaler = WS::Marshaling::SoapMarshaler.new + @encoder = WS::Encoding::SoapRpcEncoding.new @soap_action_base = options[:soap_action_base] @soap_action_base ||= URI.parse(endpoint_uri).path @driver = create_soap_rpc_driver(api, endpoint_uri) @@ -48,9 +48,9 @@ module ActionWebService # :nodoc: private def create_soap_rpc_driver(api, endpoint_uri) - @mapper.map_api(api) + register_api(@marshaler, api) driver = SoapDriver.new(endpoint_uri, nil) - driver.mapping_registry = @mapper.registry + driver.mapping_registry = @marshaler.registry api.api_methods.each do |name, info| public_name = api.public_api_method_name(name) qname = XSD::QName.new(@namespace, public_name) @@ -58,25 +58,38 @@ module ActionWebService # :nodoc: expects = info[:expects] returns = info[:returns] param_def = [] - i = 1 + i = 0 if expects - expects.each do |klass| - param_name = klass.is_a?(Hash) ? klass.keys[0] : "param#{i}" - param_klass = lookup_class(klass) - mapping = @mapper.lookup(param_klass) - param_def << ['in', param_name, mapping.registry_mapping] + expects.each do |spec| + param_name = spec.is_a?(Hash) ? spec.keys[0].to_s : "param#{i}" + type_binding = @marshaler.register_type(spec) + param_def << ['in', param_name, type_binding.mapping] i += 1 end end if returns - mapping = @mapper.lookup(lookup_class(returns[0])) - param_def << ['retval', 'return', mapping.registry_mapping] + type_binding = @marshaler.register_type(returns[0]) + param_def << ['retval', 'return', type_binding.mapping] end driver.add_method(qname, action, name.to_s, param_def) end driver end + def register_api(marshaler, api) + type_bindings = [] + api.api_methods.each do |name, info| + expects, returns = info[:expects], info[:returns] + if expects + expects.each{|type| type_bindings << marshaler.register_type(type)} + end + if returns + returns.each{|type| type_bindings << marshaler.register_type(type)} + end + end + type_bindings + end + class SoapDriver < SOAP::RPC::Driver # :nodoc: def add_method(qname, soapaction, name, param_def) @proxy.add_rpc_method(qname, soapaction, name, param_def) diff --git a/actionwebservice/lib/action_web_service/client/xmlrpc_client.rb b/actionwebservice/lib/action_web_service/client/xmlrpc_client.rb index bb52c20453..dc7ad1517f 100644 --- a/actionwebservice/lib/action_web_service/client/xmlrpc_client.rb +++ b/actionwebservice/lib/action_web_service/client/xmlrpc_client.rb @@ -31,6 +31,7 @@ module ActionWebService # :nodoc: @api = api @handler_name = options[:handler_name] @client = XMLRPC::Client.new2(endpoint_uri, options[:proxy], options[:timeout]) + @marshaler = WS::Marshaling::XmlRpcMarshaler.new end protected @@ -43,18 +44,21 @@ module ActionWebService # :nodoc: def transform_outgoing_method_params(method_name, params) info = @api.api_methods[method_name.to_sym] - signature = info[:expects] - signature_length = signature.nil?? 0 : signature.length - if signature_length != params.length - raise(ProtocolError, "API declares #{public_name(method_name)} to accept " + - "#{signature_length} parameters, but #{params.length} parameters " + - "were supplied") + expects = info[:expects] + expects_length = expects.nil?? 0 : expects.length + if expects_length != params.length + raise(ClientError, "API declares #{public_name(method_name)} to accept " + + "#{expects_length} parameters, but #{params.length} parameters " + + "were supplied") end - if signature_length > 0 - signature = Protocol::XmlRpc::XmlRpcProtocol.transform_array_types(signature) - (1..signature.size).each do |i| - i -= 1 - params[i] = Protocol::XmlRpc::XmlRpcProtocol.ruby_to_xmlrpc(params[i], lookup_class(signature[i])) + params = params.dup + if expects_length > 0 + i = 0 + expects.each do |spec| + type_binding = @marshaler.register_type(spec) + info = WS::ParamInfo.create(spec, i, type_binding) + params[i] = @marshaler.marshal(WS::Param.new(params[i], info)) + i += 1 end end params @@ -62,10 +66,11 @@ module ActionWebService # :nodoc: def transform_return_value(method_name, return_value) info = @api.api_methods[method_name.to_sym] - return true unless signature = info[:returns] - param_klass = lookup_class(signature[0]) - signature = Protocol::XmlRpc::XmlRpcProtocol.transform_array_types([param_klass]) - Protocol::XmlRpc::XmlRpcProtocol.xmlrpc_to_ruby(return_value, signature[0]) + return true unless returns = info[:returns] + type_binding = @marshaler.register_type(returns[0]) + info = WS::ParamInfo.create(returns[0], 0, type_binding) + info.name = 'return' + @marshaler.transform_inbound(WS::Param.new(return_value, info)) end def public_name(method_name) |