content_gateway 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 65fe5be0eff06af34c50732980238a937d3f8249
4
+ data.tar.gz: edd6943756c0136824ba2fefa40768e6c83fa0bd
5
+ SHA512:
6
+ metadata.gz: 4183a37c2624be76daa48c6f8238e10db77a260903583e2e4bb92123e238e3ed357d5b0393c2de56d3b723f1dc733419c0747b73aef25615a5ed14dcb03cf64c
7
+ data.tar.gz: 0405a719b4a119bcc110d6eb077b3f962a1a5d7fd0673110c348c1a713bc2cf575ef4865c4011c7e97fa330e4eb4598d1b649a502ef111d922cb909922d868c1
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ pkg/*
2
+ docs/*
3
+ *.gem
4
+ .bundle
5
+ .rvmrc
6
+ coverage/*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ content-gateway
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.0.0-p481
data/COPYING ADDED
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2014, Globo.com - Webmedia
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+ * Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ * Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+ * Neither the name of the Globo.com - Webmedia nor the
12
+ names of its contributors may be used to endorse or promote products
13
+ derived from this software without specific prior written permission.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL GLOBO.COM - WEBMEDIA BE LIABLE FOR ANY
19
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/Changelog ADDED
@@ -0,0 +1,42 @@
1
+ 2014-10-21 [0.1.0]
2
+
3
+ * Adding delete_json method.
4
+ * A lot of refactoring.
5
+
6
+ 2014-10-07 [0.0.14]
7
+
8
+ * Ignoring cache after an internal server error when skip_cache = true.
9
+ * Mapping 5xx errors to ContentGateway::ServerError.
10
+
11
+ 2014-04-01 [0.0.13]
12
+
13
+ * Added support for HTTP 409 Conflict error.
14
+
15
+ 2014-04-01 [0.0.12]
16
+
17
+ * Require debugger on spec_helper.
18
+
19
+ 2014-01-17 [0.0.11]
20
+
21
+ * Adding delete method support
22
+
23
+ 2014-01-17 [0.0.10]
24
+
25
+ * Do not depend on a specific version of activesupport.
26
+
27
+ 2013-08-15 [0.0.9]
28
+
29
+ * Using try to get proxy from config to avoid error when not exists.
30
+
31
+ 2013-08-15 [0.0.8]
32
+
33
+ * Return empty when result is not a RestClient object and do not have "code" method.
34
+
35
+ 2013-08-15 [0.0.7]
36
+
37
+ * Default params now are optional
38
+
39
+ 2013-08-14 [0.0.6]
40
+
41
+ * First release
42
+ * Replaces Esportes API gateway.rb
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+ ruby '2.0.0'
3
+
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,61 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ content_gateway (0.1.0)
5
+ activesupport
6
+ json
7
+ rest-client
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ activesupport (4.0.2)
13
+ i18n (~> 0.6, >= 0.6.4)
14
+ minitest (~> 4.2)
15
+ multi_json (~> 1.3)
16
+ thread_safe (~> 0.1)
17
+ tzinfo (~> 0.3.37)
18
+ atomic (1.1.14)
19
+ byebug (3.5.1)
20
+ columnize (~> 0.8)
21
+ debugger-linecache (~> 1.2)
22
+ slop (~> 3.6)
23
+ columnize (0.8.9)
24
+ debugger-linecache (1.2.0)
25
+ diff-lcs (1.2.5)
26
+ i18n (0.6.9)
27
+ json (1.8.1)
28
+ mime-types (2.0)
29
+ minitest (4.7.5)
30
+ multi_json (1.7.9)
31
+ rest-client (1.6.7)
32
+ mime-types (>= 1.16)
33
+ rspec (3.1.0)
34
+ rspec-core (~> 3.1.0)
35
+ rspec-expectations (~> 3.1.0)
36
+ rspec-mocks (~> 3.1.0)
37
+ rspec-core (3.1.7)
38
+ rspec-support (~> 3.1.0)
39
+ rspec-expectations (3.1.2)
40
+ diff-lcs (>= 1.2.0, < 2.0)
41
+ rspec-support (~> 3.1.0)
42
+ rspec-mocks (3.1.3)
43
+ rspec-support (~> 3.1.0)
44
+ rspec-support (3.1.2)
45
+ simplecov (0.7.1)
46
+ multi_json (~> 1.0)
47
+ simplecov-html (~> 0.7.1)
48
+ simplecov-html (0.7.1)
49
+ slop (3.6.0)
50
+ thread_safe (0.1.3)
51
+ atomic
52
+ tzinfo (0.3.38)
53
+
54
+ PLATFORMS
55
+ ruby
56
+
57
+ DEPENDENCIES
58
+ byebug
59
+ content_gateway!
60
+ rspec (>= 2.3.0)
61
+ simplecov (>= 0.7.1)
data/README.md ADDED
@@ -0,0 +1,134 @@
1
+ # Content Gateway
2
+
3
+ An easy way to get external content with two cache levels. The first is a performance cache and second is the stale.
4
+
5
+ Content Gateway lets you set a timeout for any request.
6
+ If the configured timeout is reached without response, it searches for cached data.
7
+ If cache is unavailable or expired, it returns the stale cache data.
8
+ Only then, if stale cache is also unavailable or expired, it raises an exception
9
+
10
+ ## Dependencies
11
+
12
+ - Ruby >= 1.9
13
+ - ActiveSupport (for cache store)
14
+
15
+ ## Installation
16
+
17
+ Add this line to your application's Gemfile:
18
+
19
+ gem 'content_gateway'
20
+
21
+ And then execute:
22
+
23
+ $ bundle
24
+
25
+ Or install it yourself as:
26
+
27
+ $ gem install content_gateway
28
+
29
+ ## Configuration
30
+
31
+ `ContentGateway::Gateway` class accepts a configuration object with the following parameters:
32
+
33
+ - `timeout`: request timeout in seconds
34
+ - `cache_expires_in`: cache data expiration time, in seconds
35
+ - `cache_stale_expires_in`: stale cache data expiration time, in seconds
36
+ - `cache`: cache store instance. This may be an instance of `ActiveSupport::Cache`
37
+ - `proxy`: proxy address, if needed
38
+
39
+ Configuration object example:
40
+
41
+ ```ruby
42
+ config = OpenStruct.new(
43
+ timeout: 2,
44
+ cache_expires_in: 1800,
45
+ cache_stale_expires_in: 86400,
46
+ cache: ActiveSupport::Cache.lookup_store(:memory_store),
47
+ proxy: "http://proxy.example.com/"
48
+ )
49
+ ```
50
+
51
+ ## Usage
52
+
53
+ `ContentGateway::Gateway` expects four parameters:
54
+
55
+ - a label, which is used in the log messages
56
+ - a config object, just as described above
57
+ - an URL Generator object. This may be any object that responds to a `generate` method, like this:
58
+ - an optional hash with default params. Currently, it only supports default headers
59
+
60
+ ```ruby
61
+ class UrlGenerator
62
+ def generate(resource_path, params = {})
63
+ args = ""
64
+ args = "?#{params.map {|k, v| "#{k}=#{v}"}.join("&")}" if params.any?
65
+ "http://example.com/#{resource_path}#{args}"
66
+ end
67
+ end
68
+
69
+ default_params = { headers: { Accept: "application/json" } }
70
+
71
+ gateway = ContentGateway::Gateway.new("My API", config, UrlGenerator.new, default_params)
72
+ ```
73
+
74
+ Every param may be overrided on each request.
75
+
76
+ This Gateway object supports the following methods:
77
+
78
+ ### GET
79
+
80
+ To do a GET request, you may use the `get` or `get_json` methods. The second one parses the response as JSON.
81
+ Optional parameters are supported:
82
+
83
+ - `timeout`: overwrites the default timeout
84
+ - `expires_in`: overwrites the default cache expiration time
85
+ - `stale_expires_in`: overwrites the default stale cache expiration time
86
+ - `skip_cache`: if set to `true`, ignores cache and stale cache
87
+ - `headers`: a hash with request headers
88
+
89
+ Every other parameter is passed to URLGenerator `generate` method (like query string parameters).
90
+
91
+ Examples:
92
+
93
+ ```ruby
94
+ gateway.get("/path", timeout: 3)
95
+
96
+ gateway.get_json("/path.json", skip_cache: true)
97
+ ```
98
+
99
+ ### POST, PUT and DELETE
100
+
101
+ POST, PUT and DELETE verbs are also supported, but ignore cache and stale cache.
102
+ The gateway object offers the equivalent methods for these verbs (`post`, `post_json`, `put`, `put_json`, `delete` and `delete_json`).
103
+ The only optional parameter supported by these methods is `payload`.
104
+ Every other parameter is passed to URLGenerator `generate` method (like query string parameters).
105
+
106
+ Examples:
107
+
108
+ ```ruby
109
+ gateway.post("/api/post_example", payload: { param1: "value" })
110
+
111
+ gateway.put_json("/api/put_example.json", query_string_param: "value")
112
+
113
+ gateway.delete("/api/delete_example", id: "100")
114
+ ```
115
+
116
+ ## Authors
117
+
118
+ - [Emerson Macedo](https://github.com/emerleite)
119
+ - [Guilherme Garnier](https://github.com/ggarnier)
120
+ - [Daniel Martins](https://github.com/danielfm)
121
+ - [Rafael Biriba](https://github.com/rafaelbiriba)
122
+ - [Célio Latorraca](https://github.com/celiofonseca)
123
+
124
+ ## Contributing
125
+
126
+ 1. Fork it
127
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
128
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
129
+ 4. Push to the branch (`git push origin my-new-feature`)
130
+ 5. Create new Pull Request
131
+
132
+ ## License
133
+
134
+ Copyright (c) 2014 Globo.com - Webmedia. See [COPYING](https://github.com/globocom/content_gateway/blob/master/COPYING) for more details.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ # Rake tasks
4
+ Dir.glob('lib/tasks/**/*.rake').each {|r| import r}
5
+
6
+ require "rspec/core/rake_task"
7
+ desc "Run all examples"
8
+ RSpec::Core::RakeTask.new(:spec)
9
+
10
+ task :default => :spec
@@ -0,0 +1,26 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'content_gateway/version'
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "content_gateway"
7
+ gem.version = ContentGateway::VERSION
8
+ gem.authors = ["Emerson Macedo", "Guilherme Garnier", "Daniel Martins", "Rafael Biriba", "Célio Latorraca"]
9
+ gem.email = ["emerleite@gmail.com", "guilherme.garnier@gmail.com", "daniel.tritone@gmail.com", "biribarj@gmail.com", "celio.la@gmail.com"]
10
+ gem.description = %q{An easy way to get external content with two cache levels. The first is a performance cache and second is the stale}
11
+ gem.summary = %q{Content Gateway}
12
+ gem.homepage = ""
13
+
14
+ gem.files = `git ls-files`.split($/)
15
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.require_paths = ["lib"]
18
+
19
+ gem.add_dependency "activesupport"
20
+ gem.add_dependency "rest-client"
21
+ gem.add_dependency "json"
22
+
23
+ gem.add_development_dependency "rspec", ">= 2.3.0"
24
+ gem.add_development_dependency "simplecov", ">= 0.7.1"
25
+ gem.add_development_dependency "byebug"
26
+ end
@@ -0,0 +1,59 @@
1
+ module ContentGateway
2
+ class Cache
3
+ attr_reader :status
4
+
5
+ def initialize(config, url, method, params = {})
6
+ @config = config
7
+ @url = url
8
+ @method = method.to_sym
9
+ @skip_cache = params[:skip_cache] || false
10
+ end
11
+
12
+ def use?
13
+ !@skip_cache && [:get, :head].include?(@method)
14
+ end
15
+
16
+ def fetch(request, params = {})
17
+ timeout = params[:timeout] || @config.timeout
18
+ expires_in = params[:expires_in] || @config.cache_expires_in
19
+ stale_expires_in = params[:stale_expires_in] || @config.cache_stale_expires_in
20
+
21
+ begin
22
+ Timeout.timeout(timeout) do
23
+ @config.cache.fetch(@url, expires_in: expires_in) do
24
+ @status = "MISS"
25
+ response = request.execute
26
+
27
+ @config.cache.write(stale_key, response, expires_in: stale_expires_in)
28
+ response
29
+ end
30
+ end
31
+
32
+ rescue Timeout::Error => e
33
+ begin
34
+ serve_stale
35
+ rescue ContentGateway::StaleCacheNotAvailableError
36
+ raise ContentGateway::TimeoutError.new(@url, e, timeout)
37
+ end
38
+
39
+ rescue ContentGateway::ServerError => e
40
+ begin
41
+ serve_stale
42
+ rescue ContentGateway::StaleCacheNotAvailableError
43
+ raise e
44
+ end
45
+ end
46
+ end
47
+
48
+ def serve_stale
49
+ @config.cache.read(stale_key).tap do |cached|
50
+ raise ContentGateway::StaleCacheNotAvailableError.new unless cached
51
+ @status = "STALE"
52
+ end
53
+ end
54
+
55
+ def stale_key
56
+ @stale_key ||= "stale:#{@url}"
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,79 @@
1
+ module ContentGateway
2
+ class BaseError < StandardError
3
+ attr_reader :resource_url, :wrapped_exception, :status_code, :info
4
+
5
+ def initialize(resource_url, wrapped_exception = nil, status_code = nil, info = nil)
6
+ @resource_url = resource_url
7
+ @wrapped_exception = wrapped_exception
8
+ @status_code = status_code
9
+ @info = info
10
+
11
+ message = @resource_url.dup
12
+ if @wrapped_exception
13
+ message << " - #{@wrapped_exception.message}"
14
+ message << " - #{@info}" if @info
15
+ end
16
+
17
+ super(message)
18
+ end
19
+ end
20
+
21
+ class UnauthorizedError < BaseError
22
+ def initialize(resource_url, wrapped_exception = nil)
23
+ super(resource_url, wrapped_exception, 401)
24
+ end
25
+ end
26
+
27
+ class Forbidden < BaseError
28
+ def initialize(resource_url, wrapped_exception = nil)
29
+ super(resource_url, wrapped_exception, 403)
30
+ end
31
+ end
32
+
33
+ class ResourceNotFound < BaseError
34
+ def initialize(resource_url, wrapped_exception = nil)
35
+ super(resource_url, wrapped_exception, 404)
36
+ end
37
+ end
38
+
39
+ class TimeoutError < BaseError
40
+ def initialize(resource_url, wrapped_exception = nil, timeout = nil)
41
+ info = "TIMEOUT (max #{timeout} s)" if timeout
42
+
43
+ super(resource_url, wrapped_exception, 408, info)
44
+ end
45
+ end
46
+
47
+ class ConflictError < BaseError
48
+ def initialize(resource_url, wrapped_exception = nil)
49
+ super(resource_url, wrapped_exception, 409)
50
+ end
51
+ end
52
+
53
+ class ValidationError < BaseError
54
+ attr_reader :errors
55
+
56
+ def initialize(resource_url, wrapped_exception = nil)
57
+ super(resource_url, wrapped_exception, 422)
58
+
59
+ if wrapped_exception
60
+ response = wrapped_exception.response
61
+ @errors = JSON.parse(response) if response.present?
62
+ end
63
+ end
64
+ end
65
+
66
+ class ServerError < BaseError
67
+ def initialize(resource_url, wrapped_exception = nil, status_code = nil)
68
+ super(resource_url, wrapped_exception, status_code, "SERVER ERROR")
69
+ end
70
+ end
71
+
72
+ class ConnectionFailure < BaseError
73
+ def initialize(resource_url, wrapped_exception = nil)
74
+ super(resource_url, wrapped_exception, 500)
75
+ end
76
+ end
77
+
78
+ class StaleCacheNotAvailableError < StandardError; end
79
+ end
@@ -0,0 +1,153 @@
1
+ module ContentGateway
2
+ class Gateway
3
+ def initialize(label, config, url_generator, default_params = {})
4
+ @label = label
5
+ @config = config
6
+ @url_generator = url_generator
7
+ @default_params = default_params
8
+ end
9
+
10
+ def get(resource_path, params = {})
11
+ timeout = params.delete :timeout
12
+ expires_in = params.delete :expires_in
13
+ stale_expires_in = params.delete :stale_expires_in
14
+ skip_cache = params.delete :skip_cache
15
+ headers = (params.delete :headers) || @default_params[:headers]
16
+
17
+ url = self.generate_url(resource_path, params)
18
+
19
+ measure("GET - #{url}") do
20
+ data = { method: :get, url: url }.tap do |h|
21
+ h[:headers] = headers if headers.present?
22
+ end
23
+ send_request(data, skip_cache: skip_cache, expires_in: expires_in, stale_expires_in: stale_expires_in, timeout: timeout)
24
+ end
25
+ end
26
+
27
+ def post(resource_path, params = {})
28
+ payload = params.delete :payload
29
+ url = self.generate_url(resource_path, params)
30
+
31
+ measure("POST - #{url}") do
32
+ send_request({ method: :post, url: url, payload: payload }, params)
33
+ end
34
+ end
35
+
36
+ def put(resource_path, params = {})
37
+ payload = params.delete :payload
38
+ url = self.generate_url(resource_path, params)
39
+
40
+ measure("PUT - #{url}") do
41
+ send_request({ method: :put, url: url, payload: payload }, params)
42
+ end
43
+ end
44
+
45
+ def delete(resource_path, params = {})
46
+ payload = params.delete :payload
47
+ url = self.generate_url(resource_path, params)
48
+
49
+ measure("DELETE - #{url}") do
50
+ send_request({ method: :delete, url: url, payload: payload }, params)
51
+ end
52
+ end
53
+
54
+ def get_json(resource_path, params = {})
55
+ JSON.parse get(resource_path, params)
56
+ end
57
+
58
+ def post_json(resource_path, params = {})
59
+ JSON.parse post(resource_path, params)
60
+ end
61
+
62
+ def put_json(resource_path, params = {})
63
+ JSON.parse put(resource_path, params)
64
+ end
65
+
66
+ def delete_json(resource_path, params = {})
67
+ JSON.parse delete(resource_path, params)
68
+ end
69
+
70
+ def generate_url(resource_path, params = {})
71
+ @url_generator.generate(resource_path, params)
72
+ end
73
+
74
+ private
75
+
76
+ def send_request(request_data, params = {})
77
+ method = request_data[:method] || :get
78
+ url = request_data[:url]
79
+ headers = request_data[:headers]
80
+ payload = request_data[:payload]
81
+
82
+ @cache = ContentGateway::Cache.new(@config, url, method, params)
83
+ @request = ContentGateway::Request.new(method, url, headers, payload, @config.try(:proxy))
84
+
85
+ begin
86
+ do_request(params)
87
+
88
+ rescue ContentGateway::BaseError => e
89
+ message = "#{prefix(e.status_code)} :: #{color_message(e.resource_url)}"
90
+ message << " - #{e.info}" if e.info
91
+ logger.info message
92
+
93
+ raise e
94
+ end
95
+ end
96
+
97
+ def do_request(params = {})
98
+ if @cache.use?
99
+ @cache.fetch(@request, timeout: params[:timeout], expires_in: params[:expires_in], stale_expires_in: params[:stale_expires_in])
100
+ else
101
+ @request.execute
102
+ end
103
+ end
104
+
105
+ def measure(message)
106
+ result = nil
107
+ time_elapsed = Benchmark.measure { result = yield }
108
+ sufix = "finished in #{humanize_elapsed_time(time_elapsed.real)}. "
109
+ cache_log = (@cache.status || "HIT").to_s.ljust(4, " ")
110
+ log_message = "#{prefix(code(result))} :: #{cache_log} #{color_message(message)} #{sufix}"
111
+
112
+ logger.info log_message
113
+ result
114
+ end
115
+
116
+ def code(result)
117
+ result.respond_to?(:code) ? result.code : ""
118
+ end
119
+
120
+ def humanize_elapsed_time(time_elapsed)
121
+ time_elapsed >= 1 ? "%.3f secs" % time_elapsed : "#{(time_elapsed * 1000).to_i} ms"
122
+ end
123
+
124
+ def prefix(code = nil)
125
+ "[#{@label}] #{color_code(code)}"
126
+ end
127
+
128
+ def color_message(message)
129
+ "\033[1;33m#{message}\033[0m"
130
+ end
131
+
132
+ def color_code(code)
133
+ color = code == 200 ? "32" : "31"
134
+ code_message = code.to_s.ljust(3, " ")
135
+ "\033[#{color}m#{code_message}\033[0m"
136
+ end
137
+
138
+ def logger
139
+ @logger || lambda do
140
+ if defined?(Rails)
141
+ Rails.logger
142
+ else
143
+ log = ::Logger.new STDOUT
144
+ log.formatter = lambda {|severity, datetime, progname, msg|
145
+ "#{datetime.strftime("%Y-%m-%d %H:%M:%S")} #{severity.upcase} #{msg}\n"
146
+ }
147
+
148
+ log
149
+ end
150
+ end.yield
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,48 @@
1
+ module ContentGateway
2
+ class Request
3
+ def initialize(method, url, headers = {}, payload = {}, proxy = nil)
4
+ data = { method: method, url: url, proxy: proxy || :none }.tap do |h|
5
+ h[:payload] = payload if payload.present?
6
+ h[:headers] = headers if headers.present?
7
+ end
8
+
9
+ @client = RestClient::Request.new(data)
10
+ end
11
+
12
+ def execute
13
+ @client.execute
14
+
15
+ rescue RestClient::ResourceNotFound => e1
16
+ raise ContentGateway::ResourceNotFound.new url, e1
17
+
18
+ rescue RestClient::Unauthorized => e2
19
+ raise ContentGateway::UnauthorizedError.new url, e2
20
+
21
+ rescue RestClient::UnprocessableEntity => e3
22
+ raise ContentGateway::ValidationError.new url, e3
23
+
24
+ rescue RestClient::Forbidden => e4
25
+ raise ContentGateway::Forbidden.new url, e4
26
+
27
+ rescue RestClient::Conflict => e5
28
+ raise ContentGateway::ConflictError.new url, e5
29
+
30
+ rescue RestClient::Exception => e6
31
+ status_code = e6.http_code
32
+ if status_code < 500
33
+ raise e6
34
+ else
35
+ raise ContentGateway::ServerError.new url, e6, status_code
36
+ end
37
+
38
+ rescue StandardError => e7
39
+ raise ContentGateway::ConnectionFailure.new url, e7
40
+ end
41
+
42
+ private
43
+
44
+ def url
45
+ @client.url
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,3 @@
1
+ module ContentGateway
2
+ VERSION = "0.1.0"
3
+ end