elastic-transport 8.3.5 → 8.4.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a4543af71a663d5f638c673407101529237507d56e7e2034f0c7e9fd5dd78c6a
4
- data.tar.gz: 39a000ce02f4cf2208d0ec41f51f133e74454748f90eb6617d08bac3aad7e572
3
+ metadata.gz: 88698d9c25a84a6242bfb875623c2bca0bd9a0e5c40244272e88fe291b06a9e0
4
+ data.tar.gz: 90aff86e0a0f301908c888877d97a72ac926e9b5f7f48b23ad447813a729824d
5
5
  SHA512:
6
- metadata.gz: 747447a8e84b3f71f1b8244237809c2087e60de35426820d065de72fb57b9ab17094ee1fb95e2f228c41902098b1d2ba8fd1f248f6d2cf493785d50745c08ec0
7
- data.tar.gz: 6923af2b78bf3a8ecb956038a878f1752723546dfdabd3d6d3492f545f9d51312807a8faf7a8e1adee21b34034d95569b01939172198eb572709d16e6e5ace53
6
+ metadata.gz: 3a235c8813516864b3b661790c56c9eeb6c8ee8b44a208d70a3309faca0075e9b45f25890be47d56ed29b845a70c5d3f6cd45c617592543993a0c6d788eb7211
7
+ data.tar.gz: 9cd571ba906d3e841f63f8bf3ea018820d0d9e2eddb9171f01785b6787df5ed19fecbeb0b05e494428af8853d2040c78c32f25a370c612d55a4a69ed77798682
@@ -7,7 +7,7 @@ jobs:
7
7
  - uses: actions/checkout@v4
8
8
  - uses: ruby/setup-ruby@v1
9
9
  with:
10
- ruby-version: 3
10
+ ruby-version: '3.4'
11
11
  - name: Check license headers
12
12
  run: |
13
13
  ruby ./.github/check_license_headers.rb
@@ -16,8 +16,8 @@ jobs:
16
16
  strategy:
17
17
  fail-fast: false
18
18
  matrix:
19
- ruby: ['3.3', 'jruby-9.4']
20
- es_version: ['8.15.0-SNAPSHOT']
19
+ ruby: ['3.4', 'jruby-9.4']
20
+ es_version: ['8.17.0-SNAPSHOT']
21
21
  runs-on: ubuntu-latest
22
22
  steps:
23
23
  - uses: actions/checkout@v4
@@ -15,8 +15,8 @@ jobs:
15
15
  strategy:
16
16
  fail-fast: false
17
17
  matrix:
18
- ruby: ['3.0', '3.1', '3.2', '3.3', 'jruby-9.3', 'jruby-9.4']
19
- es_version: ['8.14.2-SNAPSHOT', '8.15.0-SNAPSHOT', '8.16.0-SNAPSHOT']
18
+ ruby: ['3.1', '3.2', '3.3', '3.4', 'jruby-9.3', 'jruby-9.4']
19
+ es_version: ['8.16.0-SNAPSHOT', '8.17.0-SNAPSHOT', '8.18.0-SNAPSHOT']
20
20
  runs-on: ubuntu-latest
21
21
  steps:
22
22
  - uses: actions/checkout@v4
