elastic-transport 8.1.0 → 8.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -283,26 +283,24 @@ module Elastic
283
283
  # Auto-detect the best adapter (HTTP "driver") available, based on libraries
284
284
  # loaded by the user, preferring those with persistent connections
285
285
  # ("keep-alive") by default
286
- # Check adapters based on the usage of Faraday 1 or 2. Faraday should be defined here
287
- # since this is only called when transport class is Transport::HTTP::Faraday
288
286
  #
289
287
  # @return [Symbol]
290
288
  #
291
289
  # @api private
292
290
  #
293
291
  def __auto_detect_adapter
294
- if Gem::Version.new(Faraday::VERSION) >= Gem::Version.new(2)
295
- return :patron if defined?(Faraday::Adapter::Patron)
296
- return :typhoeus if defined?(Faraday::Adapter::Typhoeus)
297
- return :httpclient if defined?(Faraday::Adapter::HTTPClient)
298
- return :net_http_persistent if defined?(Faraday::Adapter::NetHttpPersistent)
292
+ case
293
+ when defined?(::Patron)
294
+ :patron
295
+ when defined?(::Typhoeus)
296
+ :typhoeus
297
+ when defined?(::HTTPClient)
298
+ :httpclient
299
+ when defined?(::Net::HTTP::Persistent)
300
+ :net_http_persistent
299
301
  else
300
- return :patron if defined?(::Patron)
301
- return :typhoeus if defined?(::Typhoeus)
302
- return :httpclient if defined?(::HTTPClient)
303
- return :net_http_persistent if defined?(::Net::HTTP::Persistent)
302
+ ::Faraday.default_adapter
304
303
  end
305
- ::Faraday.default_adapter
306
304
  end
307
305
  end
308
306
  end
@@ -103,31 +103,31 @@ module Elastic
103
103
  adapter_version = case @arguments[:adapter]
104
104
  when :patron
105
105
  version = Patron::VERSION if defined?(::Patron::VERSION)
106
- { pt: version }
106
+ {pt: version}
107
107
  when :net_http
108
108
  version = if defined?(Net::HTTP::VERSION)
109
109
  Net::HTTP::VERSION
110
110
  elsif defined?(Net::HTTP::HTTPVersion)
111
111
  Net::HTTP::HTTPVersion
112
112
  end
113
- { nh: version }
113
+ {nh: version}
114
114
  when :typhoeus
115
115
  version = Typhoeus::VERSION if defined?(::Typhoeus::VERSION)
116
- { ty: version }
116
+ {ty: version}
117
117
  when :httpclient
118
118
  version = HTTPClient::VERSION if defined?(HTTPClient::VERSION)
119
- { hc: version }
119
+ {hc: version}
120
120
  when :net_http_persistent
121
121
  version = Net::HTTP::Persistent::VERSION if defined?(Net::HTTP::Persistent::VERSION)
122
- { np: version }
122
+ {np: version}
123
123
  else
124
124
  {}
125
125
  end
126
- { fd: Faraday::VERSION }.merge(adapter_version)
126
+ {fd: Faraday::VERSION}.merge(adapter_version)
127
127
  elsif defined?(Transport::HTTP::Curb) && @transport_class == Transport::HTTP::Curb
128
- { cl: Curl::CURB_VERSION }
128
+ {cl: Curl::CURB_VERSION}
129
129
  elsif defined?(Transport::HTTP::Manticore) && @transport_class == Transport::HTTP::Manticore
130
- { mc: Manticore::VERSION }
130
+ {mc: Manticore::VERSION}
131
131
  end
132
132
  end
133
133
  end
@@ -322,16 +322,18 @@ module Elastic
322
322
  reload_connections! and retry
323
323
  end
324
324
 
325
+ exception = Elastic::Transport::Transport::Error.new(e.message)
326
+
325
327
  if max_retries
326
328
  log_warn "[#{e.class}] Attempt #{tries} connecting to #{connection.host.inspect}"
327
329
  if tries <= max_retries
328
330
  retry
329
331
  else
330
332
  log_fatal "[#{e.class}] Cannot connect to #{connection.host.inspect} after #{tries} tries"
