jersey 0.0.3 → 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 +4 -4
- data/.travis.yml +5 -0
- data/jersey.gemspec +1 -1
- data/lib/jersey/api.rb +14 -0
- data/lib/jersey/base.rb +10 -9
- data/lib/jersey/extensions/error_handler.rb +1 -0
- data/lib/jersey/helpers/success.rb +17 -0
- data/lib/jersey/http_errors.rb +50 -55
- data/lib/jersey/log.rb +5 -0
- data/lib/jersey/middleware/error_handler.rb +40 -0
- data/lib/jersey/version.rb +1 -1
- data/test/errors_test.rb +16 -5
- data/test/success_test.rb +35 -0
- metadata +12 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8917e3fd5a219b1f47d717b67c220309e0099e53
|
4
|
+
data.tar.gz: 877d58392cf2c2ed29f0c716be9ae96e013624d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d79189492a2066fc625ad5b89c6fd68874d7c820d65a5def6f506b5de8a9f404cb5e8c1d2cb39db9d83db1c42dfae57668100f2f1883951e150d9c6b3105cc6c
|
7
|
+
data.tar.gz: b3321888bd62a38ea83d8552be66df3fc28ec1a64179340cfa1eced4f5ad0da42d9af13b7a0a53ba2dfcd9cd1acc9972a1c1add634471404b95de5f2dc8b48ac
|
data/.travis.yml
ADDED
data/jersey.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_dependency "sinatra", "~> 1.4"
|
22
22
|
spec.add_dependency 'sinatra-contrib', "~> 1.4"
|
23
|
-
spec.add_dependency 'env-conf'
|
23
|
+
spec.add_dependency 'env-conf', '0.0.4'
|
24
24
|
spec.add_dependency 'request_store'
|
25
25
|
spec.add_development_dependency "bundler", "~> 1.7"
|
26
26
|
spec.add_development_dependency "rake", "~> 10.0"
|
data/lib/jersey/api.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'request_store'
|
2
|
+
|
1
3
|
module Jersey
|
2
4
|
module API
|
3
5
|
module Middleware
|
@@ -8,5 +10,17 @@ module Jersey
|
|
8
10
|
|
9
11
|
module Helpers
|
10
12
|
end
|
13
|
+
|
14
|
+
module HTTP
|
15
|
+
end
|
11
16
|
end
|
12
17
|
end
|
18
|
+
|
19
|
+
# jersey
|
20
|
+
require 'jersey/http_errors'
|
21
|
+
require 'jersey/middleware/request_id'
|
22
|
+
require 'jersey/middleware/error_handler'
|
23
|
+
require 'jersey/middleware/request_logger'
|
24
|
+
require 'jersey/extensions/route_signature'
|
25
|
+
require 'jersey/helpers/log'
|
26
|
+
require 'jersey/helpers/success'
|
data/lib/jersey/base.rb
CHANGED
@@ -1,22 +1,17 @@
|
|
1
1
|
require "sinatra/base"
|
2
2
|
require 'sinatra/json'
|
3
3
|
require 'json'
|
4
|
-
require 'request_store'
|
5
4
|
|
6
|
-
#
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
require 'jersey/extensions/route_signature'
|
11
|
-
require 'jersey/extensions/error_handler'
|
12
|
-
require 'jersey/helpers/log'
|
5
|
+
# Take over Sinatra's NotFound so we don't have to deal with the
|
6
|
+
# not_found block and can raise our own NotFound error
|
7
|
+
::Sinatra.send(:remove_const, :NotFound)
|
8
|
+
::Sinatra.const_set(:NotFound, ::Jersey::HTTP::Errors::NotFound)
|
13
9
|
|
14
10
|
module Jersey::API
|
15
11
|
class Base < Sinatra::Base
|
16
12
|
include Jersey::HTTP::Errors
|
17
13
|
|
18
14
|
register Jersey::Extensions::RouteSignature
|
19
|
-
register Jersey::Extensions::ErrorHandler
|
20
15
|
|
21
16
|
use Rack::Deflater
|
22
17
|
use Rack::ConditionalGet
|
@@ -24,8 +19,14 @@ module Jersey::API
|
|
24
19
|
|
25
20
|
use Jersey::Middleware::RequestID
|
26
21
|
use Jersey::Middleware::RequestLogger
|
22
|
+
use Jersey::Middleware::ErrorHandler
|
27
23
|
|
28
24
|
helpers Sinatra::JSON
|
29
25
|
helpers Jersey::Helpers::Log
|
26
|
+
helpers Jersey::Helpers::Success
|
27
|
+
|
28
|
+
set :dump_errors, false
|
29
|
+
set :raise_errors, true
|
30
|
+
set :show_exceptions, false
|
30
31
|
end
|
31
32
|
end
|
data/lib/jersey/http_errors.rb
CHANGED
@@ -1,62 +1,57 @@
|
|
1
|
-
module Jersey
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
ServerError = Class.new(HTTPError)
|
1
|
+
module Jersey::HTTP
|
2
|
+
module Errors
|
3
|
+
HTTPError = Class.new(StandardError)
|
4
|
+
ClientError = Class.new(HTTPError)
|
5
|
+
ServerError = Class.new(HTTPError)
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
7
|
+
# Define ALL the HTTP errors as constants
|
8
|
+
FOUR_HUNDRED = [
|
9
|
+
[400, 'BadRequest', :bad_request],
|
10
|
+
[401, 'Unauthorized', :unauthorized],
|
11
|
+
[402, 'PaymentRequired', :payment_required],
|
12
|
+
[403, 'Forbidden', :forbidden],
|
13
|
+
[404, 'NotFound', :not_found],
|
14
|
+
[405, 'MethodNotAllowed', :method_not_allowed],
|
15
|
+
[406, 'NotAcceptable', :not_acceptable],
|
16
|
+
[407, 'ProxyAuthenticationRequired', :proxy_authentication_required],
|
17
|
+
[408, 'RequestTimeout', :request_timeout],
|
18
|
+
[409, 'Conflict', :conflict],
|
19
|
+
[410, 'Gone', :gone],
|
20
|
+
[411, 'LengthRequired', :length_required],
|
21
|
+
[412, 'PreconditionFailed', :precondition_failed],
|
22
|
+
[413, 'RequestEntityTooLarge', :request_entity_too_large],
|
23
|
+
[414, 'RequestURITooLong', :request_uri_too_long],
|
24
|
+
[415, 'UnsupportedMediaType', :unsupported_media_type],
|
25
|
+
[416, 'RequestedRangeNotSatisfiable', :requested_range_not_satisfiable],
|
26
|
+
[417, 'ExpectationFailed', :expectation_failed],
|
27
|
+
[422, 'UnprocessableEntity', :unprocessable_entity],
|
28
|
+
[423, 'Locked', :locked],
|
29
|
+
[424, 'FailedDependency', :failed_dependency],
|
30
|
+
[426, 'UpgradeRequired', :upgrade_required],
|
31
|
+
]
|
33
32
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
33
|
+
FIVE_HUNDRED = [
|
34
|
+
[500, 'InternalServerError', :internal_server_error],
|
35
|
+
[501, 'NotImplemented', :not_implemented],
|
36
|
+
[502, 'BadGateway', :bad_gateway],
|
37
|
+
[503, 'ServiceUnavailable', :service_unavailable],
|
38
|
+
[504, 'GatewayTimeout', :gateway_timeout],
|
39
|
+
[505, 'HTTPVersionNotSupported', :http_version_not_supported],
|
40
|
+
[507, 'InsufficientStorage', :insufficient_storage],
|
41
|
+
[510, 'NotExtended', :not_extended],
|
42
|
+
]
|
44
43
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
klass.
|
53
|
-
const_set(const_name,klass)
|
44
|
+
# Dynamically Create all the necessary HTTP errors
|
45
|
+
# with appropriate status codes
|
46
|
+
(FOUR_HUNDRED + FIVE_HUNDRED).each do |s|
|
47
|
+
code, const_name, symbol = s[0],s[1],s[2]
|
48
|
+
if code >= 500
|
49
|
+
klass = Class.new(ServerError)
|
50
|
+
else
|
51
|
+
klass = Class.new(ClientError)
|
54
52
|
end
|
55
|
-
|
56
|
-
|
57
|
-
# not_found block and can raise our own NotFound error
|
58
|
-
::Sinatra.send(:remove_const, :NotFound)
|
59
|
-
::Sinatra.const_set(:NotFound, ::Jersey::HTTP::Errors::NotFound)
|
53
|
+
klass.const_set(:STATUS_CODE, code)
|
54
|
+
const_set(const_name,klass)
|
60
55
|
end
|
61
56
|
end
|
62
57
|
end
|
data/lib/jersey/log.rb
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
module Jersey::Middleware
|
2
|
+
class ErrorHandler
|
3
|
+
def initialize(app, options = {})
|
4
|
+
@app = app
|
5
|
+
ib = options[:include_backtrace]
|
6
|
+
@include_backtrace = (ib.nil? && ENV['RACK_ENV'] == 'development') || ib
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
begin
|
11
|
+
@app.call(env)
|
12
|
+
rescue => e
|
13
|
+
# get status code from Jersey Errors
|
14
|
+
if e.class.const_defined?(:STATUS_CODE)
|
15
|
+
status = e.class::STATUS_CODE
|
16
|
+
elsif e.respond_to?(:status_code)
|
17
|
+
status = e.status_code
|
18
|
+
else
|
19
|
+
status = 500
|
20
|
+
end
|
21
|
+
|
22
|
+
headers = {
|
23
|
+
'Content-Type' => 'application/json'
|
24
|
+
}
|
25
|
+
|
26
|
+
body = {error: {
|
27
|
+
type: e.class.name.split('::').last,
|
28
|
+
request_id: env['REQUEST_ID'] || env['HTTP_REQUEST_ID'],
|
29
|
+
message: e.message
|
30
|
+
}}
|
31
|
+
|
32
|
+
if @include_backtrace
|
33
|
+
body[:error][:backtrace] = e.backtrace
|
34
|
+
end
|
35
|
+
|
36
|
+
[status, headers, [body.to_json]]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/jersey/version.rb
CHANGED
data/test/errors_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require_relative 'helper'
|
2
2
|
|
3
3
|
class ErrorsTest < ApiTest
|
4
|
-
class
|
4
|
+
class App < Jersey::API::Base
|
5
5
|
get '/test-409' do
|
6
6
|
raise Conflict, "bad"
|
7
7
|
end
|
@@ -15,10 +15,6 @@ class ErrorsTest < ApiTest
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
def app
|
19
|
-
SimpleApi
|
20
|
-
end
|
21
|
-
|
22
18
|
def test_not_found
|
23
19
|
get '/not-found'
|
24
20
|
assert_equal(404, last_response.status)
|
@@ -30,6 +26,7 @@ class ErrorsTest < ApiTest
|
|
30
26
|
assert_equal(409, last_response.status)
|
31
27
|
assert_equal('Conflict', json['error']['type'])
|
32
28
|
assert_equal('bad', json['error']['message'])
|
29
|
+
assert(json['error']['request_id'])
|
33
30
|
end
|
34
31
|
|
35
32
|
def test_http_errors_500
|
@@ -37,6 +34,7 @@ class ErrorsTest < ApiTest
|
|
37
34
|
assert_equal(500, last_response.status)
|
38
35
|
assert_equal('InternalServerError', json['error']['type'])
|
39
36
|
assert_equal('bad', json['error']['message'])
|
37
|
+
assert(json['error']['request_id'])
|
40
38
|
end
|
41
39
|
|
42
40
|
def test_http_errors_Undefined
|
@@ -44,5 +42,18 @@ class ErrorsTest < ApiTest
|
|
44
42
|
assert_equal(500, last_response.status)
|
45
43
|
assert_equal('RuntimeError', json['error']['type'])
|
46
44
|
assert_equal('boom!', json['error']['message'])
|
45
|
+
assert(json['error']['request_id'])
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_errors_are_logged
|
49
|
+
Jersey.logger.stream = StringIO.new
|
50
|
+
get '/test-500'
|
51
|
+
loglines = logs.lines
|
52
|
+
assert_equal(2, loglines.size)
|
53
|
+
logdata = Logfmt.parse(loglines[0])
|
54
|
+
assert(logdata['at'], 'started')
|
55
|
+
logdata = Logfmt.parse(loglines[1])
|
56
|
+
assert(logdata['at'], 'finished')
|
57
|
+
assert(logdata['status'], '500')
|
47
58
|
end
|
48
59
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
class SuccessTest < ApiTest
|
4
|
+
class App < Jersey::API::Base
|
5
|
+
get '/test-201' do
|
6
|
+
created({foo: 'baz'})
|
7
|
+
end
|
8
|
+
|
9
|
+
get '/test-202' do
|
10
|
+
accepted({foo: 'bar'})
|
11
|
+
end
|
12
|
+
|
13
|
+
get '/test-204' do
|
14
|
+
no_content
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_created
|
19
|
+
get '/test-201'
|
20
|
+
assert_equal(201, last_response.status)
|
21
|
+
assert_equal('baz', json['foo'])
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_accepted
|
25
|
+
get '/test-202'
|
26
|
+
assert_equal(202, last_response.status)
|
27
|
+
assert_equal('bar', json['foo'])
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_no_content
|
31
|
+
get '/test-204'
|
32
|
+
assert_equal(204, last_response.status)
|
33
|
+
assert_equal('', last_response.body)
|
34
|
+
end
|
35
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jersey
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- csquared
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-02-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sinatra
|
@@ -42,16 +42,16 @@ dependencies:
|
|
42
42
|
name: env-conf
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - '='
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 0.0.4
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - '='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 0.0.4
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: request_store
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -102,6 +102,7 @@ extensions: []
|
|
102
102
|
extra_rdoc_files: []
|
103
103
|
files:
|
104
104
|
- ".gitignore"
|
105
|
+
- ".travis.yml"
|
105
106
|
- Gemfile
|
106
107
|
- LICENSE.txt
|
107
108
|
- README.md
|
@@ -114,12 +115,14 @@ files:
|
|
114
115
|
- lib/jersey/extensions/error_handler.rb
|
115
116
|
- lib/jersey/extensions/route_signature.rb
|
116
117
|
- lib/jersey/helpers/log.rb
|
118
|
+
- lib/jersey/helpers/success.rb
|
117
119
|
- lib/jersey/http_errors.rb
|
118
120
|
- lib/jersey/log.rb
|
119
121
|
- lib/jersey/logging/base_logger.rb
|
120
122
|
- lib/jersey/logging/json_logger.rb
|
121
123
|
- lib/jersey/logging/logfmt_logger.rb
|
122
124
|
- lib/jersey/logging/mixins.rb
|
125
|
+
- lib/jersey/middleware/error_handler.rb
|
123
126
|
- lib/jersey/middleware/request_id.rb
|
124
127
|
- lib/jersey/middleware/request_logger.rb
|
125
128
|
- lib/jersey/setup.rb
|
@@ -130,6 +133,7 @@ files:
|
|
130
133
|
- test/log_test.rb
|
131
134
|
- test/request_logger_test.rb
|
132
135
|
- test/setup_test.rb
|
136
|
+
- test/success_test.rb
|
133
137
|
homepage: ''
|
134
138
|
licenses:
|
135
139
|
- MIT
|
@@ -150,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
150
154
|
version: '0'
|
151
155
|
requirements: []
|
152
156
|
rubyforge_project:
|
153
|
-
rubygems_version: 2.2.
|
157
|
+
rubygems_version: 2.2.2
|
154
158
|
signing_key:
|
155
159
|
specification_version: 4
|
156
160
|
summary: Write APIs in the New Jersey Style
|
@@ -160,3 +164,4 @@ test_files:
|
|
160
164
|
- test/log_test.rb
|
161
165
|
- test/request_logger_test.rb
|
162
166
|
- test/setup_test.rb
|
167
|
+
- test/success_test.rb
|