halcyon 0.4.0 → 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 (60) hide show
  1. data/AUTHORS +1 -0
  2. data/LICENSE +20 -0
  3. data/README +107 -0
  4. data/Rakefile +8 -6
  5. data/bin/halcyon +3 -204
  6. data/lib/halcyon.rb +55 -42
  7. data/lib/halcyon/application.rb +247 -0
  8. data/lib/halcyon/application/router.rb +86 -0
  9. data/lib/halcyon/client.rb +187 -35
  10. data/lib/halcyon/client/ssl.rb +38 -0
  11. data/lib/halcyon/controller.rb +154 -0
  12. data/lib/halcyon/exceptions.rb +67 -59
  13. data/lib/halcyon/logging.rb +31 -0
  14. data/lib/halcyon/logging/analogger.rb +31 -0
  15. data/lib/halcyon/logging/helpers.rb +37 -0
  16. data/lib/halcyon/logging/log4r.rb +25 -0
  17. data/lib/halcyon/logging/logger.rb +20 -0
  18. data/lib/halcyon/logging/logging.rb +19 -0
  19. data/lib/halcyon/runner.rb +141 -0
  20. data/lib/halcyon/runner/commands.rb +141 -0
  21. data/lib/halcyon/runner/helpers.rb +9 -0
  22. data/lib/halcyon/runner/helpers/command_helper.rb +71 -0
  23. data/spec/halcyon/application_spec.rb +70 -0
  24. data/spec/halcyon/client_spec.rb +63 -0
  25. data/spec/halcyon/controller_spec.rb +68 -0
  26. data/spec/halcyon/halcyon_spec.rb +63 -0
  27. data/spec/halcyon/logging_spec.rb +31 -0
  28. data/spec/halcyon/router_spec.rb +37 -12
  29. data/spec/halcyon/runner_spec.rb +54 -0
  30. data/spec/spec_helper.rb +75 -9
  31. data/support/generators/halcyon/USAGE +0 -0
  32. data/support/generators/halcyon/halcyon_generator.rb +52 -0
  33. data/support/generators/halcyon/templates/README +26 -0
  34. data/support/generators/halcyon/templates/Rakefile +32 -0
  35. data/support/generators/halcyon/templates/app/application.rb +43 -0
  36. data/support/generators/halcyon/templates/config/config.yml +36 -0
  37. data/support/generators/halcyon/templates/config/init/environment.rb +11 -0
  38. data/support/generators/halcyon/templates/config/init/hooks.rb +39 -0
  39. data/support/generators/halcyon/templates/config/init/requires.rb +10 -0
  40. data/support/generators/halcyon/templates/config/init/routes.rb +50 -0
  41. data/support/generators/halcyon/templates/lib/client.rb +77 -0
  42. data/support/generators/halcyon/templates/runner.ru +8 -0
  43. data/support/generators/halcyon_flat/USAGE +0 -0
  44. data/support/generators/halcyon_flat/halcyon_flat_generator.rb +52 -0
  45. data/support/generators/halcyon_flat/templates/README +26 -0
  46. data/support/generators/halcyon_flat/templates/Rakefile +32 -0
  47. data/support/generators/halcyon_flat/templates/app.rb +49 -0
  48. data/support/generators/halcyon_flat/templates/lib/client.rb +17 -0
  49. data/support/generators/halcyon_flat/templates/runner.ru +8 -0
  50. metadata +73 -20
  51. data/lib/halcyon/client/base.rb +0 -261
  52. data/lib/halcyon/client/exceptions.rb +0 -41
  53. data/lib/halcyon/client/router.rb +0 -106
  54. data/lib/halcyon/server.rb +0 -62
  55. data/lib/halcyon/server/auth/basic.rb +0 -107
  56. data/lib/halcyon/server/base.rb +0 -774
  57. data/lib/halcyon/server/exceptions.rb +0 -41
  58. data/lib/halcyon/server/router.rb +0 -103
  59. data/spec/halcyon/error_spec.rb +0 -55
  60. data/spec/halcyon/server_spec.rb +0 -105
