From cba184b4cfe357e7b2051697551a3c30016c1fa7 Mon Sep 17 00:00:00 2001 From: Fernando Briano Date: Tue, 24 Mar 2020 20:37:05 +0000 Subject: [PATCH 1/5] Update to Faraday 1.0 --- elasticsearch-api/Rakefile | 2 +- elasticsearch-transport/elasticsearch-transport.gemspec | 2 +- .../lib/elasticsearch/transport/transport/http/faraday.rb | 2 +- .../spec/elasticsearch/transport/client_spec.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/elasticsearch-api/Rakefile b/elasticsearch-api/Rakefile index a50210c8fb..8eae0f7991 100644 --- a/elasticsearch-api/Rakefile +++ b/elasticsearch-api/Rakefile @@ -69,7 +69,7 @@ namespace :test do es_version_info = client.info['version'] build_hash = es_version_info['build_hash'] cluster_running = true - rescue Faraday::Error::ConnectionFailed + rescue Faraday::ConnectionFailed STDERR.puts "[!] Test cluster not running?" cluster_running = false end diff --git a/elasticsearch-transport/elasticsearch-transport.gemspec b/elasticsearch-transport/elasticsearch-transport.gemspec index fc1370272f..7b5ae31a4c 100644 --- a/elasticsearch-transport/elasticsearch-transport.gemspec +++ b/elasticsearch-transport/elasticsearch-transport.gemspec @@ -27,7 +27,7 @@ Gem::Specification.new do |s| s.required_ruby_version = '>= 2.4' s.add_dependency 'multi_json' - s.add_dependency 'faraday', '>= 0.14', '< 1' + s.add_dependency 'faraday', '~> 1' s.add_development_dependency 'cane' s.add_development_dependency 'curb' unless defined? JRUBY_VERSION diff --git a/elasticsearch-transport/lib/elasticsearch/transport/transport/http/faraday.rb b/elasticsearch-transport/lib/elasticsearch/transport/transport/http/faraday.rb index b5b8b625d7..21dbabea34 100644 --- a/elasticsearch-transport/lib/elasticsearch/transport/transport/http/faraday.rb +++ b/elasticsearch-transport/lib/elasticsearch/transport/transport/http/faraday.rb @@ -48,7 +48,7 @@ def __build_connection(host, options={}, block=nil) # @return [Array] # def host_unreachable_exceptions - [::Faraday::Error::ConnectionFailed, ::Faraday::Error::TimeoutError] + [::Faraday::ConnectionFailed, ::Faraday::TimeoutError] end private diff --git a/elasticsearch-transport/spec/elasticsearch/transport/client_spec.rb b/elasticsearch-transport/spec/elasticsearch/transport/client_spec.rb index 8b8023c1a8..29c30c7a9d 100644 --- a/elasticsearch-transport/spec/elasticsearch/transport/client_spec.rb +++ b/elasticsearch-transport/spec/elasticsearch/transport/client_spec.rb @@ -1275,7 +1275,7 @@ expect(client.perform_request('GET', '_nodes/_local')) expect { client.perform_request('GET', '_nodes/_local') - }.to raise_exception(Faraday::Error::ConnectionFailed) + }.to raise_exception(Faraday::ConnectionFailed) end end From a113b67917da9bd40fe82ce7397da705ac97a1be Mon Sep 17 00:00:00 2001 From: Fernando Briano Date: Wed, 25 Mar 2020 09:52:56 +0000 Subject: [PATCH 2/5] Update client spec to check for adapter instead of handlers (Faraday 1.0) --- .../elasticsearch/transport/client_spec.rb | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/elasticsearch-transport/spec/elasticsearch/transport/client_spec.rb b/elasticsearch-transport/spec/elasticsearch/transport/client_spec.rb index 29c30c7a9d..b04345b89b 100644 --- a/elasticsearch-transport/spec/elasticsearch/transport/client_spec.rb +++ b/elasticsearch-transport/spec/elasticsearch/transport/client_spec.rb @@ -220,41 +220,41 @@ describe 'adapter' do context 'when no adapter is specified' do let(:adapter) do - client.transport.connections.all.first.connection.builder.handlers + client.transport.connections.all.first.connection.builder.adapter end it 'uses Faraday NetHttp' do - expect(adapter).to include(Faraday::Adapter::NetHttp) + expect(adapter).to eq Faraday::Adapter::NetHttp end end context 'when the adapter is specified' do let(:adapter) do - client.transport.connections.all.first.connection.builder.handlers + client.transport.connections.all.first.connection.builder.adapter end let(:client) do - described_class.new(adapter: :typhoeus) + described_class.new(adapter: :patron) end it 'uses Faraday with the adapter' do - expect(adapter).to include(Faraday::Adapter::Typhoeus) + expect(adapter).to eq Faraday::Adapter::Patron end end context 'when the adapter is specified as a string key' do let(:adapter) do - client.transport.connections.all.first.connection.builder.handlers + client.transport.connections.all.first.connection.builder.adapter end let(:client) do - described_class.new('adapter' => :typhoeus) + described_class.new('adapter' => :patron) end it 'uses Faraday with the adapter' do - expect(adapter).to include(Faraday::Adapter::Typhoeus) + expect(adapter).to eq Faraday::Adapter::Patron end end @@ -266,11 +266,11 @@ end let(:adapter) do - client.transport.connections.all.first.connection.builder.handlers + client.transport.connections.all.first.connection.builder.adapter end it 'uses the detected adapter' do - expect(adapter).to include(Faraday::Adapter::Patron) + expect(adapter).to eq Faraday::Adapter::Patron end end @@ -278,17 +278,21 @@ let(:client) do described_class.new do |faraday| - faraday.adapter :typhoeus + faraday.adapter :patron faraday.response :logger end end + let(:adapter) do + client.transport.connections.all.first.connection.builder.adapter + end + let(:handlers) do client.transport.connections.all.first.connection.builder.handlers end it 'sets the adapter' do - expect(handlers).to include(Faraday::Adapter::Typhoeus) + expect(adapter).to eq Faraday::Adapter::Patron end it 'sets the logger' do @@ -1209,15 +1213,14 @@ end context 'when the Faraday adapter is set in the block' do - let(:client) do Elasticsearch::Client.new(host: ELASTICSEARCH_HOSTS.first, logger: logger) do |client| client.adapter(:net_http_persistent) end end - let(:connection_handler) do - client.transport.connections.first.connection.builder.handlers.first + let(:handler_name) do + client.transport.connections.first.connection.builder.adapter.name end let(:response) do @@ -1225,7 +1228,7 @@ end it 'sets the adapter' do - expect(connection_handler.name).to eq('Faraday::Adapter::NetHttpPersistent') + expect(handler_name).to eq('Faraday::Adapter::NetHttpPersistent') end it 'uses the adapter to connect' do @@ -1559,12 +1562,12 @@ { adapter: :patron } end - let(:connection_handler) do - client.transport.connections.first.connection.builder.handlers.first + let(:adapter) do + client.transport.connections.first.connection.builder.adapter end it 'uses the patron connection handler' do - expect(connection_handler).to eq('Faraday::Adapter::Patron') + expect(adapter).to eq('Faraday::Adapter::Patron') end it 'keeps connections open' do From e4ca252ad2bc421584a077b646a0d8fb1116fae6 Mon Sep 17 00:00:00 2001 From: Fernando Briano Date: Wed, 25 Mar 2020 10:49:41 +0000 Subject: [PATCH 3/5] [Client] Change how the adapter is set in the client initializer Migrating to Faraday 1.0 means we check with `adapter` to see which one has been selected. I also changed the order in which the given block is ran. There's a case where one of the adapter libraries could be loaded and an adapter is passed in with the block, but `__auto_detect_adapter` would overwrite this. So the block is now ran last. --- .../lib/elasticsearch/transport/client.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/elasticsearch-transport/lib/elasticsearch/transport/client.rb b/elasticsearch-transport/lib/elasticsearch/transport/client.rb index 1d033d82ea..be61a6d54b 100644 --- a/elasticsearch-transport/lib/elasticsearch/transport/client.rb +++ b/elasticsearch-transport/lib/elasticsearch/transport/client.rb @@ -142,10 +142,8 @@ def initialize(arguments={}, &block) transport_class = @arguments[:transport_class] || DEFAULT_TRANSPORT_CLASS if transport_class == Transport::HTTP::Faraday @transport = transport_class.new(hosts: @seeds, options: @arguments) do |faraday| - block.call faraday if block - unless (h = faraday.builder.handlers.last) && h.name.start_with?("Faraday::Adapter") - faraday.adapter(@arguments[:adapter] || __auto_detect_adapter) - end + faraday.adapter(@arguments[:adapter] || __auto_detect_adapter) + block&.call faraday end else @transport = transport_class.new(hosts: @seeds, options: @arguments) From 1079894fb1688fdf22eeb63317c70d1bdf062b61 Mon Sep 17 00:00:00 2001 From: Fernando Briano Date: Tue, 3 Mar 2020 17:24:24 +0000 Subject: [PATCH 4/5] Update elasticsearch-transport README --- elasticsearch-transport/README.md | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/elasticsearch-transport/README.md b/elasticsearch-transport/README.md index 418e6c920a..9cff86669d 100644 --- a/elasticsearch-transport/README.md +++ b/elasticsearch-transport/README.md @@ -374,17 +374,7 @@ To configure the _Faraday_ instance directly, use a block: f.adapter :typhoeus end -You can use any standard Faraday middleware and plugins in the configuration block, -for example sign the requests for the [AWS Elasticsearch service](https://aws.amazon.com/elasticsearch-service/): - - require 'faraday_middleware/aws_signers_v4' - - client = Elasticsearch::Client.new url: 'https://search-my-cluster-abc123....es.amazonaws.com' do |f| - f.request :aws_signers_v4, - credentials: Aws::Credentials.new(ENV['AWS_ACCESS_KEY'], ENV['AWS_SECRET_ACCESS_KEY']), - service_name: 'es', - region: 'us-east-1' - end +You can use any standard Faraday middleware and plugins in the configuration block, for example sign the requests for the [AWS Elasticsearch service](https://aws.amazon.com/elasticsearch-service/). See [the AWS documentation](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-request-signing.html#es-request-signing-ruby) for an example. You can also initialize the transport class yourself, and pass it to the client constructor as the `transport` argument: From 3d8cff2684ed08249d3c4d02305688207ce81d77 Mon Sep 17 00:00:00 2001 From: Fernando Briano Date: Wed, 25 Mar 2020 21:37:29 +0000 Subject: [PATCH 5/5] Update READMES --- README.md | 4 +-- elasticsearch-transport/README.md | 47 +++++++++++++++++-------------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 753a541e5e..4bfcc2d744 100644 --- a/README.md +++ b/README.md @@ -77,9 +77,7 @@ Both of these libraries are extensively documented. and the [`elasticsearch-api`](http://rubydoc.info/gems/elasticsearch-api) documentation carefully.** _Keep in mind, that for optimal performance, you should use a HTTP library which supports persistent -("keep-alive") connections, e.g. [Patron](https://github.com/toland/patron) or -[Typhoeus](https://github.com/typhoeus/typhoeus)._ These libraries are not dependencies of the elasticsearch gems, so -be sure to define a dependency in your own application. +("keep-alive") connections, e.g. [Patron](https://github.com/toland/patron)._ These libraries are not dependencies of the elasticsearch gems, so be sure to define a dependency in your own application. This repository contains these additional Ruby libraries: diff --git a/elasticsearch-transport/README.md b/elasticsearch-transport/README.md index 9cff86669d..985ed435bb 100644 --- a/elasticsearch-transport/README.md +++ b/elasticsearch-transport/README.md @@ -28,12 +28,16 @@ Features overview: * Node reloading (based on cluster state) on errors or on demand For optimal performance, use a HTTP library which supports persistent ("keep-alive") connections, -such as [Typhoeus](https://github.com/typhoeus/typhoeus). -Just require the library (`require 'typhoeus'; require 'typhoeus/adapters/faraday'`) in your code, -and it will be automatically used; currently these libraries will be automatically detected and used: -[Patron](https://github.com/toland/patron), -[HTTPClient](https://rubygems.org/gems/httpclient) and -[Net::HTTP::Persistent](https://rubygems.org/gems/net-http-persistent). +such as [patron](https://github.com/toland/patron). +Just require the library (`require 'patron'`) in your code, +and it will be automatically used. + +Currently these libraries will be automatically detected and used: +- [Patron](https://github.com/toland/patron) +- [HTTPClient](https://rubygems.org/gems/httpclient) +- [Net::HTTP::Persistent](https://rubygems.org/gems/net-http-persistent) + +**Note on [Typhoeus](https://github.com/typhoeus/typhoeus)**: Typhoeus is compatible and will be automatically detected too. However, the latest release (v1.3.1 at the moment of writing this) is not compatible with Faraday 1.0. [It still uses the deprecated `Faraday::Error` namespace](https://github.com/typhoeus/typhoeus/blob/v1.3.1/lib/typhoeus/adapters/faraday.rb#L100). If you want to use it with this gem, we suggest getting `master` from GitHub, since this has been fixed for v1.4.0. We'll update this if/when v1.4.0 is released.a For detailed information, see example configurations [below](#transport-implementations). @@ -366,12 +370,11 @@ constructor, use the `transport_options` key: To configure the _Faraday_ instance directly, use a block: - require 'typhoeus' - require 'typhoeus/adapters/faraday' + require 'patron' client = Elasticsearch::Client.new(host: 'localhost', port: '9200') do |f| f.response :logger - f.adapter :typhoeus + f.adapter :patron end You can use any standard Faraday middleware and plugins in the configuration block, for example sign the requests for the [AWS Elasticsearch service](https://aws.amazon.com/elasticsearch-service/). See [the AWS documentation](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-request-signing.html#es-request-signing-ruby) for an example. @@ -379,21 +382,23 @@ You can use any standard Faraday middleware and plugins in the configuration blo You can also initialize the transport class yourself, and pass it to the client constructor as the `transport` argument: - require 'typhoeus' - require 'typhoeus/adapters/faraday' +```ruby +require 'patron' - transport_configuration = lambda do |f| - f.response :logger - f.adapter :typhoeus - end +transport_configuration = lambda do |f| + f.response :logger + f.adapter :patron +end - transport = Elasticsearch::Transport::Transport::HTTP::Faraday.new \ - hosts: [ { host: 'localhost', port: '9200' } ], - &transport_configuration +transport = Elasticsearch::Transport::Transport::HTTP::Faraday.new \ + hosts: [ { host: 'localhost', port: '9200' } ], + &transport_configuration + +# Pass the transport to the client +# +client = Elasticsearch::Client.new transport: transport +``` - # Pass the transport to the client - # - client = Elasticsearch::Client.new transport: transport Instead of passing the transport to the constructor, you can inject it at run time: