elastomer-client 3.2.3 → 6.2.1
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/.devcontainer/devcontainer.json +46 -0
- data/.devcontainer/postCreateCommand.sh +4 -0
- data/.github/dependabot.yaml +11 -0
- data/.github/workflows/main.yml +45 -0
- data/.github/workflows/rubocop.yml +15 -0
- data/.gitignore +1 -1
- data/.rubocop.yml +13 -65
- data/.ruby-version +1 -0
- data/CHANGELOG.md +76 -0
- data/Gemfile +18 -1
- data/README.md +110 -51
- data/Rakefile +3 -1
- data/docker/compose.yaml +71 -0
- data/docker/elasticsearch8plus.yml +13 -0
- data/docs/README.md +4 -5
- data/docs/bulk_indexing.md +1 -1
- data/docs/client.md +20 -33
- data/docs/cluster.md +8 -8
- data/docs/docs.md +5 -5
- data/docs/index.md +4 -4
- data/docs/multi_search.md +1 -1
- data/docs/notifications.md +3 -3
- data/docs/scan_scroll.md +1 -1
- data/docs/snapshots.md +1 -1
- data/docs/templates.md +1 -1
- data/elastomer-client.gemspec +7 -16
- data/lib/{elastomer → elastomer_client}/client/bulk.rb +70 -47
- data/lib/{elastomer → elastomer_client}/client/cluster.rb +18 -16
- data/lib/{elastomer → elastomer_client}/client/delete_by_query.rb +6 -4
- data/lib/{elastomer → elastomer_client}/client/docs.rb +82 -72
- data/lib/{elastomer → elastomer_client}/client/errors.rb +7 -17
- data/lib/{elastomer → elastomer_client}/client/index.rb +55 -79
- data/lib/{elastomer → elastomer_client}/client/multi_percolate.rb +7 -5
- data/lib/{elastomer → elastomer_client}/client/multi_search.rb +5 -3
- data/lib/{elastomer → elastomer_client}/client/native_delete_by_query.rb +6 -6
- data/lib/{elastomer → elastomer_client}/client/nodes.rb +11 -10
- data/lib/{elastomer → elastomer_client}/client/percolator.rb +9 -10
- data/lib/elastomer_client/client/reindex.rb +34 -0
- data/lib/{elastomer → elastomer_client}/client/repository.rb +7 -5
- data/lib/{elastomer → elastomer_client}/client/rest_api_spec/api_spec.rb +7 -6
- data/lib/{elastomer → elastomer_client}/client/rest_api_spec/api_spec_v5_6.rb +1 -1
- data/lib/elastomer_client/client/rest_api_spec/api_spec_v8_13.rb +7567 -0
- data/lib/elastomer_client/client/rest_api_spec/api_spec_v8_7.rb +6553 -0
- data/lib/{elastomer → elastomer_client}/client/rest_api_spec/rest_api.rb +5 -3
- data/lib/{elastomer → elastomer_client}/client/rest_api_spec.rb +3 -2
- data/lib/{elastomer → elastomer_client}/client/scroller.rb +17 -16
- data/lib/{elastomer → elastomer_client}/client/snapshot.rb +10 -8
- data/lib/{elastomer → elastomer_client}/client/tasks.rb +9 -13
- data/lib/{elastomer → elastomer_client}/client/template.rb +10 -9
- data/lib/elastomer_client/client/update_by_query.rb +50 -0
- data/lib/{elastomer → elastomer_client}/client.rb +51 -62
- data/lib/{elastomer → elastomer_client}/core_ext/time.rb +2 -0
- data/lib/{elastomer → elastomer_client}/middleware/compress.rb +2 -2
- data/lib/{elastomer → elastomer_client}/middleware/encode_json.rb +4 -2
- data/lib/{elastomer → elastomer_client}/middleware/limit_size.rb +5 -3
- data/lib/{elastomer → elastomer_client}/middleware/opaque_id.rb +10 -7
- data/lib/{elastomer → elastomer_client}/middleware/parse_json.rb +5 -3
- data/lib/{elastomer → elastomer_client}/notifications.rb +17 -15
- data/lib/elastomer_client/version.rb +9 -0
- data/lib/elastomer_client/version_support.rb +24 -0
- data/script/bootstrap +4 -2
- data/script/console +3 -1
- data/script/generate-rest-api-spec +77 -22
- data/test/assertions.rb +32 -39
- data/test/client/bulk_test.rb +166 -141
- data/test/client/cluster_test.rb +35 -13
- data/test/client/docs_test.rb +387 -274
- data/test/client/errors_test.rb +38 -40
- data/test/client/index_test.rb +243 -202
- data/test/client/multi_percolate_test.rb +46 -41
- data/test/client/multi_search_test.rb +122 -67
- data/test/client/native_delete_by_query_test.rb +96 -88
- data/test/client/nodes_test.rb +21 -10
- data/test/client/percolator_test.rb +19 -14
- data/test/client/reindex_test.rb +100 -0
- data/test/client/repository_test.rb +31 -19
- data/test/client/rest_api_spec/api_spec_test.rb +13 -11
- data/test/client/rest_api_spec/rest_api_test.rb +9 -7
- data/test/client/scroller_test.rb +44 -70
- data/test/client/snapshot_test.rb +38 -21
- data/test/client/stubbed_client_test.rb +7 -4
- data/test/client/tasks_test.rb +12 -17
- data/test/client/template_test.rb +34 -13
- data/test/client/update_by_query_test.rb +137 -0
- data/test/client_test.rb +158 -92
- data/test/core_ext/time_test.rb +14 -12
- data/test/middleware/encode_json_test.rb +18 -7
- data/test/middleware/opaque_id_test.rb +18 -14
- data/test/middleware/parse_json_test.rb +17 -9
- data/test/mock_response.rb +30 -0
- data/test/notifications_test.rb +15 -8
- data/test/test_helper.rb +40 -97
- data/test/version_support_test.rb +13 -78
- metadata +60 -208
- data/.overcommit.yml +0 -5
- data/.travis.yml +0 -34
- data/docker/docker-compose.cibuild.yml +0 -8
- data/docker/docker-compose.es24.yml +0 -34
- data/docker/docker-compose.es56.yml +0 -37
- data/docs/warmers.md +0 -3
- data/lib/elastomer/client/app_delete_by_query.rb +0 -144
- data/lib/elastomer/client/rest_api_spec/api_spec_v2_3.rb +0 -2232
- data/lib/elastomer/client/rest_api_spec/api_spec_v2_4.rb +0 -2250
- data/lib/elastomer/client/warmer.rb +0 -98
- data/lib/elastomer/version.rb +0 -7
- data/lib/elastomer/version_support.rb +0 -182
- data/script/cibuild +0 -103
- data/script/cibuild-elastomer-client +0 -1
- data/script/cibuild-elastomer-client-es24 +0 -8
- data/script/cibuild-elastomer-client-es56 +0 -8
- data/test/client/app_delete_by_query_test.rb +0 -192
- data/test/client/es_5_x_warmer_test.rb +0 -13
- data/test/client/warmer_test.rb +0 -60
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "addressable/template"
|
2
4
|
require "faraday"
|
3
5
|
require "faraday_middleware"
|
@@ -5,25 +7,21 @@ require "multi_json"
|
|
5
7
|
require "semantic"
|
6
8
|
require "zlib"
|
7
9
|
|
8
|
-
require "
|
9
|
-
require "
|
10
|
+
require "elastomer_client/version"
|
11
|
+
require "elastomer_client/version_support"
|
10
12
|
|
11
|
-
module
|
13
|
+
module ElastomerClient
|
12
14
|
|
13
15
|
class Client
|
14
16
|
IVAR_BLACK_LIST = [:@basic_auth, :@token_auth]
|
15
|
-
IVAR_NOISY_LIST = [:@api_spec, :@cluster]
|
16
|
-
|
17
|
-
MAX_REQUEST_SIZE = 250 * 2**20 # 250 MB
|
17
|
+
IVAR_NOISY_LIST = [:@api_spec, :@cluster, :@connection]
|
18
18
|
|
19
|
-
|
19
|
+
MAX_REQUEST_SIZE = 2**20 * 250 # 250 MB
|
20
20
|
|
21
21
|
# Create a new client that can be used to make HTTP requests to the
|
22
|
-
# Elasticsearch server.
|
23
|
-
# request will be retried up to this many times with a 75ms delay between
|
24
|
-
# the retry attempts. Only non-fatal exceptions will retried automatically.
|
22
|
+
# Elasticsearch server.
|
25
23
|
#
|
26
|
-
# see lib/
|
24
|
+
# see lib/elastomer_client/client/errors.rb#L92-L94
|
27
25
|
#
|
28
26
|
# Method params:
|
29
27
|
# :host - the host as a String
|
@@ -34,8 +32,6 @@ module Elastomer
|
|
34
32
|
# :adapter - the Faraday adapter to use (defaults to :excon)
|
35
33
|
# :opaque_id - set to `true` to use the 'X-Opaque-Id' request header
|
36
34
|
# :max_request_size - the maximum allowed request size in bytes (defaults to 250 MB)
|
37
|
-
# :max_retries - the maximum number of request retires (defaults to 0)
|
38
|
-
# :retry_delay - delay in seconds between retries (defaults to 0.075)
|
39
35
|
# :strict_params - set to `true` to raise exceptions when invalid request params are used
|
40
36
|
# :es_version - set to the Elasticsearch version (example: "5.6.6") to avoid an HTTP request to get the version.
|
41
37
|
# :compress_body - set to true to enable request body compression (default: false)
|
@@ -44,10 +40,9 @@ module Elastomer
|
|
44
40
|
# :token_auth - an authentication token as a String to use on connections (overrides :basic_auth)
|
45
41
|
#
|
46
42
|
def initialize(host: "localhost", port: 9200, url: nil,
|
47
|
-
read_timeout: 5, open_timeout: 2,
|
48
|
-
opaque_id: false, adapter: Faraday.default_adapter, max_request_size: MAX_REQUEST_SIZE,
|
43
|
+
read_timeout: 5, open_timeout: 2, opaque_id: false, adapter: Faraday.default_adapter, max_request_size: MAX_REQUEST_SIZE,
|
49
44
|
strict_params: false, es_version: nil, compress_body: false, compression: Zlib::DEFAULT_COMPRESSION,
|
50
|
-
basic_auth: nil, token_auth: nil)
|
45
|
+
basic_auth: nil, token_auth: nil, &block)
|
51
46
|
|
52
47
|
@url = url || "http://#{host}:#{port}"
|
53
48
|
|
@@ -57,8 +52,6 @@ module Elastomer
|
|
57
52
|
|
58
53
|
@read_timeout = read_timeout
|
59
54
|
@open_timeout = open_timeout
|
60
|
-
@max_retries = max_retries
|
61
|
-
@retry_delay = retry_delay
|
62
55
|
@adapter = adapter
|
63
56
|
@opaque_id = opaque_id
|
64
57
|
@max_request_size = max_request_size
|
@@ -68,11 +61,12 @@ module Elastomer
|
|
68
61
|
@compression = compression
|
69
62
|
@basic_auth = basic_auth
|
70
63
|
@token_auth = token_auth
|
64
|
+
@connection_block = block
|
71
65
|
end
|
72
66
|
|
73
67
|
attr_reader :host, :port, :url
|
74
68
|
attr_reader :read_timeout, :open_timeout
|
75
|
-
attr_reader :
|
69
|
+
attr_reader :max_request_size
|
76
70
|
attr_reader :strict_params
|
77
71
|
attr_reader :es_version
|
78
72
|
attr_reader :compress_body
|
@@ -83,12 +77,12 @@ module Elastomer
|
|
83
77
|
# fashion.
|
84
78
|
def dup
|
85
79
|
self.class.new \
|
86
|
-
url
|
87
|
-
read_timeout
|
88
|
-
open_timeout
|
80
|
+
url:,
|
81
|
+
read_timeout:,
|
82
|
+
open_timeout:,
|
89
83
|
adapter: @adapter,
|
90
84
|
opaque_id: @opaque_id,
|
91
|
-
max_request_size
|
85
|
+
max_request_size:,
|
92
86
|
basic_auth: @basic_auth,
|
93
87
|
token_auth: @token_auth
|
94
88
|
end
|
@@ -140,9 +134,8 @@ module Elastomer
|
|
140
134
|
# Request compressed responses from ES and decompress them
|
141
135
|
conn.use(:gzip)
|
142
136
|
conn.request(:encode_json)
|
143
|
-
conn.request(:
|
144
|
-
conn.request(:
|
145
|
-
conn.request(:elastomer_compress, compression: compression) if compress_body
|
137
|
+
conn.request(:limit_size, max_request_size:) if max_request_size
|
138
|
+
conn.request(:elastomer_compress, compression:) if compress_body
|
146
139
|
|
147
140
|
conn.options[:timeout] = read_timeout
|
148
141
|
conn.options[:open_timeout] = open_timeout
|
@@ -153,6 +146,10 @@ module Elastomer
|
|
153
146
|
conn.basic_auth(@basic_auth[:username], @basic_auth[:password])
|
154
147
|
end
|
155
148
|
|
149
|
+
@connection_block&.call(conn)
|
150
|
+
|
151
|
+
conn.request(:opaque_id) if @opaque_id
|
152
|
+
|
156
153
|
if @adapter.is_a?(Array)
|
157
154
|
conn.adapter(*@adapter)
|
158
155
|
else
|
@@ -176,7 +173,7 @@ module Elastomer
|
|
176
173
|
# params - Parameters Hash
|
177
174
|
#
|
178
175
|
# Returns a Faraday::Response
|
179
|
-
def head(
|
176
|
+
def head(path, params = {})
|
180
177
|
request :head, path, params
|
181
178
|
end
|
182
179
|
|
@@ -186,8 +183,8 @@ module Elastomer
|
|
186
183
|
# params - Parameters Hash
|
187
184
|
#
|
188
185
|
# Returns a Faraday::Response
|
189
|
-
# Raises an
|
190
|
-
def get(
|
186
|
+
# Raises an ElastomerClient::Client::Error on 4XX and 5XX responses
|
187
|
+
def get(path, params = {})
|
191
188
|
request :get, path, params
|
192
189
|
end
|
193
190
|
|
@@ -197,8 +194,8 @@ module Elastomer
|
|
197
194
|
# params - Parameters Hash
|
198
195
|
#
|
199
196
|
# Returns a Faraday::Response
|
200
|
-
# Raises an
|
201
|
-
def put(
|
197
|
+
# Raises an ElastomerClient::Client::Error on 4XX and 5XX responses
|
198
|
+
def put(path, params = {})
|
202
199
|
request :put, path, params
|
203
200
|
end
|
204
201
|
|
@@ -208,8 +205,8 @@ module Elastomer
|
|
208
205
|
# params - Parameters Hash
|
209
206
|
#
|
210
207
|
# Returns a Faraday::Response
|
211
|
-
# Raises an
|
212
|
-
def post(
|
208
|
+
# Raises an ElastomerClient::Client::Error on 4XX and 5XX responses
|
209
|
+
def post(path, params = {})
|
213
210
|
request :post, path, params
|
214
211
|
end
|
215
212
|
|
@@ -219,8 +216,8 @@ module Elastomer
|
|
219
216
|
# params - Parameters Hash
|
220
217
|
#
|
221
218
|
# Returns a Faraday::Response
|
222
|
-
# Raises an
|
223
|
-
def delete(
|
219
|
+
# Raises an ElastomerClient::Client::Error on 4XX and 5XX responses
|
220
|
+
def delete(path, params = {})
|
224
221
|
request :delete, path, params
|
225
222
|
end
|
226
223
|
|
@@ -233,18 +230,14 @@ module Elastomer
|
|
233
230
|
# params - Parameters Hash
|
234
231
|
# :body - Will be used as the request body
|
235
232
|
# :read_timeout - Optional read timeout (in seconds) for the request
|
236
|
-
# :max_retires - Optional retry number for the request
|
237
233
|
#
|
238
234
|
# Returns a Faraday::Response
|
239
|
-
# Raises an
|
240
|
-
|
241
|
-
def request( method, path, params )
|
235
|
+
# Raises an ElastomerClient::Client::Error on 4XX and 5XX responses
|
236
|
+
def request(method, path, params)
|
242
237
|
read_timeout = params.delete(:read_timeout)
|
243
|
-
request_max_retries = params.delete(:max_retries) || max_retries
|
244
238
|
body = extract_body(params)
|
245
239
|
path = expand_path(path, params)
|
246
240
|
|
247
|
-
params[:retries] = retries = 0
|
248
241
|
instrument(path, body, params) do
|
249
242
|
begin
|
250
243
|
response =
|
@@ -276,14 +269,9 @@ module Elastomer
|
|
276
269
|
|
277
270
|
handle_errors response
|
278
271
|
|
279
|
-
# wrap Faraday errors with appropriate
|
280
|
-
rescue Faraday::Error
|
272
|
+
# wrap Faraday errors with appropriate ElastomerClient::Client error classes
|
273
|
+
rescue Faraday::Error => boom
|
281
274
|
error = wrap_faraday_error(boom, method, path)
|
282
|
-
if error.retry? && RETRYABLE_METHODS.include?(method) && (retries += 1) <= request_max_retries
|
283
|
-
params[:retries] = retries
|
284
|
-
sleep retry_delay
|
285
|
-
retry
|
286
|
-
end
|
287
275
|
raise error
|
288
276
|
rescue OpaqueIdError => boom
|
289
277
|
reset!
|
@@ -293,7 +281,7 @@ module Elastomer
|
|
293
281
|
end
|
294
282
|
# rubocop:enable Metrics/MethodLength
|
295
283
|
|
296
|
-
# Internal: Returns a new
|
284
|
+
# Internal: Returns a new ElastomerClient::Client error that wraps the given
|
297
285
|
# Faraday error. A generic Error is returned if we cannot wrap the given
|
298
286
|
# Faraday error.
|
299
287
|
#
|
@@ -303,7 +291,7 @@ module Elastomer
|
|
303
291
|
#
|
304
292
|
def wrap_faraday_error(error, method, path)
|
305
293
|
error_name = error.class.name.split("::").last
|
306
|
-
error_class =
|
294
|
+
error_class = ElastomerClient::Client.const_get(error_name) rescue ElastomerClient::Client::Error
|
307
295
|
error_class.new(error, method.upcase, path)
|
308
296
|
end
|
309
297
|
|
@@ -323,7 +311,7 @@ module Elastomer
|
|
323
311
|
# params - Parameters Hash
|
324
312
|
#
|
325
313
|
# Returns the request body as a String or `nil` if no :body is present
|
326
|
-
def extract_body(
|
314
|
+
def extract_body(params)
|
327
315
|
body = params.delete :body
|
328
316
|
return if body.nil?
|
329
317
|
|
@@ -360,14 +348,13 @@ module Elastomer
|
|
360
348
|
# #=> '/foo/no%20bar'
|
361
349
|
#
|
362
350
|
# Returns an Addressable::Uri
|
363
|
-
def expand_path(
|
351
|
+
def expand_path(path, params)
|
364
352
|
template = Addressable::Template.new path
|
365
353
|
|
366
354
|
expansions = {}
|
367
355
|
query_values = params.dup
|
368
356
|
query_values.delete :action
|
369
357
|
query_values.delete :context
|
370
|
-
query_values.delete :retries
|
371
358
|
|
372
359
|
rest_api = query_values.delete :rest_api
|
373
360
|
|
@@ -379,19 +366,21 @@ module Elastomer
|
|
379
366
|
|
380
367
|
if rest_api
|
381
368
|
query_values = if strict_params?
|
382
|
-
|
369
|
+
api_spec.validate_params!(api: rest_api, params: query_values)
|
383
370
|
else
|
384
371
|
api_spec.select_params(api: rest_api, from: query_values)
|
385
372
|
end
|
386
373
|
end
|
387
374
|
|
388
375
|
uri = template.expand(expansions)
|
389
|
-
|
376
|
+
query_values.transform_keys!(&:to_s)
|
377
|
+
uri.query_values = (uri.query_values || {}).merge(query_values) unless query_values.empty?
|
378
|
+
|
390
379
|
uri.to_s
|
391
380
|
end
|
392
381
|
|
393
382
|
# Internal: A noop method that simply yields to the block. This method
|
394
|
-
# will be replaced when the '
|
383
|
+
# will be replaced when the 'elastomer_client/notifications' module is included.
|
395
384
|
#
|
396
385
|
# path - The full request path as a String
|
397
386
|
# body - The request body as a String or `nil`
|
@@ -399,7 +388,7 @@ module Elastomer
|
|
399
388
|
# block - The block that will be instrumented
|
400
389
|
#
|
401
390
|
# Returns the response from the block
|
402
|
-
def instrument(
|
391
|
+
def instrument(path, body, params)
|
403
392
|
yield
|
404
393
|
end
|
405
394
|
|
@@ -414,9 +403,9 @@ module Elastomer
|
|
414
403
|
# response - The Faraday::Response object.
|
415
404
|
#
|
416
405
|
# Returns the response.
|
417
|
-
# Raises an
|
406
|
+
# Raises an ElastomerClient::Client::Error on 500 responses or responses
|
418
407
|
# containing and 'error' field.
|
419
|
-
def handle_errors(
|
408
|
+
def handle_errors(response)
|
420
409
|
raise ServerError, response if response.status >= 500
|
421
410
|
|
422
411
|
if response.body.is_a?(Hash) && (error = response.body["error"])
|
@@ -429,7 +418,7 @@ module Elastomer
|
|
429
418
|
when "document_already_exists_exception"; raise DocumentAlreadyExistsError, response
|
430
419
|
# Elasticsearch 5.x.x root_cause type for document already existing
|
431
420
|
when "version_conflict_engine_exception"; raise DocumentAlreadyExistsError, response
|
432
|
-
when
|
421
|
+
when "query_shard_exception", "parsing_exception"; raise QueryParsingError, response
|
433
422
|
end
|
434
423
|
|
435
424
|
raise RequestError, response
|
@@ -453,7 +442,7 @@ module Elastomer
|
|
453
442
|
#
|
454
443
|
# Returns the validated param as a String.
|
455
444
|
# Raises an ArgumentError if the param is not valid.
|
456
|
-
def assert_param_presence(
|
445
|
+
def assert_param_presence(param, name = "input value")
|
457
446
|
case param
|
458
447
|
when String, Symbol, Numeric
|
459
448
|
param = param.to_s.strip
|
@@ -501,7 +490,7 @@ module Elastomer
|
|
501
490
|
object.respond_to?(:empty?) ? !object.empty? : !!object
|
502
491
|
end
|
503
492
|
end # Client
|
504
|
-
end #
|
493
|
+
end # ElastomerClient
|
505
494
|
|
506
495
|
# require all files in the `client` sub-directory
|
507
496
|
Dir.glob(File.expand_path("../client/*.rb", __FILE__)).each { |fn| require fn }
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "stringio"
|
3
3
|
|
4
|
-
module
|
4
|
+
module ElastomerClient
|
5
5
|
module Middleware
|
6
6
|
# Request middleware that compresses request bodies with GZip for supported
|
7
7
|
# versions of Elasticsearch.
|
@@ -42,4 +42,4 @@ module Elastomer
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
Faraday::Request.register_middleware(elastomer_compress: ::
|
45
|
+
Faraday::Request.register_middleware(elastomer_compress: ElastomerClient::Middleware::Compress)
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ElastomerClient
|
2
4
|
module Middleware
|
3
5
|
# Request middleware that encodes the body as JSON.
|
4
6
|
#
|
@@ -55,4 +57,4 @@ module Elastomer
|
|
55
57
|
end
|
56
58
|
|
57
59
|
Faraday::Request.register_middleware \
|
58
|
-
:
|
60
|
+
encode_json: ElastomerClient::Middleware::EncodeJson
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ElastomerClient
|
2
4
|
module Middleware
|
3
5
|
|
4
6
|
# Request middleware that raises an exception if the request body exceeds a
|
@@ -15,7 +17,7 @@ module Elastomer
|
|
15
17
|
def call(env)
|
16
18
|
if body = env[:body]
|
17
19
|
if body.is_a?(String) && body.bytesize > max_request_size
|
18
|
-
raise ::
|
20
|
+
raise ::ElastomerClient::Client::RequestSizeError,
|
19
21
|
"Request of size `#{body.bytesize}` exceeds the maximum requst size: #{max_request_size}"
|
20
22
|
end
|
21
23
|
end
|
@@ -27,4 +29,4 @@ module Elastomer
|
|
27
29
|
end
|
28
30
|
|
29
31
|
Faraday::Request.register_middleware \
|
30
|
-
:
|
32
|
+
limit_size: ElastomerClient::Middleware::LimitSize
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "securerandom"
|
2
4
|
|
3
|
-
module
|
5
|
+
module ElastomerClient
|
4
6
|
module Middleware
|
5
7
|
|
6
8
|
# This Faraday middleware implements the "X-Opaque-Id" request / response
|
@@ -12,7 +14,7 @@ module Elastomer
|
|
12
14
|
# The SecureRandom lib is used to generate a UUID string for each request.
|
13
15
|
# This value is used as the content for the "X-Opaque-Id" header. If the
|
14
16
|
# value is different between the request and the response, then an
|
15
|
-
# `
|
17
|
+
# `ElastomerClient::Client::OpaqueIdError` is raised. In this case no response
|
16
18
|
# will be returned.
|
17
19
|
#
|
18
20
|
# See [Elasticsearch "X-Opaque-Id"
|
@@ -27,14 +29,15 @@ module Elastomer
|
|
27
29
|
# env - Faraday environment Hash
|
28
30
|
#
|
29
31
|
# Returns the environment Hash
|
30
|
-
def call(
|
32
|
+
def call(env)
|
31
33
|
uuid = generate_uuid.freeze
|
32
34
|
env[:request_headers][X_OPAQUE_ID] = uuid
|
33
35
|
|
34
36
|
@app.call(env).on_complete do |renv|
|
35
37
|
response_uuid = renv[:response_headers][X_OPAQUE_ID]
|
36
|
-
if
|
37
|
-
|
38
|
+
# Don't raise OpaqueIdError if the response is a 5xx
|
39
|
+
if !response_uuid.nil? && uuid != response_uuid && renv.status < 500
|
40
|
+
raise ::ElastomerClient::Client::OpaqueIdError,
|
38
41
|
"Conflicting 'X-Opaque-Id' headers: request #{uuid.inspect}, response #{response_uuid.inspect}"
|
39
42
|
end
|
40
43
|
end
|
@@ -65,7 +68,7 @@ module Elastomer
|
|
65
68
|
# 'X-Opaque-Id' request header and the one received in the response header.
|
66
69
|
Client::OpaqueIdError = Class.new Client::Error
|
67
70
|
|
68
|
-
end #
|
71
|
+
end # ElastomerClient
|
69
72
|
|
70
73
|
Faraday::Request.register_middleware \
|
71
|
-
:
|
74
|
+
opaque_id: ElastomerClient::Middleware::OpaqueId
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ElastomerClient
|
2
4
|
module Middleware
|
3
5
|
|
4
6
|
# Parse response bodies as JSON.
|
@@ -18,7 +20,7 @@ module Elastomer
|
|
18
20
|
def parse(body)
|
19
21
|
MultiJson.load(body) if body.respond_to?(:to_str) && !body.strip.empty?
|
20
22
|
rescue StandardError, SyntaxError => e
|
21
|
-
raise Faraday::
|
23
|
+
raise Faraday::ParsingError, e
|
22
24
|
end
|
23
25
|
|
24
26
|
def process_response?(env)
|
@@ -36,4 +38,4 @@ module Elastomer
|
|
36
38
|
end
|
37
39
|
|
38
40
|
Faraday::Response.register_middleware \
|
39
|
-
:
|
41
|
+
parse_json: ElastomerClient::Middleware::ParseJson
|
@@ -1,13 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support"
|
1
4
|
require "active_support/notifications"
|
2
5
|
require "securerandom"
|
3
|
-
require "
|
6
|
+
require "elastomer_client/client"
|
4
7
|
|
5
|
-
module
|
8
|
+
module ElastomerClient
|
6
9
|
|
7
10
|
# So you want to get notifications from your Elasticsearch client? Well,
|
8
11
|
# you've come to the right place!
|
9
12
|
#
|
10
|
-
# require '
|
13
|
+
# require 'elastomer_client/notifications'
|
11
14
|
#
|
12
15
|
# Requiring this module will add ActiveSupport notifications to all
|
13
16
|
# Elasticsearch requests. To subscribe to those requests ...
|
@@ -27,11 +30,11 @@ module Elastomer
|
|
27
30
|
# * :status - response status code
|
28
31
|
#
|
29
32
|
# If you want to use your own notifications service then you will need to
|
30
|
-
# let
|
33
|
+
# let ElastomerClient know by setting the `service` here in the Notifications
|
31
34
|
# module. The service should adhere to the ActiveSupport::Notifications
|
32
35
|
# specification.
|
33
36
|
#
|
34
|
-
#
|
37
|
+
# ElastomerClient::Notifications.service = your_own_service
|
35
38
|
#
|
36
39
|
module Notifications
|
37
40
|
|
@@ -53,23 +56,22 @@ module Elastomer
|
|
53
56
|
# block - The block that will be instrumented
|
54
57
|
#
|
55
58
|
# Returns the response from the block
|
56
|
-
def instrument(
|
59
|
+
def instrument(path, body, params)
|
57
60
|
payload = {
|
58
|
-
:
|
59
|
-
:
|
60
|
-
:
|
61
|
-
:
|
62
|
-
:
|
63
|
-
:
|
61
|
+
index: params[:index],
|
62
|
+
type: params[:type],
|
63
|
+
action: params[:action],
|
64
|
+
context: params[:context],
|
65
|
+
request_body: body,
|
66
|
+
body: # for backwards compatibility
|
64
67
|
}
|
65
68
|
|
66
|
-
::
|
69
|
+
::ElastomerClient::Notifications.service.instrument(NAME, payload) do
|
67
70
|
response = yield
|
68
71
|
payload[:url] = response.env[:url]
|
69
72
|
payload[:method] = response.env[:method]
|
70
73
|
payload[:status] = response.status
|
71
74
|
payload[:response_body] = response.body
|
72
|
-
payload[:retries] = params[:retries]
|
73
75
|
response
|
74
76
|
end
|
75
77
|
end
|
@@ -81,6 +83,6 @@ module Elastomer
|
|
81
83
|
# inject our instrument method into the Client class
|
82
84
|
class Client
|
83
85
|
remove_method :instrument
|
84
|
-
include ::
|
86
|
+
include ::ElastomerClient::Notifications
|
85
87
|
end
|
86
88
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ElastomerClient
|
4
|
+
class VersionSupport
|
5
|
+
|
6
|
+
attr_reader :version
|
7
|
+
|
8
|
+
# version - an Elasticsearch version string e.g., 5.6.6 or 8.7.0
|
9
|
+
#
|
10
|
+
# Raises ArgumentError if version is unsupported.
|
11
|
+
def initialize(version)
|
12
|
+
if version < "5.0" || version >= "9.0"
|
13
|
+
raise ArgumentError, "Elasticsearch version #{version} is not supported by elastomer-client"
|
14
|
+
end
|
15
|
+
|
16
|
+
@version = version
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns true if Elasticsearch version is 8.x or higher.
|
20
|
+
def es_version_8_plus?
|
21
|
+
version >= "8.0.0"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/script/bootstrap
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
#!/bin/sh
|
2
|
-
set -
|
2
|
+
set -ex
|
3
3
|
|
4
4
|
cd "$(dirname "$0:a")/.."
|
5
5
|
if bundle check 1>/dev/null 2>&1; then
|
6
6
|
echo "Gem environment up-to-date"
|
7
7
|
else
|
8
|
-
|
8
|
+
echo "Installing gem dependencies"
|
9
|
+
exec bundle install "$@"
|
10
|
+
exec bundle binstubs --all
|
9
11
|
fi
|