@@ -0,0 +1,26 @@
1
+ = Application
2
+
3
+
4
+ == Introduction
5
+
6
+ ...
7
+
8
+
9
+ == Installation
10
+
11
+ ...
12
+
13
+
14
+ === Dependencies
15
+
16
+ * Halcyon (halcyon >= 0.5.0)
17
+ * ...
18
+
19
+ == License
20
+
21
+ ...
22
+
23
+
24
+ == Contact
25
+
26
+ ...
@@ -0,0 +1,32 @@
1
+ %w(rubygems rake rake/clean rake/rdoctask fileutils pp halcyon).each{|dep|require dep}
2
+
3
+ include FileUtils
4
+
5
+ # Halcyon.root => the root application directory
6
+ # Halcyon.app => the application name
7
+
8
+ desc "Start the application on port 4647"
9
+ task :start do
10
+ sh "halcyon start -p 4647"
11
+ end
12
+
13
+ desc "Generate RDoc documentation"
14
+ Rake::RDocTask.new(:rdoc) do |rdoc|
15
+ rdoc.options << '--line-numbers' << '--inline-source' <<
16
+ '--main' << 'README' <<
17
+ '--title' << "#{Halcyon.app} Documentation" <<
18
+ '--charset' << 'utf-8'
19
+ rdoc.rdoc_dir = "doc"
20
+ rdoc.rdoc_files.include('README')
21
+ rdoc.rdoc_files.include('app/**/*.rb')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
24
+
25
+ # = Custom Rake Tasks
26
+ #
27
+ # Add your custom rake tasks here.
28
+
29
+ # ...
30
+
31
+ # = Default Task
32
+ task :default => Rake::Task['start']
@@ -0,0 +1,49 @@
1
+ require 'halcyon'
2
+
3
+ # = Required Libraries
4
+ %w().each {|dep|require dep}
5
+
6
+ # = Configuration
7
+ # Halcyon.config = Halcyon::Runner.load_config
8
+ Halcyon.config = {
9
+ :allow_from => 'all',
10
+ :logging => {
11
+ :type => 'Logger',
12
+ # :file => nil, # STDOUT
13
+ :level => 'debug'
14
+ }
15
+ }.to_mash
16
+
17
+ # = Environment
18
+ # Set the environment if not set above; create the <tt>Halcyon.environment</tt>
19
+ # configurable attribute. Maps to <tt>Halcyon.config[:environment]</tt>.
20
+ Halcyon.configurable_attr(:environment)
21
+ Halcyon.environment = :development unless Halcyon.environment
22
+
23
+ # = Routes
24
+ Halcyon::Application.route do |r|
25
+ r.match('/time').to(:controller => 'application', :action => 'time')
26
+
27
+ r.match('/').to(:controller => 'application', :action => 'index')
28
+
29
+ # failover
30
+ {:action => 'not_found'}
31
+ end
32
+
33
+ # = Hooks
34
+ Halcyon::Application.startup do |config|
35
+ logger.info 'Define startup tasks in Halcyon::Application.startup {}'
36
+ end
37
+
38
+ # = Application
39
+ class Application < Halcyon::Controller
40
+
41
+ def index
42
+ ok('Nothing here')
43
+ end
44
+
45
+ def time
46
+ ok(Time.now.to_s)
47
+ end
48
+
49
+ end
@@ -0,0 +1,17 @@
1
+ %w(rubygems halcyon).each{|dep|require dep}
2
+
3
+ module <%= app %>
4
+
5
+ class Client < Halcyon::Client
6
+
7
+ def self.version
8
+ VERSION.join('.')
9
+ end
10
+
11
+ def time
12
+ get('/time')[:body]
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,8 @@
1
+ require 'halcyon'
2
+ require 'app'
3
+
4
+ puts "(Starting in #{Halcyon.root})"
5
+
6
+ Thin::Logging.silent = true if defined? Thin
7
+
8
+ run Halcyon::Runner.new
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: halcyon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Todd
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-02-10 00:00:00 -05:00
12
+ date: 2008-05-29 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -19,7 +19,7 @@ dependencies:
19
19
  requirements:
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 0.2.0
22
+ version: 0.3.0
23
23
  version:
24
24
  - !ruby/object:Gem::Dependency
25
25
  name: merb
@@ -28,7 +28,7 @@ dependencies:
28
28
  requirements:
29
29
  - - ">="
30
30
  - !ruby/object:Gem::Version
31
- version: 0.4.1
31
+ version: 0.9.2
32
32
  version:
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: json_pure
@@ -37,7 +37,16 @@ dependencies:
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 1.1.1
40
+ version: 1.1.2
41
+ version:
42
+ - !ruby/object:Gem::Dependency
43
+ name: rubigen
44
+ version_requirement:
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 1.2.4
41
50
  version:
42
51
  description: A JSON App Server Framework
43
52
  email: chiology@gmail.com
@@ -50,26 +59,70 @@ extra_rdoc_files:
50
59
  files:
51
60
  - lib
52
61
  - Rakefile
62
+ - README
63
+ - LICENSE
64
+ - AUTHORS
53
65
  - spec/halcyon