331
- raise e
333
+ raise exception
332
334
  end
333
335
  else
334
- raise e
336
+ raise exception
335
337
  end
336
338
  rescue Exception => e
337
339
  log_fatal "[#{e.class}] #{e.message} (#{connection.host.inspect if connection})"
@@ -427,7 +429,7 @@ module Elastic
427
429
  end
428
430
 
429
431
  def apply_headers(client, options)
430
- headers = options[:headers] || {}
432
+ headers = options[:headers].clone || {}
431
433
  headers[CONTENT_TYPE_STR] = find_value(headers, CONTENT_TYPE_REGEX) || DEFAULT_CONTENT_TYPE
432
434
  headers[USER_AGENT_STR] = find_value(headers, USER_AGENT_REGEX) || user_agent_header(client)
433
435
  client.headers[ACCEPT_ENCODING] = GZIP if use_compression?
@@ -37,34 +37,31 @@ module Elastic
37
37
  body, headers = compress_request(body, headers)
38
38
 
39
39
  case method
40
- when 'HEAD'
41
- connection.connection.set :nobody, true
42
- when 'GET', 'POST', 'PUT', 'DELETE'
43
- connection.connection.set :nobody, false
44
- connection.connection.put_data = body if body
40
+ when 'HEAD'
41
+ connection.connection.set :nobody, true
42
+ when 'GET', 'POST', 'PUT', 'DELETE'
43
+ connection.connection.set :nobody, false
44
+ connection.connection.put_data = body if body
45
45
 
46
- if headers
47
- if connection.connection.headers
48
- connection.connection.headers.merge!(headers)
49
- else
50
- connection.connection.headers = headers
46
+ if headers
47
+ if connection.connection.headers
48
+ connection.connection.headers.merge!(headers)
49
+ else
50
+ connection.connection.headers = headers
51
+ end
51
52
  end
52
- end
53
53
 
54
- else raise ArgumentError, "Unsupported HTTP method: #{method}"
54
+ else raise ArgumentError, "Unsupported HTTP method: #{method}"
55
55
  end
56
56
 
57
57
  connection.connection.http(method.to_sym)
58
- header_string = connection.connection.header_str.to_s
59
58
 
60
- _response_status, *response_headers = header_string.split(/[\r\n]+/).map(&:strip)
61
- response_headers = Hash[response_headers.flat_map { |s| s.scan(/^(\S+): (.+)/) }].transform_keys(&:downcase)
59
+ response_headers = {}
60
+ response_headers['content-type'] = 'application/json' if connection.connection.header_str =~ /\/json/
62
61
 
63
- Response.new(
64
- connection.connection.response_code,
65
- decompress_response(connection.connection.body_str),
66
- response_headers
67
- )
62
+ Response.new connection.connection.response_code,
63
+ decompress_response(connection.connection.body_str),
64
+ response_headers
68
65
  end
69
66
  end
70
67
 
@@ -76,7 +73,7 @@ module Elastic
76
73
  client = ::Curl::Easy.new
77
74
 
78
75
  apply_headers(client, options)
79
- client.url = __full_url(host)
76
+ client.url = __full_url(host)
80
77
 
81
78
  if host[:user]
82
79
  client.http_auth_types = host[:auth_type] || :basic
@@ -108,13 +105,13 @@ module Elastic
108
105
 
109
106
  def user_agent_header(client)
110
107
  @user_agent ||= begin
111
- meta = ["RUBY_VERSION: #{RUBY_VERSION}"]
112
- if RbConfig::CONFIG && RbConfig::CONFIG['host_os']
113
- meta << "#{RbConfig::CONFIG['host_os'].split('_').first[/[a-z]+/i].downcase} #{RbConfig::CONFIG['target_cpu']}"
114
- end
115
- meta << "Curb #{Curl::CURB_VERSION}"
116
- "elastic-transport-ruby/#{VERSION} (#{meta.join('; ')})"
117
- end
108
+ meta = ["RUBY_VERSION: #{RUBY_VERSION}"]
109
+ if RbConfig::CONFIG && RbConfig::CONFIG['host_os']
110
+ meta << "#{RbConfig::CONFIG['host_os'].split('_').first[/[a-z]+/i].downcase} #{RbConfig::CONFIG['target_cpu']}"
111
+ end
112
+ meta << "Curb #{Curl::CURB_VERSION}"
113
+ "elastic-transport-ruby/#{VERSION} (#{meta.join('; ')})"
114
+ end
118
115
  end
