elasticsearch-transport 7.8.1 → 7.10.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9756e0b1fd31770784d234514a5adfa267025551dd6de0b803be689353933394
4
- data.tar.gz: e954f524303a9352aecb5591c11409a4271b65bdb7a7669ad16462e835a49356
3
+ metadata.gz: 420122a402e799e70ce7a879b1cabe62cd4750fc356438c0f980a2b78d852fc4
4
+ data.tar.gz: 420a016f766aa19fd8c6400ae8dd78c95d76090c8de38cc1658bbd06348c3136
5
5
  SHA512:
6
- metadata.gz: 42e6e84d9981eb7a96353daa3e571792394d96fef21c7c74e84f97061f39203ba359b431a01e3c7ebdb61245534875a41fa74b4849be215373a1890c6de7ec80
7
- data.tar.gz: 41f46cd5b6b5b30c822318a2743730a2a97bfc18c11abe9eee176e63f6e854a6ec8fce5df25a192f072d1e0536e16a137c9c8e3359cb56aad061382df9512de0
6
+ metadata.gz: ed848e2746878f56203c6c3a9d73a0f995f65cf5854ef262d3504f98f6a889ee74e4c5e7c67bbe0d0a89b1a03c55ddd74e56c2d6efc65adbaabcd0f557653656
7
+ data.tar.gz: c7ba8b088fad4ecb5fd55870f8c50e7fb68b66ca1c157993e69cee0db4205b6371f4b69f83431196e825f22ed08affc35be5c94f5d42b4558d22feb9e0236555
data/README.md CHANGED
@@ -136,7 +136,7 @@ Please see below for an exception to this when connecting using an Elastic Cloud
136
136
 