54
- - spec/halcyon/error_spec.rb
66
+ - spec/halcyon/application_spec.rb
67
+ - spec/halcyon/client_spec.rb
68
+ - spec/halcyon/controller_spec.rb
69
+ - spec/halcyon/halcyon_spec.rb
70
+ - spec/halcyon/logging_spec.rb
55
71
  - spec/halcyon/router_spec.rb
56
- - spec/halcyon/server_spec.rb
72
+ - spec/halcyon/runner_spec.rb
57
73
  - spec/spec_helper.rb
58
74
  - lib/halcyon
75
+ - lib/halcyon/application
76
+ - lib/halcyon/application/router.rb
77
+ - lib/halcyon/application.rb
59
78
  - lib/halcyon/client
60
- - lib/halcyon/client/base.rb
61
- - lib/halcyon/client/exceptions.rb
62
- - lib/halcyon/client/router.rb
79
+ - lib/halcyon/client/ssl.rb
63
80
  - lib/halcyon/client.rb
81
+ - lib/halcyon/controller.rb
64
82
  - lib/halcyon/exceptions.rb
65
- - lib/halcyon/server
66
- - lib/halcyon/server/auth
67
- - lib/halcyon/server/auth/basic.rb
68
- - lib/halcyon/server/base.rb
69
- - lib/halcyon/server/exceptions.rb
70
- - lib/halcyon/server/router.rb
71
- - lib/halcyon/server.rb
83
+ - lib/halcyon/logging
84
+ - lib/halcyon/logging/analogger.rb
85
+ - lib/halcyon/logging/helpers.rb
86
+ - lib/halcyon/logging/log4r.rb
87
+ - lib/halcyon/logging/logger.rb
88
+ - lib/halcyon/logging/logging.rb
89
+ - lib/halcyon/logging.rb
90
+ - lib/halcyon/runner
91
+ - lib/halcyon/runner/commands.rb
92
+ - lib/halcyon/runner/helpers
93
+ - lib/halcyon/runner/helpers/command_helper.rb
94
+ - lib/halcyon/runner/helpers.rb
95
+ - lib/halcyon/runner.rb
72
96
  - lib/halcyon.rb
97
+ - support/generators
98
+ - support/generators/halcyon
99
+ - support/generators/halcyon/halcyon_generator.rb
100
+ - support/generators/halcyon/templates
101
+ - support/generators/halcyon/templates/app
102
+ - support/generators/halcyon/templates/app/application.rb
103
+ - support/generators/halcyon/templates/config
104
+ - support/generators/halcyon/templates/config/config.yml
105
+ - support/generators/halcyon/templates/config/init
106
+ - support/generators/halcyon/templates/config/init/environment.rb
107
+ - support/generators/halcyon/templates/config/init/hooks.rb
108
+ - support/generators/halcyon/templates/config/init/requires.rb
109
+ - support/generators/halcyon/templates/config/init/routes.rb
110
+ - support/generators/halcyon/templates/lib
111
+ - support/generators/halcyon/templates/lib/client.rb
112
+ - support/generators/halcyon/templates/Rakefile
113
+ - support/generators/halcyon/templates/README
114
+ - support/generators/halcyon/templates/runner.ru
115
+ - support/generators/halcyon/USAGE
116
+ - support/generators/halcyon_flat
117
+ - support/generators/halcyon_flat/halcyon_flat_generator.rb
118
+ - support/generators/halcyon_flat/templates
119
+ - support/generators/halcyon_flat/templates/app.rb
120
+ - support/generators/halcyon_flat/templates/lib
121
+ - support/generators/halcyon_flat/templates/lib/client.rb
122
+ - support/generators/halcyon_flat/templates/Rakefile
123
+ - support/generators/halcyon_flat/templates/README
124
+ - support/generators/halcyon_flat/templates/runner.ru
125
+ - support/generators/halcyon_flat/USAGE
73
126
  has_rdoc: true
74
127
  homepage: http://halcyon.rubyforge.org
75
128
  post_install_message:
@@ -81,7 +134,7 @@ rdoc_options:
81
134
  - --line-numbers
82
135
  - --inline-source
83
136
  - --title
84
- - "\"Halcyon Documentation\""
137
+ - "\"Halcyon API\""
85
138
  - --exclude
86
139
  - "\"^(_darcs|spec|pkg|.svn)/\""
87
140
  require_paths:
@@ -100,8 +153,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
100
153
  version:
101
154
  requirements:
102
155
  - install the json gem to get faster JSON parsing
103
- rubyforge_project:
104
- rubygems_version: 0.9.5
156
+ rubyforge_project: halcyon
157
+ rubygems_version: 1.1.0
105
158
  signing_key:
