api_client 0.5.24-java → 0.5.25-java

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/lib/api_client/base.rb +77 -0
  4. data/lib/api_client/connection/abstract.rb +81 -0
  5. data/lib/api_client/connection/basic.rb +129 -0
  6. data/lib/api_client/connection/json.rb +14 -0
  7. data/lib/api_client/connection/middlewares/request/json.rb +34 -0
  8. data/lib/api_client/connection/middlewares/request/logger.rb +64 -0
  9. data/lib/api_client/connection/middlewares/request/oauth.rb +22 -0
  10. data/lib/api_client/connection/oauth.rb +18 -0
  11. data/lib/api_client/errors.rb +31 -0
  12. data/lib/api_client/mixins/configuration.rb +24 -0
  13. data/lib/api_client/mixins/connection_hooks.rb +24 -0
  14. data/lib/api_client/mixins/delegation.rb +23 -0
  15. data/lib/api_client/mixins/inheritance.rb +19 -0
  16. data/lib/api_client/mixins/instantiation.rb +29 -0
  17. data/lib/api_client/mixins/scoping.rb +49 -0
  18. data/lib/api_client/resource/base.rb +67 -0
  19. data/lib/api_client/resource/name_resolver.rb +37 -0
  20. data/lib/api_client/resource/scope.rb +73 -0
  21. data/lib/api_client/scope.rb +125 -0
  22. data/lib/api_client/utils.rb +18 -0
  23. data/lib/api_client/version.rb +3 -0
  24. data/spec/api_client/base/connection_hook_spec.rb +18 -0
  25. data/spec/api_client/base/delegation_spec.rb +15 -0
  26. data/spec/api_client/base/inheritance_spec.rb +44 -0
  27. data/spec/api_client/base/instantiation_spec.rb +55 -0
  28. data/spec/api_client/base/marshalling_spec.rb +33 -0
  29. data/spec/api_client/base/parsing_spec.rb +38 -0
  30. data/spec/api_client/base/scoping_spec.rb +60 -0
  31. data/spec/api_client/base_spec.rb +107 -0
  32. data/spec/api_client/connection/abstract_spec.rb +21 -0
  33. data/spec/api_client/connection/basic_spec.rb +191 -0
  34. data/spec/api_client/connection/oauth_spec.rb +27 -0
  35. data/spec/api_client/connection/request/json_spec.rb +30 -0
  36. data/spec/api_client/connection/request/logger_spec.rb +18 -0
  37. data/spec/api_client/connection/request/oauth_spec.rb +26 -0
  38. data/spec/api_client/resource/base_spec.rb +97 -0
  39. data/spec/api_client/resource/name_spec.rb +19 -0
  40. data/spec/api_client/resource/scope_spec.rb +122 -0
  41. data/spec/api_client/scope_spec.rb +204 -0
  42. data/spec/api_client/utils_spec.rb +32 -0
  43. data/spec/support/matchers.rb +5 -0
  44. metadata +62 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 86de6b224c93faa28969412f7d2121a53a613739959da4d0993b7e3143c2ccb3
4
- data.tar.gz: 5e51da700d497e3444e515c166459f4485e180b5705a04af3212750e3d924937
3
+ metadata.gz: a6aee99219c58bf02f29e11548ea72dd56ad18fba534f326626147053148f81b
4
+ data.tar.gz: 767a054b03b9ea36501f7dbdd71bc898d65d5db26b09962dbb1d4e4283c60203
5
5
  SHA512:
