barkibu-kb 0.32.0 → 1.1.0
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 +4 -4
- data/.github/workflows/ci.yml +27 -0
- data/CHANGELOG.md +12 -1
- data/Gemfile.lock +4 -27
- data/README.md +27 -1
- data/barkibu-kb.gemspec +1 -1
- data/lib/barkibu-kb.rb +3 -2
- data/lib/kb/client.rb +23 -7
- data/lib/kb/fake/api.rb +10 -0
- data/lib/kb/version.rb +1 -1
- metadata +7 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d6665ca6f0d74295cacf6bea9ee921b3dba5decc6b5cb3775bbaa0392fd65b86
|
|
4
|
+
data.tar.gz: 700cae8005557d25ff41c3f9583725686485eff37ccbb0eec11ff07473ad9077
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 97dac9ae9946f9398bd62b2fda16acbd978c1e4e153e23884ab78ac3a055dec7d201fcbf3a98ed4b65403324af2b03d034a6073f30d15c20690699021fccae74
|
|
7
|
+
data.tar.gz: f9ed89dff91778420037ad50e7531af48d9b7b6d11c7d92afb1d05cdc31192498310520da51d35aa32e9ed77041e808137f5d9b699fcea24d495f2d17379b475
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches: [master]
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
rubocop:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v5
|
|
13
|
+
- uses: ruby/setup-ruby@v1
|
|
14
|
+
with:
|
|
15
|
+
ruby-version: '3.4'
|
|
16
|
+
bundler-cache: true
|
|
17
|
+
- run: bundle exec rubocop lib spec
|
|
18
|
+
|
|
19
|
+
rspec:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v5
|
|
23
|
+
- uses: ruby/setup-ruby@v1
|
|
24
|
+
with:
|
|
25
|
+
ruby-version: '3.4'
|
|
26
|
+
bundler-cache: true
|
|
27
|
+
- run: bundle exec rspec
|
data/CHANGELOG.md
CHANGED
|
@@ -6,7 +6,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
8
|
## [unreleased]
|
|
9
|
-
- See diff: https://github.com/barkibu/kb-ruby/compare/
|
|
9
|
+
- See diff: https://github.com/barkibu/kb-ruby/compare/v1.1.0...HEAD
|
|
10
|
+
|
|
11
|
+
## [1.1.0]
|
|
12
|
+
- Add `read_timeout:` to `KB::Client#request` to raise the read budget for a single call (e.g. `GET /v1/pets/birthdays`, whose server-side work runs for seconds). Connect and write budgets stay global; the override does not leak into later calls on the same connection.
|
|
13
|
+
|
|
14
|
+
## [1.0.0]
|
|
15
|
+
- [Breaking changes] Split the single global request timeout into per-phase budgets: `KB.config.request.connect_timeout` (default 1s, bounds TCP connect + TLS handshake), `write_timeout` (default 3s), `read_timeout` (default 5s). `KB.config.request.timeout` is removed — assigning it now raises `NoMethodError` at boot. Migration: a previous global `timeout` maps to `read_timeout` (e.g. `KB_REQUEST_TIMEOUT_SECONDS=12` → `read_timeout = 12`).
|
|
16
|
+
- [Breaking changes] Switch the HTTP adapter from http.rb (`faraday-http`) to Net::HTTP (`faraday-net_http`) — the stock adapter honours all three phase timeouts, aligns the KB client with the rest of our outbound HTTP, and opens a one-line upgrade path to `faraday-net_http_persistent` for connection reuse. Raw error classes change accordingly (`Net::OpenTimeout`/`Net::ReadTimeout`/`Net::WriteTimeout`/`Errno::*` instead of `HTTP::*`) — relevant to APM span queries on `error.type`.
|
|
17
|
+
- Faraday-level wrapping keeps the same three classes (`Faraday::TimeoutError`/`ConnectionFailed`/`SSLError`) with one movement between them: a connect/TLS-phase expiry now surfaces as `Faraday::ConnectionFailed` (was `Faraday::TimeoutError`), making `ConnectionFailed` cleanly mean "the request never got through the pipe".
|
|
18
|
+
- Net::HTTP's idempotent auto-retry stays disabled (`max_retries = 0`, enforced by the adapter and pinned by a spec) — no behaviour change vs. the previous no-retry client.
|
|
19
|
+
- There is no total request budget anymore; worst-case wall clock is the sum of the phase budgets rather than a single number.
|
|
20
|
+
- barkibu-kb-fake: disable Sinatra's host authorization (`set :host_authorization, permitted_hosts: []`). Sinatra >= 4.1 authorizes the Host header and, when it infers a development environment, only permits localhost-style hosts — rejecting requests to the stubbed KB host with `403 Host not permitted`. Permitting the host on the consumer side stops working with the net_http adapter, because WebMock intercepts before Net::HTTP adds the Host header, so the header is absent and can never match a permitted list. Consumers can drop their own `set :host_authorization` workarounds.
|
|
10
21
|
|
|
11
22
|
## [0.32.0]
|
|
12
23
|
- Allow Ruby 3.3/3.4: raise `required_ruby_version` ceiling to `< 3.6` (floor stays `>= 2.6`)
|
data/Gemfile.lock
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
barkibu-kb (
|
|
4
|
+
barkibu-kb (1.1.0)
|
|
5
5
|
activemodel (>= 4.0.2)
|
|
6
6
|
activerecord
|
|
7
7
|
activesupport (>= 3.0.0)
|
|
8
8
|
dry-configurable (~> 0.9)
|
|
9
9
|
faraday
|
|
10
|
-
faraday-
|
|
10
|
+
faraday-net_http (~> 1.0)
|
|
11
11
|
faraday_middleware
|
|
12
12
|
i18n
|
|
13
|
-
barkibu-kb-fake (
|
|
14
|
-
barkibu-kb (=
|
|
13
|
+
barkibu-kb-fake (1.1.0)
|
|
14
|
+
barkibu-kb (= 1.1.0)
|
|
15
15
|
countries
|
|
16
16
|
sinatra
|
|
17
17
|
webmock
|
|
@@ -52,8 +52,6 @@ GEM
|
|
|
52
52
|
rexml
|
|
53
53
|
diff-lcs (1.4.4)
|
|
54
54
|
docile (1.4.0)
|
|
55
|
-
domain_name (0.5.20190701)
|
|
56
|
-
unf (>= 0.0.5, < 1.0.0)
|
|
57
55
|
drb (2.2.3)
|
|
58
56
|
dry-configurable (0.16.1)
|
|
59
57
|
dry-core (~> 0.6)
|
|
@@ -76,9 +74,6 @@ GEM
|
|
|
76
74
|
faraday-em_http (1.0.0)
|
|
77
75
|
faraday-em_synchrony (1.0.0)
|
|
78
76
|
faraday-excon (1.1.0)
|
|
79
|
-
faraday-http (1.1.0)
|
|
80
|
-
faraday (~> 1.0)
|
|
81
|
-
http (>= 4.0, < 6)
|
|
82
77
|
faraday-httpclient (1.0.1)
|
|
83
78
|
faraday-multipart (1.0.4)
|
|
84
79
|
multipart-post (~> 2)
|
|
@@ -89,25 +84,10 @@ GEM
|
|
|
89
84
|
faraday-retry (1.0.3)
|
|
90
85
|
faraday_middleware (1.2.0)
|
|
91
86
|
faraday (~> 1.0)
|
|
92
|
-
ffi (1.15.5)
|
|
93
|
-
ffi-compiler (1.0.1)
|
|
94
|
-
ffi (>= 1.0.0)
|
|
95
|
-
rake
|
|
96
87
|
hashdiff (1.0.1)
|
|
97
|
-
http (5.1.1)
|
|
98
|
-
addressable (~> 2.8)
|
|
99
|
-
http-cookie (~> 1.0)
|
|
100
|
-
http-form_data (~> 2.2)
|
|
101
|
-
llhttp-ffi (~> 0.4.0)
|
|
102
|
-
http-cookie (1.0.5)
|
|
103
|
-
domain_name (~> 0.5)
|
|
104
|
-
http-form_data (2.3.0)
|
|
105
88
|
i18n (1.15.2)
|
|
106
89
|
concurrent-ruby (~> 1.0)
|
|
107
90
|
json (2.20.0)
|
|
108
|
-
llhttp-ffi (0.4.0)
|
|
109
|
-
ffi-compiler (~> 1.0)
|
|
110
|
-
rake (~> 13.0)
|
|
111
91
|
logger (1.7.0)
|
|
112
92
|
minitest (6.0.6)
|
|
113
93
|
drb (~> 2.0)
|
|
@@ -174,9 +154,6 @@ GEM
|
|
|
174
154
|
tzinfo (2.0.6)
|
|
175
155
|
concurrent-ruby (~> 1.0)
|
|
176
156
|
unaccent (0.4.0)
|
|
177
|
-
unf (0.1.4)
|
|
178
|
-
unf_ext
|
|
179
|
-
unf_ext (0.0.8.2)
|
|
180
157
|
unicode-display_width (2.5.0)
|
|
181
158
|
uri (1.1.1)
|
|
182
159
|
webmock (3.14.0)
|
data/README.md
CHANGED
|
@@ -18,6 +18,15 @@ Or install it yourself as:
|
|
|
18
18
|
|
|
19
19
|
$ gem install kb
|
|
20
20
|
|
|
21
|
+
## Development
|
|
22
|
+
|
|
23
|
+
Specs and RuboCop run on every pull request (`.github/workflows/ci.yml`) on Ruby 3.4. Locally:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
docker compose run --rm kb bundle exec rspec
|
|
27
|
+
docker compose run --rm kb bundle exec rubocop lib spec
|
|
28
|
+
```
|
|
29
|
+
|
|
21
30
|
## Usage
|
|
22
31
|
|
|
23
32
|
This gem wraps the Knowledge Base Api and exposes CRUD-_able_ entities into the requiring application.
|
|
@@ -43,9 +52,26 @@ KB.config.log_level = :debugger # :info by default
|
|
|
43
52
|
```
|
|
44
53
|
|
|
45
54
|
#### Request timeout configuration
|
|
55
|
+
|
|
56
|
+
Timeouts are per phase, and each phase fails with its own error class:
|
|
57
|
+
`connect_timeout` maps to Net::HTTP's `open_timeout`, bounding TCP connect plus
|
|
58
|
+
the TLS handshake (`Net::OpenTimeout`); `read_timeout` bounds the wait for the
|
|
59
|
+
response (`Net::ReadTimeout`); `write_timeout` bounds sending the request
|
|
60
|
+
(`Net::WriteTimeout`).
|
|
61
|
+
|
|
46
62
|
```ruby
|
|
47
63
|
# config/initializers/kb_ruby.rb
|
|
48
|
-
KB.config.request.
|
|
64
|
+
KB.config.request.connect_timeout = 2 # 1 by default; TCP connect + TLS handshake
|
|
65
|
+
KB.config.request.write_timeout = 4 # 3 by default
|
|
66
|
+
KB.config.request.read_timeout = 10 # 5 by default
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The read budget can be raised for a single call through `KB::Client#request`, for
|
|
70
|
+
the few endpoints whose server-side work legitimately runs for seconds. Connect
|
|
71
|
+
and write budgets stay global:
|
|
72
|
+
|
|
73
|
+
```ruby
|
|
74
|
+
KB::Pet.kb_client.request('birthdays', filters: { month: 9, day: 22, size: 1000 }, read_timeout: 30)
|
|
49
75
|
```
|
|
50
76
|
|
|
51
77
|
### Exposed Entities
|
data/barkibu-kb.gemspec
CHANGED
|
@@ -51,7 +51,7 @@ Gem::Specification.new do |spec|
|
|
|
51
51
|
spec.add_runtime_dependency 'activerecord'
|
|
52
52
|
spec.add_runtime_dependency 'activesupport', '>= 3.0.0'
|
|
53
53
|
spec.add_runtime_dependency 'faraday'
|
|
54
|
-
spec.add_runtime_dependency 'faraday-
|
|
54
|
+
spec.add_runtime_dependency 'faraday-net_http', '~> 1.0'
|
|
55
55
|
spec.add_runtime_dependency 'faraday_middleware'
|
|
56
56
|
spec.add_runtime_dependency 'i18n'
|
|
57
57
|
end
|
data/lib/barkibu-kb.rb
CHANGED
|
@@ -5,7 +5,6 @@ require 'active_support'
|
|
|
5
5
|
require 'active_support/core_ext/array'
|
|
6
6
|
require 'faraday'
|
|
7
7
|
require 'faraday_middleware'
|
|
8
|
-
require 'faraday/http'
|
|
9
8
|
require 'dry/configurable'
|
|
10
9
|
|
|
11
10
|
module KB
|
|
@@ -19,7 +18,9 @@ module KB
|
|
|
19
18
|
setting :log_level, default: :info
|
|
20
19
|
|
|
21
20
|
setting :request do
|
|
22
|
-
setting :
|
|
21
|
+
setting :connect_timeout, default: 1
|
|
22
|
+
setting :write_timeout, default: 3
|
|
23
|
+
setting :read_timeout, default: 5
|
|
23
24
|
end
|
|
24
25
|
end
|
|
25
26
|
|
data/lib/kb/client.rb
CHANGED
|
@@ -7,12 +7,16 @@ module KB
|
|
|
7
7
|
@base_url = base_url
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
# `read_timeout` overrides KB.config.request.read_timeout for this one call only,
|
|
11
|
+
# for the few endpoints whose server-side work legitimately runs for seconds
|
|
12
|
+
# (e.g. GET /v1/pets/birthdays). Connect and write budgets stay global.
|
|
13
|
+
def request(sub_path, filters: nil, method: :get, read_timeout: nil)
|
|
14
|
+
options = request_options(read_timeout)
|
|
15
|
+
return connection.public_send(method, sub_path, attributes_to_json(filters), &options).body if method != :get
|
|
12
16
|
|
|
13
17
|
cache_key = "#{@base_url}/#{sub_path}/#{(filters || {}).sort.to_h}"
|
|
14
18
|
KB::Cache.fetch(cache_key) do
|
|
15
|
-
connection.public_send(method, sub_path, filters).body
|
|
19
|
+
connection.public_send(method, sub_path, filters, &options).body
|
|
16
20
|
end
|
|
17
21
|
end
|
|
18
22
|
|
|
@@ -74,9 +78,7 @@ module KB
|
|
|
74
78
|
end
|
|
75
79
|
|
|
76
80
|
def connection
|
|
77
|
-
@connection ||= Faraday.new(url: base_url,
|
|
78
|
-
headers: headers,
|
|
79
|
-
request: { timeout: KB.config.request.timeout }) do |conn|
|
|
81
|
+
@connection ||= Faraday.new(url: base_url, headers: headers, request: request_timeouts) do |conn|
|
|
80
82
|
conn.response :json
|
|
81
83
|
conn.response :raise_error
|
|
82
84
|
if KB.config.log_level == :debugger
|
|
@@ -84,8 +86,22 @@ module KB
|
|
|
84
86
|
logger.filter(/(X-api-key:\s)("\w+")/, '\1[API_KEY_SCRUBBED]')
|
|
85
87
|
end
|
|
86
88
|
end
|
|
87
|
-
conn.adapter :
|
|
89
|
+
conn.adapter :net_http
|
|
88
90
|
end
|
|
89
91
|
end
|
|
92
|
+
|
|
93
|
+
def request_options(read_timeout)
|
|
94
|
+
return nil if read_timeout.nil?
|
|
95
|
+
|
|
96
|
+
->(req) { req.options.read_timeout = read_timeout }
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def request_timeouts
|
|
100
|
+
{
|
|
101
|
+
open_timeout: KB.config.request.connect_timeout,
|
|
102
|
+
write_timeout: KB.config.request.write_timeout,
|
|
103
|
+
read_timeout: KB.config.request.read_timeout
|
|
104
|
+
}
|
|
105
|
+
end
|
|
90
106
|
end
|
|
91
107
|
end
|
data/lib/kb/fake/api.rb
CHANGED
|
@@ -44,6 +44,16 @@ module KB
|
|
|
44
44
|
include BoundedContext::PetFamily::PetContracts
|
|
45
45
|
include BoundedContext::PetFamily::Products
|
|
46
46
|
|
|
47
|
+
# Sinatra >= 4.1 ships Rack::Protection::HostAuthorization, which authorizes
|
|
48
|
+
# on the Host header and, when it infers a development environment, only
|
|
49
|
+
# permits localhost-style hosts — rejecting requests addressed to the
|
|
50
|
+
# stubbed KB host with "403 Host not permitted". Permitting specific hosts
|
|
51
|
+
# on the consumer side is no fix either: with the net_http adapter WebMock
|
|
52
|
+
# intercepts before Net::HTTP adds the Host header, so the header is absent
|
|
53
|
+
# and can never match a permitted list. An empty list disables the check;
|
|
54
|
+
# it guards against DNS rebinding, which cannot apply to an in-process fake.
|
|
55
|
+
set :host_authorization, permitted_hosts: []
|
|
56
|
+
|
|
47
57
|
set :state, ApiState.new
|
|
48
58
|
|
|
49
59
|
def self.snapshot
|
data/lib/kb/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: barkibu-kb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Léo Figea
|
|
@@ -220,19 +220,19 @@ dependencies:
|
|
|
220
220
|
- !ruby/object:Gem::Version
|
|
221
221
|
version: '0'
|
|
222
222
|
- !ruby/object:Gem::Dependency
|
|
223
|
-
name: faraday-
|
|
223
|
+
name: faraday-net_http
|
|
224
224
|
requirement: !ruby/object:Gem::Requirement
|
|
225
225
|
requirements:
|
|
226
|
-
- - "
|
|
226
|
+
- - "~>"
|
|
227
227
|
- !ruby/object:Gem::Version
|
|
228
|
-
version: '0'
|
|
228
|
+
version: '1.0'
|
|
229
229
|
type: :runtime
|
|
230
230
|
prerelease: false
|
|
231
231
|
version_requirements: !ruby/object:Gem::Requirement
|
|
232
232
|
requirements:
|
|
233
|
-
- - "
|
|
233
|
+
- - "~>"
|
|
234
234
|
- !ruby/object:Gem::Version
|
|
235
|
-
version: '0'
|
|
235
|
+
version: '1.0'
|
|
236
236
|
- !ruby/object:Gem::Dependency
|
|
237
237
|
name: faraday_middleware
|
|
238
238
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -271,6 +271,7 @@ extra_rdoc_files: []
|
|
|
271
271
|
files:
|
|
272
272
|
- ".env.example"
|
|
273
273
|
- ".github/pull_request_template.md"
|
|
274
|
+
- ".github/workflows/ci.yml"
|
|
274
275
|
- ".github/workflows/release.yaml"
|
|
275
276
|
- ".gitignore"
|
|
276
277
|
- ".rspec"
|