actionwebservice 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/{ChangeLog → CHANGELOG} +20 -0
  2. data/README +45 -1
  3. data/Rakefile +12 -10
  4. data/TODO +8 -9
  5. data/lib/action_web_service.rb +10 -6
  6. data/lib/action_web_service/api.rb +1 -2
  7. data/lib/action_web_service/api/{abstract.rb → base.rb} +14 -71
  8. data/lib/action_web_service/base.rb +0 -3
  9. data/lib/action_web_service/client/base.rb +1 -12
  10. data/lib/action_web_service/client/soap_client.rb +49 -17
  11. data/lib/action_web_service/client/xmlrpc_client.rb +20 -15
  12. data/lib/action_web_service/container.rb +3 -85
  13. data/lib/action_web_service/{api/action_controller.rb → container/action_controller_container.rb} +2 -2
  14. data/lib/action_web_service/container/delegated_container.rb +87 -0
  15. data/lib/action_web_service/container/direct_container.rb +70 -0
  16. data/lib/action_web_service/dispatcher/abstract.rb +100 -102
  17. data/lib/action_web_service/dispatcher/action_controller_dispatcher.rb +199 -137
  18. data/lib/action_web_service/protocol.rb +1 -1
  19. data/lib/action_web_service/protocol/abstract.rb +14 -112
  20. data/lib/action_web_service/protocol/discovery.rb +37 -0
  21. data/lib/action_web_service/protocol/soap_protocol.rb +32 -458
  22. data/lib/action_web_service/protocol/xmlrpc_protocol.rb +29 -149
  23. data/lib/action_web_service/struct.rb +2 -5
  24. data/lib/action_web_service/test_invoke.rb +130 -0
  25. data/lib/action_web_service/vendor/ws.rb +4 -0
  26. data/lib/action_web_service/vendor/ws/common.rb +8 -0
  27. data/lib/action_web_service/vendor/ws/encoding.rb +3 -0
  28. data/lib/action_web_service/vendor/ws/encoding/abstract.rb +26 -0
  29. data/lib/action_web_service/vendor/ws/encoding/soap_rpc_encoding.rb +90 -0
  30. data/lib/action_web_service/vendor/ws/encoding/xmlrpc_encoding.rb +53 -0
  31. data/lib/action_web_service/vendor/ws/marshaling.rb +3 -0
  32. data/lib/action_web_service/vendor/ws/marshaling/abstract.rb +17 -0
  33. data/lib/action_web_service/vendor/ws/marshaling/soap_marshaling.rb +277 -0
  34. data/lib/action_web_service/vendor/ws/marshaling/xmlrpc_marshaling.rb +116 -0
  35. data/lib/action_web_service/vendor/ws/types.rb +162 -0
  36. data/test/abstract_client.rb +8 -11
  37. data/test/abstract_dispatcher.rb +370 -0
  38. data/test/abstract_unit.rb +1 -0
  39. data/test/api_test.rb +18 -1
  40. data/test/apis/auto_load_api.rb +3 -0
  41. data/test/apis/broken_auto_load_api.rb +2 -0
  42. data/test/client_soap_test.rb +16 -3
  43. data/test/client_xmlrpc_test.rb +16 -4
  44. data/test/container_test.rb +28 -8
  45. data/test/dispatcher_action_controller_soap_test.rb +106 -0
  46. data/test/dispatcher_action_controller_xmlrpc_test.rb +44 -0
  47. data/test/gencov +1 -1
  48. data/test/invocation_test.rb +39 -3
  49. data/test/run +4 -4
  50. data/test/test_invoke_test.rb +77 -0
  51. data/test/ws/abstract_encoding.rb +68 -0
  52. data/test/ws/abstract_unit.rb +13 -0
  53. data/test/ws/gencov +3 -0
  54. data/test/ws/run +5 -0
  55. data/test/ws/soap_marshaling_test.rb +91 -0
  56. data/test/ws/soap_rpc_encoding_test.rb +47 -0
  57. data/test/ws/types_test.rb +41 -0
  58. data/test/ws/xmlrpc_encoding_test.rb +34 -0
  59. metadata +48 -19
  60. data/lib/action_web_service/protocol/registry.rb +0 -55
  61. data/lib/action_web_service/support/signature.rb +0 -100
  62. data/test/abstract_soap.rb +0 -58
  63. data/test/dispatcher_action_controller_test.rb +0 -186
  64. data/test/protocol_registry_test.rb +0 -53
  65. data/test/protocol_soap_test.rb +0 -252
  66. 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
@@ -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