6
- metadata.gz: 511be118de39ceefb8cf983e9798fec9de476f82c78e77e2b8924d97a2740f3e1b9daef81a763678407a08cb158de6a77d8b5ee5fdc9398fa363fbc9cd9a1fba
7
- data.tar.gz: bb9d276c8ce9c2442acee7b085801e8e728e5898a668678a37725b6ce747f7bd9a6855c46eb210009fa19b272437970ccbda655fec0ea569e47556478033bf88
6
+ metadata.gz: ae82881334deac2a7d458e4618d6c7502580e4a070202e04836b8166603a42bba48d6abe047efda1eaff153f540993c1ccb0109a275eebffcf35e38a01985abb
7
+ data.tar.gz: 78193bbf66f1e8c8d961f83b39ed86a23348cca2c56c235e1f896ae8b19ec676aaa0f678602c00b5a239e4c0555814d7b1b3a6b9432a3d3bc3414dda1d5ad834
@@ -1,3 +1,7 @@
1
+ # 0.5.25
2
+
3
+ * Fix broken gem build (gemspec files)
4
+
1
5
  # 0.5.23
2
6
 
3
7
  * Add support for HTTP status code: 423 Locked
@@ -0,0 +1,77 @@
1
+ module ApiClient
2
+
3
+ class Base < Hashie::Mash
4
+
5
+ extend ApiClient::Mixins::Inheritance
6
+ extend ApiClient::Mixins::Instantiation
7
+ extend ApiClient::Mixins::Scoping
8
+ extend ApiClient::Mixins::ConnectionHooks
9
+
10
+ class << self
11
+ extend ApiClient::Mixins::Delegation
12
+ extend ApiClient::Mixins::Configuration
13
+
14
+ delegate :fetch, :get, :put, :post, :patch, :delete, :headers, :endpoint, :options, :adapter, :params, :raw, :to => :scope
15
+
16
+ dsl_accessor :format, :namespace
17
+
18
+ def subkey_class
19
+ Hashie::Mash
20
+ end
21
+
22
+ def parse(response)
23
+ if response.is_a?(Faraday::Response)
24
+ return nil if response.status == 204
25
+ response = response.body
26
+ end
27
+
28
+ if self.format == :json
29
+ MultiJson.load(response)
30
+ elsif self.format == :xml
31
+ MultiXml.parse(response)
32
+ else
33
+ response
34
+ end
35
+ end
36
+
37
+ end
38
+
39
+ # Defaults
40
+ self.format :json
41
+
42
+ def id
43
+ self['id']
44
+ end
45
+
46
+ def inspect
47
+ attributes = []
48
+ attr_keys = self.keys - ['id']
49
+ attributes.push "id: #{self.id}" if self.id
50
+ attr_keys.each do |key|
51
+ attributes.push("#{key}: #{self[key].inspect}")
52
+ end
53
+ "#<#{self.class} #{attributes.join(', ')}>"
54
+ end
55
+
56
+ private
57
+ def method_missing(method_name, *args, &blk)
58
+ if respond_to?(method_name) || has_special_ending?(method_name)
59
+ super
60
+ elsif use_strict_reader?(method_name)
61
+ fetch(method_name)
62
+ else
63
+ super
64
+ end
65
+ end
66
+
67
+ def use_strict_reader?(method_name)
68
+ respond_to?(:strict_attr_reader?) &&
69
+ self.strict_attr_reader? &&
70
+ method_name != :to_ary
71
+ end
72
+
73
+ def has_special_ending?(name)
74
+ name.to_s =~ /[?=]$/
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,81 @@
1
+ module ApiClient
2
+
3
+ module Connection
4
+
5
+ class Abstract
6
+
7
+ attr_accessor :endpoint, :handler, :options
8
+
9
+ def initialize(endpoint, options = {})
10
+ raise "Cannot instantiate abstract class" if self.class == ApiClient::Connection::Abstract
11
+ @endpoint = endpoint
12
+ @options = options
13
+ create_handler
14
+ end
15
+
16
+ def create_handler
17
+ end
18
+
19
+ #### ApiClient::Connection::Abstract#get
20
+ # Performs a GET request
21
+ # Accepts three parameters:
22
+ #
23
+ # * path - the path the request should go to
24
+ # * data - (optional) the query, passed as a hash and converted into query params
25
+ # * headers - (optional) headers sent along with the request
26
+ #
27
+ def get(path, data = {}, headers = {})
28
+ end
29
+
30
+ #### ApiClient::Connection::Abstract#post
31
+ # Performs a POST request
32
+ # Accepts three parameters:
33
+ #
34
+ # * path - the path request should go to
35
+ # * data - (optional) data sent in the request
36
+ # * headers - (optional) headers sent along in the request
37
+ #
38
+ def post(path, data = {}, headers = {})
39
+ end
40
+
41
+ #### ApiClient::Connection::Abstract#patch
42
+ # Performs a PATCH request
43
+ # Accepts three parameters:
44
+ #
45
+ # * path - the path request should go to
46
+ # * data - (optional) data sent in the request
47
+ # * headers - (optional) headers sent along in the request
48
+ #
49
+ def patch(path, data = {}, headers = {})
50
+ end
51
+
52
+ #### ApiClient::Connection::Abstract#put
53
+ # Performs a PUT request
54
+ # Accepts three parameters:
55
+ #
56
+ # * path - the path request should go to
57
+ # * data - (optional) data sent in the request
58
+ # * headers - (optional) headers sent along in the request
59
+ #
60
+ def put(path, data = {}, headers = {})
61
+ end
62
+
63
+ #### FS::Connection#delete
64
+ # Performs a DELETE request
65
+ # Accepts three parameters:
66
+ #
67
+ # * path - the path request should go to
68
+ # * data - (optional) the query, passed as a hash and converted into query params
69
+ # * headers - (optional) headers sent along in the request
70
+ #
71
+ def delete(path, data = {}, headers = {})
72
+ end
73
+
74
+ def inspect
75
+ "#<#{self.class} endpoint: \"#{endpoint}\">"
76
+ end
77
+ alias :to_s :inspect
78
+
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,129 @@
1
+ module ApiClient
2
+
3
+ module Connection
4
+
5
+ class Basic < Abstract
6
+
7
+ def create_handler
8
+ # Create and memoize the connection object
9
+ # The empty block is necessary as we don't want Faraday to
10
+ # initialize itself, we build our own stack in finalize_handler
11
+ @handler = Faraday.new(@endpoint, @options[:faraday] || {}) do end
12
+ finalize_handler
13
+ end
14
+
15
+ def finalize_handler
16
+ @handler.use Middlewares::Request::Logger, ApiClient.logger if ApiClient.logger
17
+ @handler.use Faraday::Request::UrlEncoded
18
+ @handler.adapter Faraday.default_adapter
19
+ end
20
+
21
+ #### ApiClient::Connection::Abstract#get
22
+ # Performs a GET request
23
+ # Accepts three parameters:
24
+ #
25
+ # * path - the path the request should go to
26
+ # * data - (optional) the query, passed as a hash and converted into query params
27
+ # * headers - (optional) headers sent along with the request
28
+ #
29
+ def get(path, data = {}, headers = {})
30
+ exec_request(:get, path, data, headers)
31
+ end
32
+
33
+ #### ApiClient::Connection::Abstract#post
34
+ # Performs a POST request
35
+ # Accepts three parameters:
36
+ #
37
+ # * path - the path request should go to
38
+ # * data - (optional) data sent in the request
39
+ # * headers - (optional) headers sent along in the request
40
+ #
41
+ # This method automatically adds the application token header
42
+ def post(path, data = {}, headers = {})
43
+ exec_request(:post, path, data, headers)
44
+ end
45
+
46
+ #### ApiClient::Connection::Abstract#patch
47
+ # Performs a PATCH request
48
+ # Accepts three parameters:
49
+ #
50
+ # * path - the path request should go to
51
+ # * data - (optional) data sent in the request
52
+ # * headers - (optional) headers sent along in the request
53
+ #
54
+ # This method automatically adds the application token header
55
+ def patch(path, data = {}, headers = {})
56
+ exec_request(:patch, path, data, headers)
57
+ end
58
+
59
+ #### ApiClient::Connection::Abstract#put
60
+ # Performs a PUT request
61
+ # Accepts three parameters:
62
+ #
63
+ # * path - the path request should go to
64
+ # * data - (optional) data sent in the request
65
+ # * headers - (optional) headers sent along in the request
66
+ #
67
+ # This method automatically adds the application token header
68
+ def put(path, data = {}, headers = {})
69
+ exec_request(:put, path, data, headers)
70
+ end
71
+
72
+ #### FS::Connection#delete
73
+ # Performs a DELETE request
74
+ # Accepts three parameters:
75
+ #
76
+ # * path - the path request should go to
77
+ # * data - (optional) the query, passed as a hash and converted into query params
78
+ # * headers - (optional) headers sent along in the request
79
+ #
80
+ # This method automatically adds the application token header
81
+ def delete(path, data = {}, headers = {})
82
+ exec_request(:delete, path, data, headers)
83
+ end
84
+
85
+ private
86
+
87
+ def exec_request(method, path, data, headers)
88
+ response = @handler.send(method, path, data, headers)
89
+ request = { :method => method, :path => path, :data => data}
90
+ handle_response(request, response)
91
+ rescue Faraday::Error::ConnectionFailed => e
92
+ raise ApiClient::Errors::ConnectionFailed.new(e.message, request, response)
93
+ end
94
+
95
+ def handle_response(request, response)
96
+ raise ApiClient::Errors::ConnectionFailed.new(nil, request, response) unless response
97
+ case response.status
98
+ when 401
99
+ raise ApiClient::Errors::Unauthorized.new(nil, request, response)
100
+ when 403
101
+ raise ApiClient::Errors::Forbidden.new(nil, request, response)
102
+ when 404
103
+ raise ApiClient::Errors::NotFound.new(nil, request, response)
104
+ when 400
105
+ raise ApiClient::Errors::BadRequest.new(nil, request, response)
106
+ when 406
107
+ raise ApiClient::Errors::Unsupported.new(nil, request, response)
108
+ when 409
109
+ raise ApiClient::Errors::Conflict.new(nil, request, response)
110
+ when 410
111
+ raise ApiClient::Errors::Gone.new(nil, request, response)
112
+ when 422
113
+ raise ApiClient::Errors::UnprocessableEntity.new(response.body, request, response)
114
+ when 423
115
+ raise ApiClient::Errors::Locked.new(response.body, request, response)
116
+ when 429
117
+ raise ApiClient::Errors::TooManyRequests.new(response.body, request, response)
118
+ when 300..399
119
+ raise ApiClient::Errors::Redirect.new(response['Location'], request, response)
120
+ when 500..599
121
+ raise ApiClient::Errors::ServerError.new(nil, request, response)
122
+ else
123
+ response
124
+ end
125
+ end
126
+
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,14 @@
1
+ # Exactly like Basic, but uses JSON encoding for request body
2
+ # if applicable
3
+ module ApiClient
4
+ module Connection
5
+ class Json < Basic
6
+ def finalize_handler
7
+ @handler.use Middlewares::Request::Logger, ApiClient.logger if ApiClient.logger
8
+ @handler.use Middlewares::Request::Json
9
+ @handler.use Faraday::Request::UrlEncoded
10
+ @handler.adapter Faraday.default_adapter
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,34 @@
1
+ class ApiClient::Connection::Middlewares::Request::Json < Faraday::Middleware
2
+ CONTENT_TYPE = "Content-Type".freeze
3
+
4
+ class << self
5
+ attr_accessor :mime_type
6
+ end
7
+ self.mime_type = "application/json".freeze
8
+
9
+ def call(env)
10
+ match_content_type(env) do |data|
11
+ params = Faraday::Utils::ParamsHash[data]
12
+ env[:body] = MultiJson.dump(params)
13
+ end
14
+ @app.call env
15
+ end
16
+
17
+ def match_content_type(env)
18
+ if process_request?(env)
19
+ env[:request_headers][CONTENT_TYPE] ||= self.class.mime_type
20
+ yield env[:body] unless env[:body].respond_to?(:to_str)
21
+ end
22
+ end
23
+
24
+ def process_request?(env)
25
+ type = request_type(env)
26
+ env[:body] and (type.empty? or type == self.class.mime_type)
27
+ end
28
+
29
+ def request_type(env)
30
+ type = env[:request_headers][CONTENT_TYPE].to_s
31
+ type = type.split(";", 2).first if type.index(";")
32
+ type
33
+ end
34
+ end
@@ -0,0 +1,64 @@
1
+ require "logger"
2
+
3
+ class ApiClient::Connection::Middlewares::Request::Logger < Faraday::Middleware
4
+ def call(env)
5
+ debug_lines = []
6
+ should_log_details = @logger.level <= ::Logger::DEBUG
7
+
8
+ gather_request_debug_lines(env, debug_lines) if should_log_details
9
+
10
+ start = CurrentTimestamp.milis
11
+ response = @app.call(env)
12
+ taken_sec = (CurrentTimestamp.milis - start) / 1000.0
13
+
14
+ gather_response_debug_lines(response, taken_sec, debug_lines) if response && should_log_details
15
+
16
+ if should_log_details
17
+ debug_lines.each { |line| line.encode!("UTF-8", invalid: :replace, undef: :replace) }
18
+ @logger.debug { debug_lines.join("\n") }
19
+ else
20
+ @logger.info { "#{env[:method].to_s.upcase} #{env[:url]}: #{"%.4f" % taken_sec} seconds" }
21
+ end
22
+
23
+ response
24
+ end
25
+
26
+ def initialize(app, logger = nil)
27
+ @logger = logger || ::Logger.new(STDOUT)
28
+ @app = app
29
+ end
30
+
31
+ private
32
+
33
+ def gather_request_debug_lines(env, debug_lines)
34
+ debug_lines << "> #{env[:method].to_s.upcase} #{env[:url]}"
35
+ env[:request_headers].each { |k, v| debug_lines << "> #{k}: #{v}" }
36
+ debug_lines << "> "
37
+ debug_lines << "> #{env[:body]}\n> " if env[:body] && env[:body] != ""
38
+ debug_lines
39
+ end
40
+
41
+ def gather_response_debug_lines(response, taken_sec, debug_lines)
42
+ debug_lines << "< responded in #{"%.4f" % taken_sec} seconds with HTTP #{response.status}"
43
+ response.headers.each { |k, v| debug_lines << "< #{k}: #{v}" }
44
+ debug_lines << "< "
45
+ debug_lines << "< #{response.body}\n> " if response.body && response.body != ""
46
+ debug_lines
47
+ end
48
+
49
+ class CurrentTimestamp
50
+ class << self
51
+ version = RUBY_VERSION.split('.').map(&:to_i)
52
+
53
+ if (version[0] < 2) || (version[0] == 2 && version[1] < 2)
54
+ def milis
55
+ (Time.now.to_f * 1000).to_i
56
+ end
57
+ else
58
+ def milis
59
+ Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,22 @@
1
+ # Borrowed from https://github.com/pengwynn/faraday_middleware/blob/master/lib/faraday/request/oauth.rb
2
+ class ApiClient::Connection::Middlewares::Request::OAuth < Faraday::Middleware
3
+
4
+ dependency 'simple_oauth'
5
+
6
+ def call(env)
7
+ params = env[:body] || {}
8
+ signature_params = params.reject{ |k,v| v.respond_to?(:content_type) }
9
+
10
+ header = SimpleOAuth::Header.new(env[:method], env[:url], signature_params, @options || {})
11
+
12
+ env[:request_headers]['Authorization'] = header.to_s
13
+ env[:request_headers]['User-Agent'] = "ApiClient gem v#{ApiClient::VERSION}"
14
+
15
+ @app.call(env)
16
+ end
17
+
18
+ def initialize(app, options = {})
19
+ @app, @options = app, options
20
+ end
21
+
22
+ end