119
116
  end
120
117
  end
@@ -162,7 +162,7 @@ module Elastic
162
162
  private
163
163
 
164
164
  def apply_headers(options)
165
- headers = options[:headers] || options.dig(:transport_options, :headers) || {}
165
+ headers = options[:headers].clone || options.dig(:transport_options, :headers).clone || {}
166
166
  headers[CONTENT_TYPE_STR] = find_value(headers, CONTENT_TYPE_REGEX) || DEFAULT_CONTENT_TYPE
167
167
  headers[USER_AGENT_STR] = find_value(headers, USER_AGENT_REGEX) || find_value(@request_options[:headers], USER_AGENT_REGEX) || user_agent_header
168
168
  headers[ACCEPT_ENCODING] = GZIP if use_compression?
@@ -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] ]
@@ -17,6 +17,6 @@
17
17
 
18
18
  module Elastic
19
19
  module Transport
20
- VERSION = '8.1.0'.freeze
20
+ VERSION = '8.1.1'.freeze
21
21
  end
22
22
  end
@@ -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
- }.to raise_exception(Faraday::ConnectionFailed)
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
- }.to raise_exception(Faraday::ConnectionFailed)
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(Faraday::ConnectionFailed)
96
+ expect { client.perform_request('GET', '/info') }.to raise_exception(Elastic::Transport::Transport::Error)
97
97
  end
98
98
  end
99
99
 
@@ -105,8 +105,7 @@ describe Elastic::Transport::Transport::Base do
105
105
  let(:arguments) do
106
106
  {
107
107
  hosts: ['http://unavailable:9200', 'http://unavailable:9201'],
108
- retry_on_failure: 2,
109
- adapter: :net_http
108
+ retry_on_failure: 2
110
109
  }
111
110
  end
112
111
 
@@ -116,9 +115,9 @@ describe Elastic::Transport::Transport::Base do
116
115
  end
117
116
 
118
117
  it 'uses the client `retry_on_failure` value' do
119
- expect {
118
+ expect do
120
119
  client.transport.perform_request('GET', '/info')
121
- }.to raise_exception(Faraday::ConnectionFailed)
120
+ end.to raise_exception(Elastic::Transport::Transport::Error)
122
121
  end
123
122
  end
124
123
 
@@ -130,8 +129,7 @@ describe Elastic::Transport::Transport::Base do
130
129
  let(:arguments) do
131
130
  {
132
131
  hosts: ELASTICSEARCH_HOSTS,
133
- retry_on_status: ['404'],
134
- adapter: :net_http
132
+ retry_on_status: ['404']
135
133
  }
136
134
  end
137
135
 
@@ -150,7 +148,7 @@ describe Elastic::Transport::Transport::Base do
150
148
  it 'uses the option `retry_on_failure` value' do
151
149
  expect do
152
150
  client.transport.perform_request('GET', '/info', {}, nil, nil, retry_on_failure: 5)
153
- end.to raise_exception(Faraday::ConnectionFailed)
151
+ end.to raise_exception(Elastic::Transport::Transport::Error)
154
152
  end
155
153
  end
156
154
  end
@@ -162,8 +160,8 @@ describe Elastic::Transport::Transport::Base do
162
160
 
163
161
  let(:arguments) do
164
162
  {
165
- hosts: ['http://unavailable:9200', 'http://unavailable:9201'],
166
- retry_on_failure: true
163
+ hosts: ['http://unavailable:9200', 'http://unavailable:9201'],
164
+ retry_on_failure: true
167
165
  }
168
166
  end
169
167
 
@@ -173,9 +171,9 @@ describe Elastic::Transport::Transport::Base do
173
171
  end
174
172
 
175
173
  it 'uses the default `MAX_RETRIES` value' do