data/CHANGELOG.md CHANGED
@@ -1,3 +1,40 @@
1
+ ## 8.4.0
2
+
3
+ - Adds support for **[Excon](https://github.com/excon/excon)** Faraday adapter. You can use the Excon adapter by setting it in when initializing an Elasticsearch client:
4
+
5
+ ```ruby
6
+ require 'faraday/excon'
7
+
8
+ Elasticsearch::Client.new(
9
+ host: host,
10
+ transport_options: transport_options,
11
+ adapter: :excon
12
+ )
13
+ ```
14
+
15
+ Excon may need some specific configuration for HTTPS/SSL. You may see certificate verification errors when trying to connect to Elastic. Excon has certificates bundled, but these can be customized:
16
+
17
+ ```ruby
18
+ Excon.defaults[:ssl_ca_path] = path_to_certs
19
+ ENV['SSL_CERT_DIR'] = path_to_certs
20
+ Excon.defaults[:ssl_ca_file] = path_to_file
21
+ ENV['SSL_CERT_FILE'] = path_to_file
22
+ Excon.defaults[:ssl_verify_callback] = callback
23
+ # (see OpenSSL::SSL::SSLContext#verify_callback)
24
+ Excon.defaults[:ssl_verify_peer] = false` # (less secure).
25
+ ```
26
+
27
+ - Adds support for **[Async::HTTP::Faraday](https://github.com/socketry/async-http-faraday)**. You can use the adapter by setting it when initializing an Elasticsearch client:
28
+ ```ruby
29
+ require 'async-http-faraday'
30
+
31
+ Elasticsearch::Client.new(
32
+ host: host,
33
+ adapter: :async_http
34
+ )
35
+ ```
36
+ - Minor refactors, styling fixes.
37
+
1
38
  ## 8.3.5
2
39
 
3
40
  - Small updates in source code documentation.
data/CONTRIBUTING.md CHANGED
@@ -41,7 +41,13 @@ E.g.:
41
41
  $ rake docker:start[8.0.0-alpha1]
42
42
  ```
43
43
 
44
- You can find the available version in [Docker @ Elastic](https://www.docker.elastic.co/r/elasticsearch).
44
+ You can find the available version in [Docker @ Elastic](https://www.docker.elastic.co/r/elasticsearch). You can also run Elasticsearch and Kibana locally with Docker with `start-local`:
45
+
46
+ ```bash
47
+ curl -fsSL https://elastic.co/start-local | sh
48
+ ```
49
+
50
+ This will run Elasticsearch in http://localhost:9200 and Kibana in http://localhost:5601. More information is available [here](https://www.elastic.co/guide/en/elasticsearch/reference/current/run-elasticsearch-locally.html).
45
51
 
46
52
  # Contributing
47
53
 
data/Gemfile CHANGED
@@ -21,13 +21,16 @@ source 'https://rubygems.org'
21
21
  gemspec
22
22
 
23
23
  group :development, :test do
24
+ gem 'faraday-excon'
24
25
  gem 'faraday-httpclient'
25
26
  gem 'faraday-net_http_persistent'
26
27
  gem 'faraday-typhoeus'
28
+ gem 'mutex_m' if RUBY_VERSION >= '3.4'
27
29
  gem 'opentelemetry-sdk', require: false if RUBY_VERSION >= '3.0'
28
30
  if defined?(JRUBY_VERSION)
29
31
  gem 'pry-nav'
30
32
  else
33
+ gem 'async-http-faraday'
31
34
  gem 'faraday-patron'
32
35
  gem 'oj'
33
36
  gem 'pry-byebug'
@@ -123,8 +123,8 @@ module Elastic
123
123
  #
124
124
  def initialize(arguments = {}, &block)
125
125
  @arguments = arguments.transform_keys(&:to_sym)
126
- @arguments[:logger] ||= @arguments[:log] ? DEFAULT_LOGGER.call() : nil
127
- @arguments[:tracer] ||= @arguments[:trace] ? DEFAULT_TRACER.call() : nil
126
+ @arguments[:logger] ||= @arguments[:log] ? DEFAULT_LOGGER.call : nil
127
+ @arguments[:tracer] ||= @arguments[:trace] ? DEFAULT_TRACER.call : nil
128
128
  @arguments[:reload_connections] ||= false
129
129
  @arguments[:retry_on_failure] ||= false
130
130
  @arguments[:delay_on_retry] ||= 0
@@ -134,13 +134,7 @@ module Elastic
134
134
  @arguments[:http] ||= {}
135
135
  @arguments[:enable_meta_header] = arguments.fetch(:enable_meta_header, true)
136
136
 
137
- @hosts ||= __extract_hosts(@arguments[:hosts] ||
138
- @arguments[:host] ||
139
- @arguments[:url] ||
140
- @arguments[:urls] ||
141
- ENV['ELASTICSEARCH_URL'] ||
142
- DEFAULT_HOST)
143
-
137
+ @hosts ||= extract_hosts
144
138
  @send_get_body_as = @arguments[:send_get_body_as] || 'GET'
145
139
  @ca_fingerprint = @arguments.delete(:ca_fingerprint)
146
140
 
@@ -153,7 +147,7 @@ module Elastic
153
147
  else
154
148
  @transport_class = @arguments[:transport_class] || DEFAULT_TRANSPORT_CLASS
155
149
  @transport = if @transport_class == Transport::HTTP::Faraday
156
- @arguments[:adapter] ||= __auto_detect_adapter
150
+ @arguments[:adapter] ||= auto_detect_adapter
157
151
  set_meta_header # from include MetaHeader
158
152
  @transport_class.new(hosts: @hosts, options: @arguments) do |faraday|
159
153
  faraday.adapter(@arguments[:adapter])
@@ -246,7 +240,7 @@ module Elastic
246
240
  #
247
241
  # @api private
248
242
  #
249
- def __extract_hosts(hosts_config)
243
+ def extract_hosts
250
244
  hosts = case hosts_config
251
245
  when String
252
246
  hosts_config.split(',').map { |h| h.strip! || h }
@@ -257,12 +251,20 @@ module Elastic
257
251
  else
258
252
  Array(hosts_config)
259
253
  end
260
-
261
- host_list = hosts.map { |host| __parse_host(host) }
254
+ host_list = hosts.map { |host| parse_host(host) }
262
255
  @arguments[:randomize_hosts] ? host_list.shuffle! : host_list
263
256
  end
264
257
 
265
- def __parse_host(host)
258
+ def hosts_config
259
+ @arguments[:hosts] ||
260
+ @arguments[:host] ||
261
+ @arguments[:url] ||
262
+ @arguments[:urls] ||
263
+ ENV['ELASTICSEARCH_URL'] ||
264
+ DEFAULT_HOST
265
+ end
266
+
267
+ def parse_host(host)
266
268
  host_parts = case host
267
269
  when String
268
270
  if host =~ /^[a-z]+\:\/\//
@@ -313,12 +315,14 @@ module Elastic
313
315
  #
314
316
  # @api private
315
317
  #
316
- def __auto_detect_adapter
318
+ def auto_detect_adapter
317
319
  if Gem::Version.new(Faraday::VERSION) >= Gem::Version.new(2)
318
320
  return :patron if defined?(Faraday::Adapter::Patron)
319
321
  return :typhoeus if defined?(Faraday::Adapter::Typhoeus)
320
322
  return :httpclient if defined?(Faraday::Adapter::HTTPClient)
321
323
  return :net_http_persistent if defined?(Faraday::Adapter::NetHttpPersistent)
324
+ return :excon if defined?(Faraday::Adapter::Excon)
325
+ return :async_http if defined?(Async::HTTP::Faraday)
322
326
  else
323
327
  return :patron if defined?(::Patron)
324
328
  return :typhoeus if defined?(::Typhoeus)
@@ -21,70 +21,77 @@ module Elastic
21
21
  #
22
22
  # @api private
23
23
  class OpenTelemetry
24
- OTEL_TRACER_NAME = 'elasticsearch-api'
24
+ OTEL_TRACER_NAME = 'elasticsearch-api'.freeze
25
25
  # Valid values for the enabled config are 'true' and 'false'. Default is 'true'.
26
- ENV_VARIABLE_ENABLED = 'OTEL_RUBY_INSTRUMENTATION_ELASTICSEARCH_ENABLED'
26
+ ENV_VARIABLE_ENABLED = 'OTEL_RUBY_INSTRUMENTATION_ELASTICSEARCH_ENABLED'.freeze
27
27
  # Describes how to handle search queries in the request body when assigned to
28
28
  # a span attribute.
29
29
  # Valid values are 'raw', 'omit', 'sanitize'. Default is 'omit'.
30
- ENV_VARIABLE_BODY_STRATEGY = 'OTEL_RUBY_INSTRUMENTATION_ELASTICSEARCH_CAPTURE_SEARCH_QUERY'
31
- ENV_VARIABLE_DEPRECATED_BODY_STRATEGY = 'OTEL_INSTRUMENTATION_ELASTICSEARCH_CAPTURE_SEARCH_QUERY'
32
- DEFAULT_BODY_STRATEGY = 'omit'
30
+ ENV_VARIABLE_BODY_STRATEGY = 'OTEL_RUBY_INSTRUMENTATION_ELASTICSEARCH_CAPTURE_SEARCH_QUERY'.freeze
31
+ ENV_VARIABLE_DEPRECATED_BODY_STRATEGY = 'OTEL_INSTRUMENTATION_ELASTICSEARCH_CAPTURE_SEARCH_QUERY'.freeze
32
+ DEFAULT_BODY_STRATEGY = 'omit'.freeze
33
33
  # A string list of keys whose values are redacted. This is only relevant if the body strategy is
34
34
  # 'sanitize'. For example, a config 'sensitive-key,other-key' will redact the values at
35
35
  # 'sensitive-key' and 'other-key' in addition to the default keys.
36
- ENV_VARIABLE_BODY_SANITIZE_KEYS = 'OTEL_RUBY_INSTRUMENTATION_ELASTICSEARCH_SEARCH_QUERY_SANITIZE_KEYS'
36
+ ENV_VARIABLE_BODY_SANITIZE_KEYS = 'OTEL_RUBY_INSTRUMENTATION_ELASTICSEARCH_SEARCH_QUERY_SANITIZE_KEYS'.freeze
37
37
 
38
38
  # A list of the Elasticsearch endpoints that qualify as "search" endpoints. The search query in
39
39
  # the request body may be captured for these endpoints, depending on the body capture strategy.
40
40
  SEARCH_ENDPOINTS = Set[
41
- "search",
42
- "async_search.submit",
43
- "msearch",
44
- "eql.search",
45
- "terms_enum",
46
- "search_template",
47
- "msearch_template",
48
- "render_search_template",
41
+ 'search',
42
+ 'async_search.submit',
43
+ 'msearch',
44
+ 'eql.search',
45
+ 'terms_enum',
46
+ 'search_template',
47
+ 'msearch_template',
48
+ 'render_search_template',
49
49
  ]
50
50
 
51
51
  # Initialize the Open Telemetry wrapper object. Takes the options originally passed to
52
52
  # Client#initialize.
53
53
  def initialize(opts)
54
- @tracer = (opts[:opentelemetry_tracer_provider] || ::OpenTelemetry.tracer_provider).tracer(
55
- OTEL_TRACER_NAME, Elastic::Transport::VERSION
56
- )
57
- @body_strategy = ENV[ENV_VARIABLE_DEPRECATED_BODY_STRATEGY] || ENV[ENV_VARIABLE_BODY_STRATEGY] ||
58
- DEFAULT_BODY_STRATEGY
54
+ @tracer = tracer_provider(opts).tracer(OTEL_TRACER_NAME, Elastic::Transport::VERSION)
55
+ @body_strategy = ENV[ENV_VARIABLE_DEPRECATED_BODY_STRATEGY] ||
56
+ ENV[ENV_VARIABLE_BODY_STRATEGY] ||
57
+ DEFAULT_BODY_STRATEGY
59
58
  @sanitize_keys = ENV[ENV_VARIABLE_BODY_SANITIZE_KEYS]&.split(',')&.collect! do |pattern|
60
59
  Regexp.new(pattern.gsub('*', '.*'))
61
60
  end
62
61
  end
63
62
  attr_accessor :tracer
64
63
 
64
+ def tracer_provider(opts)
65
+ opts[:opentelemetry_tracer_provider] || ::OpenTelemetry.tracer_provider
66
+ end
67
+
65
68
  # Process the request body. Applies the body strategy, which can be one of the following:
66
- # 'omit': return nil
69
+ # 'omit' (DEFAULT_BODY_STRATEGY): return nil
67
70
  # 'sanitize': redact values at the default list of keys + any additional keys provided in
68
71
  # the OTEL_RUBY_INSTRUMENTATION_ELASTICSEARCH_SEARCH_QUERY_SANITIZE_KEYS env variable.
69
72
  # 'raw': return the original body, unchanged
70
73
  def process_body(body, endpoint)
71
- unless @body_strategy == 'omit' || !SEARCH_ENDPOINTS.include?(endpoint)
72
- if @body_strategy == 'sanitize'
73
- Sanitizer.sanitize(body, @sanitize_keys).to_json
74
- elsif @body_strategy == 'raw'
75
- body&.is_a?(String) ? body : body.to_json
76
- end
74
+ return if @body_strategy == DEFAULT_BODY_STRATEGY || !search_endpoint?(endpoint)
75
+
76
+ if @body_strategy == 'sanitize'
77
+ Sanitizer.sanitize(body, @sanitize_keys).to_json
78
+ elsif @body_strategy == 'raw'
79
+ body.is_a?(String) ? body : body.to_json
77
80
  end
78
81
  end
79
82
 
83
+ def search_endpoint?(endpoint)
84
+ SEARCH_ENDPOINTS.include?(endpoint)
85
+ end
86
+
80
87
  # Replaces values in a hash with 'REDACTED', given a set of keys to match on.
81
88
  class Sanitizer
82
89
  class << self
83
- FILTERED = 'REDACTED'
90
+ FILTERED = 'REDACTED'.freeze
84
91
  DEFAULT_KEY_PATTERNS =
85
92
  %w[password passwd pwd secret *key *token* *session* *credit* *card* *auth* set-cookie].map! do |p|
86
- Regexp.new(p.gsub('*', '.*'))
87
- end
93
+ Regexp.new(p.gsub('*', '.*'))
94
+ end
88
95
 
89
96
  def sanitize(body, key_patterns = [])
90
97
  patterns = DEFAULT_KEY_PATTERNS
@@ -83,7 +83,7 @@ module Elastic
83
83
  # @return [Connections::Connection]
84
84
  # @see Connections::Collection#get_connection
85
85
  #
86
- def get_connection(options={})
86
+ def get_connection(options = {})
87
87
  resurrect_dead_connections! if Time.now > @last_request_at + @resurrect_after
88
88
 
89
89
  @counter_mtx.synchronize { @counter += 1 }
@@ -120,7 +120,7 @@ module Elastic
120
120
  # @return [Connections::Collection]
121
121
  # @api private
122
122
  #
123
- def __rebuild_connections(arguments={})
123
+ def __rebuild_connections(arguments = {})
124
124
  @state_mutex.synchronize do
125
125
  @hosts = arguments[:hosts] || []
126
126
  @options = arguments[:options] || {}
@@ -232,7 +232,7 @@ module Elastic
232
232
  #
233
233
  # @api private
234
234
  #
235
- def __convert_to_json(o=nil, options={})
235
+ def __convert_to_json(o = nil, options = {})
236
236
  o.is_a?(String) ? o : serializer.dump(o, options)
237
237
  end
238
238
 
@@ -17,6 +17,6 @@
17
17
 
18
18
  module Elastic
19
19
  module Transport
20
- VERSION = '8.3.5'.freeze
20
+ VERSION = '8.4.0'.freeze
21
21
  end
22
22
  end
@@ -225,6 +225,38 @@ describe Elastic::Transport::Client do
225
225
  end
226
226
  end unless jruby?
227
227
 
228
+ context 'when the adapter is excon' do
229
+ let(:adapter) do
230
+ client.transport.connections.all.first.connection.builder.adapter
231
+ end
232
+
233
+ let(:client) do
234
+ require 'faraday/excon'
235
+
236
+ described_class.new(adapter: :excon, enable_meta_header: false)
237
+ end
238
+
239
+ it 'uses Faraday with the adapter' do
240
+ expect(adapter).to eq Faraday::Adapter::Excon
241
+ end
242
+ end if is_faraday_v2?
243
+
244
+ context 'when the adapter is async-http' do
245
+ let(:adapter) do
246
+ client.transport.connections.all.first.connection.builder.adapter
247
+ end
248
+
249
+ let(:client) do
250
+ require 'async/http/faraday'
251
+
252
+ described_class.new(adapter: :async_http, enable_meta_header: false)
253
+ end
254
+
255
+ it 'uses Faraday with the adapter' do
256
+ expect(adapter).to eq Async::HTTP::Faraday::Adapter
257
+ end
258
+ end unless jruby? || !is_faraday_v2?
259
+
228
260
  context 'when the adapter is specified as a string key' do
229
261
  let(:adapter) do
230
262
  client.transport.connections.all.first.connection.builder.adapter
@@ -1453,6 +1485,7 @@ describe Elastic::Transport::Client do
1453
1485
 
1454
1486
  context 'when using the HTTPClient adapter' do
1455
1487
  require 'faraday/httpclient'
1488
+ require 'mutex_m' if RUBY_VERSION >= '3.4'
1456
1489
 
1457
1490
  let(:client) do
1458
1491
  described_class.new(hosts: ELASTICSEARCH_HOSTS, compression: true, adapter: :httpclient, enable_meta_header: false)
@@ -72,6 +72,22 @@ class Elastic::Transport::ClientAdaptersUnitTest < Minitest::Test
72
72
  end
73
73
  end
74
74
 
75
+ should 'use Excon Faraday adapter' do
76
+ fork do
77
+ require 'faraday/excon'
78
+ client = Elastic::Transport::Client.new
79
+ assert_equal(client.transport.connections.first.connection.adapter, Faraday::Adapter::Excon)
80
+ end
81
+ end if is_faraday_v2?
82
+
83
+ should 'use Async HTTP Faraday adapter' do
84
+ fork do
85
+ require 'async/http/faraday'
86
+ client = Elastic::Transport::Client.new
87
+ assert_equal(client.transport.connections.first.connection.adapter, Async::HTTP::Faraday::Adapter)
88
+ end
89
+ end if is_faraday_v2?
90
+
75
91
  should 'use HTTPClient Faraday adapter' do
76
92
  fork do
77
93
  if is_faraday_v2?
@@ -81,7 +97,7 @@ class Elastic::Transport::ClientAdaptersUnitTest < Minitest::Test
81
97
  end
82
98
 
83
99
  client = Elastic::Transport::Client.new
84
- assert_equal(Faraday::Adapter::HTTPClient, client.transport.connections.first.connection.adapter)
100
+ assert_equal(client.transport.connections.first.connection.adapter, Faraday::Adapter::HTTPClient)
85
101
  end
86
102
  end
87
103
  end unless jruby?
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elastic-transport
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.3.5
4
+ version: 8.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic Client Library Maintainers
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-07-16 00:00:00.000000000 Z
10
+ date: 2025-02-18 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: faraday
@@ -324,7 +323,6 @@ metadata:
324
323
  changelog_uri: https://github.com/elastic/elastic-transport-ruby/blob/master/CHANGELOG.md
325
324
  source_code_uri: https://github.com/elastic/elastic-transport-ruby
326
325
  bug_tracker_uri: https://github.com/elastic/elastic-transport-ruby/issues
327
- post_install_message:
328
326
  rdoc_options:
329
327
  - "--charset=UTF-8"
330
328
  require_paths:
@@ -340,8 +338,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
340
338
  - !ruby/object:Gem::Version
341
339
  version: '0'
342
340
  requirements: []
343
- rubygems_version: 3.4.19
344
- signing_key:
341
+ rubygems_version: 3.6.2
345
342
  specification_version: 4
346
343
  summary: Low level Ruby client for Elastic services.
347
344
  test_files: