content_gateway 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 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