176
- expect {
174
+ expect do
177
175
  client.transport.perform_request('GET', '/info')
178
- }.to raise_exception(Faraday::ConnectionFailed)
176
+ end.to raise_exception(Elastic::Transport::Transport::Error)
179
177
  end
180
178
  end
181
179
 
@@ -185,9 +183,9 @@ describe Elastic::Transport::Transport::Base do
185
183
  end
186
184
 
187
185
  it 'uses the option `retry_on_failure` value' do
188
- expect {
186
+ expect do
189
187
  client.transport.perform_request('GET', '/info', {}, nil, nil, retry_on_failure: 5)
190
- }.to raise_exception(Faraday::ConnectionFailed)
188
+ end.to raise_exception(Elastic::Transport::Transport::Error)
191
189
  end
192
190
  end
193
191
  end
@@ -199,8 +197,8 @@ describe Elastic::Transport::Transport::Base do
199
197
 
200
198
  let(:arguments) do
201
199
  {
202
- hosts: ['http://unavailable:9200', 'http://unavailable:9201'],
203
- retry_on_failure: false
200
+ hosts: ['http://unavailable:9200', 'http://unavailable:9201'],
201
+ retry_on_failure: false
204
202
  }
205
203
  end
206
204
 
@@ -210,22 +208,21 @@ describe Elastic::Transport::Transport::Base do
210
208
  end
211
209
 
212
210
  it 'does not retry' do
213
- expect {
211
+ expect do
214
212
  client.transport.perform_request('GET', '/info')
215
- }.to raise_exception(Faraday::ConnectionFailed)
213
+ end.to raise_exception(Elastic::Transport::Transport::Error)
216
214
  end
217
215
  end
218
216
 
219
217
  context 'when `perform_request` is called with a `retry_on_failure` option value' do
220
-
221
218
  before do
222
219
  expect(client.transport).to receive(:get_connection).exactly(6).times.and_call_original
223
220
  end
224
221
 
225
222
  it 'uses the option `retry_on_failure` value' do
226
- expect {
223
+ expect do
227
224
  client.transport.perform_request('GET', '/info', {}, nil, nil, retry_on_failure: 5)
228
- }.to raise_exception(Faraday::ConnectionFailed)
225
+ end.to raise_exception(Elastic::Transport::Transport::Error)
229
226
  end
230
227
  end
231
228
  end
@@ -247,7 +244,7 @@ describe Elastic::Transport::Transport::Base do
247
244
  it 'does not retry' do
248
245
  expect do
249
246
  client.transport.perform_request('GET', '/info')
250
- end.to raise_exception(Faraday::ConnectionFailed)
247
+ end.to raise_exception(Elastic::Transport::Transport::Error)
251
248
  end
252
249
  end
253
250
 
@@ -259,7 +256,7 @@ describe Elastic::Transport::Transport::Base do
259
256
  it 'uses the option `retry_on_failure` value' do
260
257
  expect do
261
258
  client.transport.perform_request('GET', '/info', {}, nil, nil, retry_on_failure: 5)
262
- end.to raise_exception(Faraday::ConnectionFailed)
259
+ end.to raise_exception(Elastic::Transport::Transport::Error)
263
260
  end
264
261
  end
265
262
  end
@@ -191,8 +191,8 @@ describe Elastic::Transport::Client do
191
191
  it 'uses Faraday NetHttp' do
192
192
  expect(adapter).to eq Faraday::Adapter::NetHttp
193
193
  end
194
- end
195
- end unless jruby?
194
+ end unless jruby?
195
+ end
196
196
 
197
197
  context 'when the adapter is patron' do
198
198
  let(:adapter) do
@@ -204,10 +204,9 @@ describe Elastic::Transport::Client do
204
204
  end
205
205
 
206
206
  it 'uses Faraday with the adapter' do
207
- require 'faraday/patron'
208
207
  expect(adapter).to eq Faraday::Adapter::Patron
209
208
  end
210
- end unless jruby?
209
+ end
211
210
 
212
211
  context 'when the adapter is typhoeus' do
213
212
  let(:adapter) do
@@ -215,8 +214,6 @@ describe Elastic::Transport::Client do
215
214
  end
