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.
Files changed (54) hide show
  1. data/ChangeLog +47 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +238 -0
  4. data/Rakefile +144 -0
  5. data/TODO +13 -0
  6. data/examples/googlesearch/README +143 -0
  7. data/examples/googlesearch/autoloading/google_search_api.rb +50 -0
  8. data/examples/googlesearch/autoloading/google_search_controller.rb +57 -0
  9. data/examples/googlesearch/delegated/google_search_service.rb +108 -0
  10. data/examples/googlesearch/delegated/search_controller.rb +7 -0
  11. data/examples/googlesearch/direct/google_search_api.rb +50 -0
  12. data/examples/googlesearch/direct/search_controller.rb +58 -0
  13. data/examples/metaWeblog/README +16 -0
  14. data/examples/metaWeblog/blog_controller.rb +127 -0
  15. data/lib/action_web_service.rb +60 -0
  16. data/lib/action_web_service/api.rb +2 -0
  17. data/lib/action_web_service/api/abstract.rb +192 -0
  18. data/lib/action_web_service/api/action_controller.rb +92 -0
  19. data/lib/action_web_service/base.rb +41 -0
  20. data/lib/action_web_service/client.rb +3 -0
  21. data/lib/action_web_service/client/base.rb +39 -0
  22. data/lib/action_web_service/client/soap_client.rb +88 -0
  23. data/lib/action_web_service/client/xmlrpc_client.rb +77 -0
  24. data/lib/action_web_service/container.rb +85 -0
  25. data/lib/action_web_service/dispatcher.rb +2 -0
  26. data/lib/action_web_service/dispatcher/abstract.rb +150 -0
  27. data/lib/action_web_service/dispatcher/action_controller_dispatcher.rb +299 -0
  28. data/lib/action_web_service/invocation.rb +205 -0
  29. data/lib/action_web_service/protocol.rb +4 -0
  30. data/lib/action_web_service/protocol/abstract.rb +128 -0
  31. data/lib/action_web_service/protocol/registry.rb +55 -0
  32. data/lib/action_web_service/protocol/soap_protocol.rb +484 -0
  33. data/lib/action_web_service/protocol/xmlrpc_protocol.rb +168 -0
  34. data/lib/action_web_service/struct.rb +55 -0
  35. data/lib/action_web_service/support/class_inheritable_options.rb +26 -0
  36. data/lib/action_web_service/support/signature.rb +100 -0
  37. data/setup.rb +1360 -0
  38. data/test/abstract_client.rb +131 -0
  39. data/test/abstract_soap.rb +58 -0
  40. data/test/abstract_unit.rb +9 -0
  41. data/test/api_test.rb +52 -0
  42. data/test/base_test.rb +42 -0
  43. data/test/client_soap_test.rb +93 -0
  44. data/test/client_xmlrpc_test.rb +92 -0
  45. data/test/container_test.rb +53 -0
  46. data/test/dispatcher_action_controller_test.rb +186 -0
  47. data/test/gencov +3 -0
  48. data/test/invocation_test.rb +149 -0
  49. data/test/protocol_registry_test.rb +53 -0
  50. data/test/protocol_soap_test.rb +252 -0
  51. data/test/protocol_xmlrpc_test.rb +147 -0
  52. data/test/run +5 -0
  53. data/test/struct_test.rb +40 -0
  54. metadata +131 -0
