acfs 1.3.2 → 1.3.3

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.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. metadata +8 -141
  3. data/CHANGELOG.md +0 -325
  4. data/LICENSE +0 -22
  5. data/README.md +0 -334
  6. data/acfs.gemspec +0 -37
  7. data/lib/acfs.rb +0 -49
  8. data/lib/acfs/adapter/base.rb +0 -26
  9. data/lib/acfs/adapter/typhoeus.rb +0 -60
  10. data/lib/acfs/collection.rb +0 -27
  11. data/lib/acfs/collections/paginatable.rb +0 -75
  12. data/lib/acfs/configuration.rb +0 -113
  13. data/lib/acfs/errors.rb +0 -106
  14. data/lib/acfs/global.rb +0 -99
  15. data/lib/acfs/location.rb +0 -78
  16. data/lib/acfs/middleware/base.rb +0 -20
  17. data/lib/acfs/middleware/json.rb +0 -27
  18. data/lib/acfs/middleware/logger.rb +0 -23
  19. data/lib/acfs/middleware/msgpack.rb +0 -30
  20. data/lib/acfs/middleware/print.rb +0 -21
  21. data/lib/acfs/middleware/serializer.rb +0 -39
  22. data/lib/acfs/operation.rb +0 -81
  23. data/lib/acfs/request.rb +0 -36
  24. data/lib/acfs/request/callbacks.rb +0 -50
  25. data/lib/acfs/resource.rb +0 -37
  26. data/lib/acfs/resource/attributes.rb +0 -268
  27. data/lib/acfs/resource/attributes/base.rb +0 -28
  28. data/lib/acfs/resource/attributes/boolean.rb +0 -37
  29. data/lib/acfs/resource/attributes/date_time.rb +0 -31
  30. data/lib/acfs/resource/attributes/dict.rb +0 -37
  31. data/lib/acfs/resource/attributes/float.rb +0 -31
  32. data/lib/acfs/resource/attributes/integer.rb +0 -27
  33. data/lib/acfs/resource/attributes/list.rb +0 -34
  34. data/lib/acfs/resource/attributes/string.rb +0 -24
  35. data/lib/acfs/resource/attributes/uuid.rb +0 -47
  36. data/lib/acfs/resource/dirty.rb +0 -35
  37. data/lib/acfs/resource/initialization.rb +0 -29
  38. data/lib/acfs/resource/loadable.rb +0 -33
  39. data/lib/acfs/resource/locatable.rb +0 -128
  40. data/lib/acfs/resource/operational.rb +0 -22
  41. data/lib/acfs/resource/persistence.rb +0 -257
  42. data/lib/acfs/resource/query_methods.rb +0 -264
  43. data/lib/acfs/resource/service.rb +0 -42
  44. data/lib/acfs/resource/validation.rb +0 -37
  45. data/lib/acfs/response.rb +0 -28
  46. data/lib/acfs/response/formats.rb +0 -25
  47. data/lib/acfs/response/status.rb +0 -31
  48. data/lib/acfs/rspec.rb +0 -11
  49. data/lib/acfs/runner.rb +0 -97
  50. data/lib/acfs/service.rb +0 -91
  51. data/lib/acfs/service/middleware.rb +0 -56
  52. data/lib/acfs/service/middleware/stack.rb +0 -63
  53. data/lib/acfs/singleton_resource.rb +0 -83
  54. data/lib/acfs/stub.rb +0 -172
  55. data/lib/acfs/util.rb +0 -20
  56. data/lib/acfs/version.rb +0 -14
  57. data/lib/acfs/yard.rb +0 -5
  58. data/spec/acfs/adapter/typhoeus_spec.rb +0 -28
  59. data/spec/acfs/collection_spec.rb +0 -155
  60. data/spec/acfs/configuration_spec.rb +0 -51
  61. data/spec/acfs/global_spec.rb +0 -137
  62. data/spec/acfs/location_spec.rb +0 -23
  63. data/spec/acfs/middleware/json_spec.rb +0 -63
  64. data/spec/acfs/middleware/msgpack_spec.rb +0 -60
  65. data/spec/acfs/operation_spec.rb +0 -10
  66. data/spec/acfs/request/callbacks_spec.rb +0 -46
  67. data/spec/acfs/request_spec.rb +0 -77
  68. data/spec/acfs/resource/attributes/boolean_spec.rb +0 -56
  69. data/spec/acfs/resource/attributes/date_time_spec.rb +0 -49
  70. data/spec/acfs/resource/attributes/dict_spec.rb +0 -75
  71. data/spec/acfs/resource/attributes/float_spec.rb +0 -59
  72. data/spec/acfs/resource/attributes/integer_spec.rb +0 -34
  73. data/spec/acfs/resource/attributes/list_spec.rb +0 -58
  74. data/spec/acfs/resource/attributes/uuid_spec.rb +0 -40
  75. data/spec/acfs/resource/attributes_spec.rb +0 -179
  76. data/spec/acfs/resource/dirty_spec.rb +0 -47
  77. data/spec/acfs/resource/initialization_spec.rb +0 -30
  78. data/spec/acfs/resource/loadable_spec.rb +0 -20
  79. data/spec/acfs/resource/locatable_spec.rb +0 -116
  80. data/spec/acfs/resource/persistance_spec.rb +0 -316
  81. data/spec/acfs/resource/query_methods_spec.rb +0 -541
  82. data/spec/acfs/resource/validation_spec.rb +0 -127
  83. data/spec/acfs/response/formats_spec.rb +0 -50
  84. data/spec/acfs/response/status_spec.rb +0 -69
  85. data/spec/acfs/runner_spec.rb +0 -97
  86. data/spec/acfs/service/middleware_spec.rb +0 -33
  87. data/spec/acfs/service_spec.rb +0 -46
  88. data/spec/acfs/singleton_resource_spec.rb +0 -15
  89. data/spec/acfs/stub_spec.rb +0 -343
  90. data/spec/acfs_spec.rb +0 -203
  91. data/spec/fixtures/config.yml +0 -14
  92. data/spec/spec_helper.rb +0 -41
  93. data/spec/support/hash.rb +0 -9
  94. data/spec/support/response.rb +0 -10
  95. data/spec/support/service.rb +0 -91
  96. data/spec/support/shared/find_callbacks.rb +0 -48
