elasticsearch-transport 7.13.3 → 7.17.11
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/Gemfile +9 -9
- data/Gemfile-faraday1.gemfile +47 -0
- data/README.md +3 -8
- data/Rakefile +47 -10
- data/elasticsearch-transport.gemspec +17 -18
- data/lib/elasticsearch/transport/client.rb +34 -3
- data/lib/elasticsearch/transport/transport/base.rb +41 -22
- data/lib/elasticsearch/transport/transport/connections/connection.rb +2 -1
- data/lib/elasticsearch/transport/transport/errors.rb +1 -0
- data/lib/elasticsearch/transport/transport/http/curb.rb +44 -32
- data/lib/elasticsearch/transport/transport/http/faraday.rb +5 -3
- data/lib/elasticsearch/transport/transport/http/manticore.rb +41 -29
- data/lib/elasticsearch/transport/transport/response.rb +1 -1
- data/lib/elasticsearch/transport/version.rb +1 -1
- data/lib/elasticsearch/transport.rb +19 -30
- data/spec/elasticsearch/transport/base_spec.rb +50 -9
- data/spec/elasticsearch/transport/client_spec.rb +138 -64
- data/spec/elasticsearch/transport/http/curb_spec.rb +126 -0
- data/spec/elasticsearch/transport/http/faraday_spec.rb +141 -0
- data/spec/elasticsearch/transport/http/manticore_spec.rb +161 -0
- data/spec/elasticsearch/transport/meta_header_spec.rb +66 -30
- data/spec/spec_helper.rb +13 -5
- data/test/integration/jruby_test.rb +43 -0
- data/test/integration/transport_test.rb +89 -52
- data/test/test_helper.rb +10 -22
- data/test/unit/adapters_test.rb +88 -0
- data/test/unit/response_test.rb +1 -1
- data/test/unit/transport_base_test.rb +16 -7
- data/test/unit/transport_curb_test.rb +0 -1
- data/test/unit/transport_manticore_test.rb +242 -155
- metadata +68 -79
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59b2557cbc0cae9a06df0884cf46555a7ea77340ef225cb16a7a1609dc9406dc
|
4
|
+
data.tar.gz: 073e138b197584481816f64643555d01a8da358bfc361664deb684c146c1ca87
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 62b023fbdde3ee2b0c493fcddadf1264cdfdfedc254bd7a4981b512ea3bb40b776cf43e66decc2842a43673de3006ddde470d5a7e06a30357ab126676bfa6222
|
7
|
+
data.tar.gz: 142543397abf64b400f1ba6873fc8672b78a94e5ffdf7451c99e0eab5fe337f251087aeb68e607fa7ae1af5411745e880020678cf6d73f473a6eecf3564f14d7
|
data/Gemfile
CHANGED
@@ -20,23 +20,23 @@ source 'https://rubygems.org'
|
|
20
20
|
# Specify your gem's dependencies in elasticsearch-transport.gemspec
|
21
21
|
gemspec
|
22
22
|
|
23
|
-
if File.exist? File.expand_path('
|
24
|
-
gem 'elasticsearch-api', path: File.expand_path('
|
23
|
+
if File.exist? File.expand_path('../elasticsearch-api/elasticsearch-api.gemspec', __dir__)
|
24
|
+
gem 'elasticsearch-api', path: File.expand_path('../elasticsearch-api', __dir__), require: false
|
25
25
|
end
|
26
26
|
|
27
|
-
if File.exist? File.expand_path('
|
28
|
-
gem 'elasticsearch
|
29
|
-
end
|
30
|
-
|
31
|
-
if File.exist? File.expand_path('../../elasticsearch/elasticsearch.gemspec', __FILE__)
|
32
|
-
gem 'elasticsearch', path: File.expand_path('../../elasticsearch', __FILE__), require: false
|
27
|
+
if File.exist? File.expand_path('../elasticsearch/elasticsearch.gemspec', __dir__)
|
28
|
+
gem 'elasticsearch', path: File.expand_path('../elasticsearch', __dir__), require: false
|
33
29
|
end
|
34
30
|
|
35
31
|
group :development, :test do
|
32
|
+
gem 'faraday-httpclient'
|
33
|
+
gem 'faraday-net_http_persistent'
|
34
|
+
gem 'faraday-patron' unless defined? JRUBY_VERSION
|
35
|
+
gem 'faraday-typhoeus'
|
36
36
|
gem 'rspec'
|
37
37
|
if defined?(JRUBY_VERSION)
|
38
38
|
gem 'pry-nav'
|
39
39
|
else
|
40
|
-
gem 'pry-byebug'
|
40
|
+
gem 'pry-byebug', '~> 3.9'
|
41
41
|
end
|
42
42
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# Licensed to Elasticsearch B.V. under one or more contributor
|
2
|
+
# license agreements. See the NOTICE file distributed with
|
3
|
+
# this work for additional information regarding copyright
|
4
|
+
# ownership. Elasticsearch B.V. licenses this file to you under
|
5
|
+
# the Apache License, Version 2.0 (the "License"); you may
|
6
|
+
# not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
12
|
+
# software distributed under the License is distributed on an
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
+
# KIND, either express or implied. See the License for the
|
15
|
+
# specific language governing permissions and limitations
|
16
|
+
# under the License.
|
17
|
+
|
18
|
+
source 'https://rubygems.org'
|
19
|
+
|
20
|
+
# Usage:
|
21
|
+
#
|
22
|
+
# $ BUNDLE_GEMFILE=./Gemfile-faraday1.gemfile bundle install
|
23
|
+
# $ BUNDLE_GEMFILE=./Gemfile-faraday1.gemfile bundle exec rake test:faraday1:unit
|
24
|
+
|
25
|
+
gem 'faraday', '~> 1'
|
26
|
+
gemspec path: './'
|
27
|
+
|
28
|
+
if File.exist? File.expand_path('../elasticsearch-api/elasticsearch-api.gemspec', __dir__)
|
29
|
+
gem 'elasticsearch-api', path: File.expand_path('../elasticsearch-api', __dir__), require: false
|
30
|
+
end
|
31
|
+
|
32
|
+
if File.exist? File.expand_path('../elasticsearch/elasticsearch.gemspec', __dir__)
|
33
|
+
gem 'elasticsearch', path: File.expand_path('../elasticsearch', __dir__), require: false
|
34
|
+
end
|
35
|
+
|
36
|
+
group :development, :test do
|
37
|
+
gem 'httpclient'
|
38
|
+
gem 'net-http-persistent'
|
39
|
+
gem 'patron' unless defined? JRUBY_VERSION
|
40
|
+
gem 'typhoeus'
|
41
|
+
gem 'rspec'
|
42
|
+
if defined?(JRUBY_VERSION)
|
43
|
+
gem 'pry-nav'
|
44
|
+
else
|
45
|
+
gem 'pry-byebug'
|
46
|
+
end
|
47
|
+
end
|
data/README.md
CHANGED
@@ -424,10 +424,7 @@ To configure the _Faraday_ instance directly, use a block:
|
|
424
424
|
f.adapter :patron
|
425
425
|
end
|
426
426
|
|
427
|
-
You can use any standard Faraday middleware and plugins in the configuration block
|
428
|
-
|
429
|
-
You can also initialize the transport class yourself, and pass it to the client constructor
|
430
|
-
as the `transport` argument:
|
427
|
+
You can use any standard Faraday middleware and plugins in the configuration block. You can also initialize the transport class yourself, and pass it to the client constructor as the `transport` argument:
|
431
428
|
|
432
429
|
```ruby
|
433
430
|
require 'patron'
|
@@ -561,16 +558,14 @@ Github's pull requests and issues are used to communicate, send bug reports and
|
|
561
558
|
To work on the code, clone and bootstrap the main repository first --
|
562
559
|
please see instructions in the main [README](../README.md#development).
|
563
560
|
|
564
|
-
To run tests, launch a testing cluster
|
565
|
-
in the main [README](../README.md#development) -- and use the Rake tasks:
|
561
|
+
To run tests, launch a testing cluster and use the Rake tasks:
|
566
562
|
|
567
563
|
```
|
568
564
|
time rake test:unit
|
569
565
|
time rake test:integration
|
570
566
|
```
|
571
567
|
|
572
|
-
|
573
|
-
can use Ruby 2.x syntax and features.
|
568
|
+
Use `COVERAGE=true` before running a test task to check coverage with Simplecov.
|
574
569
|
|
575
570
|
## License
|
576
571
|
|
data/Rakefile
CHANGED
@@ -25,40 +25,77 @@ task :test => 'test:unit'
|
|
25
25
|
|
26
26
|
require 'rake/testtask'
|
27
27
|
require 'rspec/core/rake_task'
|
28
|
+
FARADAY1_GEMFILE = 'Gemfile-faraday1.gemfile'.freeze
|
29
|
+
GEMFILES = ['Gemfile', FARADAY1_GEMFILE].freeze
|
28
30
|
|
29
|
-
|
31
|
+
task :install do
|
32
|
+
GEMFILES.each do |gemfile|
|
33
|
+
gemfile = File.expand_path("../#{gemfile}", __FILE__)
|
34
|
+
sh "bundle install --gemfile #{gemfile}"
|
35
|
+
end
|
36
|
+
end
|
30
37
|
|
31
|
-
|
38
|
+
namespace :test do
|
39
|
+
desc 'Wait for Elasticsearch to be in a green state'
|
32
40
|
task :wait_for_green do
|
33
41
|
sh '../scripts/wait-cluster.sh'
|
34
42
|
end
|
35
43
|
|
36
|
-
task :spec => :wait_for_green
|
37
44
|
RSpec::Core::RakeTask.new(:spec)
|
38
45
|
|
39
46
|
Rake::TestTask.new(:unit) do |test|
|
40
47
|
test.libs << 'lib' << 'test'
|
41
|
-
test.test_files = FileList[
|
48
|
+
test.test_files = FileList['test/unit/**/*_test.rb']
|
42
49
|
test.verbose = false
|
43
50
|
test.warning = false
|
44
51
|
end
|
45
52
|
|
46
53
|
Rake::TestTask.new(:integration) do |test|
|
47
54
|
test.libs << 'lib' << 'test'
|
48
|
-
test.test_files = FileList[
|
49
|
-
test.deps = [
|
55
|
+
test.test_files = FileList['test/integration/**/*_test.rb']
|
56
|
+
test.deps = ['test:wait_for_green', 'test:spec']
|
50
57
|
test.verbose = false
|
51
58
|
test.warning = false
|
52
59
|
end
|
53
60
|
|
54
|
-
|
55
|
-
|
56
|
-
|
61
|
+
desc 'Run all tests'
|
62
|
+
task :all do
|
63
|
+
Rake::Task['test:unit'].invoke
|
64
|
+
Rake::Task['test:spec'].invoke
|
65
|
+
Rake::Task['test:integration'].invoke
|
57
66
|
end
|
58
67
|
|
59
68
|
Rake::TestTask.new(:profile) do |test|
|
60
69
|
test.libs << 'lib' << 'test'
|
61
|
-
test.test_files = FileList[
|
70
|
+
test.test_files = FileList['test/profile/**/*_test.rb']
|
71
|
+
end
|
72
|
+
|
73
|
+
namespace :faraday1 do
|
74
|
+
desc 'Faraday 1: Run RSpec with dependency on Faraday 1'
|
75
|
+
task :spec do
|
76
|
+
sh "BUNDLE_GEMFILE=#{FARADAY1_GEMFILE} bundle exec rspec"
|
77
|
+
end
|
78
|
+
|
79
|
+
desc 'Faraday 1: Run unit tests with dependency on Faraday 1'
|
80
|
+
task :unit do
|
81
|
+
Dir.glob('./test/unit/**/**.rb').each do |test|
|
82
|
+
sh "BUNDLE_GEMFILE=#{FARADAY1_GEMFILE} ruby -Ilib:test #{test}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
desc 'Faraday 1: Run integration tests with dependency on Faraday 1'
|
87
|
+
task :integration do
|
88
|
+
Dir.glob('./test/integration/**/**.rb').each do |test|
|
89
|
+
sh "BUNDLE_GEMFILE=#{FARADAY1_GEMFILE} ruby -Ilib:test #{test}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
desc 'Faraday 1: Run all tests'
|
94
|
+
task :all do
|
95
|
+
Rake::Task['test:faraday1:unit'].invoke
|
96
|
+
Rake::Task['test:faraday1:spec'].invoke
|
97
|
+
Rake::Task['test:faraday1:integration'].invoke
|
98
|
+
end
|
62
99
|
end
|
63
100
|
|
64
101
|
namespace :cluster do
|
@@ -26,12 +26,12 @@ Gem::Specification.new do |s|
|
|
26
26
|
s.authors = ['Karel Minarik']
|
27
27
|
s.email = ['karel.minarik@elasticsearch.org']
|
28
28
|
s.summary = 'Ruby client for Elasticsearch.'
|
29
|
-
s.homepage = 'https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/7.
|
29
|
+
s.homepage = 'https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/7.16/index.html'
|
30
30
|
s.license = 'Apache-2.0'
|
31
31
|
s.metadata = {
|
32
|
-
'homepage_uri' => 'https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/7.
|
33
|
-
'changelog_uri' => 'https://github.com/elastic/elasticsearch-ruby/blob/7.
|
34
|
-
'source_code_uri' => 'https://github.com/elastic/elasticsearch-ruby/tree/7.
|
32
|
+
'homepage_uri' => 'https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/7.16/index.html',
|
33
|
+
'changelog_uri' => 'https://github.com/elastic/elasticsearch-ruby/blob/7.16/CHANGELOG.md',
|
34
|
+
'source_code_uri' => 'https://github.com/elastic/elasticsearch-ruby/tree/7.16/elasticsearch-transport',
|
35
35
|
'bug_tracker_uri' => 'https://github.com/elastic/elasticsearch-ruby/issues'
|
36
36
|
}
|
37
37
|
s.files = `git ls-files`.split($/)
|
@@ -44,32 +44,31 @@ Gem::Specification.new do |s|
|
|
44
44
|
|
45
45
|
s.required_ruby_version = '>= 2.4'
|
46
46
|
|
47
|
+
s.add_dependency 'base64'
|
47
48
|
s.add_dependency 'multi_json'
|
48
|
-
s.add_dependency 'faraday', '
|
49
|
+
s.add_dependency 'faraday', '>= 1', '< 3'
|
49
50
|
|
51
|
+
# Faraday Adapters
|
52
|
+
s.add_development_dependency 'manticore' if defined? JRUBY_VERSION
|
53
|
+
s.add_development_dependency 'curb' unless defined? JRUBY_VERSION
|
54
|
+
s.add_development_dependency 'ansi'
|
55
|
+
s.add_development_dependency 'bundler'
|
50
56
|
s.add_development_dependency 'cane'
|
51
|
-
s.add_development_dependency '
|
57
|
+
s.add_development_dependency 'elasticsearch', ['>= 7', '< 8.0.0']
|
52
58
|
s.add_development_dependency 'elasticsearch-extensions'
|
59
|
+
s.add_development_dependency 'hashie'
|
53
60
|
s.add_development_dependency 'minitest'
|
54
61
|
s.add_development_dependency 'minitest-reporters'
|
55
|
-
s.add_development_dependency 'rake', '~> 13'
|
56
|
-
s.add_development_dependency 'require-prof' unless defined?(JRUBY_VERSION) || defined?(Rubinius)
|
57
|
-
s.add_development_dependency 'ruby-prof' unless defined?(JRUBY_VERSION) || defined?(Rubinius)
|
58
|
-
s.add_development_dependency 'simplecov', '~> 0.17', '< 0.18'
|
59
|
-
s.add_development_dependency 'simplecov-rcov'
|
60
|
-
s.add_development_dependency 'ansi'
|
61
|
-
s.add_development_dependency 'hashie'
|
62
|
-
s.add_development_dependency 'httpclient'
|
63
|
-
s.add_development_dependency 'manticore', '~> 0.6' if defined? JRUBY_VERSION
|
64
62
|
s.add_development_dependency 'mocha'
|
65
|
-
s.add_development_dependency 'net-http-persistent'
|
66
63
|
s.add_development_dependency 'patron' unless defined? JRUBY_VERSION
|
67
64
|
s.add_development_dependency 'pry'
|
65
|
+
s.add_development_dependency 'rake', '~> 13'
|
66
|
+
s.add_development_dependency 'require-prof' unless defined?(JRUBY_VERSION) || defined?(Rubinius)
|
67
|
+
s.add_development_dependency 'ruby-prof' unless defined?(JRUBY_VERSION) || defined?(Rubinius)
|
68
68
|
s.add_development_dependency 'shoulda-context'
|
69
|
+
s.add_development_dependency 'simplecov'
|
69
70
|
s.add_development_dependency 'test-unit', '~> 2'
|
70
|
-
s.add_development_dependency 'typhoeus', '~> 1.4'
|
71
71
|
s.add_development_dependency 'yard'
|
72
|
-
s.add_development_dependency 'bundler'
|
73
72
|
|
74
73
|
s.description = <<-DESC.gsub(/^ /, '')
|
75
74
|
Ruby client for Elasticsearch. See the `elasticsearch` gem for full integration.
|
@@ -20,14 +20,13 @@ require 'elasticsearch/transport/meta_header'
|
|
20
20
|
|
21
21
|
module Elasticsearch
|
22
22
|
module Transport
|
23
|
-
|
24
23
|
# Handles communication with an Elasticsearch cluster.
|
25
24
|
#
|
26
25
|
# See {file:README.md README} for usage and code examples.
|
27
26
|
#
|
28
27
|
class Client
|
29
28
|
include MetaHeader
|
30
|
-
DEFAULT_TRANSPORT_CLASS
|
29
|
+
DEFAULT_TRANSPORT_CLASS = Transport::HTTP::Faraday
|
31
30
|
|
32
31
|
DEFAULT_LOGGER = lambda do
|
33
32
|
require 'logger'
|
@@ -93,6 +92,8 @@ module Elasticsearch
|
|
93
92
|
#
|
94
93
|
# @option arguments [Boolean,Number] :retry_on_failure Retry X times when request fails before raising and
|
95
94
|
# exception (false by default)
|
95
|
+
# @option arguments [Number] :delay_on_retry Delay in milliseconds between each retry (0 by default)
|
96
|
+
#
|
96
97
|
# @option arguments Array<Number> :retry_on_status Retry when specific status codes are returned
|
97
98
|
#
|
98
99
|
# @option arguments [Boolean] :reload_on_failure Reload connections after failure (false by default)
|
@@ -127,6 +128,7 @@ module Elasticsearch
|
|
127
128
|
# if you're using X-Opaque-Id
|
128
129
|
# @option enable_meta_header [Boolean] :enable_meta_header Enable sending the meta data header to Cloud.
|
129
130
|
# (Default: true)
|
131
|
+
# @option ca_fingerprint [String] :ca_fingerprint provide this value to only trust certificates that are signed by a specific CA certificate
|
130
132
|
#
|
131
133
|
# @yield [faraday] Access and configure the `Faraday::Connection` instance directly with a block
|
132
134
|
#
|
@@ -137,6 +139,7 @@ module Elasticsearch
|
|
137
139
|
@arguments[:tracer] ||= @arguments[:trace] ? DEFAULT_TRACER.call() : nil
|
138
140
|
@arguments[:reload_connections] ||= false
|
139
141
|
@arguments[:retry_on_failure] ||= false
|
142
|
+
@arguments[:delay_on_retry] ||= 0
|
140
143
|
@arguments[:reload_on_failure] ||= false
|
141
144
|
@arguments[:randomize_hosts] ||= false
|
142
145
|
@arguments[:transport_options] ||= {}
|
@@ -157,6 +160,7 @@ module Elasticsearch
|
|
157
160
|
|
158
161
|
@send_get_body_as = @arguments[:send_get_body_as] || 'GET'
|
159
162
|
@opaque_id_prefix = @arguments[:opaque_id_prefix] || nil
|
163
|
+
@ca_fingerprint = @arguments.delete(:ca_fingerprint)
|
160
164
|
|
161
165
|
if @arguments[:request_timeout]
|
162
166
|
@arguments[:transport_options][:request] = { timeout: @arguments[:request_timeout] }
|
@@ -189,6 +193,7 @@ module Elasticsearch
|
|
189
193
|
opaque_id = @opaque_id_prefix ? "#{@opaque_id_prefix}#{opaque_id}" : opaque_id
|
190
194
|
headers.merge!('X-Opaque-Id' => opaque_id)
|
191
195
|
end
|
196
|
+
validate_ca_fingerprints if @ca_fingerprint
|
192
197
|
transport.perform_request(method, path, params, body, headers)
|
193
198
|
end
|
194
199
|
|
@@ -203,15 +208,41 @@ module Elasticsearch
|
|
203
208
|
|
204
209
|
def set_compatibility_header
|
205
210
|
return unless ['1', 'true'].include?(ENV['ELASTIC_CLIENT_APIVERSIONING'])
|
211
|
+
return if instance_variable_get('@options').dig(:transport_options, :headers, 'Accept')
|
206
212
|
|
207
213
|
add_header(
|
208
214
|
{
|
209
|
-
'Accept' => 'application/vnd.elasticsearch+json;compatible-with=7',
|
215
|
+
'Accept' => 'application/vnd.elasticsearch+json; compatible-with=7',
|
210
216
|
'Content-Type' => 'application/vnd.elasticsearch+json; compatible-with=7'
|
211
217
|
}
|
212
218
|
)
|
213
219
|
end
|
214
220
|
|
221
|
+
def validate_ca_fingerprints
|
222
|
+
transport.connections.connections.each do |connection|
|
223
|
+
unless connection.host[:scheme] == 'https'
|
224
|
+
raise Elasticsearch::Transport::Transport::Error, 'CA fingerprinting can\'t be configured over http'
|
225
|
+
end
|
226
|
+
|
227
|
+
next if connection.verified
|
228
|
+
|
229
|
+
ctx = OpenSSL::SSL::SSLContext.new
|
230
|
+
socket = TCPSocket.new(connection.host[:host], connection.host[:port])
|
231
|
+
ssl = OpenSSL::SSL::SSLSocket.new(socket, ctx)
|
232
|
+
ssl.connect
|
233
|
+
cert_store = ssl.peer_cert_chain
|
234
|
+
matching_certs = cert_store.select do |cert|
|
235
|
+
OpenSSL::Digest::SHA256.hexdigest(cert.to_der).upcase == @ca_fingerprint.upcase.gsub(':', '')
|
236
|
+
end
|
237
|
+
if matching_certs.empty?
|
238
|
+
raise Elasticsearch::Transport::Transport::Error,
|
239
|
+
'Server certificate CA fingerprint does not match the value configured in ca_fingerprint'
|
240
|
+
end
|
241
|
+
|
242
|
+
connection.verified = true
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
215
246
|
def add_header(header)
|
216
247
|
headers = @arguments[:transport_options]&.[](:headers) || {}
|
217
248
|
headers.merge!(header)
|
@@ -18,7 +18,6 @@
|
|
18
18
|
module Elasticsearch
|
19
19
|
module Transport
|
20
20
|
module Transport
|
21
|
-
|
22
21
|
# @abstract Module with common functionality for transport implementations.
|
23
22
|
#
|
24
23
|
module Base
|
@@ -54,6 +53,7 @@ module Elasticsearch
|
|
54
53
|
@options = arguments[:options] || {}
|
55
54
|
@options[:http] ||= {}
|
56
55
|
@options[:retry_on_status] ||= []
|
56
|
+
@options[:delay_on_retry] ||= 0
|
57
57
|
|
58
58
|
@block = block
|
59
59
|
@compression = !!@options[:compression]
|
@@ -223,7 +223,7 @@ module Elasticsearch
|
|
223
223
|
# @api private
|
224
224
|
#
|
225
225
|
def __convert_to_json(o=nil, options={})
|
226
|
-
o
|
226
|
+
o.is_a?(String) ? o : serializer.dump(o, options)
|
227
227
|
end
|
228
228
|
|
229
229
|
# Returns a full URL based on information from host
|
@@ -264,6 +264,7 @@ module Elasticsearch
|
|
264
264
|
start = Time.now
|
265
265
|
tries = 0
|
266
266
|
reload_on_failure = opts.fetch(:reload_on_failure, @options[:reload_on_failure])
|
267
|
+
delay_on_retry = opts.fetch(:delay_on_retry, @options[:delay_on_retry])
|
267
268
|
|
268
269
|
max_retries = if opts.key?(:retry_on_failure)
|
269
270
|
opts[:retry_on_failure] === true ? DEFAULT_MAX_RETRIES : opts[:retry_on_failure]
|
@@ -272,10 +273,10 @@ module Elasticsearch
|
|
272
273
|
end
|
273
274
|
|
274
275
|
params = params.clone
|
275
|
-
|
276
276
|
ignore = Array(params.delete(:ignore)).compact.map { |s| s.to_i }
|
277
277
|
|
278
278
|
begin
|
279
|
+
sleep(delay_on_retry / 1000.0) if tries > 0
|
279
280
|
tries += 1
|
280
281
|
connection = get_connection or raise Error.new('Cannot get new connection from pool.')
|
281
282
|
|
@@ -284,9 +285,7 @@ module Elasticsearch
|
|
284
285
|
end
|
285
286
|
|
286
287
|
url = connection.full_url(path, params)
|
287
|
-
|
288
288
|
response = block.call(connection, url)
|
289
|
-
|
290
289
|
connection.healthy! if connection.failures > 0
|
291
290
|
|
292
291
|
# Raise an exception so we can catch it for `retry_on_status`
|
@@ -309,7 +308,6 @@ module Elasticsearch
|
|
309
308
|
log_error "[#{e.class}] #{e.message} #{connection.host.inspect}"
|
310
309
|
|
311
310
|
connection.dead!
|
312
|
-
|
313
311
|
if reload_on_failure and tries < connections.all.size
|
314
312
|
log_warn "[#{e.class}] Reloading connections (attempt #{tries} of #{connections.all.size})"
|
315
313
|
reload_connections! and retry
|
@@ -336,14 +334,10 @@ module Elasticsearch
|
|
336
334
|
duration = Time.now - start
|
337
335
|
|
338
336
|
if response.status.to_i >= 300
|
339
|
-
__log_response
|
340
|
-
__trace
|
341
|
-
|
337
|
+
__log_response(method, path, params, body, url, response, nil, 'N/A', duration)
|
338
|
+
__trace(method, path, params, connection_headers(connection), body, url, response, nil, 'N/A', duration) if tracer
|
342
339
|
# Log the failure only when `ignore` doesn't match the response status
|
343
|
-
unless ignore.include?(response.status.to_i)
|
344
|
-
log_fatal "[#{response.status}] #{response.body}"
|
345
|
-
end
|
346
|
-
|
340
|
+
log_fatal "[#{response.status}] #{response.body}" unless ignore.include?(response.status.to_i)
|
347
341
|
__raise_transport_error response unless ignore.include?(response.status.to_i)
|
348
342
|
end
|
349
343
|
|
@@ -354,10 +348,8 @@ module Elasticsearch
|
|
354
348
|
__log_response method, path, params, body, url, response, json, took, duration
|
355
349
|
end
|
356
350
|
|
357
|
-
__trace
|
358
|
-
|
359
|
-
warnings(response.headers['warning']) if response.headers&.[]('warning')
|
360
|
-
|
351
|
+
__trace(method, path, params, connection_headers(connection), body, url, response, nil, 'N/A', duration) if tracer
|
352
|
+
log_warn(response.headers['warning']) if response.headers&.[]('warning')
|
361
353
|
Response.new response.status, json || response.body, response.headers
|
362
354
|
ensure
|
363
355
|
@last_request_at = Time.now
|
@@ -376,17 +368,38 @@ module Elasticsearch
|
|
376
368
|
|
377
369
|
USER_AGENT_STR = 'User-Agent'.freeze
|
378
370
|
USER_AGENT_REGEX = /user\-?\_?agent/
|
371
|
+
ACCEPT_ENCODING = 'Accept-Encoding'.freeze
|
372
|
+
CONTENT_ENCODING = 'Content-Encoding'.freeze
|
379
373
|
CONTENT_TYPE_STR = 'Content-Type'.freeze
|
380
374
|
CONTENT_TYPE_REGEX = /content\-?\_?type/
|
381
375
|
DEFAULT_CONTENT_TYPE = 'application/json'.freeze
|
382
376
|
GZIP = 'gzip'.freeze
|
383
|
-
ACCEPT_ENCODING = 'Accept-Encoding'.freeze
|
384
377
|
GZIP_FIRST_TWO_BYTES = '1f8b'.freeze
|
385
378
|
HEX_STRING_DIRECTIVE = 'H*'.freeze
|
386
379
|
RUBY_ENCODING = '1.9'.respond_to?(:force_encoding)
|
387
380
|
|
381
|
+
def compress_request(body, headers)
|
382
|
+
if body
|
383
|
+
headers ||= {}
|
384
|
+
|
385
|
+
if gzipped?(body)
|
386
|
+
headers[CONTENT_ENCODING] = GZIP
|
387
|
+
elsif use_compression?
|
388
|
+
headers[CONTENT_ENCODING] = GZIP
|
389
|
+
gzip = Zlib::GzipWriter.new(StringIO.new)
|
390
|
+
gzip << body
|
391
|
+
body = gzip.close.string
|
392
|
+
else
|
393
|
+
headers.delete(CONTENT_ENCODING)
|
394
|
+
end
|
395
|
+
elsif headers
|
396
|
+
headers.delete(CONTENT_ENCODING)
|
397
|
+
end
|
398
|
+
|
399
|
+
[body, headers]
|
400
|
+
end
|
401
|
+
|
388
402
|
def decompress_response(body)
|
389
|
-
return body unless use_compression?
|
390
403
|
return body unless gzipped?(body)
|
391
404
|
|
392
405
|
io = StringIO.new(body)
|
@@ -399,6 +412,8 @@ module Elasticsearch
|
|
399
412
|
end
|
400
413
|
|
401
414
|
def gzipped?(body)
|
415
|
+
return unless body && !body.empty?
|
416
|
+
|
402
417
|
body[0..1].unpack(HEX_STRING_DIRECTIVE)[0] == GZIP_FIRST_TWO_BYTES
|
403
418
|
end
|
404
419
|
|
@@ -415,7 +430,7 @@ module Elasticsearch
|
|
415
430
|
end
|
416
431
|
|
417
432
|
def find_value(hash, regex)
|
418
|
-
key_value = hash.find { |k,
|
433
|
+
key_value = hash.find { |k, _| k.to_s.downcase =~ regex }
|
419
434
|
if key_value
|
420
435
|
hash.delete(key_value[0])
|
421
436
|
key_value[1]
|
@@ -432,8 +447,12 @@ module Elasticsearch
|
|
432
447
|
end
|
433
448
|
end
|
434
449
|
|
435
|
-
def
|
436
|
-
|
450
|
+
def connection_headers(connection)
|
451
|
+
if defined?(Elasticsearch::Transport::Transport::HTTP::Manticore) && self.class == Elasticsearch::Transport::Transport::HTTP::Manticore
|
452
|
+
@request_options[:headers]
|
453
|
+
else
|
454
|
+
connection.connection.headers
|
455
|
+
end
|
437
456
|
end
|
438
457
|
end
|
439
458
|
end
|
@@ -33,6 +33,7 @@ module Elasticsearch
|
|
33
33
|
DEFAULT_RESURRECT_TIMEOUT = 60
|
34
34
|
|
35
35
|
attr_reader :host, :connection, :options, :failures, :dead_since
|
36
|
+
attr_accessor :verified
|
36
37
|
|
37
38
|
# @option arguments [Hash] :host Host information (example: `{host: 'localhost', port: 9200}`)
|
38
39
|
# @option arguments [Object] :connection The transport-specific physical connection or "session"
|
@@ -42,6 +43,7 @@ module Elasticsearch
|
|
42
43
|
@host = arguments[:host].is_a?(Hash) ? Redacted.new(arguments[:host]) : arguments[:host]
|
43
44
|
@connection = arguments[:connection]
|
44
45
|
@options = arguments[:options] || {}
|
46
|
+
@verified = false
|
45
47
|
@state_mutex = Mutex.new
|
46
48
|
|
47
49
|
@options[:resurrect_timeout] ||= DEFAULT_RESURRECT_TIMEOUT
|
@@ -153,7 +155,6 @@ module Elasticsearch
|
|
153
155
|
"<#{self.class.name} host: #{host} (#{dead? ? 'dead since ' + dead_since.to_s : 'alive'})>"
|
154
156
|
end
|
155
157
|
end
|
156
|
-
|
157
158
|
end
|
158
159
|
end
|
159
160
|
end
|