jersey 0.0.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|