elastic-transport 8.0.0.pre1
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 +7 -0
- data/.github/check_license_headers.rb +33 -0
- data/.github/license-header.txt +16 -0
- data/.github/workflows/license.yml +13 -0
- data/.github/workflows/tests.yml +45 -0
- data/.gitignore +19 -0
- data/CHANGELOG.md +224 -0
- data/Gemfile +38 -0
- data/LICENSE +202 -0
- data/README.md +552 -0
- data/Rakefile +87 -0
- data/elastic-transport.gemspec +74 -0
- data/lib/elastic/transport/client.rb +276 -0
- data/lib/elastic/transport/meta_header.rb +135 -0
- data/lib/elastic/transport/redacted.rb +73 -0
- data/lib/elastic/transport/transport/base.rb +450 -0
- data/lib/elastic/transport/transport/connections/collection.rb +126 -0
- data/lib/elastic/transport/transport/connections/connection.rb +160 -0
- data/lib/elastic/transport/transport/connections/selector.rb +91 -0
- data/lib/elastic/transport/transport/errors.rb +91 -0
- data/lib/elastic/transport/transport/http/curb.rb +120 -0
- data/lib/elastic/transport/transport/http/faraday.rb +95 -0
- data/lib/elastic/transport/transport/http/manticore.rb +179 -0
- data/lib/elastic/transport/transport/loggable.rb +83 -0
- data/lib/elastic/transport/transport/response.rb +36 -0
- data/lib/elastic/transport/transport/serializer/multi_json.rb +52 -0
- data/lib/elastic/transport/transport/sniffer.rb +101 -0
- data/lib/elastic/transport/version.rb +22 -0
- data/lib/elastic/transport.rb +37 -0
- data/lib/elastic-transport.rb +18 -0
- data/spec/elasticsearch/connections/collection_spec.rb +266 -0
- data/spec/elasticsearch/connections/selector_spec.rb +166 -0
- data/spec/elasticsearch/transport/base_spec.rb +264 -0
- data/spec/elasticsearch/transport/client_spec.rb +1651 -0
- data/spec/elasticsearch/transport/meta_header_spec.rb +274 -0
- data/spec/elasticsearch/transport/sniffer_spec.rb +275 -0
- data/spec/spec_helper.rb +90 -0
- data/test/integration/transport_test.rb +98 -0
- data/test/profile/client_benchmark_test.rb +132 -0
- data/test/test_helper.rb +83 -0
- data/test/unit/connection_test.rb +135 -0
- data/test/unit/response_test.rb +30 -0
- data/test/unit/serializer_test.rb +33 -0
- data/test/unit/transport_base_test.rb +664 -0
- data/test/unit/transport_curb_test.rb +135 -0
- data/test/unit/transport_faraday_test.rb +228 -0
- data/test/unit/transport_manticore_test.rb +251 -0
- metadata +412 -0
data/Rakefile
ADDED
@@ -0,0 +1,87 @@
|
|
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
|
+
require 'bundler/gem_tasks'
|
19
|
+
require 'mkmf'
|
20
|
+
|
21
|
+
desc "Run unit tests"
|
22
|
+
task default: 'test:unit'
|
23
|
+
task test: 'test:unit'
|
24
|
+
|
25
|
+
# ----- Test tasks ------------------------------------------------------------
|
26
|
+
require 'rake/testtask'
|
27
|
+
require 'rspec/core/rake_task'
|
28
|
+
|
29
|
+
namespace :test do
|
30
|
+
RSpec::Core::RakeTask.new(:spec)
|
31
|
+
|
32
|
+
Rake::TestTask.new(:unit) do |test|
|
33
|
+
test.libs << 'lib' << 'test'
|
34
|
+
test.test_files = FileList['test/unit/**/*_test.rb']
|
35
|
+
test.verbose = false
|
36
|
+
test.warning = false
|
37
|
+
end
|
38
|
+
|
39
|
+
Rake::TestTask.new(:integration) do |test|
|
40
|
+
test.libs << 'lib' << 'test'
|
41
|
+
test.test_files = FileList['test/integration/**/*_test.rb']
|
42
|
+
test.verbose = false
|
43
|
+
test.warning = false
|
44
|
+
end
|
45
|
+
|
46
|
+
desc 'Run all tests'
|
47
|
+
task :all do
|
48
|
+
Rake::Task['test:unit'].invoke
|
49
|
+
Rake::Task['test:integration'].invoke
|
50
|
+
end
|
51
|
+
|
52
|
+
Rake::TestTask.new(:profile) do |test|
|
53
|
+
test.libs << 'lib' << 'test'
|
54
|
+
test.test_files = FileList['test/profile/**/*_test.rb']
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
namespace :docker do
|
60
|
+
desc <<~DOC
|
61
|
+
Start Elasticsearch in a Docker container. Credentials are 'elastic:changeme'.
|
62
|
+
|
63
|
+
Default:
|
64
|
+
rake docker:start[version]
|
65
|
+
E.g.:
|
66
|
+
rake docker:start[8.0.0-SNAPSHOT]
|
67
|
+
DOC
|
68
|
+
task :start, [:version] do |_, params|
|
69
|
+
abort 'Docker not installed' unless find_executable 'docker'
|
70
|
+
abort 'You need to set a version, e.g. rake docker:start[7.x-SNAPSHOT]' unless params[:version]
|
71
|
+
|
72
|
+
system("docker run -p 9200:9200 -p 9300:9300 -e 'discovery.type=single-node' -e ELASTIC_PASSWORD=changeme docker.elastic.co/elasticsearch/elasticsearch:#{params[:version]}")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# ----- Documentation tasks ---------------------------------------------------
|
77
|
+
require 'yard'
|
78
|
+
YARD::Rake::YardocTask.new(:doc) do |t|
|
79
|
+
t.options = %w| --embed-mixins --markup=markdown |
|
80
|
+
end
|
81
|
+
|
82
|
+
# ----- Code analysis tasks ---------------------------------------------------
|
83
|
+
require 'cane/rake_task'
|
84
|
+
Cane::RakeTask.new(:quality) do |cane|
|
85
|
+
cane.abc_max = 15
|
86
|
+
cane.no_style = true
|
87
|
+
end
|
@@ -0,0 +1,74 @@
|
|
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
|
+
# coding: utf-8
|
19
|
+
lib = File.expand_path('../lib', __FILE__)
|
20
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
21
|
+
require 'elastic/transport/version'
|
22
|
+
|
23
|
+
Gem::Specification.new do |s|
|
24
|
+
s.name = "elastic-transport"
|
25
|
+
s.version = Elastic::Transport::VERSION
|
26
|
+
s.authors = ['Karel Minarik', 'Emily Stolfo', 'Fernando Briano']
|
27
|
+
s.email = ['support@elastic.co']
|
28
|
+
s.summary = 'Low level Ruby client for Elastic services.'
|
29
|
+
s.homepage = 'https://github.com/elastic/elastic-transport-ruby'
|
30
|
+
s.license = 'Apache-2.0'
|
31
|
+
s.metadata = {
|
32
|
+
'homepage_uri' => 'https://github.com/elastic/elastic-transport-ruby',
|
33
|
+
'changelog_uri' => 'https://github.com/elastic/elastic-transport-ruby/blob/master/CHANGELOG.md',
|
34
|
+
'source_code_uri' => 'https://github.com/elastic/elastic-transport-ruby',
|
35
|
+
'bug_tracker_uri' => 'https://github.com/elastic/elastic-transport-ruby/issues'
|
36
|
+
}
|
37
|
+
s.files = `git ls-files`.split($/)
|
38
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
39
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
40
|
+
s.require_paths = ['lib']
|
41
|
+
|
42
|
+
s.extra_rdoc_files = ['README.md', 'LICENSE']
|
43
|
+
s.rdoc_options = [ '--charset=UTF-8' ]
|
44
|
+
|
45
|
+
s.required_ruby_version = '>= 2.5'
|
46
|
+
|
47
|
+
s.add_dependency 'multi_json'
|
48
|
+
s.add_dependency 'faraday', '~> 1'
|
49
|
+
|
50
|
+
s.add_development_dependency 'bundler'
|
51
|
+
s.add_development_dependency 'cane'
|
52
|
+
s.add_development_dependency 'curb' unless defined? JRUBY_VERSION
|
53
|
+
s.add_development_dependency 'hashie'
|
54
|
+
s.add_development_dependency 'httpclient'
|
55
|
+
s.add_development_dependency 'manticore' if defined? JRUBY_VERSION
|
56
|
+
s.add_development_dependency 'minitest'
|
57
|
+
s.add_development_dependency 'minitest-reporters'
|
58
|
+
s.add_development_dependency 'mocha'
|
59
|
+
s.add_development_dependency 'net-http-persistent'
|
60
|
+
s.add_development_dependency 'patron' unless defined? JRUBY_VERSION
|
61
|
+
s.add_development_dependency 'pry'
|
62
|
+
s.add_development_dependency 'rake', '~> 13'
|
63
|
+
s.add_development_dependency 'require-prof' unless defined?(JRUBY_VERSION) || defined?(Rubinius)
|
64
|
+
s.add_development_dependency 'ruby-prof' unless defined?(JRUBY_VERSION) || defined?(Rubinius)
|
65
|
+
s.add_development_dependency 'shoulda-context'
|
66
|
+
s.add_development_dependency 'simplecov'
|
67
|
+
s.add_development_dependency 'test-unit', '~> 2'
|
68
|
+
s.add_development_dependency 'typhoeus', '~> 1.4'
|
69
|
+
s.add_development_dependency 'yard'
|
70
|
+
|
71
|
+
s.description = <<-DESC.gsub(/^ /, '')
|
72
|
+
Low level Ruby client for Elastic. See the `elasticsearch` or `elastic-enterprise-search` gems for full integration.
|
73
|
+
DESC
|
74
|
+
end
|
@@ -0,0 +1,276 @@
|
|
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
|
+
require 'base64'
|
19
|
+
require 'elastic/transport/meta_header'
|
20
|
+
|
21
|
+
module Elastic
|
22
|
+
module Transport
|
23
|
+
# Handles communication with an Elastic cluster.
|
24
|
+
#
|
25
|
+
# See {file:README.md README} for usage and code examples.
|
26
|
+
#
|
27
|
+
class Client
|
28
|
+
DEFAULT_TRANSPORT_CLASS = Transport::HTTP::Faraday
|
29
|
+
include MetaHeader
|
30
|
+
|
31
|
+
DEFAULT_LOGGER = lambda do
|
32
|
+
require 'logger'
|
33
|
+
logger = Logger.new(STDERR)
|
34
|
+
logger.progname = 'elastic'
|
35
|
+
logger.formatter = proc { |severity, datetime, progname, msg| "#{datetime}: #{msg}\n" }
|
36
|
+
logger
|
37
|
+
end
|
38
|
+
|
39
|
+
DEFAULT_TRACER = lambda do
|
40
|
+
require 'logger'
|
41
|
+
logger = Logger.new(STDERR)
|
42
|
+
logger.progname = 'elastic.tracer'
|
43
|
+
logger.formatter = proc { |severity, datetime, progname, msg| "#{msg}\n" }
|
44
|
+
logger
|
45
|
+
end
|
46
|
+
|
47
|
+
# The default host and port to use if not otherwise specified.
|
48
|
+
#
|
49
|
+
# @since 7.0.0
|
50
|
+
DEFAULT_HOST = 'localhost:9200'.freeze
|
51
|
+
|
52
|
+
# The default port to use if not otherwise specified.
|
53
|
+
#
|
54
|
+
# @since 7.2.0
|
55
|
+
DEFAULT_PORT = 9200
|
56
|
+
|
57
|
+
# Returns the transport object.
|
58
|
+
#
|
59
|
+
# @see Elastic::Transport::Transport::Base
|
60
|
+
# @see Elastic::Transport::Transport::HTTP::Faraday
|
61
|
+
#
|
62
|
+
attr_accessor :transport
|
63
|
+
|
64
|
+
# Create a client connected to an Elastic cluster.
|
65
|
+
#
|
66
|
+
# Specify the URL via arguments or set the `ELASTICSEARCH_URL` environment variable.
|
67
|
+
#
|
68
|
+
# @option arguments [String,Array] :hosts Single host passed as a String or Hash, or multiple hosts
|
69
|
+
# passed as an Array; `host` or `url` keys are also valid
|
70
|
+
#
|
71
|
+
# @option arguments [Boolean] :log Use the default logger (disabled by default)
|
72
|
+
#
|
73
|
+
# @option arguments [Boolean] :trace Use the default tracer (disabled by default)
|
74
|
+
#
|
75
|
+
# @option arguments [Object] :logger An instance of a Logger-compatible object
|
76
|
+
#
|
77
|
+
# @option arguments [Object] :tracer An instance of a Logger-compatible object
|
78
|
+
#
|
79
|
+
# @option arguments [Number] :resurrect_after After how many seconds a dead connection should be tried again
|
80
|
+
#
|
81
|
+
# @option arguments [Boolean,Number] :reload_connections Reload connections after X requests (false by default)
|
82
|
+
#
|
83
|
+
# @option arguments [Boolean] :randomize_hosts Shuffle connections on initialization and reload (false by default)
|
84
|
+
#
|
85
|
+
# @option arguments [Integer] :sniffer_timeout Timeout for reloading connections in seconds (1 by default)
|
86
|
+
#
|
87
|
+
# @option arguments [Boolean,Number] :retry_on_failure Retry X times when request fails before raising and
|
88
|
+
# exception (false by default)
|
89
|
+
# @option arguments Array<Number> :retry_on_status Retry when specific status codes are returned
|
90
|
+
#
|
91
|
+
# @option arguments [Boolean] :reload_on_failure Reload connections after failure (false by default)
|
92
|
+
#
|
93
|
+
# @option arguments [Integer] :request_timeout The request timeout to be passed to transport in options
|
94
|
+
#
|
95
|
+
# @option arguments [Symbol] :adapter A specific adapter for Faraday (e.g. `:patron`)
|
96
|
+
#
|
97
|
+
# @option arguments [Hash] :transport_options Options to be passed to the `Faraday::Connection` constructor
|
98
|
+
#
|
99
|
+
# @option arguments [Constant] :transport_class A specific transport class to use, will be initialized by
|
100
|
+
# the client and passed hosts and all arguments
|
101
|
+
#
|
102
|
+
# @option arguments [Object] :transport A specific transport instance
|
103
|
+
#
|
104
|
+
# @option arguments [Constant] :serializer_class A specific serializer class to use, will be initialized by
|
105
|
+
# the transport and passed the transport instance
|
106
|
+
#
|
107
|
+
# @option arguments [Constant] :selector An instance of selector strategy implemented with
|
108
|
+
# {Elastic::Transport::Transport::Connections::Selector::Base}.
|
109
|
+
#
|
110
|
+
# @option arguments [String] :send_get_body_as Specify the HTTP method to use for GET requests with a body.
|
111
|
+
# (Default: GET)
|
112
|
+
# @option arguments [true, false] :compression Whether to compress requests. Gzip compression will be used.
|
113
|
+
# The default is false. Responses will automatically be inflated if they are compressed.
|
114
|
+
# If a custom transport object is used, it must handle the request compression and response inflation.
|
115
|
+
#
|
116
|
+
# @option enable_meta_header [Boolean] :enable_meta_header Enable sending the meta data header to Cloud.
|
117
|
+
# (Default: true)
|
118
|
+
#
|
119
|
+
# @yield [faraday] Access and configure the `Faraday::Connection` instance directly with a block
|
120
|
+
#
|
121
|
+
def initialize(arguments = {}, &block)
|
122
|
+
@options = arguments.transform_keys(&:to_sym)
|
123
|
+
@arguments = @options
|
124
|
+
@arguments[:logger] ||= @arguments[:log] ? DEFAULT_LOGGER.call() : nil
|
125
|
+
@arguments[:tracer] ||= @arguments[:trace] ? DEFAULT_TRACER.call() : nil
|
126
|
+
@arguments[:reload_connections] ||= false
|
127
|
+
@arguments[:retry_on_failure] ||= false
|
128
|
+
@arguments[:reload_on_failure] ||= false
|
129
|
+
@arguments[:randomize_hosts] ||= false
|
130
|
+
@arguments[:transport_options] ||= {}
|
131
|
+
@arguments[:http] ||= {}
|
132
|
+
@arguments[:enable_meta_header] = arguments.fetch(:enable_meta_header, true)
|
133
|
+
@options[:http] ||= {}
|
134
|
+
|
135
|
+
@hosts ||= __extract_hosts(@arguments[:hosts] ||
|
136
|
+
@arguments[:host] ||
|
137
|
+
@arguments[:url] ||
|
138
|
+
@arguments[:urls] ||
|
139
|
+
ENV['ELASTICSEARCH_URL'] ||
|
140
|
+
DEFAULT_HOST)
|
141
|
+
|
142
|
+
@send_get_body_as = @arguments[:send_get_body_as] || 'GET'
|
143
|
+
|
144
|
+
if @arguments[:request_timeout]
|
145
|
+
@arguments[:transport_options][:request] = { timeout: @arguments[:request_timeout] }
|
146
|
+
end
|
147
|
+
|
148
|
+
if @arguments[:transport]
|
149
|
+
@transport = @arguments[:transport]
|
150
|
+
else
|
151
|
+
@transport_class = @arguments[:transport_class] || DEFAULT_TRANSPORT_CLASS
|
152
|
+
@transport = if @transport_class == Transport::HTTP::Faraday
|
153
|
+
@arguments[:adapter] ||= __auto_detect_adapter
|
154
|
+
set_meta_header # from include MetaHeader
|
155
|
+
@transport_class.new(hosts: @hosts, options: @arguments) do |faraday|
|
156
|
+
faraday.adapter(@arguments[:adapter])
|
157
|
+
block&.call faraday
|
158
|
+
end
|
159
|
+
else
|
160
|
+
set_meta_header # from include MetaHeader
|
161
|
+
@transport_class.new(hosts: @hosts, options: @arguments)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# Performs a request through delegation to {#transport}.
|
167
|
+
#
|
168
|
+
def perform_request(method, path, params = {}, body = nil, headers = nil)
|
169
|
+
method = @send_get_body_as if 'GET' == method && body
|
170
|
+
transport.perform_request(method, path, params, body, headers)
|
171
|
+
end
|
172
|
+
|
173
|
+
private
|
174
|
+
|
175
|
+
def add_header(header)
|
176
|
+
headers = @arguments[:transport_options]&.[](:headers) || {}
|
177
|
+
headers.merge!(header)
|
178
|
+
@arguments[:transport_options].merge!(
|
179
|
+
headers: headers
|
180
|
+
)
|
181
|
+
end
|
182
|
+
|
183
|
+
# Normalizes and returns hosts configuration.
|
184
|
+
#
|
185
|
+
# Arrayifies the `hosts_config` argument and extracts `host` and `port` info from strings.
|
186
|
+
# Performs shuffling when the `randomize_hosts` option is set.
|
187
|
+
#
|
188
|
+
# TODO: Refactor, so it's available in Elasticsearch::Transport::Base as well
|
189
|
+
#
|
190
|
+
# @return [Array<Hash>]
|
191
|
+
# @raise [ArgumentError]
|
192
|
+
#
|
193
|
+
# @api private
|
194
|
+
#
|
195
|
+
def __extract_hosts(hosts_config)
|
196
|
+
hosts = case hosts_config
|
197
|
+
when String
|
198
|
+
hosts_config.split(',').map { |h| h.strip! || h }
|
199
|
+
when Array
|
200
|
+
hosts_config
|
201
|
+
when Hash, URI
|
202
|
+
[hosts_config]
|
203
|
+
else
|
204
|
+
Array(hosts_config)
|
205
|
+
end
|
206
|
+
|
207
|
+
host_list = hosts.map { |host| __parse_host(host) }
|
208
|
+
@options[:randomize_hosts] ? host_list.shuffle! : host_list
|
209
|
+
end
|
210
|
+
|
211
|
+
def __parse_host(host)
|
212
|
+
host_parts = case host
|
213
|
+
when String
|
214
|
+
if host =~ /^[a-z]+\:\/\//
|
215
|
+
# Construct a new `URI::Generic` directly from the array returned by URI::split.
|
216
|
+
# This avoids `URI::HTTP` and `URI::HTTPS`, which supply default ports.
|
217
|
+
uri = URI::Generic.new(*URI.split(host))
|
218
|
+
|
219
|
+
default_port = uri.scheme == 'https' ? 443 : DEFAULT_PORT
|
220
|
+
|
221
|
+
{ :scheme => uri.scheme,
|
222
|
+
:user => uri.user,
|
223
|
+
:password => uri.password,
|
224
|
+
:host => uri.host,
|
225
|
+
:path => uri.path,
|
226
|
+
:port => uri.port || default_port }
|
227
|
+
else
|
228
|
+
host, port = host.split(':')
|
229
|
+
{ :host => host,
|
230
|
+
:port => port }
|
231
|
+
end
|
232
|
+
when URI
|
233
|
+
{ :scheme => host.scheme,
|
234
|
+
:user => host.user,
|
235
|
+
:password => host.password,
|
236
|
+
:host => host.host,
|
237
|
+
:path => host.path,
|
238
|
+
:port => host.port }
|
239
|
+
when Hash
|
240
|
+
host
|
241
|
+
else
|
242
|
+
raise ArgumentError, "Please pass host as a String, URI or Hash -- #{host.class} given."
|
243
|
+
end
|
244
|
+
|
245
|
+
@options[:http][:user] ||= host_parts[:user]
|
246
|
+
@options[:http][:password] ||= host_parts[:password]
|
247
|
+
host_parts[:port] = host_parts[:port].to_i if host_parts[:port]
|
248
|
+
host_parts[:path].chomp!('/') if host_parts[:path]
|
249
|
+
host_parts
|
250
|
+
end
|
251
|
+
|
252
|
+
# Auto-detect the best adapter (HTTP "driver") available, based on libraries
|
253
|
+
# loaded by the user, preferring those with persistent connections
|
254
|
+
# ("keep-alive") by default
|
255
|
+
#
|
256
|
+
# @return [Symbol]
|
257
|
+
#
|
258
|
+
# @api private
|
259
|
+
#
|
260
|
+
def __auto_detect_adapter
|
261
|
+
case
|
262
|
+
when defined?(::Patron)
|
263
|
+
:patron
|
264
|
+
when defined?(::Typhoeus)
|
265
|
+
:typhoeus
|
266
|
+
when defined?(::HTTPClient)
|
267
|
+
:httpclient
|
268
|
+
when defined?(::Net::HTTP::Persistent)
|
269
|
+
:net_http_persistent
|
270
|
+
else
|
271
|
+
::Faraday.default_adapter
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
@@ -0,0 +1,135 @@
|
|
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
|
+
require 'base64'
|
19
|
+
|
20
|
+
module Elastic
|
21
|
+
module Transport
|
22
|
+
# Methods for the Elastic meta header used by Cloud.
|
23
|
+
# X-Elastic-Client-Meta HTTP header which is used by Elastic Cloud and can be disabled when
|
24
|
+
# instantiating the Client with the :enable_meta_header parameter set to `false`.
|
25
|
+
#
|
26
|
+
module MetaHeader
|
27
|
+
def set_meta_header
|
28
|
+
return if @arguments[:enable_meta_header] == false
|
29
|
+
|
30
|
+
service, version = meta_header_service_version
|
31
|
+
|
32
|
+
meta_headers = {
|
33
|
+
service.to_sym => version,
|
34
|
+
rb: RUBY_VERSION,
|
35
|
+
t: Elastic::Transport::VERSION
|
36
|
+
}
|
37
|
+
meta_headers.merge!(meta_header_engine) if meta_header_engine
|
38
|
+
meta_headers.merge!(meta_header_adapter) if meta_header_adapter
|
39
|
+
|
40
|
+
add_header({ 'x-elastic-client-meta' => meta_headers.map { |k, v| "#{k}=#{v}" }.join(',') })
|
41
|
+
end
|
42
|
+
|
43
|
+
def meta_header_service_version
|
44
|
+
if enterprise_search?
|
45
|
+
Elastic::ENTERPRISE_SERVICE_VERSION
|
46
|
+
elsif elasticsearch?
|
47
|
+
Elastic::ELASTICSEARCH_SERVICE_VERSION
|
48
|
+
elsif defined?(Elasticsearch::VERSION)
|
49
|
+
[:es, client_meta_version(Elasticsearch::VERSION)]
|
50
|
+
else
|
51
|
+
[:es, client_meta_version(Elastic::Transport::VERSION)]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def enterprise_search?
|
56
|
+
defined?(Elastic::ENTERPRISE_SERVICE_VERSION) &&
|
57
|
+
called_from?('enterprise-search-ruby')
|
58
|
+
end
|
59
|
+
|
60
|
+
def elasticsearch?
|
61
|
+
defined?(Elastic::ELASTICSEARCH_SERVICE_VERSION) &&
|
62
|
+
called_from?('elasticsearch')
|
63
|
+
end
|
64
|
+
|
65
|
+
def called_from?(service)
|
66
|
+
!caller.select { |c| c.match?(service) }.empty?
|
67
|
+
end
|
68
|
+
|
69
|
+
# We return the current version if it's a release, but if it's a pre/alpha/beta release we
|
70
|
+
# return <VERSION_NUMBER>p
|
71
|
+
#
|
72
|
+
def client_meta_version(version)
|
73
|
+
regexp = /^([0-9]+\.[0-9]+\.[0-9]+)(\.?[a-z0-9.-]+)?$/
|
74
|
+
match = version.match(regexp)
|
75
|
+
return "#{match[1]}p" if (match[2])
|
76
|
+
|
77
|
+
version
|
78
|
+
end
|
79
|
+
|
80
|
+
def meta_header_engine
|
81
|
+
case RUBY_ENGINE
|
82
|
+
when 'ruby'
|
83
|
+
{}
|
84
|
+
when 'jruby'
|
85
|
+
{ jv: ENV_JAVA['java.version'], jr: JRUBY_VERSION }
|
86
|
+
when 'rbx'
|
87
|
+
{ rbx: RUBY_VERSION }
|
88
|
+
else
|
89
|
+
{ RUBY_ENGINE.to_sym => RUBY_VERSION }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# This function tries to define the version for the Faraday adapter. If it hasn't been loaded
|
94
|
+
# by the time we're calling this method, it's going to report the adapter (if we know it) but
|
95
|
+
# return 0 as the version. It won't report anything when using a custom adapter we don't
|
96
|
+
# identify.
|
97
|
+
#
|
98
|
+
# Returns a Hash<adapter_alias, version>
|
99
|
+
#
|
100
|
+
def meta_header_adapter
|
101
|
+
if @transport_class == Transport::HTTP::Faraday
|
102
|
+
version = '0'
|
103
|
+
adapter_version = case @arguments[:adapter]
|
104
|
+
when :patron
|
105
|
+
version = Patron::VERSION if defined?(::Patron::VERSION)
|
106
|
+
{pt: version}
|
107
|
+
when :net_http
|
108
|
+
version = if defined?(Net::HTTP::VERSION)
|
109
|
+
Net::HTTP::VERSION
|
110
|
+
elsif defined?(Net::HTTP::HTTPVersion)
|
111
|
+
Net::HTTP::HTTPVersion
|
112
|
+
end
|
113
|
+
{nh: version}
|
114
|
+
when :typhoeus
|
115
|
+
version = Typhoeus::VERSION if defined?(::Typhoeus::VERSION)
|
116
|
+
{ty: version}
|
117
|
+
when :httpclient
|
118
|
+
version = HTTPClient::VERSION if defined?(HTTPClient::VERSION)
|
119
|
+
{hc: version}
|
120
|
+
when :net_http_persistent
|
121
|
+
version = Net::HTTP::Persistent::VERSION if defined?(Net::HTTP::Persistent::VERSION)
|
122
|
+
{np: version}
|
123
|
+
else
|
124
|
+
{}
|
125
|
+
end
|
126
|
+
{fd: Faraday::VERSION}.merge(adapter_version)
|
127
|
+
elsif defined?(Transport::HTTP::Curb) && @transport_class == Transport::HTTP::Curb
|
128
|
+
{cl: Curl::CURB_VERSION}
|
129
|
+
elsif defined?(Transport::HTTP::Manticore) && @transport_class == Transport::HTTP::Manticore
|
130
|
+
{mc: Manticore::VERSION}
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|