elastic-transport 8.1.0 → 8.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/.github/workflows/tests.yml +4 -4
- data/CHANGELOG.md +16 -1
- data/CONTRIBUTING.md +58 -0
- data/README.md +6 -542
- data/Rakefile +9 -0
- data/lib/elastic/transport/transport/base.rb +55 -50
- data/lib/elastic/transport/transport/errors.rb +2 -4
- data/lib/elastic/transport/transport/http/faraday.rb +29 -27
- data/lib/elastic/transport/transport/response.rb +3 -2
- data/lib/elastic/transport/transport/sniffer.rb +3 -1
- data/lib/elastic/transport/version.rb +1 -1
- data/spec/elastic/transport/base_spec.rb +22 -23
- data/spec/elastic/transport/client_spec.rb +3 -13
- data/spec/elastic/transport/sniffer_spec.rb +18 -0
- data/spec/spec_helper.rb +0 -1
- data/test/test_helper.rb +0 -1
- data/test/unit/transport_base_test.rb +7 -8
- metadata +4 -3
data/Rakefile
CHANGED
@@ -110,6 +110,15 @@ namespace :docker do
|
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
113
|
+
desc 'Run Ruby console with the Elastic transport client libraries loaded'
|
114
|
+
task :console do
|
115
|
+
require 'irb'
|
116
|
+
require 'irb/completion'
|
117
|
+
require 'elastic-transport'
|
118
|
+
ARGV.clear
|
119
|
+
IRB.start
|
120
|
+
end
|
121
|
+
|
113
122
|
# ----- Documentation tasks ---------------------------------------------------
|
114
123
|
require 'yard'
|
115
124
|
YARD::Rake::YardocTask.new(:doc) do |t|
|
@@ -24,12 +24,12 @@ module Elastic
|
|
24
24
|
include Loggable
|
25
25
|
|
26
26
|
DEFAULT_PORT = 9200
|
27
|
-
DEFAULT_PROTOCOL = 'http'
|
27
|
+
DEFAULT_PROTOCOL = 'http'.freeze
|
28
28
|
DEFAULT_RELOAD_AFTER = 10_000 # Requests
|
29
29
|
DEFAULT_RESURRECT_AFTER = 60 # Seconds
|
30
30
|
DEFAULT_MAX_RETRIES = 3 # Requests
|
31
31
|
DEFAULT_SERIALIZER_CLASS = Serializer::MultiJson
|
32
|
-
SANITIZED_PASSWORD = '*' * (rand(14)+1)
|
32
|
+
SANITIZED_PASSWORD = '*' * (rand(14) + 1)
|
33
33
|
|
34
34
|
attr_reader :hosts, :options, :connections, :counter, :last_request_at, :protocol
|
35
35
|
attr_accessor :serializer, :sniffer, :logger, :tracer,
|
@@ -59,7 +59,7 @@ module Elastic
|
|
59
59
|
@compression = !!@options[:compression]
|
60
60
|
@connections = __build_connections
|
61
61
|
|
62
|
-
@serializer = options[:serializer] || ( options[:serializer_class] ? options[:serializer_class].new(self) : DEFAULT_SERIALIZER_CLASS.new(self)
|
62
|
+
@serializer = options[:serializer] || ( options[:serializer_class] ? options[:serializer_class].new(self) : DEFAULT_SERIALIZER_CLASS.new(self))
|
63
63
|
@protocol = options[:protocol] || DEFAULT_PROTOCOL
|
64
64
|
|
65
65
|
@logger = options[:logger]
|
@@ -72,7 +72,7 @@ module Elastic
|
|
72
72
|
@reload_connections = options[:reload_connections]
|
73
73
|
@reload_after = options[:reload_connections].is_a?(Integer) ? options[:reload_connections] : DEFAULT_RELOAD_AFTER
|
74
74
|
@resurrect_after = options[:resurrect_after] || DEFAULT_RESURRECT_AFTER
|
75
|
-
@retry_on_status = Array(options[:retry_on_status]).map
|
75
|
+
@retry_on_status = Array(options[:retry_on_status]).map(&:to_i)
|
76
76
|
end
|
77
77
|
|
78
78
|
# Returns a connection from the connection pool by delegating to {Connections::Collection#get_connection}.
|
@@ -87,7 +87,7 @@ module Elastic
|
|
87
87
|
resurrect_dead_connections! if Time.now > @last_request_at + @resurrect_after
|
88
88
|
|
89
89
|
@counter_mtx.synchronize { @counter += 1 }
|
90
|
-
reload_connections!
|
90
|
+
reload_connections! if reload_connections && (counter % reload_after).zero?
|
91
91
|
connections.get_connection(options)
|
92
92
|
end
|
93
93
|
|
@@ -97,10 +97,10 @@ module Elastic
|
|
97
97
|
#
|
98
98
|
def reload_connections!
|
99
99
|
hosts = sniffer.hosts
|
100
|
-
__rebuild_connections
|
100
|
+
__rebuild_connections(hosts: hosts, options: options)
|
101
101
|
self
|
102
102
|
rescue SnifferTimeoutError
|
103
|
-
log_error
|
103
|
+
log_error('[SnifferTimeoutError] Timeout when reloading connections.')
|
104
104
|
self
|
105
105
|
end
|
106
106
|
|
@@ -109,7 +109,7 @@ module Elastic
|
|
109
109
|
# @see Connections::Connection#resurrect!
|
110
110
|
#
|
111
111
|
def resurrect_dead_connections!
|
112
|
-
connections.dead.each
|
112
|
+
connections.dead.each(&:resurrect!)
|
113
113
|
end
|
114
114
|
|
115
115
|
# Rebuilds the connections collection in the transport.
|
@@ -128,7 +128,7 @@ module Elastic
|
|
128
128
|
__close_connections
|
129
129
|
|
130
130
|
new_connections = __build_connections
|
131
|
-
stale_connections = @connections.all.
|
131
|
+
stale_connections = @connections.all.reject { |c| new_connections.include?(c) }
|
132
132
|
new_connections = new_connections.reject { |c| @connections.all.include?(c) }
|
133
133
|
|
134
134
|
@connections.remove(stale_connections)
|
@@ -177,8 +177,8 @@ module Elastic
|
|
177
177
|
# @return [Connections::Connection]
|
178
178
|
# @api private
|
179
179
|
#
|
180
|
-
def __build_connection(host, options={}, block=nil)
|
181
|
-
raise NoMethodError,
|
180
|
+
def __build_connection(host, options = {}, block = nil)
|
181
|
+
raise NoMethodError, 'Implement this method in your class'
|
182
182
|
end
|
183
183
|
|
184
184
|
# Closes the connections collection
|
@@ -209,14 +209,14 @@ module Elastic
|
|
209
209
|
#
|
210
210
|
def __trace(method, path, params, headers, body, url, response, json, took, duration)
|
211
211
|
trace_url = "http://localhost:9200/#{path}?pretty" +
|
212
|
-
(
|
212
|
+
(params.empty? ? '' : "&#{::Faraday::Utils::ParamsHash[params].to_query}")
|
213
213
|
trace_body = body ? " -d '#{__convert_to_json(body, :pretty => true)}'" : ''
|
214
214
|
trace_command = "curl -X #{method.to_s.upcase}"
|
215
|
-
trace_command += " -H '#{headers.collect { |k,v| "#{k}: #{v}" }.join(", ")}'" if headers && !headers.empty?
|
215
|
+
trace_command += " -H '#{headers.collect { |k, v| "#{k}: #{v}" }.join(", ")}'" if headers && !headers.empty?
|
216
216
|
trace_command += " '#{trace_url}'#{trace_body}\n"
|
217
217
|
tracer.info trace_command
|
218
218
|
tracer.debug "# #{Time.now.iso8601} [#{response.status}] (#{format('%.3f', duration)}s)\n#"
|
219
|
-
tracer.debug json ? serializer.dump(json, :
|
219
|
+
tracer.debug json ? serializer.dump(json, pretty: true).gsub(/^/, '# ').sub(/\}$/, "\n# }")+"\n" : "# #{response.body}\n"
|
220
220
|
end
|
221
221
|
|
222
222
|
# Raise error specific for the HTTP response status or a generic server error
|
@@ -276,40 +276,37 @@ module Elastic
|
|
276
276
|
reload_on_failure = opts.fetch(:reload_on_failure, @options[:reload_on_failure])
|
277
277
|
delay_on_retry = opts.fetch(:delay_on_retry, @options[:delay_on_retry])
|
278
278
|
|
279
|
-
max_retries =
|
280
|
-
opts[:retry_on_failure] === true ? DEFAULT_MAX_RETRIES : opts[:retry_on_failure]
|
281
|
-
elsif options.key?(:retry_on_failure)
|
282
|
-
options[:retry_on_failure] === true ? DEFAULT_MAX_RETRIES : options[:retry_on_failure]
|
283
|
-
end
|
279
|
+
max_retries = max_retries(opts) || max_retries(options)
|
284
280
|
|
285
281
|
params = params.clone
|
286
|
-
|
282
|
+
# Transforms ignore status codes to Integer
|
283
|
+
ignore = Array(params.delete(:ignore)).compact.map(&:to_i)
|
287
284
|
|
288
285
|
begin
|
289
286
|
sleep(delay_on_retry / 1000.0) if tries > 0
|
290
|
-
tries
|
287
|
+
tries += 1
|
291
288
|
connection = get_connection or raise Error.new('Cannot get new connection from pool.')
|
292
289
|
|
293
|
-
if connection.connection.respond_to?(:params) &&
|
290
|
+
if connection.connection.respond_to?(:params) &&
|
291
|
+
connection.connection.params.respond_to?(:to_hash)
|
294
292
|
params = connection.connection.params.merge(params.to_hash)
|
295
293
|
end
|
296
294
|
|
297
|
-
url
|
295
|
+
url = connection.full_url(path, params)
|
298
296
|
response = block.call(connection, url)
|
299
|
-
connection.healthy! if connection.failures
|
297
|
+
connection.healthy! if connection.failures.positive?
|
300
298
|
|
301
299
|
# Raise an exception so we can catch it for `retry_on_status`
|
302
|
-
__raise_transport_error(response) if response.status.to_i >= 300 &&
|
300
|
+
__raise_transport_error(response) if response.status.to_i >= 300 &&
|
301
|
+
@retry_on_status.include?(response.status.to_i)
|
303
302
|
rescue Elastic::Transport::Transport::ServerError => e
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
log_fatal "[#{e.class}] Cannot get response from #{url} after #{tries} tries"
|
310
|
-
raise e
|
311
|
-
end
|
303
|
+
raise e unless response && @retry_on_status.include?(response.status)
|
304
|
+
|
305
|
+
log_warn "[#{e.class}] Attempt #{tries} to get response from #{url}"
|
306
|
+
if tries <= (max_retries || DEFAULT_MAX_RETRIES)
|
307
|
+
retry
|
312
308
|
else
|
309
|
+
log_fatal "[#{e.class}] Cannot get response from #{url} after #{tries} tries"
|
313
310
|
raise e
|
314
311
|
end
|
315
312
|
rescue *host_unreachable_exceptions => e
|
@@ -317,21 +314,21 @@ module Elastic
|
|
317
314
|
|
318
315
|
connection.dead!
|
319
316
|
|
320
|
-
if reload_on_failure
|
317
|
+
if reload_on_failure && tries < connections.all.size
|
321
318
|
log_warn "[#{e.class}] Reloading connections (attempt #{tries} of #{connections.all.size})"
|
322
319
|
reload_connections! and retry
|
323
320
|
end
|
324
321
|
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
end
|
322
|
+
exception = Elastic::Transport::Transport::Error.new(e.message)
|
323
|
+
|
324
|
+
raise exception unless max_retries
|
325
|
+
|
326
|
+
log_warn "[#{e.class}] Attempt #{tries} connecting to #{connection.host.inspect}"
|
327
|
+
if tries <= max_retries
|
328
|
+
retry
|
333
329
|
else
|
334
|
-
|
330
|
+
log_fatal "[#{e.class}] Cannot connect to #{connection.host.inspect} after #{tries} tries"
|
331
|
+
raise exception
|
335
332
|
end
|
336
333
|
rescue Exception => e
|
337
334
|
log_fatal "[#{e.class}] #{e.message} (#{connection.host.inspect if connection})"
|
@@ -349,8 +346,11 @@ module Elastic
|
|
349
346
|
__raise_transport_error response unless ignore.include?(response.status.to_i)
|
350
347
|
end
|
351
348
|
|
352
|
-
json
|
353
|
-
|
349
|
+
json = serializer.load(response.body) if response.body &&
|
350
|
+
!response.body.empty? &&
|
351
|
+
response.headers &&
|
352
|
+
response.headers["content-type"] =~ /json/
|
353
|
+
took = (json['took'] ? sprintf('%.3fs', json['took'] / 1000.0) : 'n/a') rescue 'n/a'
|
354
354
|
__log_response(method, path, params, body, url, response, json, took, duration) unless ignore.include?(response.status.to_i)
|
355
355
|
__trace(method, path, params, connection_headers(connection), body, url, response, nil, 'N/A', duration) if tracer
|
356
356
|
log_warn(response.headers['warning']) if response.headers&.[]('warning')
|
@@ -372,17 +372,21 @@ module Elastic
|
|
372
372
|
private
|
373
373
|
|
374
374
|
USER_AGENT_STR = 'User-Agent'.freeze
|
375
|
-
USER_AGENT_REGEX = /user
|
375
|
+
USER_AGENT_REGEX = /user-?_?agent/
|
376
376
|
ACCEPT_ENCODING = 'Accept-Encoding'.freeze
|
377
377
|
CONTENT_ENCODING = 'Content-Encoding'.freeze
|
378
378
|
CONTENT_TYPE_STR = 'Content-Type'.freeze
|
379
|
-
CONTENT_TYPE_REGEX = /content
|
379
|
+
CONTENT_TYPE_REGEX = /content-?_?type/
|
380
380
|
DEFAULT_CONTENT_TYPE = 'application/json'.freeze
|
381
381
|
GZIP = 'gzip'.freeze
|
382
382
|
GZIP_FIRST_TWO_BYTES = '1f8b'.freeze
|
383
383
|
HEX_STRING_DIRECTIVE = 'H*'.freeze
|
384
384
|
RUBY_ENCODING = '1.9'.respond_to?(:force_encoding)
|
385
385
|
|
386
|
+
def max_retries(opts)
|
387
|
+
opts[:retry_on_failure] == true ? DEFAULT_MAX_RETRIES : opts[:retry_on_failure]
|
388
|
+
end
|
389
|
+
|
386
390
|
def compress_request(body, headers)
|
387
391
|
if body
|
388
392
|
headers ||= {}
|
@@ -409,7 +413,7 @@ module Elastic
|
|
409
413
|
|
410
414
|
io = StringIO.new(body)
|
411
415
|
gzip_reader = if RUBY_ENCODING
|
412
|
-
Zlib::GzipReader.new(io, :
|
416
|
+
Zlib::GzipReader.new(io, encoding: 'ASCII-8BIT')
|
413
417
|
else
|
414
418
|
Zlib::GzipReader.new(io)
|
415
419
|
end
|
@@ -442,7 +446,7 @@ module Elastic
|
|
442
446
|
end
|
443
447
|
end
|
444
448
|
|
445
|
-
def user_agent_header(
|
449
|
+
def user_agent_header(_client)
|
446
450
|
@user_agent ||= begin
|
447
451
|
meta = ["RUBY_VERSION: #{RUBY_VERSION}"]
|
448
452
|
if RbConfig::CONFIG && RbConfig::CONFIG['host_os']
|
@@ -453,7 +457,8 @@ module Elastic
|
|
453
457
|
end
|
454
458
|
|
455
459
|
def connection_headers(connection)
|
456
|
-
if defined?(Elastic::Transport::Transport::HTTP::Manticore) &&
|
460
|
+
if defined?(Elastic::Transport::Transport::HTTP::Manticore) &&
|
461
|
+
instance_of?(Elastic::Transport::Transport::HTTP::Manticore)
|
457
462
|
@request_options[:headers]
|
458
463
|
else
|
459
464
|
connection.connection.headers
|
@@ -18,7 +18,6 @@
|
|
18
18
|
module Elastic
|
19
19
|
module Transport
|
20
20
|
module Transport
|
21
|
-
|
22
21
|
# Generic client error
|
23
22
|
#
|
24
23
|
class Error < StandardError; end
|
@@ -78,14 +77,13 @@ module Elastic
|
|
78
77
|
505 => 'HTTPVersionNotSupported',
|
79
78
|
506 => 'VariantAlsoNegotiates',
|
80
79
|
510 => 'NotExtended'
|
81
|
-
}
|
80
|
+
}.freeze
|
82
81
|
|
83
|
-
ERRORS = HTTP_STATUSES.
|
82
|
+
ERRORS = HTTP_STATUSES.each_with_object({}) do |error, sum|
|
84
83
|
status, name = error
|
85
84
|
sum[status] = Errors.const_set name, Class.new(ServerError)
|
86
85
|
sum
|
87
86
|
end
|
88
|
-
|
89
87
|
end
|
90
88
|
end
|
91
89
|
end
|
@@ -34,26 +34,27 @@ module Elastic
|
|
34
34
|
#
|
35
35
|
def perform_request(method, path, params = {}, body = nil, headers = nil, opts = {})
|
36
36
|
super do |connection, url|
|
37
|
-
headers =
|
38
|
-
if !headers.nil?
|
39
|
-
connection.connection.headers.merge(headers)
|
40
|
-
else
|
41
|
-
connection.connection.headers
|
42
|
-
end
|
43
|
-
else
|
44
|
-
headers
|
45
|
-
end
|
37
|
+
headers = parse_headers(headers, connection)
|
46
38
|
body = body ? __convert_to_json(body) : nil
|
47
39
|
body, headers = compress_request(body, headers)
|
48
40
|
|
49
|
-
response = connection.connection.run_request(
|
50
|
-
method.downcase.to_sym,
|
51
|
-
url,
|
52
|
-
body,
|
53
|
-
headers
|
54
|
-
)
|
41
|
+
response = connection.connection.run_request(method.downcase.to_sym, url, body, headers)
|
55
42
|
|
56
|
-
Response.new
|
43
|
+
Response.new(response.status, decompress_response(response.body), response.headers)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Merges headers already present in the connection and the ones passed in to perform_request
|
48
|
+
#
|
49
|
+
def parse_headers(headers, connection)
|
50
|
+
if connection.connection.headers
|
51
|
+
if !headers.nil?
|
52
|
+
connection.connection.headers.merge(headers)
|
53
|
+
else
|
54
|
+
connection.connection.headers
|
55
|
+
end
|
56
|
+
else
|
57
|
+
headers
|
57
58
|
end
|
58
59
|
end
|
59
60
|
|
@@ -73,10 +74,10 @@ module Elastic
|
|
73
74
|
#
|
74
75
|
def host_unreachable_exceptions
|
75
76
|
[
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
77
|
+
::Faraday::ConnectionFailed,
|
78
|
+
::Faraday::TimeoutError,
|
79
|
+
::Faraday.const_defined?(:ServerError) ? ::Faraday::ServerError : nil,
|
80
|
+
::Faraday::SSLError
|
80
81
|
].compact
|
81
82
|
end
|
82
83
|
|
@@ -84,13 +85,14 @@ module Elastic
|
|
84
85
|
|
85
86
|
def user_agent_header(client)
|
86
87
|
@user_agent ||= begin
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
88
|
+
meta = ["RUBY_VERSION: #{RUBY_VERSION}"]
|
89
|
+
if RbConfig::CONFIG && RbConfig::CONFIG['host_os']
|
90
|
+
meta << "#{RbConfig::CONFIG['host_os'].split('_').first[/[a-z]+/i].downcase} " \
|
91
|
+
"#{RbConfig::CONFIG['target_cpu']}"
|
92
|
+
end
|
93
|
+
meta << client.headers[USER_AGENT_STR]
|
94
|
+
"elastic-transport-ruby/#{VERSION} (#{meta.join('; ')})"
|
95
|
+
end
|
94
96
|
end
|
95
97
|
end
|
96
98
|
end
|
@@ -19,14 +19,15 @@ module Elastic
|
|
19
19
|
module Transport
|
20
20
|
module Transport
|
21
21
|
# Wraps the response from Elasticsearch.
|
22
|
-
#
|
22
|
+
# It provides `body`, `status` and `headers` methods, but you can treat is as a hash and
|
23
|
+
# access the keys directly.
|
23
24
|
class Response
|
24
25
|
attr_reader :status, :body, :headers
|
25
26
|
|
26
27
|
# @param status [Integer] Response status code
|
27
28
|
# @param body [String] Response body
|
28
29
|
# @param headers [Hash] Response headers
|
29
|
-
def initialize(status, body, headers={})
|
30
|
+
def initialize(status, body, headers = {})
|
30
31
|
@status, @body, @headers = status, body, headers
|
31
32
|
@body = body.force_encoding('UTF-8') if body.respond_to?(:force_encoding)
|
32
33
|
end
|
@@ -76,7 +76,9 @@ module Elastic
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def parse_publish_address(publish_address)
|
79
|
-
# publish_address is in the format hostname/ip:port
|
79
|
+
# When publish_address is in the format 'inet[hostname/ip:port]'
|
80
|
+
return parse_address_port(publish_address[6..-2]) if publish_address =~ /^inet\[.*\]$/
|
81
|
+
|
80
82
|
if publish_address =~ /\//
|
81
83
|
parts = publish_address.partition('/')
|
82
84
|
[ parts[0], parse_address_port(parts[2])[1] ]
|
@@ -30,16 +30,16 @@ describe Elastic::Transport::Transport::Base do
|
|
30
30
|
|
31
31
|
it 'does not include the password in the logged string' do
|
32
32
|
expect(logger).not_to receive(:error).with(/secret_password/)
|
33
|
-
expect
|
33
|
+
expect do
|
34
34
|
client.perform_request('GET', '/_cluster/stats')
|
35
|
-
|
35
|
+
end.to raise_exception(Elastic::Transport::Transport::Error)
|
36
36
|
end
|
37
37
|
|
38
38
|
it 'replaces the password with the string \'REDACTED\'' do
|
39
39
|
expect(logger).to receive(:error).with(/REDACTED/)
|
40
|
-
expect
|
40
|
+
expect do
|
41
41
|
client.perform_request('GET', '/_cluster/stats')
|
42
|
-
|
42
|
+
end.to raise_exception(Elastic::Transport::Transport::Error)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -93,7 +93,7 @@ describe Elastic::Transport::Transport::Base do
|
|
93
93
|
end
|
94
94
|
|
95
95
|
it 'raises an exception' do
|
96
|
-
expect { client.perform_request('GET', '/info') }.to raise_exception(
|
96
|
+
expect { client.perform_request('GET', '/info') }.to raise_exception(Elastic::Transport::Transport::Error)
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
@@ -116,9 +116,9 @@ describe Elastic::Transport::Transport::Base do
|
|
116
116
|
end
|
117
117
|
|
118
118
|
it 'uses the client `retry_on_failure` value' do
|
119
|
-
expect
|
119
|
+
expect do
|
120
120
|
client.transport.perform_request('GET', '/info')
|
121
|
-
|
121
|
+
end.to raise_exception(Elastic::Transport::Transport::Error)
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
@@ -150,7 +150,7 @@ describe Elastic::Transport::Transport::Base do
|
|
150
150
|
it 'uses the option `retry_on_failure` value' do
|
151
151
|
expect do
|
152
152
|
client.transport.perform_request('GET', '/info', {}, nil, nil, retry_on_failure: 5)
|
153
|
-
end.to raise_exception(
|
153
|
+
end.to raise_exception(Elastic::Transport::Transport::Error)
|
154
154
|
end
|
155
155
|
end
|
156
156
|
end
|
@@ -162,8 +162,8 @@ describe Elastic::Transport::Transport::Base do
|
|
162
162
|
|
163
163
|
let(:arguments) do
|
164
164
|
{
|
165
|
-
|
166
|
-
|
165
|
+
hosts: ['http://unavailable:9200', 'http://unavailable:9201'],
|
166
|
+
retry_on_failure: true
|
167
167
|
}
|
168
168
|
end
|
169
169
|
|
@@ -173,9 +173,9 @@ describe Elastic::Transport::Transport::Base do
|
|
173
173
|
end
|
174
174
|
|
175
175
|
it 'uses the default `MAX_RETRIES` value' do
|
176
|
-
expect
|
176
|
+
expect do
|
177
177
|
client.transport.perform_request('GET', '/info')
|
178
|
-
|
178
|
+
end.to raise_exception(Elastic::Transport::Transport::Error)
|
179
179
|
end
|
180
180
|
end
|
181
181
|
|
@@ -185,9 +185,9 @@ describe Elastic::Transport::Transport::Base do
|
|
185
185
|
end
|
186
186
|
|
187
187
|
it 'uses the option `retry_on_failure` value' do
|
188
|
-
expect
|
188
|
+
expect do
|
189
189
|
client.transport.perform_request('GET', '/info', {}, nil, nil, retry_on_failure: 5)
|
190
|
-
|
190
|
+
end.to raise_exception(Elastic::Transport::Transport::Error)
|
191
191
|
end
|
192
192
|
end
|
193
193
|
end
|
@@ -199,8 +199,8 @@ describe Elastic::Transport::Transport::Base do
|
|
199
199
|
|
200
200
|
let(:arguments) do
|
201
201
|
{
|
202
|
-
|
203
|
-
|
202
|
+
hosts: ['http://unavailable:9200', 'http://unavailable:9201'],
|
203
|
+
retry_on_failure: false
|
204
204
|
}
|
205
205
|
end
|
206
206
|
|
@@ -210,22 +210,21 @@ describe Elastic::Transport::Transport::Base do
|
|
210
210
|
end
|
211
211
|
|
212
212
|
it 'does not retry' do
|
213
|
-
expect
|
213
|
+
expect do
|
214
214
|
client.transport.perform_request('GET', '/info')
|
215
|
-
|
215
|
+
end.to raise_exception(Elastic::Transport::Transport::Error)
|
216
216
|
end
|
217
217
|
end
|
218
218
|
|
219
219
|
context 'when `perform_request` is called with a `retry_on_failure` option value' do
|
220
|
-
|
221
220
|
before do
|
222
221
|
expect(client.transport).to receive(:get_connection).exactly(6).times.and_call_original
|
223
222
|
end
|
224
223
|
|
225
224
|
it 'uses the option `retry_on_failure` value' do
|
226
|
-
expect
|
225
|
+
expect do
|
227
226
|
client.transport.perform_request('GET', '/info', {}, nil, nil, retry_on_failure: 5)
|
228
|
-
|
227
|
+
end.to raise_exception(Elastic::Transport::Transport::Error)
|
229
228
|
end
|
230
229
|
end
|
231
230
|
end
|
@@ -247,7 +246,7 @@ describe Elastic::Transport::Transport::Base do
|
|
247
246
|
it 'does not retry' do
|
248
247
|
expect do
|
249
248
|
client.transport.perform_request('GET', '/info')
|
250
|
-
end.to raise_exception(
|
249
|
+
end.to raise_exception(Elastic::Transport::Transport::Error)
|
251
250
|
end
|
252
251
|
end
|
253
252
|
|
@@ -259,7 +258,7 @@ describe Elastic::Transport::Transport::Base do
|
|
259
258
|
it 'uses the option `retry_on_failure` value' do
|
260
259
|
expect do
|
261
260
|
client.transport.perform_request('GET', '/info', {}, nil, nil, retry_on_failure: 5)
|
262
|
-
end.to raise_exception(
|
261
|
+
end.to raise_exception(Elastic::Transport::Transport::Error)
|
263
262
|
end
|
264
263
|
end
|
265
264
|
end
|
@@ -1194,17 +1194,7 @@ describe Elastic::Transport::Client do
|
|
1194
1194
|
|
1195
1195
|
context 'when the client connects to Elasticsearch' do
|
1196
1196
|
let(:logger) do
|
1197
|
-
Logger.new(
|
1198
|
-
logger.formatter = proc do |severity, datetime, progname, msg|
|
1199
|
-
color = case severity
|
1200
|
-
when /INFO/ then :green
|
1201
|
-
when /ERROR|WARN|FATAL/ then :red
|
1202
|
-
when /DEBUG/ then :cyan
|
1203
|
-
else :white
|
1204
|
-
end
|
1205
|
-
ANSI.ansi(severity[0] + ' ', color, :faint) + ANSI.ansi(msg, :white, :faint) + "\n"
|
1206
|
-
end
|
1207
|
-
end unless ENV['QUIET']
|
1197
|
+
Logger.new($stderr) unless ENV['QUIET']
|
1208
1198
|
end
|
1209
1199
|
|
1210
1200
|
let(:port) do
|
@@ -1327,9 +1317,9 @@ describe Elastic::Transport::Client do
|
|
1327
1317
|
|
1328
1318
|
it 'retries only the specified number of times' do
|
1329
1319
|
expect(client.perform_request('GET', '_nodes/_local'))
|
1330
|
-
expect
|
1320
|
+
expect do
|
1331
1321
|
client.perform_request('GET', '_nodes/_local')
|
1332
|
-
|
1322
|
+
end.to raise_exception(Elastic::Transport::Transport::Error)
|
1333
1323
|
end
|
1334
1324
|
end
|
1335
1325
|
|
@@ -257,6 +257,24 @@ describe Elastic::Transport::Transport::Sniffer do
|
|
257
257
|
end
|
258
258
|
end
|
259
259
|
|
260
|
+
context 'when the address is IPv4' do
|
261
|
+
let(:publish_address) do
|
262
|
+
'inet[/127.0.0.1:9200]'
|
263
|
+
end
|
264
|
+
|
265
|
+
it 'parses the response' do
|
266
|
+
expect(hosts.size).to eq(1)
|
267
|
+
end
|
268
|
+
|
269
|
+
it 'correctly parses the host' do
|
270
|
+
expect(hosts[0][:host]).to eq('127.0.0.1')
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'correctly parses the port' do
|
274
|
+
expect(hosts[0][:port]).to eq('9200')
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
260
278
|
context 'when the transport has :randomize_hosts option' do
|
261
279
|
let(:raw_response) do
|
262
280
|
{ 'nodes' => { 'n1' => { 'http' => { 'publish_address' => '127.0.0.1:9250' } },
|
data/spec/spec_helper.rb
CHANGED