137
137
  If you are using [Elastic Cloud](https://www.elastic.co/cloud), you can provide your cloud id to the client.
138
138
  You must supply your username and password separately, and optionally a port. If no port is supplied,
139
- port 9243 will be used.
139
+ port 443 will be used.
140
140
 
141
141
  Note: Do not enable sniffing when using Elastic Cloud. The nodes are behind a load balancer so
142
142
  Elastic Cloud will take care of everything for you.
@@ -293,11 +293,16 @@ on a different host:
293
293
 
294
294
  Elasticsearch::Client.new hosts: ['localhost:9200', 'localhost:9201'], retry_on_failure: true
295
295
 
296
- You can specify how many times should the client retry the request before it raises an exception
297
- (the default is 3 times):
296
+ By default, the client will retry the request 3 times. You can specify how many times to retry before it raises an exception by passing a number to `retry_on_failure`:
298
297
 
299
298
  Elasticsearch::Client.new hosts: ['localhost:9200', 'localhost:9201'], retry_on_failure: 5
300
299
 
300
+ These two parameters can also be used together:
301
+
302
+ ```ruby
303
+ Elasticsearch::Client.new hosts: ['localhost:9200', 'localhost:9201'], retry_on_status: [502, 503], retry_on_failure: 10
304
+ ```
305
+
301
306
  ### Reloading Hosts
302
307
 
303
308
  Elasticsearch by default dynamically discovers new nodes in the cluster. You can leverage this
@@ -49,9 +49,15 @@ module Elasticsearch
49
49
  DEFAULT_HOST = 'localhost:9200'.freeze
50
50
 
51
51
  # The default port to use if connecting using a Cloud ID.
52
+ # Updated from 9243 to 443 in client version 7.10.1
52
53
  #
53
54
  # @since 7.2.0
54
- DEFAULT_CLOUD_PORT = 9243
55
+ DEFAULT_CLOUD_PORT = 443
56
+
57
+ # The default port to use if not otherwise specified.
58
+ #
59
+ # @since 7.2.0
60
+ DEFAULT_PORT = 9200
55
61
 
56
62
  # Returns the transport object.
57
63
  #
@@ -190,14 +196,27 @@ module Elasticsearch
190
196
  end
191
197
 
192
198
  def extract_cloud_creds(arguments)
193
- return unless arguments[:cloud_id]
199
+ return unless arguments[:cloud_id] && !arguments[:cloud_id].empty?
200
+
194
201
  name = arguments[:cloud_id].split(':')[0]
195
202
  cloud_url, elasticsearch_instance = Base64.decode64(arguments[:cloud_id].gsub("#{name}:", '')).split('$')
196
- [ { scheme: 'https',
203
+
204
+ if cloud_url.include?(':')
205
+ url, port = cloud_url.split(':')
206
+ host = "#{elasticsearch_instance}.#{url}"
207
+ else
208
+ host = "#{elasticsearch_instance}.#{cloud_url}"
209
+ port = arguments[:port] || DEFAULT_CLOUD_PORT
210
+ end
211
+ [
212
+ {
213
+ scheme: 'https',
197
214
  user: arguments[:user],
198
215
  password: arguments[:password],
199
- host: "#{elasticsearch_instance}.#{cloud_url}",
200
- port: arguments[:port] || DEFAULT_CLOUD_PORT } ]
216
+ host: host,
217
+ port: port.to_i
218
+ }
219
+ ]
201
220
  end
202
221
 
203
222
  # Normalizes and returns hosts configuration.
@@ -230,36 +249,38 @@ module Elasticsearch
230
249
 
231
250
  def __parse_host(host)
232
251
  host_parts = case host
233
- when String
234
- if host =~ /^[a-z]+\:\/\//
235
- # Construct a new `URI::Generic` directly from the array returned by URI::split.
236
- # This avoids `URI::HTTP` and `URI::HTTPS`, which supply default ports.
237
- uri = URI::Generic.new(*URI.split(host))
238
-
239
- { :scheme => uri.scheme,
240
- :user => uri.user,
241
- :password => uri.password,
242
- :host => uri.host,
243
- :path => uri.path,
244
- :port => uri.port }
245
- else
246
- host, port = host.split(':')
247
- { :host => host,
248
- :port => port }
249
- end
250
- when URI
251
- { :scheme => host.scheme,
252
- :user => host.user,
253
- :password => host.password,
254
- :host => host.host,
255
- :path => host.path,
256
- :port => host.port }
257
- when Hash
258
- host
259
- else
260
- raise ArgumentError, "Please pass host as a String, URI or Hash -- #{host.class} given."
261
- end
262
-
252
+ when String
253
+ if host =~ /^[a-z]+\:\/\//
254
+ # Construct a new `URI::Generic` directly from the array returned by URI::split.
255
+ # This avoids `URI::HTTP` and `URI::HTTPS`, which supply default ports.
256
+ uri = URI::Generic.new(*URI.split(host))
257
+ default_port = uri.scheme == 'https' ? 443 : DEFAULT_PORT
258
+ {
259
+ scheme: uri.scheme,
260
+ user: uri.user,
261
+ password: uri.password,
262
+ host: uri.host,
263
+ path: uri.path,
264
+ port: uri.port || default_port
265
+ }
266
+ else
267
+ host, port = host.split(':')
268
+ { host: host, port: port }
269
+ end
270
+ when URI
271
+ {
272
+ scheme: host.scheme,
273
+ user: host.user,
274
+ password: host.password,
275
+ host: host.host,
276
+ path: host.path,
277
+ port: host.port
278
+ }
279
+ when Hash
280
+ host
281
+ else
282
+ raise ArgumentError, "Please pass host as a String, URI or Hash -- #{host.class} given."
283
+ end
263
284
  if @api_key
264
285
  # Remove Basic Auth if using API KEY
265
286
  host_parts.delete(:user)
@@ -47,7 +47,7 @@ module Elasticsearch
47
47
  #
48
48
  # @see Client#initialize
49
49
  #
50
- def initialize(arguments={}, &block)
50
+ def initialize(arguments = {}, &block)
51
51
  @state_mutex = Mutex.new
52
52
 
53
53
  @hosts = arguments[:hosts] || []
@@ -234,9 +234,9 @@ module Elasticsearch
234
234
  def __full_url(host)
235
235
  url = "#{host[:protocol]}://"
236
236
  url += "#{CGI.escape(host[:user])}:#{CGI.escape(host[:password])}@" if host[:user]
237
- url += "#{host[:host]}"
237
+ url += host[:host]
238
238
  url += ":#{host[:port]}" if host[:port]
239
- url += "#{host[:path]}" if host[:path]
239
+ url += host[:path] if host[:path]
240
240
  url
241
241
  end
242
242
 
@@ -258,8 +258,9 @@ module Elasticsearch
258
258
  # @raise [ServerError] If request failed on server
259
259
  # @raise [Error] If no connection is available
260
260
  #
261
- def perform_request(method, path, params={}, body=nil, headers=nil, opts={}, &block)
262
- raise NoMethodError, "Implement this method in your transport class" unless block_given?
261
+ def perform_request(method, path, params = {}, body = nil, headers = nil, opts = {}, &block)
262
+ raise NoMethodError, 'Implement this method in your transport class' unless block_given?
263
+
263
264
  start = Time.now
264
265
  tries = 0
265
266
  reload_on_failure = opts.fetch(:reload_on_failure, @options[:reload_on_failure])
@@ -276,15 +277,15 @@ module Elasticsearch
276
277
 
277
278
  begin
278
279
  tries += 1
279
- connection = get_connection or raise Error.new("Cannot get new connection from pool.")
280
+ connection = get_connection or raise Error.new('Cannot get new connection from pool.')
280
281
 
281
282
  if connection.connection.respond_to?(:params) && connection.connection.params.respond_to?(:to_hash)
282
283
  params = connection.connection.params.merge(params.to_hash)
283
284
  end
284
285
 
285
- url = connection.full_url(path, params)
286
+ url = connection.full_url(path, params)
286
287
 
287
- response = block.call(connection, url)
288
+ response = block.call(connection, url)
288
289
 
289
290
  connection.healthy! if connection.failures > 0
290
291
 
@@ -19,7 +19,6 @@ module Elasticsearch
19
19
  module Transport
20
20
  module Transport
21
21
  module Connections
22
-
23
22
  # Wraps the connection information and logic.
24
23
  #
25
24
  # The Connection instance wraps the host information (hostname, port, attributes, etc),
@@ -54,12 +53,14 @@ module Elasticsearch
54
53
  #
55
54
  # @return [String]
56
55
  #
57
- def full_url(path, params={})
56
+ def full_url(path, params = {})
58
57
  url = "#{host[:protocol]}://"
59
58
  url += "#{CGI.escape(host[:user])}:#{CGI.escape(host[:password])}@" if host[:user]
60
59
  url += "#{host[:host]}:#{host[:port]}"
61
60
  url += "#{host[:path]}" if host[:path]
62
- url += "/#{full_path(path, params)}"
61
+ full_path = full_path(path, params)
62
+ url += '/' unless full_path.match?(/^\//)
63
+ url += full_path
63
64
  end
64
65
 
65
66
  # Returns the complete endpoint path with serialized parameters.
@@ -135,14 +136,15 @@ module Elasticsearch
135
136
  }
136
137
  end
137
138
 
138
- # Equality operator based on connection protocol, host and port
139
+ # Equality operator based on connection protocol, host, port and attributes
139
140
  #
140
141
  # @return [Boolean]
141
142
  #
142
143
  def ==(other)
143
144
  self.host[:protocol] == other.host[:protocol] && \
144
145
  self.host[:host] == other.host[:host] && \
145
- self.host[:port].to_i == other.host[:port].to_i
146
+ self.host[:port].to_i == other.host[:port].to_i && \
147
+ self.host[:attributes] == other.host[:attributes]
146
148
  end
147
149
 
148
150
  # @return [String]
@@ -45,21 +45,21 @@ module Elasticsearch
45
45
  #
46
46
  def hosts
47
47
  Timeout::timeout(timeout, SnifferTimeoutError) do
48
- nodes = transport.perform_request('GET', '_nodes/http', {}, nil, nil,
49
- reload_on_failure: false).body
48
+ nodes = perform_sniff_request.body
50
49
 
51
50
  hosts = nodes['nodes'].map do |id, info|
52
- if info[PROTOCOL]
53
- host, port = parse_publish_address(info[PROTOCOL]['publish_address'])
51
+ next unless info[PROTOCOL]
52
+ host, port = parse_publish_address(info[PROTOCOL]['publish_address'])
54
53
 
55
- { :id => id,
56
- :name => info['name'],
57
- :version => info['version'],
58
- :host => host,
59
- :port => port,
60
- :roles => info['roles'],
61
- :attributes => info['attributes'] }
62
- end
54
+ {
55
+ id: id,
56
+ name: info['name'],
57
+ version: info['version'],
58
+ host: host,
59
+ port: port,
60
+ roles: info['roles'],
61
+ attributes: info['attributes']
62
+ }
63
63
  end.compact
64
64
 
65
65
  hosts.shuffle! if transport.options[:randomize_hosts]
@@ -69,6 +69,13 @@ module Elasticsearch
69
69
 
70
70
  private
71
71
 
72
+ def perform_sniff_request
73
+ transport.perform_request(
74
+ 'GET', '_nodes/http', {}, nil, nil,
75
+ reload_on_failure: false
76
+ )
77
+ end
78
+
72
79
  def parse_publish_address(publish_address)
73
80
  # publish_address is in the format hostname/ip:port
74
81
  if publish_address =~ /\//
@@ -17,6 +17,6 @@
17
17
 
18
18
  module Elasticsearch
19
19
  module Transport
20
- VERSION = "7.8.1"
20
+ VERSION = "7.10.1"
21
21
  end
22
22
  end
@@ -46,10 +46,12 @@ describe Elasticsearch::Transport::Transport::Base do
46
46
 
47
47
  context 'when the user and password are provided as separate arguments' do
48
48
  let(:arguments) do
49
- { hosts: 'fake',
49
+ {
50
+ hosts: 'fake',
50
51
  logger: logger,
51
52
  password: 'secret_password',
52
- user: 'test' }
53
+ user: 'test'
54
+ }
53
55
  end
54
56
 
55
57
  it_behaves_like 'a redacted string'
@@ -57,8 +59,10 @@ describe Elasticsearch::Transport::Transport::Base do
57
59
 
58
60
  context 'when the user and password are provided in the string URI' do
59
61
  let(:arguments) do
60
- { hosts: 'https://test:secret_password@fake_local_elasticsearch',
61
- logger: logger }
62
+ {
63
+ hosts: 'https://test:secret_password@fake_local_elasticsearch',
64
+ logger: logger
65
+ }
62
66
  end
63
67
 
64
68
  it_behaves_like 'a redacted string'
@@ -66,8 +70,10 @@ describe Elasticsearch::Transport::Transport::Base do
66
70
 
67
71
  context 'when the user and password are provided in the URI object' do
68
72
  let(:arguments) do
69
- { hosts: URI.parse('https://test:secret_password@fake_local_elasticsearch'),
70
- logger: logger }
73
+ {
74
+ hosts: URI.parse('https://test:secret_password@fake_local_elasticsearch'),
75
+ logger: logger
76
+ }
71
77
  end
72
78
 
73
79
  it_behaves_like 'a redacted string'
@@ -75,36 +81,32 @@ describe Elasticsearch::Transport::Transport::Base do
75
81
  end
76
82
 
77
83
  context 'when reload_on_failure is true and and hosts are unreachable' do
78
-
79
84
  let(:client) do
80
85
  Elasticsearch::Transport::Client.new(arguments)
81
86
  end
82
87
 
83
88
  let(:arguments) do
84
89
  {
85
- hosts: ['http://unavailable:9200', 'http://unavailable:9201'],
86
- reload_on_failure: true,
87
- sniffer_timeout: 5
90
+ hosts: ['http://unavailable:9200', 'http://unavailable:9201'],
91
+ reload_on_failure: true,
92
+ sniffer_timeout: 5
88
93
  }
89
94
  end
90
95
 
91
96
  it 'raises an exception' do
92
- expect {
93
- client.info
94
- }.to raise_exception(Faraday::ConnectionFailed)
97
+ expect { client.info }.to raise_exception(Faraday::ConnectionFailed)
95
98
  end
96
99
  end
97
100
 
98
101
  context 'when the client has `retry_on_failure` set to an integer' do
99
-
100
102
  let(:client) do
101
103
  Elasticsearch::Transport::Client.new(arguments)
102
104
  end
103
105
 
104
106
  let(:arguments) do
105
107
  {
106
- hosts: ['http://unavailable:9200', 'http://unavailable:9201'],
107
- retry_on_failure: 2
108
+ hosts: ['http://unavailable:9200', 'http://unavailable:9201'],
109
+ retry_on_failure: 2
108
110
  }
109
111
  end
110
112
 
@@ -120,15 +122,34 @@ describe Elasticsearch::Transport::Transport::Base do
120
122
  end
121
123
  end
122
124
 
125
+ context 'when `perform_request` is called with a `retry_on_status` option value' do
126
+ before do
127
+ expect(client.transport).to receive(:__raise_transport_error).exactly(6).times.and_call_original
128
+ end
129
+
130
+ let(:arguments) do
131
+ {
132
+ hosts: ['http://localhost:9250'],
133
+ retry_on_status: ['404']
134
+ }
135
+ end
136
+
137
+ it 'retries on 404 status the specified number of max_retries' do
138
+ expect do
139
+ client.transport.perform_request('GET', 'myindex/mydoc/1?routing=FOOBARBAZ', {}, nil, nil, retry_on_failure: 5)
140
+ end.to raise_exception(Elasticsearch::Transport::Transport::Errors::NotFound)
141
+ end
142
+ end
143
+
123
144
  context 'when `perform_request` is called with a `retry_on_failure` option value' do
124
145
  before do
125
146
  expect(client.transport).to receive(:get_connection).exactly(6).times.and_call_original
126
147
  end
127
148
 
128
149
  it 'uses the option `retry_on_failure` value' do
129
- expect {
150
+ expect do
130
151
  client.transport.perform_request('GET', '/info', {}, nil, nil, retry_on_failure: 5)
131
- }.to raise_exception(Faraday::ConnectionFailed)
152
+ end.to raise_exception(Faraday::ConnectionFailed)
132
153
  end
133
154
  end
134
155
  end
@@ -209,40 +230,35 @@ describe Elasticsearch::Transport::Transport::Base do
209
230
  end
210
231
 
211
232
  context 'when the client has no `retry_on_failure` set' do
212
-
213
233
  let(:client) do
214
234
  Elasticsearch::Transport::Client.new(arguments)
215
235
  end
216
236
 
217
237
  let(:arguments) do
218
- {
219
- hosts: ['http://unavailable:9200', 'http://unavailable:9201'],
220
- }
238
+ { hosts: ['http://unavailable:9200', 'http://unavailable:9201'] }
221
239
  end
222
240
 
223
241
  context 'when `perform_request` is called without a `retry_on_failure` option value' do
224
-
225
242
  before do
226
243
  expect(client.transport).to receive(:get_connection).exactly(1).times.and_call_original
227
244
  end
228
245
 
229
246
  it 'does not retry' do
230
- expect {
247
+ expect do
231
248
  client.transport.perform_request('GET', '/info')
232
- }.to raise_exception(Faraday::ConnectionFailed)
249
+ end.to raise_exception(Faraday::ConnectionFailed)
233
250
  end
234
251
  end
235
252
 
236
253
  context 'when `perform_request` is called with a `retry_on_failure` option value' do
237
-
238
254
  before do
239
255
  expect(client.transport).to receive(:get_connection).exactly(6).times.and_call_original
240
256
  end
241
257
 
242
258
  it 'uses the option `retry_on_failure` value' do
243
- expect {
259
+ expect do
244
260
  client.transport.perform_request('GET', '/info', {}, nil, nil, retry_on_failure: 5)
245
- }.to raise_exception(Faraday::ConnectionFailed)
261
+ end.to raise_exception(Faraday::ConnectionFailed)
246
262
  end
247
263
  end
248
264
  end