elastomer-client 3.2.2 → 6.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 +29 -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 +6 -4
- 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 +165 -143
- 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 +76 -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
|