actionwebservice 0.5.0 → 0.6.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.
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