acfs 1.3.2 → 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +39 -0
- data/README.md +10 -23
- data/acfs.gemspec +19 -20
- data/lib/acfs.rb +2 -0
- data/lib/acfs/adapter/base.rb +6 -8
- data/lib/acfs/adapter/typhoeus.rb +25 -6
- data/lib/acfs/collection.rb +2 -1
- data/lib/acfs/collections/paginatable.rb +4 -3
- data/lib/acfs/configuration.rb +14 -7
- data/lib/acfs/errors.rb +60 -19
- data/lib/acfs/global.rb +2 -0
- data/lib/acfs/location.rb +9 -5
- data/lib/acfs/middleware/base.rb +5 -1
- data/lib/acfs/middleware/json.rb +6 -2
- data/lib/acfs/middleware/logger.rb +2 -0
- data/lib/acfs/middleware/msgpack.rb +2 -0
- data/lib/acfs/middleware/print.rb +2 -0
- data/lib/acfs/middleware/serializer.rb +2 -0
- data/lib/acfs/operation.rb +20 -3
- data/lib/acfs/request.rb +5 -1
- data/lib/acfs/request/callbacks.rb +5 -1
- data/lib/acfs/resource.rb +2 -0
- data/lib/acfs/resource/attributes.rb +7 -4
- data/lib/acfs/resource/attributes/base.rb +2 -1
- data/lib/acfs/resource/attributes/boolean.rb +2 -0
- data/lib/acfs/resource/attributes/date_time.rb +3 -2
- data/lib/acfs/resource/attributes/dict.rb +2 -0
- data/lib/acfs/resource/attributes/float.rb +5 -3
- data/lib/acfs/resource/attributes/integer.rb +2 -0
- data/lib/acfs/resource/attributes/list.rb +2 -0
- data/lib/acfs/resource/attributes/string.rb +2 -0
- data/lib/acfs/resource/attributes/uuid.rb +4 -3
- data/lib/acfs/resource/dirty.rb +2 -0
- data/lib/acfs/resource/initialization.rb +2 -0
- data/lib/acfs/resource/loadable.rb +2 -0
- data/lib/acfs/resource/locatable.rb +10 -6
- data/lib/acfs/resource/operational.rb +2 -1
- data/lib/acfs/resource/persistence.rb +7 -6
- data/lib/acfs/resource/query_methods.rb +6 -4
- data/lib/acfs/resource/service.rb +3 -1
- data/lib/acfs/resource/validation.rb +19 -7
- data/lib/acfs/response.rb +2 -0
- data/lib/acfs/response/formats.rb +2 -0
- data/lib/acfs/response/status.rb +3 -1
- data/lib/acfs/rspec.rb +2 -0
- data/lib/acfs/runner.rb +6 -1
- data/lib/acfs/service.rb +24 -13
- data/lib/acfs/service/middleware.rb +2 -0
- data/lib/acfs/service/middleware/stack.rb +5 -3
- data/lib/acfs/singleton_resource.rb +4 -2
- data/lib/acfs/stub.rb +32 -11
- data/lib/acfs/util.rb +2 -0
- data/lib/acfs/version.rb +4 -2
- data/lib/acfs/yard.rb +1 -0
- data/spec/acfs/adapter/typhoeus_spec.rb +30 -3
- data/spec/acfs/collection_spec.rb +7 -5
- data/spec/acfs/configuration_spec.rb +2 -0
- data/spec/acfs/global_spec.rb +6 -3
- data/spec/acfs/location_spec.rb +2 -0
- data/spec/acfs/middleware/json_spec.rb +17 -1
- data/spec/acfs/middleware/msgpack_spec.rb +2 -0
- data/spec/acfs/operation_spec.rb +2 -0
- data/spec/acfs/request/callbacks_spec.rb +2 -0
- data/spec/acfs/request_spec.rb +3 -1
- data/spec/acfs/resource/attributes/boolean_spec.rb +2 -0
- data/spec/acfs/resource/attributes/date_time_spec.rb +2 -0
- data/spec/acfs/resource/attributes/dict_spec.rb +4 -2
- data/spec/acfs/resource/attributes/float_spec.rb +3 -1
- data/spec/acfs/resource/attributes/integer_spec.rb +2 -0
- data/spec/acfs/resource/attributes/list_spec.rb +5 -3
- data/spec/acfs/resource/attributes/uuid_spec.rb +2 -0
- data/spec/acfs/resource/attributes_spec.rb +8 -8
- data/spec/acfs/resource/dirty_spec.rb +2 -0
- data/spec/acfs/resource/initialization_spec.rb +8 -2
- data/spec/acfs/resource/loadable_spec.rb +2 -0
- data/spec/acfs/resource/locatable_spec.rb +2 -0
- data/spec/acfs/resource/persistance_spec.rb +10 -4
- data/spec/acfs/resource/query_methods_spec.rb +24 -17
- data/spec/acfs/resource/validation_spec.rb +2 -0
- data/spec/acfs/response/formats_spec.rb +3 -1
- data/spec/acfs/response/status_spec.rb +2 -0
- data/spec/acfs/runner_spec.rb +6 -8
- data/spec/acfs/service/middleware_spec.rb +2 -0
- data/spec/acfs/service_spec.rb +3 -1
- data/spec/acfs/singleton_resource_spec.rb +2 -0
- data/spec/acfs/stub_spec.rb +2 -0
- data/spec/acfs_spec.rb +2 -0
- data/spec/spec_helper.rb +3 -1
- data/spec/support/hash.rb +2 -0
- data/spec/support/response.rb +2 -0
- data/spec/support/service.rb +1 -0
- data/spec/support/shared/find_callbacks.rb +2 -0
- metadata +26 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 55e1388e9df4207138b2a54f1e9d56c349ac407e52364b849887e9682abfee7e
|
4
|
+
data.tar.gz: ccf1b3550de8f5222988333d14e480ec07742fb0398d3adfb9504be4ca4168b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d34c6fd3d4e83e22757633efc72c8d399778b86665f4b5bb6fb46c8d4f93782f996fe307904ac83f9b16701157ecb8418977466cad9d9c5a78c6ea1074e9ddd7
|
7
|
+
data.tar.gz: 3460436cd3a9d61241155658e4c46ef556b69d00fd389aca73c78ca6484b29bac9b3c45a0fd310b41259aba68f8aad55c7ca95a259e18075c2d88b2515bacd52
|
data/CHANGELOG.md
CHANGED
@@ -14,6 +14,45 @@
|
|
14
14
|
### Breaks
|
15
15
|
|
16
16
|
|
17
|
+
## 1.5.1 - (2020-12-30)
|
18
|
+
---
|
19
|
+
|
20
|
+
### Changes
|
21
|
+
* Revert back to using `::MultiJson`
|
22
|
+
|
23
|
+
|
24
|
+
## 1.5.0 - (2020-06-19)
|
25
|
+
---
|
26
|
+
|
27
|
+
### New
|
28
|
+
* Error classes for more HTTP error responses: `400`, `401`, `403`, `500`, `502`, `503`, `504`.
|
29
|
+
|
30
|
+
### Changes
|
31
|
+
* Replace deprecated MultiJson with core JSON module
|
32
|
+
|
33
|
+
|
34
|
+
## 1.4.0 - (2020-06-12)
|
35
|
+
---
|
36
|
+
|
37
|
+
### New
|
38
|
+
* Use strict TCP keepalive probing by default (5s/5s)
|
39
|
+
* Adapter accepts curl request opts
|
40
|
+
|
41
|
+
|
42
|
+
## 1.3.4 - (2020-03-22)
|
43
|
+
---
|
44
|
+
|
45
|
+
### Fixes
|
46
|
+
* Empty package build for Gem release 1.3.3
|
47
|
+
|
48
|
+
|
49
|
+
## 1.3.3 - (2020-03-22)
|
50
|
+
---
|
51
|
+
|
52
|
+
### Changes
|
53
|
+
* Improved handling of low-level connection errors and timeouts
|
54
|
+
|
55
|
+
|
17
56
|
## 1.3.2 - (2019-09-24)
|
18
57
|
|
19
58
|
|
data/README.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# Acfs - *API client for services*
|
2
2
|
|
3
|
-
[![Gem Version](https://
|
4
|
-
[![Build Status](
|
3
|
+
[![Gem Version](https://img.shields.io/gem/v/acfs?logo=ruby)](https://rubygems.org/gems/acfs)
|
4
|
+
[![Build Status](https://img.shields.io/travis/jgraichen/acfs/master?logo=travis)](https://travis-ci.org/jgraichen/acfs)
|
5
|
+
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/jgraichen/acfs/Test/master?logo=github)](https://github.com/jgraichen/acfs/actions?query=branch%3Amaster)
|
5
6
|
[![Coverage Status](http://img.shields.io/coveralls/jgraichen/acfs/master.svg)](https://coveralls.io/r/jgraichen/acfs)
|
6
7
|
[![RubyDoc Documentation](http://img.shields.io/badge/rubydoc-here-blue.svg)](http://rubydoc.info/github/jgraichen/acfs/master/frames)
|
7
8
|
|
@@ -9,6 +10,7 @@ Acfs is a library to develop API client libraries for single services within a l
|
|
9
10
|
|
10
11
|
Acfs covers model and service abstraction, convenient query and filter methods, full middleware stack for pre-processing requests and responses on a per service level and automatic request queuing and parallel processing. See Usage for more.
|
11
12
|
|
13
|
+
|
12
14
|
## Installation
|
13
15
|
|
14
16
|
Add this line to your application's Gemfile:
|
@@ -23,6 +25,7 @@ Or install it yourself as:
|
|
23
25
|
|
24
26
|
> gem install acfs
|
25
27
|
|
28
|
+
|
26
29
|
## Usage
|
27
30
|
|
28
31
|
First you need to define your service(s):
|
@@ -144,6 +147,7 @@ Acfs has basic update support using `PUT` requests:
|
|
144
147
|
@user.persisted? # => true
|
145
148
|
```
|
146
149
|
|
150
|
+
|
147
151
|
## Singleton resources
|
148
152
|
|
149
153
|
Singletons can be used in Acfs by creating a new resource which inherits from `SingletonResource`:
|
@@ -182,6 +186,7 @@ my_single = Single.find name: 'Max'
|
|
182
186
|
Acfs.run # sends GET request with param to /single?name=Max
|
183
187
|
```
|
184
188
|
|
189
|
+
|
185
190
|
## Resource Inheritance
|
186
191
|
|
187
192
|
Acfs provides a resource inheritance similar to ActiveRecord Single Table Inheritance. If a
|
@@ -218,6 +223,7 @@ Acfs.run
|
|
218
223
|
@computer[2].class # => Pc
|
219
224
|
```
|
220
225
|
|
226
|
+
|
221
227
|
## Stubbing
|
222
228
|
|
223
229
|
You can stub resources in applications using an Acfs service client:
|
@@ -278,6 +284,7 @@ it 'should find user number one' do
|
|
278
284
|
end
|
279
285
|
```
|
280
286
|
|
287
|
+
|
281
288
|
## Instrumentation
|
282
289
|
|
283
290
|
Acfs supports [instrumentation via active support][1].
|
@@ -295,21 +302,6 @@ Read [official guide][2] to see to to subscribe.
|
|
295
302
|
[1]: http://guides.rubyonrails.org/active_support_instrumentation.html
|
296
303
|
[2]: http://guides.rubyonrails.org/active_support_instrumentation.html#subscribing-to-an-event
|
297
304
|
|
298
|
-
## Roadmap
|
299
|
-
|
300
|
-
* Update
|
301
|
-
* Better new? detection eg. storing ETag from request resources.
|
302
|
-
* Use PATCH for with only changed attributes and `If-Unmodifed-Since`
|
303
|
-
and `If-Match` header fields if resource was surly loaded from service
|
304
|
-
and not created with an id (e.g `User.new id: 5, name: "john"`).
|
305
|
-
* Conflict detection (ETag / If-Unmodified-Since)
|
306
|
-
* High level features
|
307
|
-
* Support for custom mime types on client and server side. (`application/vnd.myservice.user.v2+msgpack`)
|
308
|
-
* Server side components
|
309
|
-
* Reusing model definitions for generating responses?
|
310
|
-
* Rails responders providing REST operations with integrated ETag,
|
311
|
-
Modified Headers, conflict detection, ...
|
312
|
-
* Documentation
|
313
305
|
|
314
306
|
## Contributing
|
315
307
|
|
@@ -321,14 +313,9 @@ Read [official guide][2] to see to to subscribe.
|
|
321
313
|
7. Push to the branch (`git push origin my-new-feature`)
|
322
314
|
8. Create new Pull Request
|
323
315
|
|
324
|
-
## Contributors
|
325
|
-
|
326
|
-
* [Nicolas Fricke](https://github.com/nicolas-fricke)
|
327
|
-
* [Tino Junge](https://github.com/tino-junge)
|
328
|
-
* [Malte Swart](https://github.com/mswart)
|
329
316
|
|
330
317
|
## License
|
331
318
|
|
332
319
|
MIT License
|
333
320
|
|
334
|
-
Copyright (c) 2013 Jan Graichen. MIT license, see LICENSE for more details.
|
321
|
+
Copyright (c) 2013-2020 Jan Graichen. MIT license, see LICENSE for more details.
|
data/acfs.gemspec
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'acfs/version'
|
5
6
|
|
@@ -7,31 +8,29 @@ Gem::Specification.new do |spec|
|
|
7
8
|
spec.name = 'acfs'
|
8
9
|
spec.version = Acfs::VERSION
|
9
10
|
spec.authors = ['Jan Graichen']
|
10
|
-
spec.email = %w
|
11
|
-
spec.description = 'API Client For Services'
|
12
|
-
spec.summary = 'An abstract API base client for service oriented application.'
|
11
|
+
spec.email = %w[jgraichen@altimos.de]
|
13
12
|
spec.homepage = 'https://github.com/jgraichen/acfs'
|
14
13
|
spec.license = 'MIT'
|
14
|
+
spec.description = 'API Client For Services'
|
15
|
+
spec.summary = <<~SUMMARY.strip
|
16
|
+
An abstract API base client for service oriented application.
|
17
|
+
SUMMARY
|
18
|
+
|
19
|
+
spec.files = Dir['**/*'].grep(%r{
|
20
|
+
^((bin|lib|test|spec|features)/|
|
21
|
+
.*\.gemspec|.*LICENSE.*|.*README.*|.*CHANGELOG.*)
|
22
|
+
}xi)
|
15
23
|
|
16
|
-
spec.files = Dir['**/*'].grep(%r{^((bin|lib|test|spec|features)/|.*\.gemspec|.*LICENSE.*|.*README.*|.*CHANGELOG.*)})
|
17
24
|
spec.executables = spec.files.grep(%r{^bin/}) {|f| File.basename(f) }
|
18
25
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = %w
|
20
|
-
|
21
|
-
spec.add_runtime_dependency 'activesupport', '>= 4.2'
|
22
|
-
spec.add_runtime_dependency 'activemodel', '>= 4.2'
|
23
|
-
spec.add_runtime_dependency 'actionpack', '>= 4.2'
|
24
|
-
spec.add_runtime_dependency 'multi_json'
|
25
|
-
|
26
|
-
# Bundle update w/o version resolves to 0.3.3 ...
|
27
|
-
spec.add_runtime_dependency 'typhoeus', '~> 1.0'
|
26
|
+
spec.require_paths = %w[lib]
|
28
27
|
|
28
|
+
spec.add_runtime_dependency 'actionpack', '>= 5.2'
|
29
|
+
spec.add_runtime_dependency 'activemodel', '>= 5.2'
|
30
|
+
spec.add_runtime_dependency 'activesupport', '>= 5.2'
|
31
|
+
spec.add_runtime_dependency 'multi_json', '~> 1.0'
|
29
32
|
spec.add_runtime_dependency 'rack'
|
33
|
+
spec.add_runtime_dependency 'typhoeus', '~> 1.0'
|
30
34
|
|
31
35
|
spec.add_development_dependency 'bundler'
|
32
|
-
|
33
|
-
if ENV['TRAVIS_BUILD_NUMBER'] && !ENV['TRAVIS_TAG']
|
34
|
-
# Append travis build number for auto-releases
|
35
|
-
spec.version = "#{spec.version}.1.b#{ENV['TRAVIS_BUILD_NUMBER']}"
|
36
|
-
end
|
37
36
|
end
|
data/lib/acfs.rb
CHANGED
data/lib/acfs/adapter/base.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Acfs::Adapter
|
2
4
|
# Base adapter handling operation queuing
|
3
5
|
# and processing.
|
@@ -5,22 +7,18 @@ module Acfs::Adapter
|
|
5
7
|
class Base
|
6
8
|
# Start processing queued requests.
|
7
9
|
#
|
8
|
-
def start
|
9
|
-
end
|
10
|
+
def start; end
|
10
11
|
|
11
12
|
# Abort running and queued requests.
|
12
13
|
#
|
13
|
-
def abort
|
14
|
-
end
|
14
|
+
def abort; end
|
15
15
|
|
16
16
|
# Run request right now skipping queue.
|
17
17
|
#
|
18
|
-
def run(_)
|
19
|
-
end
|
18
|
+
def run(_); end
|
20
19
|
|
21
20
|
# Enqueue request to be run later.
|
22
21
|
#
|
23
|
-
def queue(_)
|
24
|
-
end
|
22
|
+
def queue(_); end
|
25
23
|
end
|
26
24
|
end
|
@@ -1,17 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'typhoeus'
|
2
4
|
|
3
5
|
module Acfs
|
4
6
|
module Adapter
|
7
|
+
DEFAULT_OPTIONS = {
|
8
|
+
tcp_keepalive: true,
|
9
|
+
tcp_keepidle: 5,
|
10
|
+
tcp_keepintvl: 5
|
11
|
+
}.freeze
|
12
|
+
|
5
13
|
# Adapter for Typhoeus.
|
6
14
|
#
|
7
15
|
class Typhoeus < Base
|
8
|
-
def initialize(**kwargs)
|
9
|
-
@
|
16
|
+
def initialize(opts: {}, **kwargs)
|
17
|
+
@opts = DEFAULT_OPTIONS.merge(opts)
|
18
|
+
@kwargs = kwargs
|
10
19
|
end
|
11
20
|
|
12
21
|
def start
|
13
22
|
hydra.run
|
14
|
-
rescue
|
23
|
+
rescue StandardError
|
15
24
|
@hydra = nil
|
16
25
|
raise
|
17
26
|
end
|
@@ -29,20 +38,30 @@ module Acfs
|
|
29
38
|
protected
|
30
39
|
|
31
40
|
def hydra
|
32
|
-
@hydra ||= ::Typhoeus::Hydra.new(**@
|
41
|
+
@hydra ||= ::Typhoeus::Hydra.new(**@kwargs)
|
33
42
|
end
|
34
43
|
|
35
44
|
def convert_request(req)
|
36
|
-
|
45
|
+
opts = {
|
37
46
|
method: req.method,
|
38
47
|
params: req.params,
|
39
48
|
headers: req.headers.merge(
|
40
|
-
'Expect'
|
49
|
+
'Expect' => '',
|
41
50
|
'Transfer-Encoding' => ''
|
42
51
|
),
|
43
52
|
body: req.body
|
53
|
+
}
|
54
|
+
|
55
|
+
request = ::Typhoeus::Request.new(req.url, **@opts.merge(opts))
|
44
56
|
|
45
57
|
request.on_complete do |response|
|
58
|
+
raise ::Acfs::TimeoutError.new(req) if response.timed_out?
|
59
|
+
|
60
|
+
if response.code.zero?
|
61
|
+
# Failed to get HTTP response
|
62
|
+
raise ::Acfs::RequestError.new(req, response.return_message)
|
63
|
+
end
|
64
|
+
|
46
65
|
req.complete! convert_response(req, response)
|
47
66
|
end
|
48
67
|
|
data/lib/acfs/collection.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Acfs::Collections
|
2
|
-
#
|
3
4
|
module Paginatable
|
4
5
|
extend ActiveSupport::Concern
|
5
6
|
|
@@ -67,8 +68,8 @@ module Acfs::Collections
|
|
67
68
|
def setup_params(params)
|
68
69
|
@current_page = begin
|
69
70
|
Integer params.fetch(:page, 1)
|
70
|
-
|
71
|
-
|
71
|
+
rescue ArgumentError
|
72
|
+
params[:page]
|
72
73
|
end
|
73
74
|
end
|
74
75
|
end
|
data/lib/acfs/configuration.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'uri'
|
2
4
|
require 'yaml'
|
3
5
|
|
@@ -25,7 +27,7 @@ module Acfs
|
|
25
27
|
# @return [undefined]
|
26
28
|
#
|
27
29
|
def configure(&block)
|
28
|
-
if block.arity
|
30
|
+
if block.arity.positive?
|
29
31
|
block.call self
|
30
32
|
else
|
31
33
|
instance_eval(&block)
|
@@ -37,8 +39,12 @@ module Acfs
|
|
37
39
|
# @overload locate(service, uri)
|
38
40
|
# Configures URL where a service can be reached.
|
39
41
|
#
|
40
|
-
# @param [Symbol] service
|
41
|
-
#
|
42
|
+
# @param [Symbol] service
|
43
|
+
# Service identity key for service that is reachable under given URL.
|
44
|
+
#
|
45
|
+
# @param [String] uri
|
46
|
+
# URL where service is reachable. Will be passed to {URI.parse}.
|
47
|
+
#
|
42
48
|
# @return [undefined]
|
43
49
|
#
|
44
50
|
# @overload locate(service)
|
@@ -64,7 +70,7 @@ module Acfs
|
|
64
70
|
# @return [undefined]
|
65
71
|
#
|
66
72
|
def load(filename)
|
67
|
-
config = YAML.
|
73
|
+
config = YAML.safe_load(File.read(filename), [], [], true)
|
68
74
|
env = ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development'
|
69
75
|
|
70
76
|
config = config[env] if config.key? env
|
@@ -95,18 +101,19 @@ module Acfs
|
|
95
101
|
# @return [Configuration]
|
96
102
|
#
|
97
103
|
def current
|
98
|
-
@
|
104
|
+
@current ||= new
|
99
105
|
end
|
100
106
|
|
101
107
|
# @api private
|
102
108
|
#
|
103
|
-
# Swap configuration object with given new one. Must be
|
109
|
+
# Swap configuration object with given new one. Must be
|
110
|
+
# a {Configuration} object.
|
104
111
|
#
|
105
112
|
# @param [Configuration] configuration
|
106
113
|
# @return [undefined]
|
107
114
|
#
|
108
115
|
def set(configuration)
|
109
|
-
@
|
116
|
+
@current = configuration if configuration.is_a? Configuration
|
110
117
|
end
|
111
118
|
end
|
112
119
|
end
|
data/lib/acfs/errors.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Acfs
|
2
4
|
# Acfs base error.
|
3
5
|
#
|
@@ -10,6 +12,24 @@ module Acfs
|
|
10
12
|
|
11
13
|
class UnsupportedOperation < StandardError; end
|
12
14
|
|
15
|
+
class RequestError < Error
|
16
|
+
attr_reader :request
|
17
|
+
|
18
|
+
def initialize(request, message)
|
19
|
+
@request = request
|
20
|
+
|
21
|
+
message = "#{message}: #{request.method.upcase} #{request.url}"
|
22
|
+
|
23
|
+
super message: message
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class TimeoutError < RequestError
|
28
|
+
def initialize(request)
|
29
|
+
super(request, 'Timeout reached')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
13
33
|
# Response error containing the responsible response object.
|
14
34
|
#
|
15
35
|
class ErroneousResponse < Error
|
@@ -17,17 +37,15 @@ module Acfs
|
|
17
37
|
|
18
38
|
def initialize(opts = {})
|
19
39
|
@response = opts[:response]
|
20
|
-
|
21
|
-
if response
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
message ||= 'Received erroneous response'
|
30
|
-
end
|
40
|
+
|
41
|
+
message = if response
|
42
|
+
(opts[:message] ? opts[:message] + ':' : 'Received') +
|
43
|
+
" #{response.code} for #{response.request.method.upcase}" \
|
44
|
+
" #{response.request.url} #{response.request.format}"
|
45
|
+
else
|
46
|
+
opts[:message] || 'Received erroneous response'
|
47
|
+
end
|
48
|
+
|
31
49
|
super opts, message
|
32
50
|
end
|
33
51
|
end
|
@@ -41,17 +59,27 @@ module Acfs
|
|
41
59
|
@stubs = opts.delete :stubs
|
42
60
|
@operation = opts.delete :operation
|
43
61
|
|
44
|
-
|
45
|
-
|
62
|
+
message = "Ambiguous stubs for #{operation.action} " \
|
63
|
+
"on #{operation.resource}.\n" +
|
64
|
+
stubs.map {|s| " #{s.opts.pretty_inspect}" }.join
|
65
|
+
|
66
|
+
super opts, message
|
46
67
|
end
|
47
68
|
end
|
48
69
|
|
49
|
-
#
|
50
|
-
|
51
|
-
class ResourceNotFound < ErroneousResponse
|
52
|
-
end
|
70
|
+
# 400
|
71
|
+
class BadRequest < ErroneousResponse; end
|
53
72
|
|
54
|
-
#
|
73
|
+
# 401
|
74
|
+
class Unauthorized < ErroneousResponse; end
|
75
|
+
|
76
|
+
# 403
|
77
|
+
class Forbidden < ErroneousResponse; end
|
78
|
+
|
79
|
+
# 404
|
80
|
+
class ResourceNotFound < ErroneousResponse; end
|
81
|
+
|
82
|
+
# 422
|
55
83
|
class InvalidResource < ErroneousResponse
|
56
84
|
attr_reader :errors, :resource
|
57
85
|
|
@@ -71,6 +99,18 @@ module Acfs
|
|
71
99
|
end
|
72
100
|
end
|
73
101
|
|
102
|
+
# 500
|
103
|
+
class ServerError < ErroneousResponse; end
|
104
|
+
|
105
|
+
# 502
|
106
|
+
class BadGateway < ErroneousResponse; end
|
107
|
+
|
108
|
+
# 503
|
109
|
+
class ServiceUnavailable < ErroneousResponse; end
|
110
|
+
|
111
|
+
# 504
|
112
|
+
class GatewayTimeout < ErroneousResponse; end
|
113
|
+
|
74
114
|
# A ResourceNotLoaded error will be thrown when calling some
|
75
115
|
# modifing methods on not loaded resources as it is usally
|
76
116
|
# unwanted to call e.g. `update_attributes` on a not loaded
|
@@ -97,7 +137,8 @@ module Acfs
|
|
97
137
|
def initialize(opts = {})
|
98
138
|
@base_class = opts.delete :base_class
|
99
139
|
@type_name = opts.delete :type_name
|
100
|
-
opts[:message] = "Received resource type `#{type_name}`
|
140
|
+
opts[:message] = "Received resource type `#{type_name}` " \
|
141
|
+
"is no subclass of #{base_class}"
|
101
142
|
super
|
102
143
|
end
|
103
144
|
end
|