data/ChangeLog ADDED
@@ -0,0 +1,47 @@
1
+ *0.5.0* (24th February, 2005)
2
+
3
+ * lib/action_service/dispatcher*: replace "router" fragments with
4
+ one file for Action Controllers, moves dispatching work out of
5
+ the container
6
+ * lib/*,test/*,examples/*: rename project to
7
+ ActionWebService. prefix all generic "service" type names with web_.
8
+ update all using code as well as the RDoc.
9
+ * lib/action_service/router/wsdl.rb: ensure that #wsdl is
10
+ defined in the final container class, or the new ActionPack
11
+ filtering will exclude it
12
+ * lib/action_service/struct.rb,test/struct_test.rb: create a
13
+ default #initialize on inherit that accepts a Hash containing
14
+ the default member values
15
+ * lib/action_service/api/action_controller.rb: add support and
16
+ tests for #client_api in controller
17
+ * test/router_wsdl_test.rb: add tests to ensure declared
18
+ service names don't contain ':', as ':' causes interoperability
19
+ issues
20
+ * lib/*, test/*: rename "interface" concept to "api", and change all
21
+ related uses to reflect this change. update all uses of Inflector
22
+ to call the method on String instead.
23
+ * test/api_test.rb: add test to ensure API definition not
24
+ instantiatable
25
+ * lib/action_service/invocation.rb: change @invocation_params to
26
+ @method_params
27
+ * lib/*: update RDoc
28
+ * lib/action_service/struct.rb: update to support base types
29
+ * lib/action_service/support/signature.rb: support the notion of
30
+ "base types" in signatures, with well-known unambiguous names such as :int,
31
+ :bool, etc, which map to the correct Ruby class. accept the same names
32
+ used by ActiveRecord as well as longer versions of each, as aliases.
33
+ * examples/*: update for seperate API definition updates
34
+ * lib/action_service/*, test/*: extensive refactoring: define API methods in
35
+ a seperate class, and specify it wherever used with 'service_api'.
36
+ this makes writing a client API for accessing defined API methods
37
+ with ActionWebService really easy.
38
+ * lib/action_service/container.rb: fix a bug in default call
39
+ handling for direct dispatching, and add ActionController filter
40
+ support for direct dispatching.
41
+ * test/router_action_controller_test.rb: add tests to ensure
42
+ ActionController filters are actually called.
43
+ * test/protocol_soap_test.rb: add more tests for direct dispatching.
44
+
45
+ 0.3.0
46
+
47
+ * First public release
data/MIT-LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (C) 2005 Leon Breedt
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
data/README ADDED
@@ -0,0 +1,238 @@
1
+ = Action Web Service -- Serving APIs on rails
2
+
3
+ Action Web Service provides a way to publish interoperable web service APIs with
4
+ Rails without spending a lot of time delving into protocol details.
5
+
6
+
7
+ == Features
8
+
9
+ * SOAP RPC protocol support
10
+ * Dynamic WSDL generation for APIs
11
+ * XML-RPC protocol support
12
+ * Clients that use the same API definitions as the server for
13
+ easy interoperability with other Action Web Service based applications
14
+ * Type signature hints to improve interoperability with static languages
15
+ * Active Record model class support in signatures
16
+
17
+
18
+ == Defining your APIs
19
+
20
+ You specify the methods you want to make available as API methods in an
21
+ ActionWebService::API::Base derivative, and then specify this API
22
+ definition class wherever you want to use that API.
23
+
24
+ The implementation of the methods is done seperately to the API
25
+ specification.
26
+
27
+
28
+ ==== Method name inflection
29
+
30
+ Action Web Service will camelcase the method names according to Rails Inflector
31
+ rules for the API visible to public callers. What this means, for example
32
+ is that the method names in generated WSDL will be camelcased, and callers will
33
+ have to supply the camelcased name in their requests for the request to
34
+ succeed.
35
+
36
+ If you do not desire this behaviour, you can turn it off with the
37
+ ActionWebService::API::Base +inflect_names+ option.
38
+
39
+
40
+ ==== Inflection examples
41
+
42
+ :add => Add
43
+ :find_all => FindAll
44
+
45
+
46
+ ==== Disabling inflection
47
+
48
+ class PersonAPI < ActionWebService::API::Base
49
+ inflect_names false
50
+ end
51
+
52
+
53
+ ==== API definition example
54
+
55
+ class PersonAPI < ActionWebService::API::Base
56
+ api_method :add, :expects => [:string, :string, :bool], :returns => [:int]
57
+ api_method :remove, :expects => [:int], :returns => [:bool]
58
+ end
59
+
60
+ ==== API usage example
61
+
62
+ class PersonController < ActionController::Base
63
+ web_service_api PersonAPI
64
+
65
+ def add
66
+ end
67
+
68
+ def remove
69
+ end
70
+ end
71
+
72
+
73
+ == Publishing your APIs
74
+
75
+ Action Web Service uses Action Pack to process protocol requests. There are two
76
+ modes of dispatching protocol requests, _Direct_, and _Delegated_.
77
+
78
+
79
+ === Direct dispatching
80
+
81
+ This is the default mode. In this mode, controller actions implement the API
82
+ methods, and parameters for incoming method calls will be placed in
83
+ <tt>@params</tt> (keyed by name), and <tt>@method_params</tt> (ordered list).
84
+
85
+ The return value of the action is sent back as the return value to the
86
+ caller.
87
+
88
+ In this mode, a special <tt>api</tt> action is generated in the target
89
+ controller to unwrap the protocol request, forward it on to the relevant action
90
+ and send back the wrapped return value. <em>This action must not be
91
+ overridden.</em>
92
+
93
+ ==== Direct dispatching example
94
+
95
+ class PersonController < ApplicationController
96
+ web_service_api PersonAPI
97
+
98
+ def add
99
+ end
100
+
101
+ def remove
102
+ end
103
+ end
104
+
105
+ class PersonAPI < ActionWebService::API::Base
106
+ ...
107
+ end
108
+
109
+
110
+ For this example, protocol requests for +Add+ and +Remove+ methods sent to
111
+ <tt>/person/api</tt> will be routed to the actions +add+ and +remove+.
112
+
113
+
114
+ === Delegated dispatching
115
+
116
+ This mode can be turned on by setting the +web_service_dispatching_mode+ option
117
+ in a controller.
118
+
119
+ In this mode, the controller contains one or more web service objects (objects
120
+ that implement an ActionWebService::API::Base definition). These web service
121
+ objects are each mapped onto one controller action only.
122
+
123
+ ==== Delegated dispatching example
124
+
125
+ class ApiController < ApplicationController
126
+ web_service_dispatching_mode :delegated
127
+
128
+ web_service :person, PersonService.new
129
+ end
130
+
131
+ class PersonService < ActionWebService::Base
132
+ web_service_api PersonAPI
133
+
134
+ def add
135
+ end
136
+
137
+ def remove
138
+ end
139
+ end
140
+
141
+ class PersonAPI < ActionWebService::API::Base
142
+ ...
143
+ end
144
+
145
+
146
+ For this example, all protocol requests for +PersonService+ are
147
+ sent to the <tt>/api/person</tt> action.
148
+
149
+ The <tt>/api/person</tt> action is generated when the +web_service+
150
+ method is called. <em>This action must not be overridden.</em>
151
+
152
+ Other controller actions (actions that aren't the target of a +web_service+ call)
153
+ are ignored for ActionWebService purposes, and can do normal action tasks.
154
+
155
+
156
+ == Using the client support
157
+
158
+ Action Web Service includes client classes that can use the same API
159
+ definition as the server. The advantage of this approach is that your client
160
+ will have the same support for Active Record and structured types as the
161
+ server, and can just use them directly, and rely on the marshaling to Do The
162
+ Right Thing.
163
+
164
+ *Note*: The client support is intended for communication between Ruby on Rails
165
+ applications that both use Action Web Service. It may work with other servers, but
166
+ that is not its intended use, and interoperability can't be guaranteed, especially
167
+ not for .NET web services.
168
+
169
+ Web services protocol specifications are complex, and Action Web Service client
170
+ support can only be guaranteed to work with a subset.
171
+
172
+
173
+ ==== Factory created client example
174
+
175
+ class BlogManagerController < ApplicationController
176
+ web_client_api :blogger, :xmlrpc, 'http://url/to/blog/api/RPC2', :handler_name => 'blogger'
177
+ end
178
+
179
+ class SearchingController < ApplicationController
180
+ web_client_api :google, :soap, 'http://url/to/blog/api/beta', :service_name => 'GoogleSearch'
181
+ end
182
+
183
+ See ActionWebService::API::ActionController::ClassMethods for more details.
184
+
185
+ ==== Manually created client example
186
+
187
+ class PersonAPI < ActionWebService::API::Base
188
+ api_method :find_all, :returns => [[Person]]
189
+ end
190
+
191
+ soap_client = ActionWebService::Client::Soap.new(PersonAPI, "http://...")
192
+ persons = soap_client.find_all
193
+
194
+ class BloggerAPI < ActionWebService::API::Base
195
+ inflect_names false
196
+ api_method :getRecentPosts, :returns => [[Blog::Post]]
197
+ end
198
+
199
+ blog = ActionWebService::Client::XmlRpc.new(BloggerAPI, "http://.../xmlrpc", :handler_name => "blogger")
200
+ posts = blog.getRecentPosts
201
+
202
+
203
+ See ActionWebService::Client::Soap and ActionWebService::Client::XmlRpc for more details.
204
+
205
+ == Dependencies
206
+
207
+ Action Web Service requires that the Action Pack and Active Record are either
208
+ available to be required immediately or are accessible as GEMs.
209
+
210
+ It also requires a version of Ruby that includes SOAP support in the standard
211
+ library. At least version 1.8.2 final (2004-12-25) of Ruby is recommended, this
212
+ is the version tested against.
213
+
214
+
215
+ == Download
216
+
217
+ The latest Action Web Service version can be downloaded from
218
+ http://rubyforge.org/projects/actionservice
219
+
220
+
221
+ == Installation
222
+
223
+ You can install Action Web Service with the following command.
224
+
225
+ % [sudo] ruby setup.rb
226
+
227
+
228
+ == License
229
+
230
+ Action Web Service is released under the MIT license.
231
+
232
+
233
+ == Support
234
+
235
+ The Ruby on Rails mailing list
236
+
237
+ Or, to contact the author, send mail to bitserf@gmail.com
238
+
data/Rakefile ADDED
@@ -0,0 +1,144 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/contrib/rubyforgepublisher'
8
+ require 'fileutils'
9
+
10
+ PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
11
+ PKG_NAME = 'actionwebservice'
12
+ PKG_VERSION = '0.5.0' + PKG_BUILD
13
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
14
+ PKG_DESTINATION = ENV["RAILS_PKG_DESTINATION"] || "../#{PKG_NAME}"
15
+
16
+ desc "Default Task"
17
+ task :default => [ :test ]
18
+
19
+
20
+ # Run the unit tests
21
+ Rake::TestTask.new { |t|
22
+ t.libs << "test"
23
+ t.pattern = 'test/*_test.rb'
24
+ t.verbose = true
25
+ }
26
+
27
+
28
+ # Generate the RDoc documentation
29
+ Rake::RDocTask.new { |rdoc|
30
+ rdoc.rdoc_dir = 'doc'
31
+ rdoc.title = "Action Web Service -- Web services for Action Pack"
32
+ rdoc.options << '--line-numbers --inline-source --main README --accessor class_inheritable_option=RW'
33
+ rdoc.rdoc_files.include('README')
34
+ rdoc.rdoc_files.include('lib/action_web_service.rb')
35
+ rdoc.rdoc_files.include('lib/action_web_service/*.rb')
36
+ rdoc.rdoc_files.include('lib/action_web_service/api/*.rb')
37
+ rdoc.rdoc_files.include('lib/action_web_service/client/*.rb')
38
+ rdoc.rdoc_files.include('lib/action_web_service/protocol/*.rb')
39
+ rdoc.rdoc_files.include('lib/action_web_service/dispatcher/*.rb')
40
+ rdoc.rdoc_files.include('lib/action_web_service/support/*.rb')
41
+ }
42
+
43
+
44
+ # Create compressed packages
45
+ spec = Gem::Specification.new do |s|
46
+ s.platform = Gem::Platform::RUBY
47
+ s.name = PKG_NAME
48
+ s.summary = "Web service support for Action Pack."
49
+ s.description = %q{Adds WSDL/SOAP and XML-RPC web service support to Action Pack}
50
+ s.version = PKG_VERSION
51
+
52
+ s.author = "Leon Breedt"
53
+ s.email = "bitserf@gmail.com"
54
+ s.rubyforge_project = "aws"
55
+ s.homepage = "http://www.rubyonrails.org"
56
+
57
+ s.add_dependency('actionpack', '= 1.5.0' + PKG_BUILD)
58
+ s.add_dependency('activerecord', '= 1.7.0' + PKG_BUILD)
59
+ s.add_dependency('activesupport', '= 1.0.0' + PKG_BUILD)
60
+
61
+ s.has_rdoc = true
62
+ s.requirements << 'none'
63
+ s.require_path = 'lib'
64
+ s.autorequire = 'action_web_service'
65
+
66
+ s.files = [ "Rakefile", "setup.rb", "README", "TODO", "ChangeLog", "MIT-LICENSE" ]
67
+ s.files = s.files + Dir.glob( "examples/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
68
+ s.files = s.files + Dir.glob( "lib/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
69
+ s.files = s.files + Dir.glob( "test/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
70
+ end
71
+ Rake::GemPackageTask.new(spec) do |p|
72
+ p.gem_spec = spec
73
+ p.need_tar = true
74
+ p.need_zip = true
75
+ end
76
+
77
+
78
+ # Publish beta gem
79
+ desc "Publish the API documentation"
80
+ task :pgem => [:package] do
81
+ Rake::SshFilePublisher.new("davidhh@comox.textdrive.com", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
82
+ `ssh davidhh@comox.textdrive.com './gemupdate.sh'`
83
+ end
84
+
85
+ # Publish documentation
86
+ desc "Publish the API documentation"
87
+ task :pdoc => [:rdoc] do
88
+ Rake::SshDirPublisher.new("davidhh@comox.textdrive.com", "public_html/as", "doc").upload
89
+ end
90
+
91
+
92
+ def each_source_file(*args)
93
+ prefix, includes, excludes, open_file = args
94
+ prefix ||= File.dirname(__FILE__)
95
+ open_file = true if open_file.nil?
96
+ includes ||= %w[lib\/action_web_service\.rb$ lib\/action_web_service\/.*\.rb$]
97
+ excludes ||= %w[]
98
+ Find.find(prefix) do |file_name|
99
+ next if file_name =~ /\.svn/
100
+ file_name.gsub!(/^\.\//, '')
101
+ continue = false
102
+ includes.each do |inc|
103
+ if file_name.match(/#{inc}/)
104
+ continue = true
105
+ break
106
+ end
107
+ end
108
+ next unless continue
109
+ excludes.each do |exc|
110
+ if file_name.match(/#{exc}/)
111
+ continue = false
112
+ break
113
+ end
114
+ end
115
+ next unless continue
116
+ if open_file
117
+ File.open(file_name) do |f|
118
+ yield file_name, f
119
+ end
120
+ else
121
+ yield file_name
122
+ end
123
+ end
124
+ end
125
+
126
+ desc "Count lines of the source code"
127
+ task :lines do
128
+ total_lines = total_loc = 0
129
+ puts "Per File:"
130
+ each_source_file do |file_name, f|
131
+ file_lines = file_loc = 0
132
+ while line = f.gets
133
+ file_lines += 1
134
+ next if line =~ /^\s*$/
135
+ next if line =~ /^\s*#/
136
+ file_loc += 1
137
+ end
138
+ puts " #{file_name}: Lines #{file_lines}, LOC #{file_loc}"
139
+ total_lines += file_lines
140
+ total_loc += file_loc
141
+ end
142
+ puts "Total:"
143
+ puts " Lines #{total_lines}, LOC #{total_loc}"
144
+ end