nxt_http_client 0.2.9 → 0.3.0

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
2
  SHA256:
3
- metadata.gz: d0f3125c7163d56e5656ded82aeb30d4d52982f6a4f7cccfdc0fab3c43114af3
4
- data.tar.gz: 4a818011bbf91ad2a9240b8f16bf0224c6b009b8147e5430972762ac0a9bd964
3
+ metadata.gz: 22aa2f16ec7170133779ae75097fdd0c164a3a3a793a98f8d565d6ddfd2ca96c
4
+ data.tar.gz: c21b929937fe483cd7d56754d50ba37ae9d83b10bb120e5b772b425f3a04e559
5
5
  SHA512:
6
- metadata.gz: 145ccc07ab888597f7dca77c568cab3117580d97bd47bd343119a0b89d302e5c8263fe4513544595f48cf0944648d7dc2a8e51933cb62a8a720c2c0569d03210
7
- data.tar.gz: 030f4cdd69ed052bcafe85e246ac580a1468c96d6f6c70c567c4d918aa0a36048316ccb9ebf04f95d06ecea74ea9279a04506da4bd1b4992c35b47366f9bada5
6
+ metadata.gz: be208ed0c5e3b617d48dcca068c8c588e9748ab34f23a538d9039f6b7ed1649dd96f54ec0dbb716de3c823b5f6ff452b06eadfd79a85514f97106d4fef0d7fd4
7
+ data.tar.gz: 0743b9d3371ff51381c8a0f5b45547bc86302f0282e8064fe7a93f268e195361ca055ed7a085df38b82653909542488cd6de02a2d5b95abcf547068215097278
@@ -0,0 +1,57 @@
1
+ # Ruby CircleCI 2.0 configuration file
2
+ #
3
+ # Check https://circleci.com/docs/2.0/language-ruby/ for more details
4
+ #
5
+ version: 2
6
+ jobs:
7
+ build:
8
+ docker:
9
+ - image: circleci/ruby:2.7.0-node
10
+ - image: circleci/redis:5.0.4
11
+ environment:
12
+ BUNDLER_VERSION: 2.1.4
13
+
14
+ working_directory: ~/repo
15
+
16
+ steps:
17
+ - checkout
18
+
19
+ # Download and cache dependencies
20
+ - restore_cache:
21
+ keys:
22
+ - v1-dependencies-{{ checksum "Gemfile.lock" }}
23
+
24
+ - run: gem install bundler --version $BUNDLER_VERSION
25
+
26
+ - run:
27
+ name: install dependencies
28
+ command: |
29
+ bundle install --jobs=4 --retry=3 --path vendor/bundle
30
+
31
+ - save_cache:
32
+ paths:
33
+ - ./vendor/bundle
34
+ key: v1-dependencies-{{ checksum "Gemfile.lock" }}
35
+
36
+ # run tests!
37
+ - run:
38
+ name: run tests
39
+ command: |
40
+ mkdir /tmp/test-results
41
+ TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | \
42
+ circleci tests split --split-by=timings)"
43
+
44
+ bundle exec rspec \
45
+ --format progress \
46
+ --format RspecJunitFormatter \
47
+ --out /tmp/test-results/rspec.xml \
48
+ --format progress \
49
+ $TEST_FILES
50
+
51
+ # collect reports
52
+ - store_artifacts:
53
+ path: /tmp/rspec/
54
+ destination: rspec
55
+
56
+ - store_test_results:
57
+ path: /tmp/rspec/
@@ -0,0 +1,8 @@
1
+ # v0.2.10 2020-03-10
2
+
3
+ ### Refactored
4
+
5
+ - [internal] Added CHANGELOG.MD
6
+ - Refactored a bit
7
+
8
+ [Compare v0.2.9...v0.2.10](https://github.com/nxt-insurance/nxt_http_client/compare/v0.2.9...v0.2.10)
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nxt_http_client (0.2.9)
4
+ nxt_http_client (0.3.0)
5
5
  activesupport (~> 6.0.0)
6
6
  nxt_registry
7
7
  typhoeus
@@ -9,38 +9,38 @@ PATH
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- activesupport (6.0.2.1)
12
+ activesupport (6.0.3.2)
13
13
  concurrent-ruby (~> 1.0, >= 1.0.2)
14
14
  i18n (>= 0.7, < 2)
15
15
  minitest (~> 5.1)
16
16
  tzinfo (~> 1.1)
17
- zeitwerk (~> 2.2)
17
+ zeitwerk (~> 2.2, >= 2.2.2)
18
18
  addressable (2.7.0)
19
19
  public_suffix (>= 2.0.2, < 5.0)
20
20
  coderay (1.1.2)
21
- concurrent-ruby (1.1.5)
21
+ concurrent-ruby (1.1.6)
22
22
  crack (0.4.3)
23
23
  safe_yaml (~> 1.0.0)
24
24
  diff-lcs (1.3)
25
25
  ethon (0.12.0)
26
26
  ffi (>= 1.3.0)
27
- ffi (1.12.1)
28
- hashdiff (1.0.0)
29
- i18n (1.8.2)
27
+ ffi (1.12.2)
28
+ hashdiff (1.0.1)
29
+ i18n (1.8.5)
30
30
  concurrent-ruby (~> 1.0)
31
- method_source (0.9.2)
32
- minitest (5.14.0)
33
- nxt_registry (0.1.4)
31
+ method_source (1.0.0)
32
+ minitest (5.14.1)
33
+ nxt_registry (0.2.0)
34
34
  activesupport
35
35
  nxt_vcr_harness (0.1.3)
36
36
  rspec (~> 3.0)
37
37
  vcr (~> 5.0)
38
- pry (0.12.2)
39
- coderay (~> 1.1.0)
40
- method_source (~> 0.9.0)
41
- public_suffix (4.0.1)
42
- rake (10.5.0)
43
- redis (4.1.3)
38
+ pry (0.13.1)
39
+ coderay (~> 1.1)
40
+ method_source (~> 1.0)
41
+ public_suffix (4.0.3)
42
+ rake (13.0.1)
43
+ redis (4.2.1)
44
44
  rspec (3.9.0)
45
45
  rspec-core (~> 3.9.0)
46
46
  rspec-expectations (~> 3.9.0)
@@ -54,18 +54,20 @@ GEM
54
54
  diff-lcs (>= 1.2.0, < 2.0)
55
55
  rspec-support (~> 3.9.0)
56
56
  rspec-support (3.9.0)
57
+ rspec_junit_formatter (0.4.1)
58
+ rspec-core (>= 2, < 4, != 2.12.0)
57
59
  safe_yaml (1.0.5)
58
60
  thread_safe (0.3.6)
59
- typhoeus (1.3.1)
61
+ typhoeus (1.4.0)
60
62
  ethon (>= 0.9.0)
61
- tzinfo (1.2.6)
63
+ tzinfo (1.2.7)
62
64
  thread_safe (~> 0.1)
63
- vcr (5.0.0)
64
- webmock (3.7.6)
65
+ vcr (5.1.0)
66
+ webmock (3.8.3)
65
67
  addressable (>= 2.3.6)
66
68
  crack (>= 0.3.2)
67
69
  hashdiff (>= 0.4.0, < 2.0.0)
68
- zeitwerk (2.2.2)
70
+ zeitwerk (2.4.0)
69
71
 
70
72
  PLATFORMS
71
73
  ruby
@@ -75,9 +77,10 @@ DEPENDENCIES
75
77
  nxt_http_client!
76
78
  nxt_vcr_harness
77
79
  pry
78
- rake (~> 10.0)
80
+ rake (~> 13.0)
79
81
  redis
80
82
  rspec (~> 3.0)
83
+ rspec_junit_formatter
81
84
  vcr
82
85
  webmock
83
86
 
data/README.md CHANGED
@@ -43,6 +43,7 @@ class MyClient < NxtHttpClient
43
43
 
44
44
  register_response_handler do |handler|
45
45
  handler.on(:error) do |response|
46
+ Raven.extra_context(error_details: error.to_h) # call error.to_h to inspect request and response
46
47
  raise StandardError, "I can't handle this: #{response.code}"
47
48
  end
48
49
  end
@@ -1,51 +1,22 @@
1
1
  module NxtHttpClient
2
2
  class Client
3
3
  extend ClientDsl
4
- CACHE_STRATEGIES = %w[global thread]
4
+ CACHE_STRATEGIES = %w[global thread].freeze
5
+ HTTP_METHODS = %w[get post patch put delete head].freeze
5
6
 
6
7
  def build_request(url, **opts)
7
- base_url = opts.delete(:base_url) || default_config.base_url
8
- url = [base_url, url].reject(&:blank?).join('/')
9
-
10
- duplicated_slashes = url.match(/([^:]\/{2,})/)
11
- duplicated_slashes && duplicated_slashes.captures.each do |capture|
12
- url.gsub!(capture, "#{capture[0]}/")
13
- end
14
-
15
- opts = default_config.request_options.with_indifferent_access.deep_merge(opts.with_indifferent_access)
16
- opts[:headers] ||= {}
17
-
18
- if default_config.x_request_id_proc
19
- opts[:headers]['X-Request-ID'] ||= default_config.x_request_id_proc.call
20
- end
21
-
22
- if opts[:cache] ||= false
23
- strategy = opts.delete(:cache)
24
-
25
- case strategy.to_s
26
- when 'thread'
27
- cache_key = Thread.current[:nxt_http_client_cache_key] ||= "#{SecureRandom.base58}::#{DateTime.current}"
28
- opts[:headers].reverse_merge!(cache_key: cache_key)
29
- when 'global'
30
- opts[:headers].delete(:cache_key)
31
- else
32
- raise ArgumentError, "Cache strategy unknown: #{strategy}. Options are #{CACHE_STRATEGIES}"
33
- end
34
- end
8
+ url = build_url(opts, url)
9
+ opts = build_headers(opts)
35
10
 
36
11
  Typhoeus::Request.new(url, **opts.symbolize_keys)
37
12
  end
38
13
 
39
- def fire(url = '', **opts, &block)
40
- # calling_method = caller_locations(1,1)[0].label
41
- response_handler = opts.fetch(:response_handler) do
42
- dup_handler_from_class || NxtHttpClient::ResponseHandler.new
43
- end
14
+ delegate :before_fire_callback, :after_fire_callback, to: :class
44
15
 
16
+ def fire(url = '', **opts, &block)
17
+ response_handler = opts.fetch(:response_handler) { dup_handler_from_class || NxtHttpClient::ResponseHandler.new }
45
18
  response_handler.configure(&block) if block_given?
46
- request = build_request(url, opts.except(:response_handler))
47
-
48
- before_fire_callback = self.class.before_fire_callback
19
+ request = build_request(url, **opts.except(:response_handler))
49
20
  before_fire_callback && instance_exec(self, request, response_handler, &before_fire_callback)
50
21
 
51
22
  if response_handler.callbacks['headers']
@@ -61,20 +32,17 @@ module NxtHttpClient
61
32
  end
62
33
 
63
34
  result = nil
64
- error = nil
35
+ current_error = nil
65
36
 
66
37
  request.on_complete do |response|
67
- callback = response_handler.callback_for_response(response)
68
- result = callback && instance_exec(response, &callback) || response
69
- rescue StandardError => e
70
- error = e
38
+ result = callback_or_response(response, response_handler)
39
+ rescue StandardError => error
40
+ current_error = error
71
41
  ensure
72
- after_fire_callback = self.class.after_fire_callback
73
-
74
42
  if after_fire_callback
75
- result = instance_exec(self, request, response, result, error, &after_fire_callback)
43
+ result = instance_exec(self, request, response, result, current_error, &after_fire_callback)
76
44
  else
77
- result || (raise error)
45
+ result || (raise current_error)
78
46
  end
79
47
  end
80
48
 
@@ -83,10 +51,32 @@ module NxtHttpClient
83
51
  result
84
52
  end
85
53
 
86
- %w[get post patch put delete head].each do |method|
54
+ HTTP_METHODS.each do |method|
87
55
  define_method method do |url = '', **opts, &block|
88
- fire(url, opts.reverse_merge(method: method), &block)
56
+ fire(url, **opts.reverse_merge(method: method), &block)
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ def build_url(opts, url)
63
+ base_url = opts.delete(:base_url) || default_config.base_url
64
+ url = [base_url, url].reject(&:blank?).join('/')
65
+
66
+ url_without_duplicated_hashes(url)
67
+ url
68
+ end
69
+
70
+ def build_headers(opts)
71
+ opts = default_config.request_options.with_indifferent_access.deep_merge(opts.with_indifferent_access)
72
+ opts[:headers] ||= {}
73
+
74
+ if default_config.x_request_id_proc
75
+ opts[:headers]['X-Request-ID'] ||= default_config.x_request_id_proc.call
89
76
  end
77
+
78
+ build_cache_header(opts)
79
+ opts
90
80
  end
91
81
 
92
82
  def dup_handler_from_class
@@ -96,5 +86,35 @@ module NxtHttpClient
96
86
  def default_config
97
87
  self.class.default_config
98
88
  end
89
+
90
+ def build_cache_header(opts)
91
+ if opts[:cache] ||= false
92
+ strategy = opts.delete(:cache)
93
+
94
+ case strategy.to_s
95
+ when 'thread'
96
+ cache_key = Thread.current[:nxt_http_client_cache_key] ||= "#{SecureRandom.base58}::#{DateTime.current}"
97
+ opts[:headers].reverse_merge!(cache_key: cache_key)
98
+ when 'global'
99
+ opts[:headers].delete(:cache_key)
100
+ else
101
+ raise ArgumentError, "Cache strategy unknown: #{strategy}. Options are #{CACHE_STRATEGIES}"
102
+ end
103
+ end
104
+ end
105
+
106
+ def url_without_duplicated_hashes(url)
107
+ duplicated_slashes = url.match(/([^:]\/{2,})/)
108
+ duplicated_slashes && duplicated_slashes.captures.each do |capture|
109
+ url.gsub!(capture, "#{capture[0]}/")
110
+ end
111
+
112
+ url
113
+ end
114
+
115
+ def callback_or_response(response, response_handler)
116
+ callback = response_handler.callback_for_response(response)
117
+ callback && instance_exec(response, &callback) || response
118
+ end
99
119
  end
100
120
  end
@@ -1,9 +1,7 @@
1
1
  module NxtHttpClient
2
2
  module ClientDsl
3
3
  def configure(opts = {}, &block)
4
- opts.each do |k,v|
5
- default_config.send(k, v)
6
- end
4
+ opts.each { |k, v| default_config.send(k, v) }
7
5
  default_config.tap { |d| block.call(d) }
8
6
  default_config
9
7
  end
@@ -13,7 +11,7 @@ module NxtHttpClient
13
11
  end
14
12
 
15
13
  def before_fire_callback
16
- @before_fire ||= dup_instance_variable_from_ancestor_chain(:@before_fire_callback)
14
+ @before_fire_callback ||= dup_instance_variable_from_ancestor_chain(:@before_fire_callback)
17
15
  end
18
16
 
19
17
  def after_fire(&block)
@@ -44,21 +42,16 @@ module NxtHttpClient
44
42
  end
45
43
 
46
44
  def instance_variable_from_ancestor_chain(instance_variable_name)
47
- client = client_ancestors.find do |client|
48
- client.instance_variable_get(instance_variable_name)
49
- end
45
+ client = client_ancestors.find { |c| c.instance_variable_get(instance_variable_name) }
50
46
 
51
47
  client.instance_variable_get(instance_variable_name)
52
48
  end
53
49
 
54
50
  def dup_instance_variable_from_ancestor_chain(instance_variable_name)
55
51
  result = instance_variable_from_ancestor_chain(instance_variable_name).dup
52
+ return result unless block_given?
56
53
 
57
- if block_given?
58
- result || yield
59
- else
60
- result
61
- end
54
+ result || yield
62
55
  end
63
56
  end
64
57
  end
@@ -1,5 +1,5 @@
1
1
  module NxtHttpClient
2
- CONFIGURABLE_OPTIONS = %i[request_options base_url x_request_id_proc]
2
+ CONFIGURABLE_OPTIONS = %i[request_options base_url x_request_id_proc].freeze
3
3
 
4
4
  DefaultConfig = Struct.new('DefaultConfig', *CONFIGURABLE_OPTIONS) do
5
5
  def initialize(request_options: ActiveSupport::HashWithIndifferentAccess.new, base_url: '', x_request_id_proc: nil)
@@ -2,9 +2,10 @@ module NxtHttpClient
2
2
  class Error < StandardError
3
3
  def initialize(response)
4
4
  @response = response.blank? ? Typhoeus::Response.new : response
5
+ @id = SecureRandom.uuid
5
6
  end
6
7
 
7
- attr_reader :response
8
+ attr_reader :response, :id
8
9
 
9
10
  def to_s
10
11
  "NxtHttpClient::Error::#{response_code}"
@@ -12,6 +13,7 @@ module NxtHttpClient
12
13
 
13
14
  def to_h
14
15
  {
16
+ id: id,
15
17
  url: url,
16
18
  response_code: response_code,
17
19
  request_options: request_options,
@@ -4,20 +4,14 @@ module NxtHttpClient
4
4
  include NxtRegistry
5
5
 
6
6
  def initialize
7
- @callbacks = registry(
8
- :callbacks,
9
- call: false,
10
- on_key_already_registered: ->(key) { raise_callback_already_registered(key) }
11
- )
12
-
13
7
  @result = nil
14
8
  end
15
9
 
16
10
  attr_accessor :result
17
- attr_reader :callbacks
18
11
 
19
12
  def eval_callback(target, key, response)
20
13
  return unless callbacks.resolve!(key)
14
+
21
15
  target.instance_exec(response, &callbacks.resolve(key))
22
16
  end
23
17
 
@@ -37,8 +31,8 @@ module NxtHttpClient
37
31
  register_callback(code, overwrite: true, &block)
38
32
  end
39
33
 
40
- alias_method :on, :register_callback
41
- alias_method :on!, :register_callback!
34
+ alias on register_callback
35
+ alias on! register_callback!
42
36
 
43
37
  def callback_for_response(response)
44
38
  key_from_response = response.code.to_s
@@ -50,10 +44,18 @@ module NxtHttpClient
50
44
  end
51
45
 
52
46
  first_matching_key && callbacks[first_matching_key] ||
53
- response.success? && callbacks['success'] ||
54
- response.timed_out? && callbacks['timed_out'] ||
55
- !response.success? && callbacks['error'] ||
56
- callbacks['others']
47
+ response.success? && callbacks['success'] ||
48
+ response.timed_out? && callbacks['timed_out'] ||
49
+ !response.success? && callbacks['error'] ||
50
+ callbacks['others']
51
+ end
52
+
53
+ def callbacks
54
+ @callbacks ||= NxtRegistry::Registry.new(
55
+ :callbacks,
56
+ call: false,
57
+ on_key_already_registered: ->(key) { raise_callback_already_registered(key) }
58
+ )
57
59
  end
58
60
 
59
61
  private
@@ -1,3 +1,3 @@
1
1
  module NxtHttpClient
2
- VERSION = "0.2.9"
2
+ VERSION = '0.3.0'
3
3
  end
@@ -40,11 +40,12 @@ Gem::Specification.new do |spec|
40
40
  spec.add_dependency 'nxt_registry'
41
41
 
42
42
  spec.add_development_dependency 'bundler', '~> 1.17'
43
- spec.add_development_dependency 'rake', '~> 10.0'
43
+ spec.add_development_dependency 'rake', '~> 13.0'
44
44
  spec.add_development_dependency 'rspec', '~> 3.0'
45
45
  spec.add_development_dependency 'pry'
46
46
  spec.add_development_dependency 'vcr'
47
47
  spec.add_development_dependency 'webmock'
48
48
  spec.add_development_dependency 'nxt_vcr_harness'
49
49
  spec.add_development_dependency 'redis'
50
+ spec.add_development_dependency 'rspec_junit_formatter'
50
51
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nxt_http_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.9
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andreas Robecke
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: exe
13
13
  cert_chain: []
14
- date: 2020-01-15 00:00:00.000000000 Z
14
+ date: 2020-07-30 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: typhoeus
@@ -75,14 +75,14 @@ dependencies:
75
75
  requirements:
76
76
  - - "~>"
77
77
  - !ruby/object:Gem::Version
78
- version: '10.0'
78
+ version: '13.0'
79
79
  type: :development
80
80
  prerelease: false
81
81
  version_requirements: !ruby/object:Gem::Requirement
82
82
  requirements:
83
83
  - - "~>"
84
84
  - !ruby/object:Gem::Version
85
- version: '10.0'
85
+ version: '13.0'
86
86
  - !ruby/object:Gem::Dependency
87
87
  name: rspec
88
88
  requirement: !ruby/object:Gem::Requirement
@@ -167,6 +167,20 @@ dependencies:
167
167
  - - ">="
168
168
  - !ruby/object:Gem::Version
169
169
  version: '0'
170
+ - !ruby/object:Gem::Dependency
171
+ name: rspec_junit_formatter
172
+ requirement: !ruby/object:Gem::Requirement
173
+ requirements:
174
+ - - ">="
175
+ - !ruby/object:Gem::Version
176
+ version: '0'
177
+ type: :development
178
+ prerelease: false
179
+ version_requirements: !ruby/object:Gem::Requirement
180
+ requirements:
181
+ - - ">="
182
+ - !ruby/object:Gem::Version
183
+ version: '0'
170
184
  description: NxtHttpClinet allows you to easily create and configure http clients.
171
185
  email:
172
186
  - a.robecke@getsafe.de
@@ -174,9 +188,11 @@ executables: []
174
188
  extensions: []
175
189
  extra_rdoc_files: []
176
190
  files:
191
+ - ".circleci/config.yml"
177
192
  - ".gitignore"
178
193
  - ".rspec"
179
194
  - ".travis.yml"
195
+ - CHANGELOG.md
180
196
  - Gemfile
181
197
  - Gemfile.lock
182
198
  - LICENSE.txt
@@ -214,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
214
230
  - !ruby/object:Gem::Version
215
231
  version: '0'
216
232
  requirements: []
217
- rubygems_version: 3.0.6
233
+ rubygems_version: 3.0.3
218
234
  signing_key:
219
235
  specification_version: 4
220
236
  summary: NxtHttpClinet is a simple DSL on top the typhoeus http gem