garage_client 2.3.3 → 2.4.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 01091c33f1717e47d9c9924aafdf5847b365db08
4
- data.tar.gz: ab7c2d9b32b4231d4cb4d94620dc4c0adfc14f7e
2
+ SHA256:
3
+ metadata.gz: 580980067ed04267e85d03e5a9f0fdfef39ebac8142e9110a9bc42f622e2fb02
4
+ data.tar.gz: 59bc77a7d6499d2f22e7bb3434b0756d2315abfe104cbd883bef653fe2cda52b
5
5
  SHA512:
6
- metadata.gz: 8cbdf835d83bf950e9efa95d38bea94c2df496886fb5495e098e0648fb4092f34faba05acabd7c743e64d0892bcd90f16f9e49119a1115bae926e33091720b25
7
- data.tar.gz: 26a64ed17b4ae544897eea66ca80072ec9ec63760c213a4f05b24cc36ed66de55e57488f39c1224adee73625879fd8c93bf23292dcd297aef9af84af56ed2bf4
6
+ metadata.gz: 8a7cba1f1cba35a7bf16bb0c2f00bbcb046a759ed372bddea33878a355bef8a7e39f8b9914645d2d25e86a36e66544632122b186b966afc7f37527d469fb3518
7
+ data.tar.gz: e58414b3291d9b60dae0d7d82f516e7b587b9005facc1b2f889a6fa0f3632111109f2cac3e434c68409765f7d31a8c7f4f12bc9f0e7c4a8de45b0622581f6c43
@@ -2,8 +2,10 @@ language: ruby
2
2
 
3
3
  rvm:
4
4
  - ruby-head
5
- - 2.3.1
6
- - 2.2.5
5
+ - 2.5.3
6
+ - 2.4.5
7
+ - 2.3.8
8
+ - 2.2.10
7
9
  matrix:
8
10
  allow_failures:
9
11
  - rvm: "ruby-head"
@@ -1,3 +1,20 @@
1
+ ## 2.4.4
2
+ - Remove activesupport dependency
3
+ - Fix request ID not being propagated
4
+
5
+ ## 2.4.3
6
+ - Support query methods on GarageClient::Resource
7
+ - Use Module#module_parent_name for Rails 6.0
8
+
9
+ ## 2.4.2
10
+ - Fixes for latest aws-xray gem. Require `aws/xray/faraday`.
11
+
12
+ ## 2.4.1
13
+ - Record http request/response even if API returns errors.
14
+
15
+ ## 2.4.0
16
+ - Support distributed tracing.
17
+
1
18
  ## 2.3.3
2
19
  - Fix a bug to not resolve application name when garage_client-rails is bundled.
3
20
  - Stop to support ruby version < 2.2.2.
data/README.md CHANGED
@@ -93,10 +93,12 @@ There are the following options:
93
93
  - `adapter` - faraday adapter for http client (default: `:net_http`)
94
94
  - `cacher` - take a cacher class in which caching logic is defined (default: nil)
95
95
  - `name` - Client's application name, which is embedded in User-Agent by default (default: nil. For Rails, `Rails.application.class.parent_name.underscore` is set by default.)
96
+ - `name` must be configured globally.
96
97
  - `headers` - default http headers (default: `{ "Accept" => "application/json", "User-Agent" => "garage_client #{VERSION} #{name}" }`)
97
98
  - `endpoint` - Garage application API endpoint (default: nil)
98
99
  - `path_prefix` - API path prefix (default: `'/v1'`)
99
100
  - `verbose` - Enable verbose http log (default: `false`)
101
+ - `tracing` - (client instance only) Enable distributed tracing and set a logical name of the down stream service. See detail in "Tracing" section below.
100
102
 
101
103
  You can configure the global settings:
102
104
 
@@ -115,7 +117,6 @@ client = GarageClient::Client.new(
115
117
  adapter: :test,
116
118
  headers: { "Host" => "garage.example.com" },
117
119
  endpoint: "http://localhost:3000",
118
- name: 'my-awesome-client',
119
120
  path_prefix: "/v2",
120
121
  verbose: true,
121
122
  )
