acfs 0.50.0 → 1.0.0.dev.1.b297
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 +13 -5
- data/CHANGELOG.md +0 -80
- data/README.md +9 -8
- data/acfs.gemspec +7 -7
- data/lib/acfs.rb +5 -7
- data/lib/acfs/adapter/base.rb +2 -0
- data/lib/acfs/adapter/typhoeus.rb +13 -17
- data/lib/acfs/collections/paginatable.rb +10 -10
- data/lib/acfs/configuration.rb +5 -4
- data/lib/acfs/errors.rb +9 -10
- data/lib/acfs/global.rb +7 -16
- data/lib/acfs/location.rb +11 -11
- data/lib/acfs/middleware/base.rb +2 -1
- data/lib/acfs/middleware/json_decoder.rb +16 -0
- data/lib/acfs/middleware/json_encoder.rb +20 -0
- data/lib/acfs/middleware/logger.rb +2 -0
- data/lib/acfs/middleware/msgpack_decoder.rb +26 -0
- data/lib/acfs/middleware/msgpack_encoder.rb +19 -0
- data/lib/acfs/middleware/print.rb +2 -0
- data/lib/acfs/operation.rb +5 -5
- data/lib/acfs/request.rb +4 -4
- data/lib/acfs/request/callbacks.rb +3 -2
- data/lib/acfs/resource.rb +2 -2
- data/lib/acfs/resource/attributes.rb +38 -11
- data/lib/acfs/resource/attributes/base.rb +19 -10
- data/lib/acfs/resource/attributes/boolean.rb +8 -10
- data/lib/acfs/resource/attributes/date_time.rb +9 -6
- data/lib/acfs/resource/attributes/float.rb +5 -11
- data/lib/acfs/resource/attributes/integer.rb +5 -7
- data/lib/acfs/resource/attributes/list.rb +6 -13
- data/lib/acfs/resource/attributes/string.rb +5 -3
- data/lib/acfs/resource/attributes/uuid.rb +17 -8
- data/lib/acfs/resource/dirty.rb +15 -3
- data/lib/acfs/resource/loadable.rb +1 -0
- data/lib/acfs/resource/locatable.rb +4 -0
- data/lib/acfs/resource/operational.rb +2 -0
- data/lib/acfs/resource/persistence.rb +17 -17
- data/lib/acfs/resource/query_methods.rb +7 -8
- data/lib/acfs/resource/service.rb +2 -0
- data/lib/acfs/resource/validation.rb +4 -4
- data/lib/acfs/response.rb +2 -1
- data/lib/acfs/response/formats.rb +3 -2
- data/lib/acfs/response/status.rb +5 -3
- data/lib/acfs/runner.rb +11 -21
- data/lib/acfs/service.rb +6 -4
- data/lib/acfs/service/middleware.rb +30 -20
- data/lib/acfs/singleton_resource.rb +2 -0
- data/lib/acfs/stub.rb +21 -30
- data/lib/acfs/util.rb +1 -1
- data/lib/acfs/version.rb +4 -6
- data/spec/acfs/adapter/typhoeus_spec.rb +4 -12
- data/spec/acfs/collection_spec.rb +33 -45
- data/spec/acfs/configuration_spec.rb +1 -9
- data/spec/acfs/global_spec.rb +3 -21
- data/spec/acfs/middleware/json_decoder_spec.rb +45 -0
- data/spec/acfs/middleware/msgpack_decoder_spec.rb +36 -0
- data/spec/acfs/request/callbacks_spec.rb +8 -8
- data/spec/acfs/request_spec.rb +5 -5
- data/spec/acfs/resource/attributes/boolean_spec.rb +9 -40
- data/spec/acfs/resource/attributes/date_time_spec.rb +35 -29
- data/spec/acfs/resource/attributes/float_spec.rb +9 -48
- data/spec/acfs/resource/attributes/list_spec.rb +19 -43
- data/spec/acfs/resource/attributes/uuid_spec.rb +54 -31
- data/spec/acfs/resource/attributes_spec.rb +31 -17
- data/spec/acfs/resource/locatable_spec.rb +2 -2
- data/spec/acfs/resource/persistance_spec.rb +34 -65
- data/spec/acfs/resource/query_methods_spec.rb +90 -97
- data/spec/acfs/resource/validation_spec.rb +5 -4
- data/spec/acfs/response/formats_spec.rb +4 -4
- data/spec/acfs/response/status_spec.rb +1 -1
- data/spec/acfs/runner_spec.rb +3 -28
- data/spec/acfs/service/middleware_spec.rb +20 -4
- data/spec/acfs/service_spec.rb +5 -3
- data/spec/acfs/singleton_resource_spec.rb +2 -1
- data/spec/acfs/stub_spec.rb +22 -137
- data/spec/acfs_spec.rb +19 -22
- data/spec/spec_helper.rb +2 -3
- data/spec/support/service.rb +6 -10
- data/spec/support/shared/find_callbacks.rb +7 -7
- metadata +36 -43
- data/lib/acfs/middleware/json.rb +0 -27
- data/lib/acfs/middleware/msgpack.rb +0 -30
- data/lib/acfs/middleware/serializer.rb +0 -39
- data/lib/acfs/resource/attributes/dict.rb +0 -37
- data/lib/acfs/service/middleware/stack.rb +0 -63
- data/spec/acfs/middleware/json_spec.rb +0 -63
- data/spec/acfs/middleware/msgpack_spec.rb +0 -60
- data/spec/acfs/operation_spec.rb +0 -10
- data/spec/acfs/resource/attributes/dict_spec.rb +0 -75
- data/spec/acfs/resource/attributes/integer_spec.rb +0 -34
data/lib/acfs/response.rb
CHANGED
@@ -3,6 +3,7 @@ require 'acfs/response/status'
|
|
3
3
|
require 'active_support/core_ext/module/delegation'
|
4
4
|
|
5
5
|
module Acfs
|
6
|
+
|
6
7
|
# This represents a response. In addition to an standard HTTP
|
7
8
|
# it has a field `data` for storing the encoded body.
|
8
9
|
#
|
@@ -13,7 +14,7 @@ module Acfs
|
|
13
14
|
include Response::Formats
|
14
15
|
include Response::Status
|
15
16
|
|
16
|
-
#
|
17
|
+
#delegate :status, :status_message, :success?, :modified?, :timed_out?,
|
17
18
|
# :response_body, :response_headers, :response_code, :headers,
|
18
19
|
# to: :response
|
19
20
|
|
@@ -2,18 +2,19 @@ require 'action_dispatch'
|
|
2
2
|
|
3
3
|
module Acfs
|
4
4
|
class Response
|
5
|
+
|
5
6
|
# Quick accessors for format handling.
|
6
7
|
module Formats
|
8
|
+
|
7
9
|
def content_type
|
8
10
|
@content_type ||= read_content_type
|
9
11
|
end
|
10
12
|
|
11
13
|
def json?
|
12
|
-
content_type == Mime
|
14
|
+
content_type == Mime::JSON
|
13
15
|
end
|
14
16
|
|
15
17
|
private
|
16
|
-
|
17
18
|
def read_content_type
|
18
19
|
return 'text/plain' unless headers && headers['Content-Type']
|
19
20
|
|
data/lib/acfs/response/status.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
1
|
module Acfs
|
2
2
|
class Response
|
3
|
+
|
3
4
|
# Method to fetch information about response status.
|
4
5
|
#
|
5
6
|
module Status
|
7
|
+
|
6
8
|
# Return response status code. Will return zero if
|
7
9
|
# request was not executed or failed on client side.
|
8
10
|
#
|
9
11
|
def status_code
|
10
12
|
return @status.to_i if defined? :@status
|
11
|
-
#
|
12
|
-
#
|
13
|
+
#return response.response_code unless response.nil?
|
14
|
+
#0
|
13
15
|
end
|
14
|
-
|
16
|
+
alias :code :status_code
|
15
17
|
|
16
18
|
# Return true if response was successful indicated by
|
17
19
|
# response status code.
|
data/lib/acfs/runner.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'acfs/service/middleware'
|
2
2
|
|
3
3
|
module Acfs
|
4
|
+
|
4
5
|
# @api private
|
5
6
|
#
|
6
7
|
class Runner
|
@@ -16,7 +17,6 @@ module Acfs
|
|
16
17
|
# and parallel operations will be queued.
|
17
18
|
#
|
18
19
|
def process(op)
|
19
|
-
::ActiveSupport::Notifications.instrument 'acfs.operation.before_process', operation: op
|
20
20
|
op.synchronous? ? run(op) : enqueue(op)
|
21
21
|
end
|
22
22
|
|
@@ -24,7 +24,7 @@ module Acfs
|
|
24
24
|
#
|
25
25
|
def run(op)
|
26
26
|
::ActiveSupport::Notifications.instrument 'acfs.runner.sync_run', operation: op do
|
27
|
-
op_request(op) {|req| adapter.run req }
|
27
|
+
op_request(op) { |req| adapter.run req }
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -39,7 +39,7 @@ module Acfs
|
|
39
39
|
def enqueue(op)
|
40
40
|
::ActiveSupport::Notifications.instrument 'acfs.runner.enqueue', operation: op do
|
41
41
|
if running?
|
42
|
-
op_request(op) {|req| adapter.queue req }
|
42
|
+
op_request(op) { |req| adapter.queue req }
|
43
43
|
else
|
44
44
|
queue << op
|
45
45
|
end
|
@@ -55,13 +55,15 @@ module Acfs
|
|
55
55
|
# Start processing queued operations.
|
56
56
|
#
|
57
57
|
def start
|
58
|
-
return if running?
|
59
|
-
|
60
58
|
enqueue_operations
|
61
|
-
|
59
|
+
|
60
|
+
@running = true
|
61
|
+
adapter.start
|
62
62
|
rescue
|
63
63
|
queue.clear
|
64
64
|
raise
|
65
|
+
ensure
|
66
|
+
@running = false
|
65
67
|
end
|
66
68
|
|
67
69
|
def clear
|
@@ -71,27 +73,15 @@ module Acfs
|
|
71
73
|
end
|
72
74
|
|
73
75
|
private
|
74
|
-
|
75
|
-
def start_all
|
76
|
-
@running = true
|
77
|
-
adapter.start
|
78
|
-
ensure
|
79
|
-
@running = false
|
80
|
-
end
|
81
|
-
|
82
76
|
def enqueue_operations
|
83
77
|
while (op = queue.shift)
|
84
|
-
op_request(op) {|req| adapter.queue req }
|
78
|
+
op_request(op) { |req| adapter.queue req }
|
85
79
|
end
|
86
80
|
end
|
87
81
|
|
88
82
|
def op_request(op)
|
89
|
-
return if Acfs::Stub.enabled?
|
90
|
-
|
91
|
-
return unless req.is_a? Acfs::Request
|
92
|
-
req = prepare req
|
93
|
-
return unless req.is_a? Acfs::Request
|
94
|
-
yield req
|
83
|
+
return if Acfs::Stub.enabled? and Acfs::Stub.stubbed(op)
|
84
|
+
yield prepare op.service.prepare op.request
|
95
85
|
end
|
96
86
|
end
|
97
87
|
end
|
data/lib/acfs/service.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'acfs/service/middleware'
|
2
2
|
|
3
3
|
module Acfs
|
4
|
+
|
4
5
|
# User {Acfs::Service} to define your services. That includes
|
5
6
|
# an identity used to identify the service in configuration files
|
6
7
|
# and middlewares the service uses.
|
@@ -34,14 +35,14 @@ module Acfs
|
|
34
35
|
# @return [Location]
|
35
36
|
#
|
36
37
|
def location(resource_class, opts = {})
|
37
|
-
opts.reverse_merge! options
|
38
|
+
opts.reverse_merge! self.options
|
38
39
|
|
39
40
|
action = opts[:action] || :list
|
40
41
|
|
41
|
-
path = if opts[:path]
|
42
|
+
path = if Hash === opts[:path] && opts[:path].has_key?(action)
|
42
43
|
opts[:path].fetch(action)
|
43
44
|
else
|
44
|
-
path = if opts[:path]
|
45
|
+
path = if Hash === opts[:path]
|
45
46
|
opts[:path][:all].to_s
|
46
47
|
else
|
47
48
|
opts[:path].to_s
|
@@ -58,6 +59,7 @@ module Acfs
|
|
58
59
|
end
|
59
60
|
|
60
61
|
class << self
|
62
|
+
|
61
63
|
# @api public
|
62
64
|
#
|
63
65
|
# @overload identity()
|
@@ -81,7 +83,7 @@ module Acfs
|
|
81
83
|
#
|
82
84
|
def base_url
|
83
85
|
unless (base = Acfs::Configuration.current.locate identity)
|
84
|
-
raise ArgumentError
|
86
|
+
raise ArgumentError, "#{identity} not configured. Add `locate '#{identity.to_s.underscore}', 'http://service.url/'` to your configuration."
|
85
87
|
end
|
86
88
|
|
87
89
|
base.to_s
|
@@ -1,7 +1,6 @@
|
|
1
|
-
require 'acfs/service/middleware/stack'
|
2
|
-
|
3
1
|
module Acfs
|
4
2
|
class Service
|
3
|
+
|
5
4
|
# Module providing all function to register middlewares
|
6
5
|
# on services and process queued request through the
|
7
6
|
# middleware stack.
|
@@ -17,25 +16,28 @@ module Acfs
|
|
17
16
|
end
|
18
17
|
|
19
18
|
module ClassMethods
|
20
|
-
|
21
|
-
#
|
19
|
+
|
20
|
+
# @api public
|
22
21
|
#
|
23
|
-
#
|
22
|
+
# Register a new middleware to be used for this service.
|
24
23
|
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
24
|
+
# @example
|
25
|
+
# class MyService < Acfs::Service
|
26
|
+
# self.base_url = 'http://my.srv'
|
27
|
+
# use Acfs::Middleware::JsonDecoder
|
28
|
+
# end
|
30
29
|
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
# @return [undefined]
|
30
|
+
# @param [Class] klass Middleware class to instantiate and append to middleware stack.
|
31
|
+
# @param [Hash, Object] options Options to delegate to middleware class initializer.
|
32
|
+
# @return [undefined]
|
35
33
|
#
|
36
|
-
def use(klass,
|
37
|
-
|
38
|
-
|
34
|
+
def use(klass, options = {})
|
35
|
+
@middlewares ||= []
|
36
|
+
|
37
|
+
return false if @middlewares.include? klass
|
38
|
+
|
39
|
+
@middlewares << klass
|
40
|
+
@middleware = klass.new(middleware, options)
|
39
41
|
end
|
40
42
|
|
41
43
|
# @api private
|
@@ -45,11 +47,19 @@ module Acfs
|
|
45
47
|
# @return [#call]
|
46
48
|
#
|
47
49
|
def middleware
|
48
|
-
@middleware ||=
|
50
|
+
@middleware ||= proc { |request| request}
|
49
51
|
end
|
50
52
|
|
51
|
-
# @
|
52
|
-
|
53
|
+
# @api public
|
54
|
+
#
|
55
|
+
# Clear all registered middlewares.
|
56
|
+
#
|
57
|
+
# @return [undefined]
|
58
|
+
#
|
59
|
+
def clear
|
60
|
+
@middleware = nil
|
61
|
+
@middlewares = []
|
62
|
+
end
|
53
63
|
end
|
54
64
|
end
|
55
65
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
module Acfs
|
2
|
+
|
2
3
|
# Acfs SingletonResources
|
3
4
|
#
|
4
5
|
# Usage explanation:
|
@@ -13,6 +14,7 @@ module Acfs
|
|
13
14
|
# always only a single instance of the resource is being returned
|
14
15
|
#
|
15
16
|
class SingletonResource < Acfs::Resource
|
17
|
+
|
16
18
|
# @api public
|
17
19
|
#
|
18
20
|
# Destroy resource by sending a DELETE request.
|
data/lib/acfs/stub.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'rack/utils'
|
2
2
|
|
3
3
|
module Acfs
|
4
|
+
|
4
5
|
# Global handler for stubbing resources.
|
5
6
|
#
|
6
7
|
class Stub
|
@@ -13,7 +14,7 @@ module Acfs
|
|
13
14
|
|
14
15
|
@opts[:with].stringify_keys! if @opts[:with].is_a? Hash
|
15
16
|
@opts[:return].stringify_keys! if @opts[:return].is_a? Hash
|
16
|
-
@opts[:return].map! {|h| h.stringify_keys! if h.is_a? Hash } if @opts[:return].is_a? Array
|
17
|
+
@opts[:return].map! { |h| h.stringify_keys! if h.is_a? Hash } if @opts[:return].is_a? Array
|
17
18
|
end
|
18
19
|
|
19
20
|
def accept?(op)
|
@@ -21,21 +22,14 @@ module Acfs
|
|
21
22
|
|
22
23
|
params = op.full_params.stringify_keys
|
23
24
|
data = op.data.stringify_keys
|
24
|
-
|
25
|
-
|
26
|
-
return true if with.nil?
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
return true if with.reject {|_, v| v.nil? } == data.reject {|_, v| v.nil? }
|
33
|
-
false
|
34
|
-
when :inclusion
|
35
|
-
with.each_pair.all? do |k, v|
|
36
|
-
(params.key?(k) && params[k] == v) || (data.key?(k) && data[k] == v)
|
37
|
-
end
|
38
|
-
end
|
25
|
+
|
26
|
+
return true if opts[:with] == params || data == opts[:with]
|
27
|
+
return true if (opts[:with].nil? && params.empty? && data.empty?)
|
28
|
+
|
29
|
+
return true if opts[:with].reject { |k, v| v.nil? } == params.reject { |k, v| v.nil? }
|
30
|
+
return true if opts[:with].reject { |k, v| v.nil? } == data.reject { |k, v| v.nil? }
|
31
|
+
|
32
|
+
false
|
39
33
|
end
|
40
34
|
|
41
35
|
def calls
|
@@ -56,20 +50,17 @@ module Acfs
|
|
56
50
|
if err
|
57
51
|
raise_error op, err, opts[:return]
|
58
52
|
elsif data
|
59
|
-
data = data.call(op) if data.respond_to?(:call)
|
60
|
-
|
61
53
|
response = Acfs::Response.new op.request,
|
62
|
-
|
63
|
-
|
64
|
-
|
54
|
+
headers: opts[:headers] || {},
|
55
|
+
status: opts[:status] || 200,
|
56
|
+
data: data || {}
|
65
57
|
op.call data, response
|
66
58
|
else
|
67
|
-
raise ArgumentError
|
59
|
+
raise ArgumentError, 'Unsupported stub.'
|
68
60
|
end
|
69
61
|
end
|
70
62
|
|
71
63
|
private
|
72
|
-
|
73
64
|
def raise_error(op, name, data)
|
74
65
|
raise name if name.is_a? Class
|
75
66
|
data.stringify_keys! if data.respond_to? :stringify_keys!
|
@@ -78,12 +69,13 @@ module Acfs
|
|
78
69
|
end
|
79
70
|
|
80
71
|
class << self
|
72
|
+
|
81
73
|
# Stub a resource with given handler block. An already created handler
|
82
74
|
# for same resource class will be overridden.
|
83
75
|
#
|
84
|
-
def resource(klass, action, opts = {}, &
|
76
|
+
def resource(klass, action, opts = {}, &block)
|
85
77
|
action = action.to_sym
|
86
|
-
raise ArgumentError
|
78
|
+
raise ArgumentError, "Unknown action `#{action}`." unless ACTIONS.include? action
|
87
79
|
|
88
80
|
Stub.new(opts).tap do |stub|
|
89
81
|
stubs[klass] ||= {}
|
@@ -104,11 +96,11 @@ module Acfs
|
|
104
96
|
@enabled ||= false
|
105
97
|
end
|
106
98
|
|
107
|
-
def enable
|
99
|
+
def enable;
|
108
100
|
@enabled = true
|
109
101
|
end
|
110
102
|
|
111
|
-
def disable
|
103
|
+
def disable;
|
112
104
|
@enabled = false
|
113
105
|
end
|
114
106
|
|
@@ -126,7 +118,7 @@ module Acfs
|
|
126
118
|
return false unless (classes = stubs[op.resource])
|
127
119
|
return false unless (stubs = classes[op.action])
|
128
120
|
|
129
|
-
accepted_stubs = stubs.select {|stub| stub.accept? op }
|
121
|
+
accepted_stubs = stubs.select { |stub| stub.accept? op }
|
130
122
|
|
131
123
|
raise AmbiguousStubError.new stubs: accepted_stubs, operation: op if accepted_stubs.size > 1
|
132
124
|
|
@@ -150,9 +142,8 @@ module Acfs
|
|
150
142
|
end
|
151
143
|
|
152
144
|
private
|
153
|
-
|
154
145
|
def pretty_print
|
155
|
-
out =
|
146
|
+
out = String.new
|
156
147
|
stubs.each do |klass, actions|
|
157
148
|
out << ' ' << klass.name << ":\n"
|
158
149
|
actions.each do |action, stubs|
|
data/lib/acfs/util.rb
CHANGED
data/lib/acfs/version.rb
CHANGED
@@ -1,14 +1,12 @@
|
|
1
1
|
module Acfs
|
2
2
|
module VERSION
|
3
|
-
MAJOR =
|
4
|
-
MINOR =
|
3
|
+
MAJOR = 1
|
4
|
+
MINOR = 0
|
5
5
|
PATCH = 0
|
6
|
-
STAGE =
|
6
|
+
STAGE = 'dev'
|
7
7
|
|
8
8
|
STRING = [MAJOR, MINOR, PATCH, STAGE].reject(&:nil?).join('.')
|
9
9
|
|
10
|
-
def self.to_s
|
11
|
-
STRING
|
12
|
-
end
|
10
|
+
def self.to_s; STRING end
|
13
11
|
end
|
14
12
|
end
|
@@ -5,24 +5,16 @@ describe Acfs::Adapter::Typhoeus do
|
|
5
5
|
before { WebMock.allow_net_connect! }
|
6
6
|
|
7
7
|
it 'raises an error' do
|
8
|
-
request1 = Acfs::Request.new 'http://altimos.de/404.1' do |
|
8
|
+
request1 = Acfs::Request.new 'http://altimos.de/404.1' do |rsp|
|
9
9
|
raise '404-1'
|
10
10
|
end
|
11
|
-
request2 = Acfs::Request.new 'http://altimos.de/404.2' do |
|
11
|
+
request2 = Acfs::Request.new 'http://altimos.de/404.2' do |rsp|
|
12
12
|
raise '404-2'
|
13
13
|
end
|
14
14
|
adapter.queue request1
|
15
15
|
adapter.queue request2
|
16
16
|
|
17
|
-
expect
|
18
|
-
expect
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'passes arguments to typhoeus hydra' do
|
22
|
-
value = {key: 1, key2: 2}
|
23
|
-
|
24
|
-
expect(::Typhoeus::Hydra).to receive(:new).with(value)
|
25
|
-
|
26
|
-
described_class.new(**value).send :hydra
|
17
|
+
expect{ adapter.start }.to raise_error /404\-[12]/
|
18
|
+
expect{ adapter.start }.to_not raise_error
|
27
19
|
end
|
28
20
|
end
|