actionwebservice 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/{ChangeLog → CHANGELOG} +20 -0
- data/README +45 -1
- data/Rakefile +12 -10
- data/TODO +8 -9
- data/lib/action_web_service.rb +10 -6
- data/lib/action_web_service/api.rb +1 -2
- data/lib/action_web_service/api/{abstract.rb → base.rb} +14 -71
- data/lib/action_web_service/base.rb +0 -3
- data/lib/action_web_service/client/base.rb +1 -12
- data/lib/action_web_service/client/soap_client.rb +49 -17
- data/lib/action_web_service/client/xmlrpc_client.rb +20 -15
- data/lib/action_web_service/container.rb +3 -85
- data/lib/action_web_service/{api/action_controller.rb → container/action_controller_container.rb} +2 -2
- data/lib/action_web_service/container/delegated_container.rb +87 -0
- data/lib/action_web_service/container/direct_container.rb +70 -0
- data/lib/action_web_service/dispatcher/abstract.rb +100 -102
- data/lib/action_web_service/dispatcher/action_controller_dispatcher.rb +199 -137
- data/lib/action_web_service/protocol.rb +1 -1
- data/lib/action_web_service/protocol/abstract.rb +14 -112
- data/lib/action_web_service/protocol/discovery.rb +37 -0
- data/lib/action_web_service/protocol/soap_protocol.rb +32 -458
- data/lib/action_web_service/protocol/xmlrpc_protocol.rb +29 -149
- data/lib/action_web_service/struct.rb +2 -5
- data/lib/action_web_service/test_invoke.rb +130 -0
- data/lib/action_web_service/vendor/ws.rb +4 -0
- data/lib/action_web_service/vendor/ws/common.rb +8 -0
- data/lib/action_web_service/vendor/ws/encoding.rb +3 -0
- data/lib/action_web_service/vendor/ws/encoding/abstract.rb +26 -0
- data/lib/action_web_service/vendor/ws/encoding/soap_rpc_encoding.rb +90 -0
- data/lib/action_web_service/vendor/ws/encoding/xmlrpc_encoding.rb +53 -0
- data/lib/action_web_service/vendor/ws/marshaling.rb +3 -0
- data/lib/action_web_service/vendor/ws/marshaling/abstract.rb +17 -0
- data/lib/action_web_service/vendor/ws/marshaling/soap_marshaling.rb +277 -0
- data/lib/action_web_service/vendor/ws/marshaling/xmlrpc_marshaling.rb +116 -0
- data/lib/action_web_service/vendor/ws/types.rb +162 -0
- data/test/abstract_client.rb +8 -11
- data/test/abstract_dispatcher.rb +370 -0
- data/test/abstract_unit.rb +1 -0
- data/test/api_test.rb +18 -1
- data/test/apis/auto_load_api.rb +3 -0
- data/test/apis/broken_auto_load_api.rb +2 -0
- data/test/client_soap_test.rb +16 -3
- data/test/client_xmlrpc_test.rb +16 -4
- data/test/container_test.rb +28 -8
- data/test/dispatcher_action_controller_soap_test.rb +106 -0
- data/test/dispatcher_action_controller_xmlrpc_test.rb +44 -0
- data/test/gencov +1 -1
- data/test/invocation_test.rb +39 -3
- data/test/run +4 -4
- data/test/test_invoke_test.rb +77 -0
- data/test/ws/abstract_encoding.rb +68 -0
- data/test/ws/abstract_unit.rb +13 -0
- data/test/ws/gencov +3 -0
- data/test/ws/run +5 -0
- data/test/ws/soap_marshaling_test.rb +91 -0
- data/test/ws/soap_rpc_encoding_test.rb +47 -0
- data/test/ws/types_test.rb +41 -0
- data/test/ws/xmlrpc_encoding_test.rb +34 -0
- metadata +48 -19
- data/lib/action_web_service/protocol/registry.rb +0 -55
- data/lib/action_web_service/support/signature.rb +0 -100
- data/test/abstract_soap.rb +0 -58
- data/test/dispatcher_action_controller_test.rb +0 -186
- data/test/protocol_registry_test.rb +0 -53
- data/test/protocol_soap_test.rb +0 -252
- data/test/protocol_xmlrpc_test.rb +0 -147
@@ -1,55 +0,0 @@
|
|
1
|
-
module ActionWebService # :nodoc:
|
2
|
-
module Protocol # :nodoc:
|
3
|
-
HeaderAndBody = :header_and_body
|
4
|
-
BodyOnly = :body_only
|
5
|
-
|
6
|
-
module Registry # :nodoc:
|
7
|
-
def self.append_features(base) # :nodoc:
|
8
|
-
super
|
9
|
-
base.extend(ClassMethods)
|
10
|
-
base.send(:include, ActionWebService::Protocol::Registry::InstanceMethods)
|
11
|
-
end
|
12
|
-
|
13
|
-
module ClassMethods # :nodoc:
|
14
|
-
def register_protocol(type, klass) # :nodoc:
|
15
|
-
case type
|
16
|
-
when HeaderAndBody
|
17
|
-
write_inheritable_array("header_and_body_protocols", [klass])
|
18
|
-
when BodyOnly
|
19
|
-
write_inheritable_array("body_only_protocols", [klass])
|
20
|
-
else
|
21
|
-
raise(ProtocolError, "unknown protocol type #{type}")
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
module InstanceMethods # :nodoc:
|
27
|
-
private
|
28
|
-
def probe_request_protocol(action_pack_request)
|
29
|
-
(header_and_body_protocols + body_only_protocols).each do |protocol|
|
30
|
-
protocol_request = protocol.create_protocol_request(self.class, action_pack_request)
|
31
|
-
return protocol_request if protocol_request
|
32
|
-
end
|
33
|
-
raise(ProtocolError, "unsupported request message format")
|
34
|
-
end
|
35
|
-
|
36
|
-
def probe_protocol_client(api, protocol_name, endpoint_uri, options)
|
37
|
-
(header_and_body_protocols + body_only_protocols).each do |protocol|
|
38
|
-
protocol_client = protocol.create_protocol_client(api, protocol_name, endpoint_uri, options)
|
39
|
-
return protocol_client if protocol_client
|
40
|
-
end
|
41
|
-
raise(ProtocolError, "unsupported client protocol :#{protocol_name}")
|
42
|
-
end
|
43
|
-
|
44
|
-
def header_and_body_protocols
|
45
|
-
self.class.read_inheritable_attribute("header_and_body_protocols") || []
|
46
|
-
end
|
47
|
-
|
48
|
-
def body_only_protocols
|
49
|
-
self.class.read_inheritable_attribute("body_only_protocols") || []
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
@@ -1,100 +0,0 @@
|
|
1
|
-
module ActionWebService # :nodoc:
|
2
|
-
# Action Web Service parameter specifiers may contain symbols or strings
|
3
|
-
# instead of Class objects, for a limited set of base types.
|
4
|
-
#
|
5
|
-
# This provides an unambiguous way to specify that a given parameter
|
6
|
-
# contains an integer or boolean value, for example.
|
7
|
-
#
|
8
|
-
# The allowed set of symbol/string aliases:
|
9
|
-
#
|
10
|
-
# [<tt>:int</tt>] any integer value
|
11
|
-
# [<tt>:float</tt>] any floating point value
|
12
|
-
# [<tt>:string</tt>] any string value
|
13
|
-
# [<tt>:bool</tt>] any boolean value
|
14
|
-
# [<tt>:time</tt>] any value containing both date and time
|
15
|
-
# [<tt>:date</tt>] any value containing only a date
|
16
|
-
module Signature
|
17
|
-
class SignatureError < StandardError # :nodoc:
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
def canonical_signature(params)
|
22
|
-
return nil if params.nil?
|
23
|
-
params.map do |param|
|
24
|
-
klass = signature_parameter_class(param)
|
25
|
-
if param.is_a?(Hash)
|
26
|
-
param[param.keys[0]] = klass
|
27
|
-
param
|
28
|
-
else
|
29
|
-
klass
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def signature_parameter_class(param)
|
35
|
-
param = param.is_a?(Hash) ? param.values[0] : param
|
36
|
-
is_array = param.is_a?(Array)
|
37
|
-
param = is_array ? param[0] : param
|
38
|
-
param = param.is_a?(String) ? param.to_sym : param
|
39
|
-
param = param.is_a?(Symbol) ? signature_ruby_class(param) : param
|
40
|
-
is_array ? [param] : param
|
41
|
-
end
|
42
|
-
|
43
|
-
|
44
|
-
def canonical_signature_base_type(base_type)
|
45
|
-
base_type = base_type.to_sym
|
46
|
-
case base_type
|
47
|
-
when :int, :integer, :fixnum, :bignum
|
48
|
-
:int
|
49
|
-
when :string, :base64
|
50
|
-
:string
|
51
|
-
when :bool, :boolean
|
52
|
-
:bool
|
53
|
-
when :float, :double
|
54
|
-
:float
|
55
|
-
when :time, :datetime, :timestamp
|
56
|
-
:time
|
57
|
-
when :date
|
58
|
-
:date
|
59
|
-
else
|
60
|
-
raise(SignatureError, ":#{base_type} is not an ActionWebService base type")
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def signature_ruby_class(base_type)
|
65
|
-
case canonical_signature_base_type(base_type)
|
66
|
-
when :int
|
67
|
-
Integer
|
68
|
-
when :string
|
69
|
-
String
|
70
|
-
when :bool
|
71
|
-
TrueClass
|
72
|
-
when :float
|
73
|
-
Float
|
74
|
-
when :time
|
75
|
-
Time
|
76
|
-
when :date
|
77
|
-
Date
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def signature_base_type(ruby_class)
|
82
|
-
case ruby_class
|
83
|
-
when Bignum, Integer, Fixnum
|
84
|
-
:int
|
85
|
-
when String
|
86
|
-
:string
|
87
|
-
when TrueClass, FalseClass
|
88
|
-
:bool
|
89
|
-
when Float, Numeric, Precision
|
90
|
-
:float
|
91
|
-
when Time, DateTime
|
92
|
-
:time
|
93
|
-
when Date
|
94
|
-
:date
|
95
|
-
else
|
96
|
-
raise(SignatureError, "#{ruby_class.name} is not an ActionWebService base type")
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
data/test/abstract_soap.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/abstract_unit'
|
2
|
-
require 'soap/rpc/element'
|
3
|
-
|
4
|
-
class SoapTestError < StandardError
|
5
|
-
end
|
6
|
-
|
7
|
-
class AbstractSoapTest < Test::Unit::TestCase
|
8
|
-
def default_test
|
9
|
-
end
|
10
|
-
|
11
|
-
protected
|
12
|
-
def service_name
|
13
|
-
raise NotImplementedError
|
14
|
-
end
|
15
|
-
|
16
|
-
def do_soap_call(public_method_name, *args)
|
17
|
-
mapper = @container.class.soap_mapper
|
18
|
-
param_def = []
|
19
|
-
i = 1
|
20
|
-
args.each do |arg|
|
21
|
-
mapping = mapper.lookup(arg.class)
|
22
|
-
param_def << ["in", "param#{i}", mapping.registry_mapping]
|
23
|
-
i += 1
|
24
|
-
end
|
25
|
-
qname = XSD::QName.new('urn:ActionWebService', public_method_name)
|
26
|
-
request = SOAP::RPC::SOAPMethodRequest.new(qname, param_def)
|
27
|
-
soap_args = []
|
28
|
-
i = 1
|
29
|
-
args.each do |arg|
|
30
|
-
soap_args << ["param#{i}", SOAP::Mapping.obj2soap(arg)]
|
31
|
-
i += 1
|
32
|
-
end
|
33
|
-
request.set_param(soap_args)
|
34
|
-
header = SOAP::SOAPHeader.new
|
35
|
-
body = SOAP::SOAPBody.new(request)
|
36
|
-
envelope = SOAP::SOAPEnvelope.new(header, body)
|
37
|
-
raw_request = SOAP::Processor.marshal(envelope)
|
38
|
-
test_request = ActionController::TestRequest.new
|
39
|
-
test_request.request_parameters['action'] = service_name
|
40
|
-
test_request.env['REQUEST_METHOD'] = "POST"
|
41
|
-
test_request.env['HTTP_CONTENTTYPE'] = 'text/xml'
|
42
|
-
test_request.env['HTTP_SOAPACTION'] = "/soap/#{service_name}/#{public_method_name}"
|
43
|
-
test_request.env['RAW_POST_DATA'] = raw_request
|
44
|
-
test_response = ActionController::TestResponse.new
|
45
|
-
response = yield test_request, test_response
|
46
|
-
raw_body = response.respond_to?(:body) ? response.body : response.raw_body
|
47
|
-
envelope = SOAP::Processor.unmarshal(raw_body)
|
48
|
-
if envelope
|
49
|
-
if envelope.body.response
|
50
|
-
SOAP::Mapping.soap2obj(envelope.body.response)
|
51
|
-
else
|
52
|
-
nil
|
53
|
-
end
|
54
|
-
else
|
55
|
-
raise(SoapTestError, "empty/invalid body from server")
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,186 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/abstract_soap'
|
2
|
-
require 'wsdl/parser'
|
3
|
-
|
4
|
-
module DispatcherActionControllerTest
|
5
|
-
class API < ActionWebService::API::Base
|
6
|
-
api_method :add, :expects => [:int, :int], :returns => [:int]
|
7
|
-
end
|
8
|
-
|
9
|
-
class DirectAPI < ActionWebService::API::Base
|
10
|
-
api_method :add, :expects => [{:a=>:int}, {:b=>:int}], :returns => [:int]
|
11
|
-
api_method :before_filtered
|
12
|
-
api_method :after_filtered, :returns => [:int]
|
13
|
-
api_method :thrower
|
14
|
-
end
|
15
|
-
|
16
|
-
class Service < ActionWebService::Base
|
17
|
-
web_service_api API
|
18
|
-
|
19
|
-
attr :added
|
20
|
-
|
21
|
-
def add(a, b)
|
22
|
-
@added = a + b
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
class AbstractController < ActionController::Base
|
27
|
-
def generate_wsdl(container, uri, soap_action_base)
|
28
|
-
to_wsdl(container, uri, soap_action_base)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
class DelegatedController < AbstractController
|
33
|
-
web_service_dispatching_mode :delegated
|
34
|
-
|
35
|
-
web_service(:test_service) { @service ||= Service.new; @service }
|
36
|
-
end
|
37
|
-
|
38
|
-
class DirectController < AbstractController
|
39
|
-
web_service_api DirectAPI
|
40
|
-
web_service_dispatching_mode :direct
|
41
|
-
|
42
|
-
before_filter :alwaysfail, :only => [:before_filtered]
|
43
|
-
after_filter :alwaysok, :only => [:after_filtered]
|
44
|
-
|
45
|
-
attr :added
|
46
|
-
attr :before_filter_called
|
47
|
-
attr :before_filter_target_called
|
48
|
-
attr :after_filter_called
|
49
|
-
attr :after_filter_target_called
|
50
|
-
|
51
|
-
def initialize
|
52
|
-
@before_filter_called = false
|
53
|
-
@before_filter_target_called = false
|
54
|
-
@after_filter_called = false
|
55
|
-
@after_filter_target_called = false
|
56
|
-
end
|
57
|
-
|
58
|
-
def add
|
59
|
-
@added = @params['a'] + @params['b']
|
60
|
-
end
|
61
|
-
|
62
|
-
def before_filtered
|
63
|
-
@before_filter_target_called = true
|
64
|
-
end
|
65
|
-
|
66
|
-
def after_filtered
|
67
|
-
@after_filter_target_called = true
|
68
|
-
5
|
69
|
-
end
|
70
|
-
|
71
|
-
def thrower
|
72
|
-
raise "Hi, I'm a SOAP exception"
|
73
|
-
end
|
74
|
-
|
75
|
-
protected
|
76
|
-
def alwaysfail
|
77
|
-
@before_filter_called = true
|
78
|
-
false
|
79
|
-
end
|
80
|
-
|
81
|
-
def alwaysok
|
82
|
-
@after_filter_called = true
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
class TC_DispatcherActionController < AbstractSoapTest
|
88
|
-
include DispatcherActionControllerTest
|
89
|
-
|
90
|
-
def test_direct_dispatching
|
91
|
-
@container = DirectController.new
|
92
|
-
assert(do_soap_call('Add', 20, 50) == 70)
|
93
|
-
assert(@container.added == 70)
|
94
|
-
end
|
95
|
-
|
96
|
-
def test_direct_entrypoint
|
97
|
-
@container = DirectController.new
|
98
|
-
assert(@container.respond_to?(:api))
|
99
|
-
end
|
100
|
-
|
101
|
-
def test_direct_filtering
|
102
|
-
@container = DirectController.new
|
103
|
-
assert(@container.before_filter_called == false)
|
104
|
-
assert(@container.before_filter_target_called == false)
|
105
|
-
assert(do_soap_call('BeforeFiltered').nil?)
|
106
|
-
assert(@container.before_filter_called == true)
|
107
|
-
assert(@container.before_filter_target_called == false)
|
108
|
-
assert(@container.after_filter_called == false)
|
109
|
-
assert(@container.after_filter_target_called == false)
|
110
|
-
assert(do_soap_call('AfterFiltered') == 5)
|
111
|
-
assert(@container.after_filter_called == true)
|
112
|
-
assert(@container.after_filter_target_called == true)
|
113
|
-
end
|
114
|
-
|
115
|
-
def test_delegated_dispatching
|
116
|
-
@container = DelegatedController.new
|
117
|
-
assert(do_soap_call('Add', 50, 80) == 130)
|
118
|
-
assert(service.added == 130)
|
119
|
-
end
|
120
|
-
|
121
|
-
def test_exception_marshaling
|
122
|
-
@container = DirectController.new
|
123
|
-
result = do_soap_call('Thrower')
|
124
|
-
exception = result.detail
|
125
|
-
assert(exception.cause.is_a?(RuntimeError))
|
126
|
-
assert_equal("Hi, I'm a SOAP exception", exception.cause.message)
|
127
|
-
@container.web_service_exception_reporting = false
|
128
|
-
assert_raises(SoapTestError) do
|
129
|
-
do_soap_call('Thrower')
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
def test_wsdl_generation
|
134
|
-
ensure_valid_wsdl_generation DelegatedController.new
|
135
|
-
ensure_valid_wsdl_generation DirectController.new
|
136
|
-
end
|
137
|
-
|
138
|
-
def
|
139
|
-
|
140
|
-
def test_wsdl_action
|
141
|
-
ensure_valid_wsdl_action DelegatedController.new
|
142
|
-
ensure_valid_wsdl_action DirectController.new
|
143
|
-
end
|
144
|
-
|
145
|
-
protected
|
146
|
-
def service_name
|
147
|
-
@container.is_a?(DelegatedController) ? 'test_service' : 'api'
|
148
|
-
end
|
149
|
-
|
150
|
-
def service
|
151
|
-
@container.web_service_object(:test_service)
|
152
|
-
end
|
153
|
-
|
154
|
-
def do_soap_call(public_method_name, *args)
|
155
|
-
super(public_method_name, *args) do |test_request, test_response|
|
156
|
-
response = @container.process(test_request, test_response)
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
def ensure_valid_wsdl_generation(controller)
|
161
|
-
wsdl = controller.generate_wsdl(controller, 'http://localhost:3000/test/', '/test')
|
162
|
-
ensure_valid_wsdl(wsdl)
|
163
|
-
end
|
164
|
-
|
165
|
-
def ensure_valid_wsdl(wsdl)
|
166
|
-
definitions = WSDL::Parser.new.parse(wsdl)
|
167
|
-
assert(definitions.is_a?(WSDL::Definitions))
|
168
|
-
definitions.bindings.each do |binding|
|
169
|
-
assert(binding.name.name.index(':').nil?)
|
170
|
-
end
|
171
|
-
definitions.services.each do |service|
|
172
|
-
service.ports.each do |port|
|
173
|
-
assert(port.name.name.index(':').nil?)
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
def ensure_valid_wsdl_action(controller)
|
179
|
-
test_request = ActionController::TestRequest.new({ 'action' => 'wsdl' })
|
180
|
-
test_request.env['REQUEST_METHOD'] = 'GET'
|
181
|
-
test_request.env['HTTP_HOST'] = 'localhost:3000'
|
182
|
-
test_response = ActionController::TestResponse.new
|
183
|
-
wsdl = controller.process(test_request, test_response).body
|
184
|
-
ensure_valid_wsdl(wsdl)
|
185
|
-
end
|
186
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/abstract_unit'
|
2
|
-
|
3
|
-
|
4
|
-
module Foo
|
5
|
-
include ActionWebService::Protocol
|
6
|
-
|
7
|
-
def self.append_features(base)
|
8
|
-
super
|
9
|
-
base.register_protocol(BodyOnly, FooMinimalProtocol)
|
10
|
-
base.register_protocol(HeaderAndBody, FooMinimalProtocolTwo)
|
11
|
-
base.register_protocol(HeaderAndBody, FooMinimalProtocolTwo)
|
12
|
-
base.register_protocol(HeaderAndBody, FooFullProtocol)
|
13
|
-
end
|
14
|
-
|
15
|
-
class FooFullProtocol < AbstractProtocol
|
16
|
-
def self.create_protocol_request(klass, request)
|
17
|
-
protocol = FooFullProtocol.new klass
|
18
|
-
ActionWebService::Protocol::ProtocolRequest.new(protocol, '', '', '', '')
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
class FooMinimalProtocol < AbstractProtocol
|
23
|
-
def self.create_protocol_request(klass, request)
|
24
|
-
protocol = FooMinimalProtocol.new klass
|
25
|
-
ActionWebService::Protocol::ProtocolRequest.new(protocol, '', '', '', '')
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
class FooMinimalProtocolTwo < AbstractProtocol
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
class ProtocolRegistry
|
34
|
-
include ActionWebService::Protocol::Registry
|
35
|
-
include Foo
|
36
|
-
|
37
|
-
def all_protocols
|
38
|
-
header_and_body_protocols + body_only_protocols
|
39
|
-
end
|
40
|
-
|
41
|
-
def protocol_request
|
42
|
-
probe_request_protocol(nil)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
|
47
|
-
class TC_ProtocolRegistry < Test::Unit::TestCase
|
48
|
-
def test_registration
|
49
|
-
registry = ProtocolRegistry.new
|
50
|
-
assert(registry.all_protocols.length == 4)
|
51
|
-
assert(registry.protocol_request.protocol.is_a?(Foo::FooFullProtocol))
|
52
|
-
end
|
53
|
-
end
|