aboutsummaryrefslogtreecommitdiffstats
path: root/actionwebservice/lib/action_web_service/client/soap_client.rb
diff options
context:
space:
mode:
authorLeon Breedt <bitserf@gmail.com>2005-02-19 08:29:42 +0000
committerLeon Breedt <bitserf@gmail.com>2005-02-19 08:29:42 +0000
commit418d487020d24e69b528fdbedfecb20a87f99fcb (patch)
tree1956d6982123df1638bdef8274dff50ae71b25c2 /actionwebservice/lib/action_web_service/client/soap_client.rb
parente7499638d06023ae493d14ec1dc4f58bad8ac168 (diff)
downloadrails-418d487020d24e69b528fdbedfecb20a87f99fcb.tar.gz
rails-418d487020d24e69b528fdbedfecb20a87f99fcb.tar.bz2
rails-418d487020d24e69b528fdbedfecb20a87f99fcb.zip
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
Diffstat (limited to 'actionwebservice/lib/action_web_service/client/soap_client.rb')
-rw-r--r--actionwebservice/lib/action_web_service/client/soap_client.rb87
1 files changed, 87 insertions, 0 deletions
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:
+ # [<tt>:service_name</tt>] 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