@@ -1,91 +0,0 @@
1
- require 'acfs/service/middleware'
2
-
3
- module Acfs
4
- # User {Acfs::Service} to define your services. That includes
5
- # an identity used to identify the service in configuration files
6
- # and middlewares the service uses.
7
- #
8
- # Configure your service URLs in a YAML file loaded in an
9
- # initializer using the identity as a key:
10
- #
11
- # production:
12
- # services:
13
- # user_service_key: "http://users.service.org/base/path"
14
- #
15
- # @example
16
- # class UserService < Acfs::Service
17
- # identity :user_service_key
18
- #
19
- # use Acfs::Middleware::MessagePackDecoder
20
- # end
21
- #
22
- class Service
23
- attr_accessor :options
24
-
25
- include Service::Middleware
26
-
27
- # @api private
28
- #
29
- def initialize(options = {})
30
- @options = options
31
- end
32
-
33
- # @api private
34
- # @return [Location]
35
- #
36
- def location(resource_class, opts = {})
37
- opts.reverse_merge! options
38
-
39
- action = opts[:action] || :list
40
-
41
- path = if opts[:path].is_a?(Hash) && opts[:path].key?(action)
42
- opts[:path].fetch(action)
43
- else
44
- path = if opts[:path].is_a?(Hash)
45
- opts[:path][:all].to_s
46
- else
47
- opts[:path].to_s
48
- end
49
-
50
- path = (resource_class.name || 'class').pluralize.underscore if path.blank?
51
-
52
- resource_class.location_default_path(action, path.strip)
53
- end
54
-
55
- raise ArgumentError.new "Location for `#{action}' explicit disabled by set to nil." if path.nil?
56
-
57
- Location.new [self.class.base_url.to_s, path.to_s].join('/')
58
- end
59
-
60
- class << self
61
- # @api public
62
- #
63
- # @overload identity()
64
- # Return configured identity key or derive key from class name.
65
- #
66
- # @return [Symbol] Service identity key.
67
- #
68
- # @overload identity(identity)
69
- # Set identity key.
70
- #
71
- # @param [#to_s] identity New identity key.
72
- # @return [Symbol] New set identity key.
73
- #
74
- def identity(identity = nil)
75
- @identity = identity.to_s.to_sym unless identity.nil?
76
- @identity ||= name.to_sym
77
- end
78
-
79
- # @api private
80
- # @return [String]
81
- #
82
- def base_url
83
- unless (base = Acfs::Configuration.current.locate identity)
84
- raise ArgumentError.new "#{identity} not configured. Add `locate '#{identity.to_s.underscore}', 'http://service.url/'` to your configuration."
85
- end
86
-
87
- base.to_s
88
- end
89
- end
90
- end
91
- end
@@ -1,56 +0,0 @@
1
- require 'acfs/service/middleware/stack'
2
-
3
- module Acfs
4
- class Service
5
- # Module providing all function to register middlewares
6
- # on services and process queued request through the
7
- # middleware stack.
8
- #
9
- module Middleware
10
- extend ActiveSupport::Concern
11
-
12
- # @api private
13
- # @return [Request]
14
- #
15
- def prepare(request)
16
- self.class.middleware.call request
17
- end
18
-
19
- module ClassMethods
20
- # @!method use(klass, *args, &block)
21
- # @api public
22
- #
23
- # Register a new middleware to be used for this service.
24
- #
25
- # @example
26
- # class MyService < Acfs::Service
27
- # self.base_url = 'http://my.srv'
28
- # use Acfs::Middleware::JSON
29
- # end
30
- #
31
- # @param [Class] klass Middleware class to append
32
- # @param [Array<Object>] args Arguments passed to klass initialize
33
- # @param [Proc] block Block passed to klass initialize
34
- # @return [undefined]
35
- #
36
- def use(klass, *args, &block)
37
- # Backward compatible behavior
38
- middleware.insert(0, klass, *args, &block)
39
- end
40
-
41
- # @api private
42
- #
43
- # Return top most middleware.
44
- #
45
- # @return [#call]
46
- #
47
- def middleware
48
- @middleware ||= Stack.new
49
- end
50
-
51
- # @deprecated
52
- delegate :clear, to: :middleware
53
- end
54
- end
55
- end
56
- end
@@ -1,63 +0,0 @@
1
- module Acfs
2
- class Service
3
- module Middleware
4
- class Stack
5
- include Enumerable
6
-
7
- MUTEX = Mutex.new
8
- IDENTITY = -> (i) { i }
9
-
10
- attr_reader :middlewares
11
-
12
- def initialize
13
- @middlewares = []
14
- end
15
-
16
- def call(request)
17
- build! unless @app
18
-
19
- @app.call request
20
- end
21
-
22
- def build!
23
- return if @app
24
-
25
- MUTEX.synchronize do
26
- return if @app
27
-
28
- @app = build
29
- end
30
- end
31
-
32
- def build(app = IDENTITY)
33
- middlewares.reverse.inject(app) do |next_middleware, current_middleware|
34
- klass, args, block = current_middleware
35
- args ||= []
36
-
37
- if klass.is_a?(Class)
38
- klass.new(next_middleware, *args, &block)
39
- elsif klass.respond_to?(:call)
40
- lambda do |env|
41
- next_middleware.call(klass.call(env, *args))
42
- end
43
- else
44
- fail "Invalid middleware, doesn't respond to `call`: #{klass.inspect}"
45
- end
46
- end
47
- end
48
-
49
- def insert(index, klass, *args, &block)
50
- middlewares.insert(index, [klass, args, block])
51
- end
52
-
53
- def each
54
- middlewares.each { |x| yield x.first }
55
- end
56
-
57
- def clear
58
- middlewares.clear
59
- end
60
- end
61
- end
62
- end
63
- end
@@ -1,83 +0,0 @@
1
- module Acfs
2
- # Acfs SingletonResources
3
- #
4
- # Usage explanation:
5
- # Single.find => sends GET request to http://service:port/single
6
- # my_single.save => sends POST request to http://service:port/single
7
- # if my_single is a new object
8
- # or sends PUT request to http://service:port/single
9
- # if my_single has been requested before
10
- # my_single.delete => sends DELETE request to http://service:port/single
11
- #
12
- # SingletonResources do not support the Resource method :all, since
13
- # always only a single instance of the resource is being returned
14
- #
15
- class SingletonResource < Acfs::Resource
16
- # @api public
17
- #
18
- # Destroy resource by sending a DELETE request.
19
- # Will raise an error in case something goes wrong.
20
- #
21
- # Deleting a resource is a synchronous operation.
22
- #
23
- # @raise [Acfs::ErroneousResponse]
24
- # If remote service respond with not successful response.
25
- # @return [undefined]
26
- # @see #delete
27
- #
28
- def delete!(opts = {})
29
- opts[:params] ||= {}
30
-
31
- operation :delete, opts do |data|
32
- update_with data
33
- freeze
34
- end
35
- end
36
-
37
- # @api private
38
- def need_primary_key?
39
- false
40
- end
41
-
42
- class << self
43
- # @api public
44
- #
45
- # @overload find(id, opts = {})
46
- # Find a singleton resource, optionally with params.
47
- #
48
- # @example
49
- # single = Singleton.find # Will query `http://base.url/singletons/`
50
- #
51
- # @param [ Hash ] opts Additional options.
52
- # @option opts [ Hash ] :params Additional parameters added to request.
53
- #
54
- # @yield [ resource ] Callback block to be executed after
55
- # resource was fetched successfully.
56
- # @yieldparam resource [ self ] Fetched resources.
57
- #
58
- # @return [ self ] Resource object.
59
- #
60
- def find(*attrs, &block)
61
- find_single nil, params: attrs.extract_options!, &block
62
- end
63
-
64
- # @api public
65
- #
66
- # Undefined, raises NoMethodError.
67
- # A singleton always only returns one object, therefore the
68
- # methods :all and :where are not defined.
69
- # :find_by is not defined on singletons, use :find instead
70
- #
71
- def all
72
- raise ::Acfs::UnsupportedOperation.new
73
- end
74
- alias_method :find_by, :all
75
- alias_method :find_by!, :all
76
-
77
- # @api private
78
- def location_default_path(_, path)
79
- path
80
- end
81
- end
82
- end
83
- end
@@ -1,172 +0,0 @@
1
- require 'rack/utils'
2
-
3
- module Acfs
4
- # Global handler for stubbing resources.
5
- #
6
- class Stub
7
- ACTIONS = [:read, :create, :update, :delete, :list]
8
-
9
- attr_reader :opts
10
-
11
- def initialize(opts)
12
- @opts = opts
13
-
14
- @opts[:with].stringify_keys! if @opts[:with].is_a? Hash
15
- @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
- end
18
-
19
- def accept?(op)
20
- return opts[:with].call op if opts[:with].respond_to? :call
21
-
22
- params = op.full_params.stringify_keys
23
- data = op.data.stringify_keys
24
- with = opts[:with]
25
-
26
- return true if with.nil?
27
-
28
- case opts.fetch(:match, :inclusion)
29
- when :legacy
30
- return true if with.empty? && params.empty? && data.empty?
31
- return true if with.reject {|_, v| v.nil? } == params.reject {|_, v| v.nil? }
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
39
- end
40
-
41
- def calls
42
- @calls ||= []
43
- end
44
-
45
- def called?(count = nil)
46
- count = count.count if count.respond_to? :count # For `5.times` Enumerators
47
- count.nil? ? calls.any? : calls.size == count
48
- end
49
-
50
- def call(op)
51
- calls << op
52
-
53
- err = opts[:raise]
54
- data = opts[:return]
55
-
56
- if err
57
- raise_error op, err, opts[:return]
58
- elsif data
59
- data = data.call(op) if data.respond_to?(:call)
60
-
61
- response = Acfs::Response.new op.request,
62
- headers: opts[:headers] || {},
63
- status: opts[:status] || 200,
64
- data: data || {}
65
- op.call data, response
66
- else
67
- raise ArgumentError.new 'Unsupported stub.'
68
- end
69
- end
70
-
71
- private
72
-
73
- def raise_error(op, name, data)
74
- raise name if name.is_a? Class
75
- data.stringify_keys! if data.respond_to? :stringify_keys!
76
-
77
- op.handle_failure ::Acfs::Response.new op.request, status: Rack::Utils.status_code(name), data: data
78
- end
79
-
80
- class << self
81
- # Stub a resource with given handler block. An already created handler
82
- # for same resource class will be overridden.
83
- #
84
- def resource(klass, action, opts = {}, &_block)
85
- action = action.to_sym
86
- raise ArgumentError.new "Unknown action `#{action}`." unless ACTIONS.include? action
87
-
88
- Stub.new(opts).tap do |stub|
89
- stubs[klass] ||= {}
90
- stubs[klass][action] ||= []
91
- stubs[klass][action] << stub
92
- end
93
- end
94
-
95
- def allow_requests=(allow)
96
- @allow_requests = allow ? true : false
97
- end
98
-
99
- def allow_requests?
100
- @allow_requests ||= false
101
- end
102
-
103
- def enabled?
104
- @enabled ||= false
105
- end
106
-
107
- def enable
108
- @enabled = true
109
- end
110
-
111
- def disable
112
- @enabled = false
113
- end
114
-
115
- # Clear all stubs.
116
- #
117
- def clear(klass = nil)
118
- klass.nil? ? stubs.clear : stubs[klass].try(:clear)
119
- end
120
-
121
- def stubs
122
- @stubs ||= {}
123
- end
124
-
125
- def stub_for(op)
126
- return false unless (classes = stubs[op.resource])
127
- return false unless (stubs = classes[op.action])
128
-
129
- accepted_stubs = stubs.select {|stub| stub.accept? op }
130
-
131
- raise AmbiguousStubError.new stubs: accepted_stubs, operation: op if accepted_stubs.size > 1
132
-
133
- accepted_stubs.first
134
- end
135
-
136
- def stubbed(op)
137
- stub = stub_for op
138
- unless stub
139
- return false if allow_requests?
140
- raise RealRequestsNotAllowedError.new <<-MSG.strip.gsub(/^[ ]{12}/, '')
141
- No stub found for `#{op.action}' on `#{op.resource.name}' with params `#{op.full_params.inspect}', data `#{op.data.inspect}' and id `#{op.id}'.
142
-
143
- Available stubs:
144
- #{pretty_print}
145
- MSG
146
- end
147
-
148
- stub.call op
149
- true
150
- end
151
-
152
- private
153
-
154
- def pretty_print
155
- out = ''
156
- stubs.each do |klass, actions|
157
- out << ' ' << klass.name << ":\n"
158
- actions.each do |action, stubs|
159
- stubs.each do |stub|
160
- out << " #{action}"
161
- out << " with #{stub.opts[:with].inspect}" if stub.opts[:with]
162
- out << " and return #{stub.opts[:return].inspect}" if stub.opts[:return]
163
- out << " and raise #{stub.opts[:raise].inspect}" if stub.opts[:raise]
164
- out << "\n"
165
- end
166
- end
167
- end
168
- out
169
- end
170
- end
171
- end
172
- end