sunstone 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +29 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +4 -0
- data/Rakefile.rb +37 -0
- data/TODO.md +89 -0
- data/lib/sunstone.rb +361 -0
- data/lib/sunstone/exception.rb +43 -0
- data/lib/sunstone/model.rb +23 -0
- data/lib/sunstone/model/associations.rb +89 -0
- data/lib/sunstone/model/attributes.rb +99 -0
- data/lib/sunstone/model/persistence.rb +168 -0
- data/lib/sunstone/parser.rb +93 -0
- data/lib/sunstone/schema.rb +38 -0
- data/lib/sunstone/type/boolean.rb +19 -0
- data/lib/sunstone/type/date_time.rb +20 -0
- data/lib/sunstone/type/decimal.rb +19 -0
- data/lib/sunstone/type/integer.rb +17 -0
- data/lib/sunstone/type/mutable.rb +16 -0
- data/lib/sunstone/type/string.rb +18 -0
- data/lib/sunstone/type/value.rb +97 -0
- data/sunstone.gemspec +34 -0
- data/test/sunstone/model/associations_test.rb +55 -0
- data/test/sunstone/model/attributes_test.rb +60 -0
- data/test/sunstone/model/persistence_test.rb +173 -0
- data/test/sunstone/model_test.rb +11 -0
- data/test/sunstone/parser_test.rb +124 -0
- data/test/sunstone/schema_test.rb +25 -0
- data/test/sunstone/type/boolean_test.rb +24 -0
- data/test/sunstone/type/date_time_test.rb +31 -0
- data/test/sunstone/type/decimal_test.rb +27 -0
- data/test/sunstone/type/integer_test.rb +29 -0
- data/test/sunstone/type/string_test.rb +54 -0
- data/test/sunstone/type/value_test.rb +27 -0
- data/test/sunstone_test.rb +302 -0
- data/test/test_helper.rb +70 -0
- metadata +318 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5c574fe947ca4f3c808d4b1d843ae0e2bb4ce9ea
|
4
|
+
data.tar.gz: a2410c511c64d0f2b7a85dbc5cbbff3b23a2f7a1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3837b844459bdf78f20fd3562f44b6a91cb53c3fa3f4474d32bf3e7375b96400a2b39a45e907ff0fc2cf0d60730d2984606f01a13bfa7b03a01e330878d5be75
|
7
|
+
data.tar.gz: bf4c9c42165f389bc6e5e1475b19641a24d41ed6b7f8007fa37a549fdf6917656db7ebdcb609156b649d3c793eac053db84aa9fad2be3fabcc603430e8009d61
|
data/.gitignore
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
/.config
|
4
|
+
/coverage/
|
5
|
+
/InstalledFiles
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/test/tmp/
|
9
|
+
/test/version_tmp/
|
10
|
+
/tmp/
|
11
|
+
|
12
|
+
## Documentation cache and generated files:
|
13
|
+
/.yardoc/
|
14
|
+
/_yardoc/
|
15
|
+
/doc/
|
16
|
+
/rdoc/
|
17
|
+
|
18
|
+
## Environment normalisation:
|
19
|
+
/.bundle/
|
20
|
+
/lib/bundler/man/
|
21
|
+
|
22
|
+
# for a library or gem, you might want to ignore these files since the code is
|
23
|
+
# intended to run in multiple environments; otherwise, check them in:
|
24
|
+
Gemfile.lock
|
25
|
+
.ruby-version
|
26
|
+
.ruby-gemset
|
27
|
+
|
28
|
+
# Text Editor scraps
|
29
|
+
*~
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Jon Bracy
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
data/Rakefile.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
Bundler.require(:development)
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rdoc/task'
|
6
|
+
|
7
|
+
task :console do
|
8
|
+
exec 'irb -I lib -r sunstone.rb'
|
9
|
+
end
|
10
|
+
task :c => :console
|
11
|
+
|
12
|
+
Rake::TestTask.new do |t|
|
13
|
+
t.libs << 'lib' << 'test'
|
14
|
+
t.test_files = FileList['test/**/*_test.rb']
|
15
|
+
#t.warning = true
|
16
|
+
#t.verbose = true
|
17
|
+
end
|
18
|
+
|
19
|
+
Rake::RDocTask.new do |rd|
|
20
|
+
rd.main = 'README.md'
|
21
|
+
rd.title = 'Sunstone Documentation'
|
22
|
+
rd.rdoc_dir = 'doc'
|
23
|
+
|
24
|
+
rd.options << '-f' << 'sdoc'
|
25
|
+
rd.options << '-T' << '42floors'
|
26
|
+
rd.options << '-g' # Generate github links
|
27
|
+
|
28
|
+
rd.rdoc_files.include('README.rdoc')
|
29
|
+
rd.rdoc_files.include('lib/**/*.rb')
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "Run tests"
|
33
|
+
task :default => :test
|
34
|
+
|
35
|
+
namespace :pages do
|
36
|
+
#TODO: https://github.com/defunkt/sdoc-helpers/blob/master/lib/sdoc_helpers/pages.rb
|
37
|
+
end
|
data/TODO.md
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
- Check if `Sunstone#to_key` needs to be added
|
2
|
+
|
3
|
+
- Add `Sunstone::Model::Persistance` with the following methods:
|
4
|
+
|
5
|
+
- `#new_record?`
|
6
|
+
- `#persisted?`
|
7
|
+
- `#save`
|
8
|
+
- `#save!`
|
9
|
+
- `#update`
|
10
|
+
- `#update!`
|
11
|
+
- `#create`
|
12
|
+
- `#to_param` ?
|
13
|
+
- `::all`
|
14
|
+
- `::where` (probably goes in an Arel like engine)
|
15
|
+
- `::build`
|
16
|
+
- `::create!`
|
17
|
+
- `#==`
|
18
|
+
- `::create`
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
# Creates an object and saves it to the MLS. The resulting object is returned
|
22
|
+
# whether or no the object was saved successfully to the MLS or not.
|
23
|
+
#
|
24
|
+
# ==== Examples
|
25
|
+
# #!ruby
|
26
|
+
# # Create a single new object
|
27
|
+
# User.create(:first_name => 'Jamie')
|
28
|
+
#
|
29
|
+
# # Create a single object and pass it into a block to set other attributes.
|
30
|
+
# User.create(:first_name => 'Jamie') do |u|
|
31
|
+
# u.is_admin = false
|
32
|
+
# end
|
33
|
+
def self.create(attributes={}, &block) # TODO: testme
|
34
|
+
model = self.new(attributes)
|
35
|
+
yield(model) if block_given?
|
36
|
+
model.save
|
37
|
+
model
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
- Look at https://gist.github.com/malomalo/91f360fe52db3dbe1c99 files for inspiration, came from
|
42
|
+
Rails code I think
|
43
|
+
|
44
|
+
- Simplify `Sunstone::Type::Value` to `Sunstone::Type`
|
45
|
+
|
46
|
+
- Add a `find_class(type)` in `Sunstone::Schema`
|
47
|
+
|
48
|
+
- Possibly use Classes to hold information about each attribute in addition to the type
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
class MLS::Attribute
|
52
|
+
|
53
|
+
DEFAULT_OPTIONS = { :serialize => true }
|
54
|
+
|
55
|
+
attr_reader :model, :name, :instance_variable_name, :options, :default
|
56
|
+
attr_reader :reader_visibility, :writer_visibility
|
57
|
+
|
58
|
+
def initialize(name, options={})
|
59
|
+
@name = name
|
60
|
+
@instance_variable_name = "@#{@name}".freeze
|
61
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
62
|
+
|
63
|
+
@default = @options[:default]
|
64
|
+
@reader_visibility = @options[:reader] || :public
|
65
|
+
@writer_visibility = @options[:writer] || :public
|
66
|
+
end
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
- Use Association classes to model the association:
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
class MLS::Association
|
74
|
+
class BelongsTo
|
75
|
+
attr_reader :klass, :foreign_key, :foreign_type, :primary_key, :polymorphic
|
76
|
+
|
77
|
+
def initialize(name, options={})
|
78
|
+
@name = name
|
79
|
+
@klass = options[:class_name] ? options[:class_name].constantize : name.camelize.constantize
|
80
|
+
|
81
|
+
@polymorphic = options[:polymorphic] || false
|
82
|
+
@foreign_key = options[:foreign_key] || "#{name}_id".to_sym
|
83
|
+
@foreign_type = options[:foreign_type] || "#{name}_type".to_sym
|
84
|
+
@primary_key = options[:primary_key] || :id
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
```
|
data/lib/sunstone.rb
ADDED
@@ -0,0 +1,361 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'uri'
|
3
|
+
require 'net/https'
|
4
|
+
|
5
|
+
require 'wankel'
|
6
|
+
require 'cookie_store'
|
7
|
+
require 'connection_pool'
|
8
|
+
|
9
|
+
require 'active_support'
|
10
|
+
require 'active_support/core_ext'
|
11
|
+
|
12
|
+
require 'active_model'
|
13
|
+
|
14
|
+
require 'sunstone/exception'
|
15
|
+
require 'sunstone/schema'
|
16
|
+
require 'sunstone/model'
|
17
|
+
require 'sunstone/parser'
|
18
|
+
|
19
|
+
# _Sunstone_ is a low-level API. It provides basic HTTP #get, #post, #put, and
|
20
|
+
# #delete calls to the Sunstone Server. It can also provides basic error
|
21
|
+
# checking of responses.
|
22
|
+
module Sunstone
|
23
|
+
VERSION = 0.1
|
24
|
+
|
25
|
+
extend self
|
26
|
+
|
27
|
+
attr_reader :site
|
28
|
+
|
29
|
+
# Set the User-Agent of the client. Will be joined with other User-Agent info
|
30
|
+
attr_writer :user_agent
|
31
|
+
attr_accessor :api_key, :host, :port, :use_ssl
|
32
|
+
|
33
|
+
# Sets the Protocol, API Token, and Host and Port of the API Server
|
34
|
+
#
|
35
|
+
# #!ruby
|
36
|
+
# Sunstone.site = "https://API_KEY@host.com"
|
37
|
+
def site=(url)
|
38
|
+
@site = url
|
39
|
+
uri = URI.parse(url)
|
40
|
+
@api_key = uri.user ? CGI.unescape(uri.user) : nil
|
41
|
+
@host, @port = uri.host, uri.port
|
42
|
+
@use_ssl = (uri.scheme == 'https')
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns the User-Agent of the client. Defaults to:
|
46
|
+
# "sunstone-ruby/SUNSTONE_VERSION RUBY_VERSION-pPATCH_LEVEL PLATFORM"
|
47
|
+
def user_agent
|
48
|
+
[
|
49
|
+
@user_agent,
|
50
|
+
"Sunstone/#{Sunstone::VERSION}",
|
51
|
+
"Ruby/#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}",
|
52
|
+
RUBY_PLATFORM
|
53
|
+
].compact.join(' ')
|
54
|
+
end
|
55
|
+
|
56
|
+
# Set a cookie jar to use during request sent during the
|
57
|
+
def with_cookie_store(store, &block)
|
58
|
+
Thread.current[:sunstone_cookie_store] = store
|
59
|
+
yield
|
60
|
+
ensure
|
61
|
+
Thread.current[:sunstone_cookie_store] = nil
|
62
|
+
end
|
63
|
+
|
64
|
+
# Sends a Net::HTTPRequest to the server. The headers returned from
|
65
|
+
# Sunestone#headers are automatically added to the request. The appropriate
|
66
|
+
# error is raised if the response is not in the 200..299 range.
|
67
|
+
#
|
68
|
+
# Paramaters::
|
69
|
+
#
|
70
|
+
# * +request+ - A Net::HTTPRequest to send to the server
|
71
|
+
# * +body+ - Optional, a String, IO Object, or a Ruby object which is
|
72
|
+
# converted into JSON and sent as the body
|
73
|
+
# * +block+ - An optional block to call with the +Net::HTTPResponse+ object.
|
74
|
+
#
|
75
|
+
# Return Value::
|
76
|
+
#
|
77
|
+
# Returns the return value of the <tt>&block</tt> if given, otherwise the
|
78
|
+
# response object (a Net::HTTPResponse)
|
79
|
+
#
|
80
|
+
# Examples:
|
81
|
+
#
|
82
|
+
# #!ruby
|
83
|
+
# Sunstone.send_request(#<Net::HTTP::Get>) # => #<Net::HTTP::Response>
|
84
|
+
#
|
85
|
+
# Sunstone.send_request(#<Net::HTTP::Get @path="/404">) # => raises Sunstone::Exception::NotFound
|
86
|
+
#
|
87
|
+
# # this will still raise an exception if the response_code is not valid
|
88
|
+
# # and the block will not be called
|
89
|
+
# Sunstone.send_request(#<Net::HTTP::Get>) do |response|
|
90
|
+
# # ...
|
91
|
+
# end
|
92
|
+
#
|
93
|
+
# # The following example shows how to stream a response:
|
94
|
+
# Sunstone.send_request(#<Net::HTTP::Get>) do |response|
|
95
|
+
# response.read_body do |chunk|
|
96
|
+
# io.write(chunk)
|
97
|
+
# end
|
98
|
+
# end
|
99
|
+
def send_request(request, body=nil, &block)
|
100
|
+
request_headers.each { |k, v| request[k] = v }
|
101
|
+
|
102
|
+
if body.is_a?(IO)
|
103
|
+
request['Transfer-Encoding'] = 'chunked'
|
104
|
+
request.body_stream = body
|
105
|
+
elsif body.is_a?(String)
|
106
|
+
request.body = body
|
107
|
+
elsif body
|
108
|
+
request.body = Wankel.encode(body)
|
109
|
+
end
|
110
|
+
|
111
|
+
return_value = nil
|
112
|
+
with_connection do |connection|
|
113
|
+
connection.request(request) do |response|
|
114
|
+
|
115
|
+
if response['X-42Floors-API-Version-Deprecated']
|
116
|
+
logger.warn("DEPRECATION WARNING: API v#{API_VERSION} is being phased out")
|
117
|
+
end
|
118
|
+
|
119
|
+
validate_response_code(response)
|
120
|
+
|
121
|
+
# Get the cookies
|
122
|
+
response.each_header do |key, value|
|
123
|
+
if key.downcase == 'set-cookie' && Thread.current[:sunstone_cookie_store]
|
124
|
+
Thread.current[:sunstone_cookie_store].set_cookie("#{site}#{request.path}", value)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
if block_given?
|
129
|
+
return_value =yield(response)
|
130
|
+
else
|
131
|
+
return_value =response
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
return_value
|
137
|
+
end
|
138
|
+
|
139
|
+
# Send a GET request to +path+ on the Sunstone Server via +Sunstone#send_request+.
|
140
|
+
# See +Sunstone#send_request+ for more details on how the response is handled.
|
141
|
+
#
|
142
|
+
# Paramaters::
|
143
|
+
#
|
144
|
+
# * +path+ - The +path+ on the server to GET to.
|
145
|
+
# * +params+ - Either a String, Hash, or Ruby Object that responds to
|
146
|
+
# #to_param. Appended on the URL as query params
|
147
|
+
# * +block+ - An optional block to call with the +Net::HTTPResponse+ object.
|
148
|
+
#
|
149
|
+
# Return Value::
|
150
|
+
#
|
151
|
+
# See +Sunstone#send_request+
|
152
|
+
#
|
153
|
+
# Examples:
|
154
|
+
#
|
155
|
+
# #!ruby
|
156
|
+
# Sunstone.get('/example') # => #<Net::HTTP::Response>
|
157
|
+
#
|
158
|
+
# Sunstone.get('/example', 'query=stuff') # => #<Net::HTTP::Response>
|
159
|
+
#
|
160
|
+
# Sunstone.get('/example', {:query => 'stuff'}) # => #<Net::HTTP::Response>
|
161
|
+
#
|
162
|
+
# Sunstone.get('/404') # => raises Sunstone::Exception::NotFound
|
163
|
+
#
|
164
|
+
# Sunstone.get('/act') do |response|
|
165
|
+
# # ...
|
166
|
+
# end
|
167
|
+
def get(path, params='', &block)
|
168
|
+
params ||= ''
|
169
|
+
request = Net::HTTP::Get.new(path + '?' + params.to_param)
|
170
|
+
|
171
|
+
send_request(request, nil, &block)
|
172
|
+
end
|
173
|
+
|
174
|
+
# Send a POST request to +path+ on the Sunstone Server via +Sunstone#send_request+.
|
175
|
+
# See +Sunstone#send_request+ for more details on how the response is handled.
|
176
|
+
#
|
177
|
+
# Paramaters::
|
178
|
+
#
|
179
|
+
# * +path+ - The +path+ on the server to POST to.
|
180
|
+
# * +body+ - Optional, See +Sunstone#send_request+.
|
181
|
+
# * +block+ - Optional, See +Sunstone#send_request+
|
182
|
+
#
|
183
|
+
# Return Value::
|
184
|
+
#
|
185
|
+
# See +Sunstone#send_request+
|
186
|
+
#
|
187
|
+
# Examples:
|
188
|
+
#
|
189
|
+
# #!ruby
|
190
|
+
# Sunstone.post('/example') # => #<Net::HTTP::Response>
|
191
|
+
#
|
192
|
+
# Sunstone.post('/example', 'body') # => #<Net::HTTP::Response>
|
193
|
+
#
|
194
|
+
# Sunstone.post('/example', #<IO Object>) # => #<Net::HTTP::Response>
|
195
|
+
#
|
196
|
+
# Sunstone.post('/example', {:example => 'data'}) # => #<Net::HTTP::Response>
|
197
|
+
#
|
198
|
+
# Sunstone.post('/404') # => raises Sunstone::Exception::NotFound
|
199
|
+
#
|
200
|
+
# Sunstone.post('/act') do |response|
|
201
|
+
# # ...
|
202
|
+
# end
|
203
|
+
def post(path, body=nil, &block)
|
204
|
+
request = Net::HTTP::Post.new(path)
|
205
|
+
|
206
|
+
send_request(request, body, &block)
|
207
|
+
end
|
208
|
+
|
209
|
+
# Send a PUT request to +path+ on the Sunstone Server via +Sunstone#send_request+.
|
210
|
+
# See +Sunstone#send_request+ for more details on how the response is handled.
|
211
|
+
#
|
212
|
+
# Paramaters::
|
213
|
+
#
|
214
|
+
# * +path+ - The +path+ on the server to POST to.
|
215
|
+
# * +body+ - Optional, See +Sunstone#send_request+.
|
216
|
+
# * +block+ - Optional, See +Sunstone#send_request+
|
217
|
+
#
|
218
|
+
# Return Value::
|
219
|
+
#
|
220
|
+
# See +Sunstone#send_request+
|
221
|
+
#
|
222
|
+
# Examples:
|
223
|
+
#
|
224
|
+
# #!ruby
|
225
|
+
# Sunstone.put('/example') # => #<Net::HTTP::Response>
|
226
|
+
#
|
227
|
+
# Sunstone.put('/example', 'body') # => #<Net::HTTP::Response>
|
228
|
+
#
|
229
|
+
# Sunstone.put('/example', #<IO Object>) # => #<Net::HTTP::Response>
|
230
|
+
#
|
231
|
+
# Sunstone.put('/example', {:example => 'data'}) # => #<Net::HTTP::Response>
|
232
|
+
#
|
233
|
+
# Sunstone.put('/404') # => raises Sunstone::Exception::NotFound
|
234
|
+
#
|
235
|
+
# Sunstone.put('/act') do |response|
|
236
|
+
# # ...
|
237
|
+
# end
|
238
|
+
def put(path, body=nil, *valid_response_codes, &block)
|
239
|
+
request = Net::HTTP::Put.new(path)
|
240
|
+
|
241
|
+
send_request(request, body, &block)
|
242
|
+
end
|
243
|
+
|
244
|
+
# Send a DELETE request to +path+ on the Sunstone Server via +Sunstone#send_request+.
|
245
|
+
# See +Sunstone#send_request+ for more details on how the response is handled
|
246
|
+
#
|
247
|
+
# Paramaters::
|
248
|
+
#
|
249
|
+
# * +path+ - The +path+ on the server to POST to.
|
250
|
+
# * +block+ - Optional, See +Sunstone#send_request+
|
251
|
+
#
|
252
|
+
# Return Value::
|
253
|
+
#
|
254
|
+
# See +Sunstone#send_request+
|
255
|
+
#
|
256
|
+
# Examples:
|
257
|
+
#
|
258
|
+
# #!ruby
|
259
|
+
# Sunstone.delete('/example') # => #<Net::HTTP::Response>
|
260
|
+
#
|
261
|
+
# Sunstone.delete('/404') # => raises Sunstone::Exception::NotFound
|
262
|
+
#
|
263
|
+
# Sunstone.delete('/act') do |response|
|
264
|
+
# # ...
|
265
|
+
# end
|
266
|
+
def delete(path, &block)
|
267
|
+
request = Net::HTTP::Delete.new(path)
|
268
|
+
|
269
|
+
send_request(request, nil, &block)
|
270
|
+
end
|
271
|
+
|
272
|
+
# Get a connection from the connection pool and perform the block with
|
273
|
+
# the connection
|
274
|
+
def with_connection(&block)
|
275
|
+
connection_pool.with({}, &block)
|
276
|
+
end
|
277
|
+
|
278
|
+
# Ping the Sunstone. If everything is configured and operating correctly
|
279
|
+
# <tt>"pong"</tt> will be returned. Otherwise and Sunstone::Exception should be
|
280
|
+
# thrown.
|
281
|
+
#
|
282
|
+
# #!ruby
|
283
|
+
# Sunstone.ping # => "pong"
|
284
|
+
#
|
285
|
+
# Sunstone.ping # raises Sunstone::Exception::ServiceUnavailable if a 503 is returned
|
286
|
+
def ping
|
287
|
+
get('/ping').body
|
288
|
+
end
|
289
|
+
|
290
|
+
def config
|
291
|
+
@config ||= Wankel.parse(get('/config').body, :symbolize_keys => true)
|
292
|
+
end
|
293
|
+
|
294
|
+
private
|
295
|
+
|
296
|
+
def request_headers
|
297
|
+
headers = {
|
298
|
+
'Content-Type' => 'application/json',
|
299
|
+
'User-Agent' => user_agent
|
300
|
+
}
|
301
|
+
|
302
|
+
headers['Api-Key'] = api_key if api_key
|
303
|
+
|
304
|
+
headers
|
305
|
+
end
|
306
|
+
|
307
|
+
# Raise an Sunstone::Exception based on the response_code, unless the response_code
|
308
|
+
# is include in the valid_response_codes Array
|
309
|
+
#
|
310
|
+
# Paramaters::
|
311
|
+
#
|
312
|
+
# * +response+ - The Net::HTTP::Response object
|
313
|
+
#
|
314
|
+
# Return Value::
|
315
|
+
#
|
316
|
+
# If an exception is not raised the +response+ is returned
|
317
|
+
#
|
318
|
+
# Examples:
|
319
|
+
#
|
320
|
+
# #!ruby
|
321
|
+
# Sunstone.validate_response_code(<Net::HTTP::Response @code=200>) # => <Net::HTTP::Response @code=200>
|
322
|
+
#
|
323
|
+
# Sunstone.validate_response_code(<Net::HTTP::Response @code=404>) # => raises Sunstone::Exception::NotFound
|
324
|
+
#
|
325
|
+
# Sunstone.validate_response_code(<Net::HTTP::Response @code=500>) # => raises Sunstone::Exception
|
326
|
+
def validate_response_code(response)
|
327
|
+
code = response.code.to_i
|
328
|
+
|
329
|
+
if !(200..299).include?(code)
|
330
|
+
case code
|
331
|
+
when 400
|
332
|
+
raise Sunstone::Exception::BadRequest, response
|
333
|
+
when 401
|
334
|
+
raise Sunstone::Exception::Unauthorized, response
|
335
|
+
when 404
|
336
|
+
raise Sunstone::Exception::NotFound, response
|
337
|
+
when 410
|
338
|
+
raise Sunstone::Exception::Gone, response
|
339
|
+
when 422
|
340
|
+
raise Sunstone::Exception::ApiVersionUnsupported, response
|
341
|
+
when 503
|
342
|
+
raise Sunstone::Exception::ServiceUnavailable, response
|
343
|
+
when 301
|
344
|
+
raise Sunstone::Exception::MovedPermanently, response
|
345
|
+
when 300..599
|
346
|
+
raise Sunstone::Exception, response
|
347
|
+
else
|
348
|
+
raise Sunstone::Exception, response
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
def connection_pool
|
354
|
+
@connection_pool ||= ConnectionPool.new(size: 5, timeout: 5) do
|
355
|
+
connection = Net::HTTP.new(@host, @port)
|
356
|
+
connection.use_ssl = @ssl
|
357
|
+
connection
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
end
|