216
215
 
217
216
  let(:client) do
218
- require 'faraday/typhoeus' if is_faraday_v2?
219
-
220
217
  described_class.new(adapter: :typhoeus, enable_meta_header: false)
221
218
  end
222
219
 
@@ -237,7 +234,7 @@ describe Elastic::Transport::Client do
237
234
  it 'uses Faraday with the adapter' do
238
235
  expect(adapter).to eq Faraday::Adapter::Patron
239
236
  end
240
- end unless jruby?
237
+ end
241
238
 
242
239
  context 'when the adapter can be detected', unless: jruby? do
243
240
  around do |example|
@@ -277,7 +274,7 @@ describe Elastic::Transport::Client do
277
274
  it 'sets the logger' do
278
275
  expect(handlers).to include(Faraday::Response::Logger)
279
276
  end
280
- end unless jruby?
277
+ end
281
278
  end
282
279
 
283
280
  shared_examples_for 'a client that extracts hosts' do
@@ -1266,8 +1263,6 @@ describe Elastic::Transport::Client do
1266
1263
  end
1267
1264
 
1268
1265
  context 'when the Faraday adapter is set in the block' do
1269
- require 'faraday/net_http_persistent' if is_faraday_v2?
1270
-
1271
1266
  let(:client) do
1272
1267
  Elastic::Transport::Client.new(host: ELASTICSEARCH_HOSTS.first, logger: logger) do |client|
1273
1268
  client.adapter(:net_http_persistent)
@@ -1327,9 +1322,9 @@ describe Elastic::Transport::Client do
1327
1322
 
1328
1323
  it 'retries only the specified number of times' do
1329
1324
  expect(client.perform_request('GET', '_nodes/_local'))
1330
- expect {
1325
+ expect do
1331
1326
  client.perform_request('GET', '_nodes/_local')
1332
- }.to raise_exception(Faraday::ConnectionFailed)
1327
+ end.to raise_exception(Elastic::Transport::Transport::Error)
1333
1328
  end
1334
1329
  end
1335
1330
 
@@ -1419,8 +1414,6 @@ describe Elastic::Transport::Client do
1419
1414
  end
1420
1415
 
1421
1416
  context 'when using the HTTPClient adapter' do
1422
- require 'faraday/httpclient'
1423
-
1424
1417
  let(:client) do
1425
1418
  described_class.new(hosts: ELASTICSEARCH_HOSTS, compression: true, adapter: :httpclient, enable_meta_header: false)
1426
1419
  end
@@ -155,7 +155,7 @@ describe Elastic::Transport::Client do
155
155
  expect(headers).to include('x-elastic-client-meta' => meta)
156
156
 
157
157
  Typhoeus = @klass if was_required
158
- end
158
+ end unless jruby?
159
159
 
160
160
  it 'sets adapter in the meta header' do
161
161
  require 'typhoeus'
@@ -163,7 +163,7 @@ describe Elastic::Transport::Client do
163
163
  meta = "#{meta_header},ty=#{Typhoeus::VERSION}"
164
164
  expect(headers).to include('x-elastic-client-meta' => meta)
165
165
  end
166
- end unless jruby?
166
+ end
167
167
 
168
168
  unless jruby?
169
169
  let(:adapter) { :patron }
@@ -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
@@ -74,10 +74,6 @@ def default_client
74
74
  $client ||= Elastic::Transport::Client.new(hosts: ELASTICSEARCH_HOSTS)
75
75
  end
76
76
 
77
- def is_faraday_v2?
78
- Gem::Version.new(Faraday::VERSION) >= Gem::Version.new(2)
79
- end
80
-
81
77
  module Config
82
78
  def self.included(context)
83
79
  # Get the hosts to use to connect an elasticsearch client.
@@ -21,7 +21,7 @@ if JRUBY
21
21
  require 'elastic/transport/transport/http/manticore'
22
22
 
23
23
  class Elastic::Transport::ClientManticoreIntegrationTest < Minitest::Test
24
- context 'Transport' do
24
+ context "Transport" do
25
25
  setup do
26
26
  uri = URI(HOST)
27
27
  @host = {