actionwebservice 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +47 -0
- data/MIT-LICENSE +21 -0
- data/README +238 -0
- data/Rakefile +144 -0
- data/TODO +13 -0
- data/examples/googlesearch/README +143 -0
- data/examples/googlesearch/autoloading/google_search_api.rb +50 -0
- data/examples/googlesearch/autoloading/google_search_controller.rb +57 -0
- data/examples/googlesearch/delegated/google_search_service.rb +108 -0
- data/examples/googlesearch/delegated/search_controller.rb +7 -0
- data/examples/googlesearch/direct/google_search_api.rb +50 -0
- data/examples/googlesearch/direct/search_controller.rb +58 -0
- data/examples/metaWeblog/README +16 -0
- data/examples/metaWeblog/blog_controller.rb +127 -0
- data/lib/action_web_service.rb +60 -0
- data/lib/action_web_service/api.rb +2 -0
- data/lib/action_web_service/api/abstract.rb +192 -0
- data/lib/action_web_service/api/action_controller.rb +92 -0
- data/lib/action_web_service/base.rb +41 -0
- data/lib/action_web_service/client.rb +3 -0
- data/lib/action_web_service/client/base.rb +39 -0
- data/lib/action_web_service/client/soap_client.rb +88 -0
- data/lib/action_web_service/client/xmlrpc_client.rb +77 -0
- data/lib/action_web_service/container.rb +85 -0
- data/lib/action_web_service/dispatcher.rb +2 -0
- data/lib/action_web_service/dispatcher/abstract.rb +150 -0
- data/lib/action_web_service/dispatcher/action_controller_dispatcher.rb +299 -0
- data/lib/action_web_service/invocation.rb +205 -0
- data/lib/action_web_service/protocol.rb +4 -0
- data/lib/action_web_service/protocol/abstract.rb +128 -0
- data/lib/action_web_service/protocol/registry.rb +55 -0
- data/lib/action_web_service/protocol/soap_protocol.rb +484 -0
- data/lib/action_web_service/protocol/xmlrpc_protocol.rb +168 -0
- data/lib/action_web_service/struct.rb +55 -0
- data/lib/action_web_service/support/class_inheritable_options.rb +26 -0
- data/lib/action_web_service/support/signature.rb +100 -0
- data/setup.rb +1360 -0
- data/test/abstract_client.rb +131 -0
- data/test/abstract_soap.rb +58 -0
- data/test/abstract_unit.rb +9 -0
- data/test/api_test.rb +52 -0
- data/test/base_test.rb +42 -0
- data/test/client_soap_test.rb +93 -0
- data/test/client_xmlrpc_test.rb +92 -0
- data/test/container_test.rb +53 -0
- data/test/dispatcher_action_controller_test.rb +186 -0
- data/test/gencov +3 -0
- data/test/invocation_test.rb +149 -0
- data/test/protocol_registry_test.rb +53 -0
- data/test/protocol_soap_test.rb +252 -0
- data/test/protocol_xmlrpc_test.rb +147 -0
- data/test/run +5 -0
- data/test/struct_test.rb +40 -0
- metadata +131 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'action_web_service/support/class_inheritable_options'
|
2
|
+
require 'action_web_service/support/signature'
|
3
|
+
|
4
|
+
module ActionWebService # :nodoc:
|
5
|
+
class ActionWebServiceError < StandardError # :nodoc:
|
6
|
+
end
|
7
|
+
|
8
|
+
# An Action Web Service object implements a specified API.
|
9
|
+
#
|
10
|
+
# Used by controllers operating in _Delegated_ dispatching mode.
|
11
|
+
#
|
12
|
+
# ==== Example
|
13
|
+
#
|
14
|
+
# class PersonService < ActionWebService::Base
|
15
|
+
# web_service_api PersonAPI
|
16
|
+
#
|
17
|
+
# def find_person(criteria)
|
18
|
+
# Person.find_all [...]
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# def delete_person(id)
|
22
|
+
# Person.find_by_id(id).destroy
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# class PersonAPI < ActionWebService::API::Base
|
27
|
+
# api_method :find_person, :expects => [SearchCriteria], :returns => [[Person]]
|
28
|
+
# api_method :delete_person, :expects => [:int]
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# class SearchCriteria < ActionStruct::Base
|
32
|
+
# member :firstname, :string
|
33
|
+
# member :lastname, :string
|
34
|
+
# member :email, :string
|
35
|
+
# end
|
36
|
+
class Base
|
37
|
+
# Whether to report exceptions back to the caller in the protocol's exception
|
38
|
+
# format
|
39
|
+
class_inheritable_option :web_service_exception_reporting, true
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module ActionWebService # :nodoc:
|
2
|
+
module Client # :nodoc:
|
3
|
+
class ClientError < StandardError # :nodoc:
|
4
|
+
end
|
5
|
+
|
6
|
+
class Base # :nodoc:
|
7
|
+
def initialize(api, endpoint_uri)
|
8
|
+
@api = api
|
9
|
+
@endpoint_uri = endpoint_uri
|
10
|
+
end
|
11
|
+
|
12
|
+
def method_missing(name, *args) # :nodoc:
|
13
|
+
call_name = method_name(name)
|
14
|
+
return super(name, *args) if call_name.nil?
|
15
|
+
perform_invocation(call_name, args)
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
def perform_invocation(method_name, args) # :nodoc:
|
20
|
+
raise NotImplementedError, "use a protocol-specific client"
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def method_name(name)
|
25
|
+
if @api.has_api_method?(name.to_sym)
|
26
|
+
name.to_s
|
27
|
+
elsif @api.has_public_api_method?(name.to_s)
|
28
|
+
@api.api_method_name(name.to_s).to_s
|
29
|
+
else
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def lookup_class(klass)
|
35
|
+
klass.is_a?(Hash) ? klass.values[0] : klass
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'soap/rpc/driver'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
module ActionWebService # :nodoc:
|
5
|
+
module Client # :nodoc:
|
6
|
+
|
7
|
+
# Implements SOAP client support (using RPC encoding for the messages).
|
8
|
+
#
|
9
|
+
# ==== Example Usage
|
10
|
+
#
|
11
|
+
# class PersonAPI < ActionWebService::API::Base
|
12
|
+
# api_method :find_all, :returns => [[Person]]
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# soap_client = ActionWebService::Client::Soap.new(PersonAPI, "http://...")
|
16
|
+
# persons = soap_client.find_all
|
17
|
+
#
|
18
|
+
class Soap < Base
|
19
|
+
|
20
|
+
# Creates a new web service client using the SOAP RPC protocol.
|
21
|
+
#
|
22
|
+
# +api+ must be an ActionWebService::API::Base derivative, and
|
23
|
+
# +endpoint_uri+ must point at the relevant URL to which protocol requests
|
24
|
+
# will be sent with HTTP POST.
|
25
|
+
#
|
26
|
+
# Valid options:
|
27
|
+
# [<tt>:service_name</tt>] If the remote server has used a custom +wsdl_service_name+
|
28
|
+
# option, you must specify it here
|
29
|
+
def initialize(api, endpoint_uri, options={})
|
30
|
+
super(api, endpoint_uri)
|
31
|
+
@service_name = options[:service_name] || 'ActionWebService'
|
32
|
+
@namespace = "urn:#{@service_name}"
|
33
|
+
@mapper = ActionWebService::Protocol::Soap::SoapMapper.new(@namespace)
|
34
|
+
@protocol = ActionWebService::Protocol::Soap::SoapProtocol.new(@mapper)
|
35
|
+
@soap_action_base = options[:soap_action_base]
|
36
|
+
@soap_action_base ||= URI.parse(endpoint_uri).path
|
37
|
+
@driver = create_soap_rpc_driver(api, endpoint_uri)
|
38
|
+
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
def perform_invocation(method_name, args)
|
42
|
+
@driver.send(method_name, *args)
|
43
|
+
end
|
44
|
+
|
45
|
+
def soap_action(method_name)
|
46
|
+
"#{@soap_action_base}/#{method_name}"
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
def create_soap_rpc_driver(api, endpoint_uri)
|
51
|
+
@mapper.map_api(api)
|
52
|
+
driver = SoapDriver.new(endpoint_uri, nil)
|
53
|
+
driver.mapping_registry = @mapper.registry
|
54
|
+
api.api_methods.each do |name, info|
|
55
|
+
public_name = api.public_api_method_name(name)
|
56
|
+
qname = XSD::QName.new(@namespace, public_name)
|
57
|
+
action = soap_action(public_name)
|
58
|
+
expects = info[:expects]
|
59
|
+
returns = info[:returns]
|
60
|
+
param_def = []
|
61
|
+
i = 1
|
62
|
+
if expects
|
63
|
+
expects.each do |klass|
|
64
|
+
param_name = klass.is_a?(Hash) ? klass.keys[0] : "param#{i}"
|
65
|
+
param_klass = lookup_class(klass)
|
66
|
+
mapping = @mapper.lookup(param_klass)
|
67
|
+
param_def << ['in', param_name, mapping.registry_mapping]
|
68
|
+
i += 1
|
69
|
+
end
|
70
|
+
end
|
71
|
+
if returns
|
72
|
+
mapping = @mapper.lookup(lookup_class(returns[0]))
|
73
|
+
param_def << ['retval', 'return', mapping.registry_mapping]
|
74
|
+
end
|
75
|
+
driver.add_method(qname, action, name.to_s, param_def)
|
76
|
+
end
|
77
|
+
driver
|
78
|
+
end
|
79
|
+
|
80
|
+
class SoapDriver < SOAP::RPC::Driver # :nodoc:
|
81
|
+
def add_method(qname, soapaction, name, param_def)
|
82
|
+
@proxy.add_rpc_method(qname, soapaction, name, param_def)
|
83
|
+
add_rpc_method_interface(name, param_def)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'xmlrpc/client'
|
3
|
+
|
4
|
+
module ActionWebService # :nodoc:
|
5
|
+
module Client # :nodoc:
|
6
|
+
|
7
|
+
# Implements XML-RPC client support
|
8
|
+
#
|
9
|
+
# ==== Example Usage
|
10
|
+
#
|
11
|
+
# class BloggerAPI < ActionWebService::API::Base
|
12
|
+
# inflect_names false
|
13
|
+
# api_method :getRecentPosts, :returns => [[Blog::Post]]
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# blog = ActionWebService::Client::XmlRpc.new(BloggerAPI, "http://.../RPC", :handler_name => "blogger")
|
17
|
+
# posts = blog.getRecentPosts
|
18
|
+
class XmlRpc < Base
|
19
|
+
|
20
|
+
# Creates a new web service client using the XML-RPC protocol.
|
21
|
+
#
|
22
|
+
# +api+ must be an ActionWebService::API::Base derivative, and
|
23
|
+
# +endpoint_uri+ must point at the relevant URL to which protocol requests
|
24
|
+
# will be sent with HTTP POST.
|
25
|
+
#
|
26
|
+
# Valid options:
|
27
|
+
# [<tt>:handler_name</tt>] If the remote server defines its services inside special
|
28
|
+
# handler (the Blogger API uses a <tt>"blogger"</tt> handler name for example),
|
29
|
+
# provide it here, or your method calls will fail
|
30
|
+
def initialize(api, endpoint_uri, options={})
|
31
|
+
@api = api
|
32
|
+
@handler_name = options[:handler_name]
|
33
|
+
@client = XMLRPC::Client.new2(endpoint_uri, options[:proxy], options[:timeout])
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
def perform_invocation(method_name, args)
|
38
|
+
args = transform_outgoing_method_params(method_name, args)
|
39
|
+
ok, return_value = @client.call2(public_name(method_name), *args)
|
40
|
+
return transform_return_value(method_name, return_value) if ok
|
41
|
+
raise(ClientError, "#{return_value.faultCode}: #{return_value.faultString}")
|
42
|
+
end
|
43
|
+
|
44
|
+
def transform_outgoing_method_params(method_name, params)
|
45
|
+
info = @api.api_methods[method_name.to_sym]
|
46
|
+
signature = info[:expects]
|
47
|
+
signature_length = signature.nil?? 0 : signature.length
|
48
|
+
if signature_length != params.length
|
49
|
+
raise(ProtocolError, "API declares #{public_name(method_name)} to accept " +
|
50
|
+
"#{signature_length} parameters, but #{params.length} parameters " +
|
51
|
+
"were supplied")
|
52
|
+
end
|
53
|
+
if signature_length > 0
|
54
|
+
signature = Protocol::XmlRpc::XmlRpcProtocol.transform_array_types(signature)
|
55
|
+
(1..signature.size).each do |i|
|
56
|
+
i -= 1
|
57
|
+
params[i] = Protocol::XmlRpc::XmlRpcProtocol.ruby_to_xmlrpc(params[i], lookup_class(signature[i]))
|
58
|
+
end
|
59
|
+
end
|
60
|
+
params
|
61
|
+
end
|
62
|
+
|
63
|
+
def transform_return_value(method_name, return_value)
|
64
|
+
info = @api.api_methods[method_name.to_sym]
|
65
|
+
return true unless signature = info[:returns]
|
66
|
+
param_klass = lookup_class(signature[0])
|
67
|
+
signature = Protocol::XmlRpc::XmlRpcProtocol.transform_array_types([param_klass])
|
68
|
+
Protocol::XmlRpc::XmlRpcProtocol.xmlrpc_to_ruby(return_value, signature[0])
|
69
|
+
end
|
70
|
+
|
71
|
+
def public_name(method_name)
|
72
|
+
public_name = @api.public_api_method_name(method_name)
|
73
|
+
@handler_name ? "#{@handler_name}.#{public_name}" : public_name
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module ActionWebService # :nodoc:
|
2
|
+
module Container # :nodoc:
|
3
|
+
class ContainerError < ActionWebService::ActionWebServiceError # :nodoc:
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.append_features(base) # :nodoc:
|
7
|
+
super
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
base.send(:include, ActionWebService::Container::InstanceMethods)
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
# Declares a web service that will provides access to the API of the given
|
14
|
+
# +object+. +object+ must be an ActionWebService::Base derivative.
|
15
|
+
#
|
16
|
+
# Web service object creation can either be _immediate_, where the object
|
17
|
+
# instance is given at class definition time, or _deferred_, where
|
18
|
+
# object instantiation is delayed until request time.
|
19
|
+
#
|
20
|
+
# ==== Immediate web service object example
|
21
|
+
#
|
22
|
+
# class ApiController < ApplicationController
|
23
|
+
# web_service_dispatching_mode :delegated
|
24
|
+
#
|
25
|
+
# web_service :person, PersonService.new
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# For deferred instantiation, a block should be given instead of an
|
29
|
+
# object instance. This block will be executed in controller instance
|
30
|
+
# context, so it can rely on controller instance variables being present.
|
31
|
+
#
|
32
|
+
# ==== Deferred web service object example
|
33
|
+
#
|
34
|
+
# class ApiController < ApplicationController
|
35
|
+
# web_service_dispatching_mode :delegated
|
36
|
+
#
|
37
|
+
# web_service(:person) { PersonService.new(@request.env) }
|
38
|
+
# end
|
39
|
+
def web_service(name, object=nil, &block)
|
40
|
+
if (object && block_given?) || (object.nil? && block.nil?)
|
41
|
+
raise(ContainerError, "either service, or a block must be given")
|
42
|
+
end
|
43
|
+
name = name.to_sym
|
44
|
+
if block_given?
|
45
|
+
info = { name => { :block => block } }
|
46
|
+
else
|
47
|
+
info = { name => { :object => object } }
|
48
|
+
end
|
49
|
+
write_inheritable_hash("web_services", info)
|
50
|
+
call_web_service_definition_callbacks(self, name, info)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Whether this service contains a service with the given +name+
|
54
|
+
def has_web_service?(name)
|
55
|
+
web_services.has_key?(name.to_sym)
|
56
|
+
end
|
57
|
+
|
58
|
+
def web_services # :nodoc:
|
59
|
+
read_inheritable_attribute("web_services") || {}
|
60
|
+
end
|
61
|
+
|
62
|
+
def add_web_service_definition_callback(&block) # :nodoc:
|
63
|
+
write_inheritable_array("web_service_definition_callbacks", [block])
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
def call_web_service_definition_callbacks(container_class, web_service_name, service_info)
|
68
|
+
(read_inheritable_attribute("web_service_definition_callbacks") || []).each do |block|
|
69
|
+
block.call(container_class, web_service_name, service_info)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
module InstanceMethods # :nodoc:
|
75
|
+
def web_service_object(web_service_name)
|
76
|
+
info = self.class.web_services[web_service_name.to_sym]
|
77
|
+
unless info
|
78
|
+
raise(ContainerError, "no such web service '#{web_service_name}'")
|
79
|
+
end
|
80
|
+
service = info[:block]
|
81
|
+
service ? instance_eval(&service) : info[:object]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
|
3
|
+
module ActionWebService # :nodoc:
|
4
|
+
module Dispatcher # :nodoc:
|
5
|
+
class DispatcherError < ActionWebService::ActionWebServiceError # :nodoc:
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.append_features(base) # :nodoc:
|
9
|
+
super
|
10
|
+
base.class_inheritable_option(:web_service_dispatching_mode, :direct)
|
11
|
+
base.class_inheritable_option(:web_service_exception_reporting, true)
|
12
|
+
base.send(:include, ActionWebService::Dispatcher::InstanceMethods)
|
13
|
+
end
|
14
|
+
|
15
|
+
module InstanceMethods # :nodoc:
|
16
|
+
private
|
17
|
+
def dispatch_web_service_request(action_pack_request)
|
18
|
+
protocol_request = protocol_response = nil
|
19
|
+
bm = Benchmark.measure do
|
20
|
+
protocol_request = probe_request_protocol(action_pack_request)
|
21
|
+
protocol_response = dispatch_protocol_request(protocol_request)
|
22
|
+
end
|
23
|
+
[protocol_request, protocol_response, bm.real, nil]
|
24
|
+
rescue Exception => e
|
25
|
+
protocol_response = prepare_exception_response(protocol_request, e)
|
26
|
+
[protocol_request, prepare_exception_response(protocol_request, e), nil, e]
|
27
|
+
end
|
28
|
+
|
29
|
+
def dispatch_protocol_request(protocol_request)
|
30
|
+
case web_service_dispatching_mode
|
31
|
+
when :direct
|
32
|
+
dispatch_direct_request(protocol_request)
|
33
|
+
when :delegated
|
34
|
+
dispatch_delegated_request(protocol_request)
|
35
|
+
else
|
36
|
+
raise(ContainerError, "unsupported dispatching mode :#{web_service_dispatching_mode}")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def dispatch_direct_request(protocol_request)
|
41
|
+
request = prepare_dispatch_request(protocol_request)
|
42
|
+
return_value = direct_invoke(request)
|
43
|
+
protocol_request.marshal(return_value)
|
44
|
+
end
|
45
|
+
|
46
|
+
def dispatch_delegated_request(protocol_request)
|
47
|
+
request = prepare_dispatch_request(protocol_request)
|
48
|
+
return_value = delegated_invoke(request)
|
49
|
+
protocol_request.marshal(return_value)
|
50
|
+
end
|
51
|
+
|
52
|
+
def direct_invoke(request)
|
53
|
+
return nil unless before_direct_invoke(request)
|
54
|
+
return_value = send(request.method_name)
|
55
|
+
after_direct_invoke(request)
|
56
|
+
return_value
|
57
|
+
end
|
58
|
+
|
59
|
+
def before_direct_invoke(request)
|
60
|
+
@method_params = request.params
|
61
|
+
end
|
62
|
+
|
63
|
+
def after_direct_invoke(request)
|
64
|
+
end
|
65
|
+
|
66
|
+
def delegated_invoke(request)
|
67
|
+
cancellation_reason = nil
|
68
|
+
web_service = request.web_service
|
69
|
+
return_value = web_service.perform_invocation(request.method_name, request.params) do |x|
|
70
|
+
cancellation_reason = x
|
71
|
+
end
|
72
|
+
if cancellation_reason
|
73
|
+
raise(DispatcherError, "request canceled: #{cancellation_reason}")
|
74
|
+
end
|
75
|
+
return_value
|
76
|
+
end
|
77
|
+
|
78
|
+
def prepare_dispatch_request(protocol_request)
|
79
|
+
api = method_name = web_service_name = web_service = params = nil
|
80
|
+
public_method_name = protocol_request.public_method_name
|
81
|
+
case web_service_dispatching_mode
|
82
|
+
when :direct
|
83
|
+
api = self.class.web_service_api
|
84
|
+
when :delegated
|
85
|
+
web_service_name = protocol_request.web_service_name
|
86
|
+
web_service = web_service_object(web_service_name)
|
87
|
+
api = web_service.class.web_service_api
|
88
|
+
end
|
89
|
+
method_name = api.api_method_name(public_method_name)
|
90
|
+
signature = nil
|
91
|
+
if method_name
|
92
|
+
signature = api.api_methods[method_name]
|
93
|
+
protocol_request.type = Protocol::CheckedMessage
|
94
|
+
protocol_request.signature = signature[:expects]
|
95
|
+
protocol_request.return_signature = signature[:returns]
|
96
|
+
else
|
97
|
+
method_name = api.default_api_method
|
98
|
+
if method_name
|
99
|
+
protocol_request.type = Protocol::UncheckedMessage
|
100
|
+
else
|
101
|
+
raise(DispatcherError, "no such method #{web_service_name}##{public_method_name}")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
params = protocol_request.unmarshal
|
105
|
+
DispatchRequest.new(
|
106
|
+
:api => api,
|
107
|
+
:public_method_name => public_method_name,
|
108
|
+
:method_name => method_name,
|
109
|
+
:signature => signature,
|
110
|
+
:web_service_name => web_service_name,
|
111
|
+
:web_service => web_service,
|
112
|
+
:params => params)
|
113
|
+
end
|
114
|
+
|
115
|
+
def prepare_exception_response(protocol_request, exception)
|
116
|
+
if protocol_request && exception
|
117
|
+
case web_service_dispatching_mode
|
118
|
+
when :direct
|
119
|
+
if web_service_exception_reporting
|
120
|
+
return protocol_request.protocol.marshal_exception(exception)
|
121
|
+
end
|
122
|
+
when :delegated
|
123
|
+
web_service = web_service_object(protocol_request.web_service_name)
|
124
|
+
if web_service && web_service.class.web_service_exception_reporting
|
125
|
+
return protocol_request.protocol.marshal_exception(exception)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
else
|
129
|
+
protocol_request.protocol.marshal_exception(RuntimeError.new("missing protocol request or exception"))
|
130
|
+
end
|
131
|
+
rescue Exception
|
132
|
+
nil
|
133
|
+
end
|
134
|
+
|
135
|
+
class DispatchRequest
|
136
|
+
attr :api
|
137
|
+
attr :public_method_name
|
138
|
+
attr :method_name
|
139
|
+
attr :signature
|
140
|
+
attr :web_service_name
|
141
|
+
attr :web_service
|
142
|
+
attr :params
|
143
|
+
|
144
|
+
def initialize(values={})
|
145
|
+
values.each{|k,v| instance_variable_set("@#{k.to_s}", v)}
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|