106
159
  specification_version: 2
107
160
  summary: A JSON App Server Framework
@@ -1,261 +0,0 @@
1
- #--
2
- # Created by Matt Todd on 2007-12-14.
3
- # Copyright (c) 2007. All rights reserved.
4
- #++
5
-
6
- #--
7
- # dependencies
8
- #++
9
-
10
- %w(net/http uri json).each {|dep|require dep}
11
-
12
- #--
13
- # module
14
- #++
15
-
16
- module Halcyon
17
- class Client
18
-
19
- DEFAULT_OPTIONS = {}
20
- USER_AGENT = "JSON/#{JSON::VERSION} Compatible (en-US) Halcyon/#{Halcyon.version} Client/#{Halcyon::Client.version}"
21
- CONTENT_TYPE = 'application/json'
22
-
23
- # = Building Custom Clients
24
- #
25
- # Once your Halcyon JSON Server App starts to take shape, it may be useful
26
- # to begin to write tests on expected functionality, and then to implement
27
- # API calls with a designated Client lib for your Ruby or Rails apps, etc.
28
- # The Base class provides a standard implementation and several options for
29
- # wrapping up functionality of your app from the server side into the
30
- # client side so that you may begin to use response data.
31
- #
32
- # == Creating Your Client
33
- #
34
- # Creating a simple client can be as simple as this:
35
- #
36
- # class Simple < Halcyon::Client::Base
37
- # def greet(name)
38
- # get("/hello/#{name}")
39
- # end
40
- # end
41
- #
42
- # The only thing simply may be actually using the Simple client you just
43
- # created.
44
- #
45
- # But to actually get in and use the library, one has to take full
46
- # advantage of the HTTP request methods, +get+, +post+, +put+, and
47
- # +delete+. These methods simply return the JSON-parsed data from the
48
- # server, effectively returning a hash with two key values, +status+ which
49
- # contains the HTTP status code, and +body+ which contains the body of the
50
- # content returned which can be any number of objects, including, but not
51
- # limited to Hash, Array, Numeric, Nil, Boolean, String, etc.
52
- #
53
- # You are not limited to what your methods can call: they are arbitrarily
54
- # and solely up to your whims and needs. It is simply a matter of good
55
- # design and performance when it comes to structuring and implementing
56
- # client actions which can be complex or simple series of requests to the
57
- # server.
58
- #
59
- # == Acceptable Clients
60
- #
61
- # The Halcyon Server is intended to be very picky with whom it will speak
62
- # to, so it requires that we specifically mention that we speak only
63
- # "application/html", that we're "JSON/1.1.1 Compatible", and that we're
64
- # local to the server itself (in process, anyways). This ensures that it
65
- # has to deal with as little noise as possible and focus it's attention on
66
- # performing our requests.
67
- #
68
- # This shouldn't affect usage when working with the Client or in production
69
- # but might if you're trying to check things in your browser. Just make
70
- # certain that the debug option is turned on (-d for the +halcyon+ command)
71
- # when you start the server so that it knows to be a little more lenient
72
- # about to whom it speaks.
73
- class Base
74
-
75
- #--
76
- # Initialization and setup
77
- #++
78
-
79
- # = Connecting to the Server
80
- #
81
- # Creates a new Client object to allow for requests and responses from
82
- # the specified server.
83
- #
84
- # The +uri+ param contains the URL to the actual server, and should be in
85
- # the format: "http://localhost:3801" or "http://app.domain.com:3401/"
86
- #
87
- # == Server Connections
88
- #
89
- # Connecting only occurs at the actual event that a request is performed,
90
- # so there is no need to worry about closing connections or managing
91
- # connections in general other than good object housecleaning. (Be nice
92
- # to your Garbage Collector.)
93
- #
94
- # == Usage
95
- #
96
- # You can either provide a block to perform all of your requests and
97
- # processing inside of or you can simply accept the object in response
98
- # and call your request methods off of the returned object.
99
- #
100
- # Alternatively, you could do both.
101
- #
102
- # An example of creating and using a Simple client:
103
- #
104
- # class Simple < Halcyon::Client::Base
105
- # def greet(name)
106
- # get("/hello/#{name}")
107
- # end
108
- # end
109
- # Simple.new('http://localhost:3801') do |s|
110
- # puts s.greet("Johnny").inspect
111
- # end
112
- #
113
- # This should effectively call +inspect+ on a response hash similar to
114
- # this:
115
- #
116
- # {:status => 200, :body => 'Hello Johnny'}
117
- #
118
- # Alternatively, you could perform the same with the following:
119
- #
120
- # s = Simple.new('http://localhost:3801')
121
- # puts s.greet("Johnny").inspect
122
- #
123
- # This should generate the exact same outcome as the previous example,
124
- # except that it is not executed in a block.
125
- #
126
- # The differences are purely semantic and of personal taste.
127
- def initialize(uri)
128
- @uri = URI.parse(uri)
129
- if block_given?
130
- yield self
131
- end
132
- end
133
-
134
- #--
135
- # Reverse Routing
136
- #++
137
-
138
- # = Reverse Routing
139
- #
140
- # The concept of writing our Routes in our Client is to be able to
141
- # automatically generate the appropriate URL based on the hash given
142
- # and where it was called from. This makes writing actions in Clients
143
- # go from something like this:
144
- #
145
- # def greet(name)
146
- # get("/hello/#{name}")
147
- # end
148
- #
149
- # to this:
150
- #
151
- # def greet(name)
152
- # get(url_for(__method__, :name))
153
- # end
154
- #
155
- # This doesn't immediately seem to be beneficial, but it is better for
156
- # automating URL generating, taking out the hardcoding, and has room to
157
- # to improve in the future.
158
- def url_for(action, params = {})
159
- Halcyon::Client::Router.route(action, params)
160
- end
161
-
162
- # Sets up routing for creating preparing +url_for+ URLs. See the
163
- # +url_for+ method documentation and the Halcyon::Client::Router docs.
164
- def self.route
165
- if block_given?
166
- Halcyon::Client::Router.prepare do |r|
167
- Halcyon::Client::Router.default_to yield(r)
168
- end
169
- else
170
- warn "Routes should be defined in a block."
171
- end
172
- end
173
-
174
- #--
175
- # Request Handling
176
- #++
177
-
178
- # Performs a GET request on the URI specified.
179
- def get(uri, headers={})
180
- req = Net::HTTP::Get.new(uri)
181
- request(req, headers)
182
- end
183
-
184
- # Performs a POST request on the URI specified.
185
- def post(uri, data, headers={})
186
- req = Net::HTTP::Post.new(uri)
187
- req.body = format_body(data)
188
- request(req, headers)
189
- end
190
-
191
- # Performs a DELETE request on the URI specified.
192
- def delete(uri, headers={})
193
- req = Net::HTTP::Delete.new(uri)
194
- request(req, headers)
195
- end
196
-
197
- # Performs a PUT request on the URI specified.
198
- def put(uri, data, headers={})
199
- req = Net::HTTP::Put.new(uri)
200
- req.body = format_body(data)
201
- request(req, headers)
202
- end
203
-
204
- private
205
-
206
- # Performs an arbitrary HTTP request, receive the response, parse it with
207
- # JSON, and return it to the caller. This is a private method because the
208
- # user/developer should be quite satisfied with the +get+, +post+, +put+,
209
- # and +delete+ methods.
210
- #
211
- # == Request Failures
212
- #
213
- # If the server responds with any kind of failure (anything with a status
214
- # that isn't 200), Halcyon will in turn raise the respective exception
215
- # (defined in Halcyon::Exceptions) which all inherit from
216
- # +Halcyon::Exceptions::Base+. It is up to the client to handle these
217
- # exceptions specifically.
218
- def request(req, headers={})
219
- # define essential headers for Halcyon::Server's picky requirements
220
- req["Content-Type"] = CONTENT_TYPE
221
- req["User-Agent"] = USER_AGENT
222
-
223
- # apply provided headers
224
- headers.each do |pair|
225
- header, value = pair
226
- req[header] = value
227
- end
228
-
229
- # provide hook for modifying the headers
230
- req = headers(req) if respond_to? :headers
231
-
232
- # prepare and send HTTP request
233
- res = Net::HTTP.start(@uri.host, @uri.port) {|http|http.request(req)}
234
-
235
- # parse response
236
- body = JSON.parse(res.body)
237
- body.symbolize_keys!
238
-
239
- # handle non-successes
240
- raise Halcyon::Client::Base::Exceptions.lookup(body[:status]).new unless res.kind_of? Net::HTTPSuccess
241
-
242
- # return response
243
- body
244
- rescue Halcyon::Exceptions::Base => e
245
- # log exception if logger is in place
246
- raise
247
- end
248
-
249
- # Formats the data of a POST or PUT request (the body) into an acceptable
250
- # format according to Net::HTTP for sending through as a Hash.
251
- def format_body(data)
252
- data = {:body => data} unless data.is_a? Hash
253
- data.symbolize_keys!
254
- # uses the Merb Hash#to_params method defined in merb/core_ext.
255
- data.to_params
256
- end
257
-
258
- end
259
-
260
- end
261
- end