@@ -199,3 +200,17 @@ end
199
200
 
200
201
  GarageClient::Client.new(cacher: MyCacher)
201
202
  ```
203
+
204
+ ## Tracing
205
+ GarageClient supports distributed tracing. To enable tracing, specify `tracing.tracer` option for `GarageClient::Client` instance.
206
+ Choose one of supported tracers from below. If you want to add new tracer, please give us a PR.
207
+
208
+ ### aws-xray
209
+ Bundle [aws-xray](https://github.com/taiki45/aws-xray) gem in your `Gemfile`, then configure `GarageClient::Client` instance with `tracing.service` option:
210
+
211
+ ```ruby
212
+ require 'aws/xray/faraday'
213
+ GarageClient::Client.new(..., tracing: { tracer: 'aws-xray', service: 'user' })
214
+ ```
215
+
216
+ `service` will be `name` of the sub segments.
@@ -16,14 +16,11 @@ Gem::Specification.new do |s|
16
16
  s.authors = ['Cookpad Inc.']
17
17
  s.email = ['kaihatsu@cookpad.com']
18
18
 
19
- s.add_dependency 'activesupport', '> 3.2.0'
20
19
  s.add_dependency 'faraday', '>= 0.8.0'
21
20
  s.add_dependency 'faraday_middleware'
22
21
  s.add_dependency 'hashie', '>= 1.2.0'
23
22
  s.add_dependency 'link_header'
24
23
 
25
- s.add_dependency 'system_timer' if RUBY_VERSION < '1.9'
26
-
27
24
  s.add_development_dependency "rails"
28
25
  s.add_development_dependency "rake", ">= 0.9.2"
29
26
  s.add_development_dependency "rspec"
@@ -32,4 +29,5 @@ Gem::Specification.new do |s|
32
29
  s.add_development_dependency "pry"
33
30
  # Until bug fixed: https://github.com/colszowka/simplecov/issues/281
34
31
  s.add_development_dependency "simplecov", "~> 0.7.1"
32
+ s.add_development_dependency "aws-xray", ">= 0.30.0"
35
33
  end
@@ -1,4 +1,3 @@
1
- require 'active_support/all'
2
1
  require 'faraday'
3
2
  require 'faraday_middleware'
4
3
 
@@ -11,7 +11,13 @@ module GarageClient
11
11
  if response
12
12
  # Faraday::Response#marshal_dump is drop request object and url
13
13
  # https://github.com/lostisland/faraday/blob/edacd5eb57ea13accab3097649690ae5f48f421a/lib/faraday/response.rb#L74
14
- response.env.merge!(@env) {|_, self_val, other_val| self_val || other_val }
14
+ #
15
+ # XXX: We can't use #merge! here because Faraday::Env does not implement
16
+ # the method as same as Hash#merge! with Faraday v0.12.1.
17
+ @env.each do |k, v|
18
+ original = response.env[k]
19
+ response.env[k] = v if !original && v
20
+ end
15
21
  else
16
22
  response = yield
17
23
  store.write(key, response, options) if written_to_cache?
@@ -20,6 +20,7 @@ module GarageClient
20
20
  property :path_prefix
21
21
  property :verbose
22
22
 
23
+ # @option opts [Hash] :tracing enable tracing. See README for detail.
23
24
  def initialize(options = {})
24
25
  require_necessaries(options)
25
26
  @options = options
@@ -69,6 +70,19 @@ module GarageClient
69
70
  builder.use GarageClient::Request::JsonEncoded
70
71
  builder.use GarageClient::Request::PropagateRequestId
71
72
 
73
+ # Tracing Middlewares
74
+ if options[:tracing]
75
+ case options[:tracing][:tracer]
76
+ when 'aws-xray'
77
+ service = options[:tracing][:service]
78
+ raise 'Configure target service name with `tracing.service`' unless service
79
+ require 'aws/xray/faraday'
80
+ builder.use Aws::Xray::Faraday, service
81
+ else
82
+ raise "`tracing` option specified but GarageClient does not support the tracer: #{options[:tracing][:tracer]}"
83
+ end
84
+ end
85
+
72
86
  # Low-level Middlewares
73
87
  apply_auth_middleware builder
74
88
  builder.adapter(*adapter)
@@ -85,9 +99,6 @@ module GarageClient
85
99
  if !options[:endpoint] && !default_options.endpoint
86
100
  raise "Missing endpoint configuration"
87
101
  end
88
- if !options[:name] && !default_options.name
89
- raise "Missing name configuration"
90
- end
91
102
  end
92
103
 
93
104
  def default_options
@@ -9,7 +9,13 @@ module GarageClient
9
9
  def self.set_default_name
10
10
  unless GarageClient.configuration.options[:name]
11
11
  GarageClient.configure do |c|
12
- c.name = ::Rails.application.class.parent_name.underscore
12
+ klass = ::Rails.application.class
13
+ parent_name = if klass.respond_to?(:module_parent_name)
14
+ klass.module_parent_name
15
+ else
16
+ klass.parent_name
17
+ end
18
+ c.name = parent_name.underscore
13
19
  end
14
20
  end
15
21
  end
@@ -2,8 +2,8 @@ module GarageClient
2
2
  module Request
3
3
  class PropagateRequestId < Faraday::Middleware
4
4
  def call(env)
5
- if Thread.current[:request_id] && !env[:request_headers]["HTTP_X_REQUEST_ID"]
6
- env[:request_headers]["HTTP_X_REQUEST_ID"] = Thread.current[:request_id]
5
+ if Thread.current[:request_id] && !env[:request_headers]["X-Request-Id"]
6
+ env[:request_headers]["X-Request-Id"] = Thread.current[:request_id]
7
7
  end
8
8
  @app.call(env)
9
9
  end
@@ -41,6 +41,8 @@ module GarageClient
41
41
  else
42
42
  value
43
43
  end
44
+ elsif query_method?(name)
45
+ data.__send__(name)
44
46
  elsif links.include?(name)
45
47
  path = data._links[name].href
46
48
  client.get(path, *args)
@@ -53,11 +55,20 @@ module GarageClient
53
55
  end
54
56
 
55
57
  def respond_to_missing?(name, include_private)
56
- !!(properties.include?(name) || links.include?(name) || nested_resource_creation_method?(name))
58
+ !!(properties.include?(name) || query_method?(name) || links.include?(name) || nested_resource_creation_method?(name))
57
59
  end
58
60
 
59
61
  def nested_resource_creation_method?(name)
60
62
  !!(name =~ /\Acreate_(.+)\z/ && links.include?($1.to_sym))
61
63
  end
64
+
65
+ private
66
+
67
+ def query_method?(name)
68
+ if name.to_s.end_with?('?')
69
+ key = name.to_s[0..-2]
70
+ properties.include?(key.to_sym)
71
+ end
72
+ end
62
73
  end
63
74
  end
@@ -1,3 +1,3 @@
1
1
  module GarageClient
2
- VERSION = '2.3.3'
2
+ VERSION = '2.4.4'
3
3
  end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+ require 'aws/xray'
3
+
4
+ RSpec.describe 'Tracing support' do
5
+ context 'when `tracing` option is specified' do
6
+ around do |ex|
7
+ Aws::Xray.config.client_options = { sock: io }
8
+ Aws::Xray.config.sampling_rate = 1
9
+ Aws::Xray.trace(name: 'test-app') { ex.run }
10
+ end
11
+
12
+ let(:io) { Aws::Xray::TestSocket.new }
13
+ let(:client) do
14
+ GarageClient::Client.new(
15
+ adapter: [:test, stubs],
16
+ endpoint: 'http://127.0.0.1',
17
+ tracing: {
18
+ tracer: 'aws-xray',
19
+ service: 'target-app',
20
+ },
21
+ )
22
+ end
23
+ let(:stubs) do
24
+ Faraday::Adapter::Test::Stubs.new do |stub|
25
+ stub.get('/campaign') { |env| [200, {'Content-Type' => 'application/json'}, '{"campaign": false}'] }
26
+ end
27
+ end
28
+
29
+ specify 'client enables tracing and sends trace data to a local agent' do
30
+ res = client.get('/campaign')
31
+ expect(res.body.campaign).to eq(false)
32
+
33
+ io.rewind
34
+ sent_jsons = io.read.split("\n")
35
+ expect(sent_jsons.size).to eq(2)
36
+ body = JSON.parse(sent_jsons[1])
37
+ expect(body['name']).to eq('target-app')
38
+ end
39
+
40
+ context 'API returns client errors' do
41
+ let(:stubs) do
42
+ Faraday::Adapter::Test::Stubs.new do |stub|
43
+ stub.get('/campaign') { |env| [404, {'Content-Type' => 'application/json'}, '{"error": "not_found"}'] }
44
+ end
45
+ end
46
+
47
+ specify 'client traces HTTP request and response and records errors' do
48
+ expect { client.get('/campaign') }.to raise_error(GarageClient::NotFound)
49
+
50
+ io.rewind
51
+ sent_jsons = io.read.split("\n")
52
+ expect(sent_jsons.size).to eq(2)
53
+ body = JSON.parse(sent_jsons[1])
54
+ expect(body['name']).to eq('target-app')
55
+ expect(body['error']).to eq(true)
56
+ expect(body['http']['request']['method']).to eq('GET')
57
+ expect(body['http']['response']['status']).to eq(404)
58
+ end
59
+ end
60
+
61
+ context 'API returns server errors' do
62
+ let(:stubs) do
63
+ Faraday::Adapter::Test::Stubs.new do |stub|
64
+ stub.get('/campaign') { |env| [500, {'Content-Type' => 'application/json'}, '{"error": "internal_server_error"}'] }
65
+ end
66
+ end
67
+
68
+ specify 'client traces HTTP request and response and marks as fault' do
69
+ expect { client.get('/campaign') }.to raise_error(GarageClient::InternalServerError)
70
+
71
+ io.rewind
72
+ sent_jsons = io.read.split("\n")
73
+ expect(sent_jsons.size).to eq(2)
74
+ body = JSON.parse(sent_jsons[1])
75
+ expect(body['name']).to eq('target-app')
76
+ expect(body['error']).to eq(false)
77
+ expect(body['fault']).to eq(true)
78
+ expect(body['http']['request']['method']).to eq('GET')
79
+ expect(body['http']['response']['status']).to eq(500)
80
+ end
81
+ end
82
+ end
83
+ end
@@ -64,10 +64,6 @@ describe GarageClient::Cachers::Base do
64
64
 
65
65
  # Check dump data. Because cache data not broken on the version up of faraday.
66
66
  describe "check Faraday::Response marshal" do
67
- specify do
68
- expect(Faraday::VERSION).to be < "1.0.0", "This spec is no longer needed. Delete this 'describe' section!"
69
- end
70
-
71
67
  context "v0.9.1's marshal data" do
72
68
  let(:res) do
73
69
  Marshal.load(File.read(File.expand_path('../fixtures/faraday_0.9.1_response.dump', __dir__)))
@@ -75,7 +71,7 @@ describe GarageClient::Cachers::Base do
75
71
 
76
72
  it "load data" do
77
73
  expect(res).to be_instance_of Faraday::Response
78
- expect(res.env[:body]).to eq fixture("example.yaml")[:body]
74
+ expect(res.env[:body]).to eq fixture("example.yaml")["body"]
79
75
  end
80
76
  end
81
77
 
@@ -86,7 +82,7 @@ describe GarageClient::Cachers::Base do
86
82
 
87
83
  it "load data" do
88
84
  expect(res).to be_instance_of Faraday::Response
89
- expect(res.env[:body]).to eq fixture("example.yaml")[:body]
85
+ expect(res.env[:body]).to eq fixture("example.yaml")["body"]
90
86
  end
91
87
  end
92
88
  end
@@ -13,7 +13,7 @@ describe GarageClient::Request::PropagateRequestId do
13
13
  end
14
14
 
15
15
  it 'sends request_id via header' do
16
- stub_get("/examples").with(headers: { 'HTTP_X_REQUEST_ID' => 'request_id' })
16
+ stub_get("/examples").with(headers: { 'X-Request-Id' => 'request_id' })
17
17
  expect { client.get("/examples") }.not_to raise_error
18
18
  end
19
19
 
@@ -24,7 +24,7 @@ describe GarageClient::Request::PropagateRequestId do
24
24
 
25
25
  it 'does not send request_id via header' do
26
26
  stub_get("/examples").with do |request|
27
- !request.headers.include?('HTTP_X_REQUEST_ID')
27
+ !request.headers.include?('X-Request-Id')
28
28
  end
29
29
  expect { client.get("/examples") }.not_to raise_error
30
30
  end
@@ -32,11 +32,11 @@ describe GarageClient::Request::PropagateRequestId do
32
32
 
33
33
  context 'if already has request_id' do
34
34
  let(:client) do
35
- GarageClient::Client.new(headers: { 'HTTP_X_REQUEST_ID' => 'another_id' })
35
+ GarageClient::Client.new(headers: { 'X-Request-Id' => 'another_id' })
36
36
  end
37
37
 
38
38
  it 'does not overwrite request_id' do
39
- stub_get("/examples").with(headers: { 'HTTP_X_REQUEST_ID' => 'another_id' })
39
+ stub_get("/examples").with(headers: { 'X-Request-Id' => 'another_id' })
40
40
  expect { client.get("/examples") }.not_to raise_error
41
41
  end
42
42
  end
@@ -84,6 +84,12 @@ describe GarageClient::Resource do
84
84
  resource.user.should be_kind_of(GarageClient::Resource)
85
85
  end
86
86
  end
87
+
88
+ context 'with property query' do
89
+ it 'returns presence' do
90
+ resource.name?.should == true
91
+ end
92
+ end
87
93
  end
88
94
 
89
95
  describe 'link' do
@@ -47,7 +47,7 @@ end
47
47
  def fixture(file)
48
48
  prefix = File.expand_path('../fixtures', __FILE__)
49
49
  path = File.join(prefix, file)
50
- HashWithIndifferentAccess.new(YAML.load_file(path))
50
+ YAML.load_file(path)
51
51
  end
52
52
 
53
53
  RSpec.configure do |config|
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: garage_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.3
4
+ version: 2.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cookpad Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-18 00:00:00.000000000 Z
11
+ date: 2021-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: activesupport
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">"
18
- - !ruby/object:Gem::Version
19
- version: 3.2.0
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">"
25
- - !ruby/object:Gem::Version
26
- version: 3.2.0
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: faraday
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -178,6 +164,20 @@ dependencies:
178
164
  - - "~>"
179
165
  - !ruby/object:Gem::Version
180
166
  version: 0.7.1
167
+ - !ruby/object:Gem::Dependency
168
+ name: aws-xray
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: 0.30.0
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: 0.30.0
181
181
  description: Ruby client library for the Garage API
182
182
  email:
183
183
  - kaihatsu@cookpad.com
@@ -210,6 +210,7 @@ files:
210
210
  - lib/garage_client/response/raise_http_exception.rb
211
211
  - lib/garage_client/version.rb
212
212
  - spec/features/configuration_spec.rb
213
+ - spec/features/tracing_spec.rb
213
214
  - spec/fixtures/example.yaml
214
215
  - spec/fixtures/examples.yaml
215
216
  - spec/fixtures/examples_dictionary.yaml
@@ -245,13 +246,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
245
246
  - !ruby/object:Gem::Version
246
247
  version: '0'
247
248
  requirements: []
248
- rubyforge_project:
249
- rubygems_version: 2.5.1
249
+ rubygems_version: 3.1.4
250
250
  signing_key:
251
251
  specification_version: 4
252
252
  summary: Ruby client library for the Garage API
253
253
  test_files:
254
254
  - spec/features/configuration_spec.rb
255
+ - spec/features/tracing_spec.rb
255
256
  - spec/fixtures/example.yaml
256
257
  - spec/fixtures/examples.yaml
257
258
  - spec/fixtures/examples_dictionary.yaml