From 418d487020d24e69b528fdbedfecb20a87f99fcb Mon Sep 17 00:00:00 2001 From: Leon Breedt Date: Sat, 19 Feb 2005 08:29:42 +0000 Subject: refactoring: * move dispatching out of the Container into Dispatcher, it makes more sense for Container to only contain the list of web services defined in it. * collapse Wsdl and ActionController "routers" into an ActionController-specific module, no advantage to having them seperate as they were quite tightly coupled. rename to Dispatcher, to avoi confusion with Routing. * add a "_thing" suffix to concept-specific filenames. this is so that we don't end up with many soap.rb files, for example. * remove "virtual invocation" support. adds complexity, and it doesn't seem to add any value. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@679 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- .../lib/action_web_service/client/soap.rb | 87 ---------------------- .../lib/action_web_service/client/soap_client.rb | 87 ++++++++++++++++++++++ .../lib/action_web_service/client/xmlrpc.rb | 76 ------------------- .../lib/action_web_service/client/xmlrpc_client.rb | 76 +++++++++++++++++++ 4 files changed, 163 insertions(+), 163 deletions(-) delete mode 100644 actionwebservice/lib/action_web_service/client/soap.rb create mode 100644 actionwebservice/lib/action_web_service/client/soap_client.rb delete mode 100644 actionwebservice/lib/action_web_service/client/xmlrpc.rb create mode 100644 actionwebservice/lib/action_web_service/client/xmlrpc_client.rb (limited to 'actionwebservice/lib/action_web_service/client') diff --git a/actionwebservice/lib/action_web_service/client/soap.rb b/actionwebservice/lib/action_web_service/client/soap.rb deleted file mode 100644 index 3557f88594..0000000000 --- a/actionwebservice/lib/action_web_service/client/soap.rb +++ /dev/null @@ -1,87 +0,0 @@ -require 'soap/rpc/driver' -require 'uri' - -module ActionWebService # :nodoc: - module Client # :nodoc: - - # Implements SOAP client support (using RPC encoding for the messages). - # - # ==== Example Usage - # - # class PersonAPI < ActionWebService::API::Base - # api_method :find_all, :returns => [[Person]] - # end - # - # soap_client = ActionWebService::Client::Soap.new(PersonAPI, "http://...") - # persons = soap_client.find_all - # - class Soap < Base - - # Creates a new web service client using the SOAP RPC protocol. - # - # +api+ must be an ActionWebService::API::Base derivative, and - # +endpoint_uri+ must point at the relevant URL to which protocol requests - # will be sent with HTTP POST. - # - # Valid options: - # [:service_name] If the remote server has used a custom +wsdl_service_name+ - # 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) - @soap_action_base = options[:soap_action_base] - @soap_action_base ||= URI.parse(endpoint_uri).path - @driver = create_soap_rpc_driver(api, endpoint_uri) - end - - protected - def perform_invocation(method_name, args) - @driver.send(method_name, *args) - end - - def soap_action(method_name) - "#{@soap_action_base}/#{method_name}" - end - - private - def create_soap_rpc_driver(api, endpoint_uri) - @mapper.map_api(api) - driver = SoapDriver.new(endpoint_uri, nil) - driver.mapping_registry = @mapper.registry - api.api_methods.each do |name, info| - public_name = api.public_api_method_name(name) - qname = XSD::QName.new(@namespace, public_name) - action = soap_action(public_name) - expects = info[:expects] - returns = info[:returns] - param_def = [] - i = 1 - if expects - expects.each do |klass| - param_name = klass.is_a?(Hash) ? klass.keys[0] : "param#{i}" - mapping = @mapper.lookup(klass) - param_def << ['in', param_name, mapping.registry_mapping] - i += 1 - end - end - if returns - mapping = @mapper.lookup(returns[0]) - param_def << ['retval', 'return', mapping.registry_mapping] - end - driver.add_method(qname, action, name.to_s, param_def) - end - driver - end - - class SoapDriver < SOAP::RPC::Driver # :nodoc: - def add_method(qname, soapaction, name, param_def) - @proxy.add_rpc_method(qname, soapaction, name, param_def) - add_rpc_method_interface(name, param_def) - end - 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 new file mode 100644 index 0000000000..3557f88594 --- /dev/null +++ b/actionwebservice/lib/action_web_service/client/soap_client.rb @@ -0,0 +1,87 @@ +require 'soap/rpc/driver' +require 'uri' + +module ActionWebService # :nodoc: + module Client # :nodoc: + + # Implements SOAP client support (using RPC encoding for the messages). + # + # ==== Example Usage + # + # class PersonAPI < ActionWebService::API::Base + # api_method :find_all, :returns => [[Person]] + # end + # + # soap_client = ActionWebService::Client::Soap.new(PersonAPI, "http://...") + # persons = soap_client.find_all + # + class Soap < Base + + # Creates a new web service client using the SOAP RPC protocol. + # + # +api+ must be an ActionWebService::API::Base derivative, and + # +endpoint_uri+ must point at the relevant URL to which protocol requests + # will be sent with HTTP POST. + # + # Valid options: + # [:service_name] If the remote server has used a custom +wsdl_service_name+ + # 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) + @soap_action_base = options[:soap_action_base] + @soap_action_base ||= URI.parse(endpoint_uri).path + @driver = create_soap_rpc_driver(api, endpoint_uri) + end + + protected + def perform_invocation(method_name, args) + @driver.send(method_name, *args) + end + + def soap_action(method_name) + "#{@soap_action_base}/#{method_name}" + end + + private + def create_soap_rpc_driver(api, endpoint_uri) + @mapper.map_api(api) + driver = SoapDriver.new(endpoint_uri, nil) + driver.mapping_registry = @mapper.registry + api.api_methods.each do |name, info| + public_name = api.public_api_method_name(name) + qname = XSD::QName.new(@namespace, public_name) + action = soap_action(public_name) + expects = info[:expects] + returns = info[:returns] + param_def = [] + i = 1 + if expects + expects.each do |klass| + param_name = klass.is_a?(Hash) ? klass.keys[0] : "param#{i}" + mapping = @mapper.lookup(klass) + param_def << ['in', param_name, mapping.registry_mapping] + i += 1 + end + end + if returns + mapping = @mapper.lookup(returns[0]) + param_def << ['retval', 'return', mapping.registry_mapping] + end + driver.add_method(qname, action, name.to_s, param_def) + end + driver + end + + class SoapDriver < SOAP::RPC::Driver # :nodoc: + def add_method(qname, soapaction, name, param_def) + @proxy.add_rpc_method(qname, soapaction, name, param_def) + add_rpc_method_interface(name, param_def) + end + end + end + end +end diff --git a/actionwebservice/lib/action_web_service/client/xmlrpc.rb b/actionwebservice/lib/action_web_service/client/xmlrpc.rb deleted file mode 100644 index df51230b81..0000000000 --- a/actionwebservice/lib/action_web_service/client/xmlrpc.rb +++ /dev/null @@ -1,76 +0,0 @@ -require 'uri' -require 'xmlrpc/client' - -module ActionWebService # :nodoc: - module Client # :nodoc: - - # Implements XML-RPC client support - # - # ==== Example Usage - # - # class BloggerAPI < ActionWebService::API::Base - # inflect_names false - # api_method :getRecentPosts, :returns => [[Blog::Post]] - # end - # - # blog = ActionWebService::Client::XmlRpc.new(BloggerAPI, "http://.../RPC", :handler_name => "blogger") - # posts = blog.getRecentPosts - class XmlRpc < Base - - # Creates a new web service client using the XML-RPC protocol. - # - # +api+ must be an ActionWebService::API::Base derivative, and - # +endpoint_uri+ must point at the relevant URL to which protocol requests - # will be sent with HTTP POST. - # - # Valid options: - # [:handler_name] If the remote server defines its services inside special - # handler (the Blogger API uses a "blogger" handler name for example), - # provide it here, or your method calls will fail - def initialize(api, endpoint_uri, options={}) - @api = api - @handler_name = options[:handler_name] - @client = XMLRPC::Client.new2(endpoint_uri, options[:proxy], options[:timeout]) - end - - protected - def perform_invocation(method_name, args) - args = transform_outgoing_method_params(method_name, args) - ok, return_value = @client.call2(public_name(method_name), *args) - return transform_return_value(method_name, return_value) if ok - raise(ClientError, "#{return_value.faultCode}: #{return_value.faultString}") - end - - 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") - 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], signature[i]) - end - end - params - end - - def transform_return_value(method_name, return_value) - info = @api.api_methods[method_name.to_sym] - return true unless signature = info[:returns] - signature = Protocol::XmlRpc::XmlRpcProtocol.transform_array_types(signature) - Protocol::XmlRpc::XmlRpcProtocol.xmlrpc_to_ruby(return_value, signature[0]) - end - - def public_name(method_name) - public_name = @api.public_api_method_name(method_name) - @handler_name ? "#{@handler_name}.#{public_name}" : public_name - end - end - end -end diff --git a/actionwebservice/lib/action_web_service/client/xmlrpc_client.rb b/actionwebservice/lib/action_web_service/client/xmlrpc_client.rb new file mode 100644 index 0000000000..df51230b81 --- /dev/null +++ b/actionwebservice/lib/action_web_service/client/xmlrpc_client.rb @@ -0,0 +1,76 @@ +require 'uri' +require 'xmlrpc/client' + +module ActionWebService # :nodoc: + module Client # :nodoc: + + # Implements XML-RPC client support + # + # ==== Example Usage + # + # class BloggerAPI < ActionWebService::API::Base + # inflect_names false + # api_method :getRecentPosts, :returns => [[Blog::Post]] + # end + # + # blog = ActionWebService::Client::XmlRpc.new(BloggerAPI, "http://.../RPC", :handler_name => "blogger") + # posts = blog.getRecentPosts + class XmlRpc < Base + + # Creates a new web service client using the XML-RPC protocol. + # + # +api+ must be an ActionWebService::API::Base derivative, and + # +endpoint_uri+ must point at the relevant URL to which protocol requests + # will be sent with HTTP POST. + # + # Valid options: + # [:handler_name] If the remote server defines its services inside special + # handler (the Blogger API uses a "blogger" handler name for example), + # provide it here, or your method calls will fail + def initialize(api, endpoint_uri, options={}) + @api = api + @handler_name = options[:handler_name] + @client = XMLRPC::Client.new2(endpoint_uri, options[:proxy], options[:timeout]) + end + + protected + def perform_invocation(method_name, args) + args = transform_outgoing_method_params(method_name, args) + ok, return_value = @client.call2(public_name(method_name), *args) + return transform_return_value(method_name, return_value) if ok + raise(ClientError, "#{return_value.faultCode}: #{return_value.faultString}") + end + + 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") + 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], signature[i]) + end + end + params + end + + def transform_return_value(method_name, return_value) + info = @api.api_methods[method_name.to_sym] + return true unless signature = info[:returns] + signature = Protocol::XmlRpc::XmlRpcProtocol.transform_array_types(signature) + Protocol::XmlRpc::XmlRpcProtocol.xmlrpc_to_ruby(return_value, signature[0]) + end + + def public_name(method_name) + public_name = @api.public_api_method_name(method_name) + @handler_name ? "#{@handler_name}.#{public_name}" : public_name + end + end + end +end -- cgit v1.2.3