1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
|
[[transport]]
=== Transport
The `elasticsearch-transport` library provides a low-level Ruby client for
connecting to an {es} cluster.
It handles connecting to multiple nodes in the cluster, rotating across
connections, logging and tracing requests and responses, maintaining failed
connections, discovering nodes in the cluster, and provides an abstraction for
data serialization and transport.
It does not handle calling the {es} API.
For optimal performance, use a HTTP library which supports persistent
("keep-alive") connections, such as https://github.com/toland/patron[patron] or
https://github.com/typhoeus/typhoeus[Typhoeus]. Require the library
(require 'patron') in your code, and it will be automatically used.
[discrete]
[[transport-install]]
==== Installation
Install the package from https://rubygems.org/[Rubygems]:
```
gem install elasticsearch-transport
```
To use an unreleased version, either add it to your `Gemfile` for
http://gembundler.com/[Bundler]:
```
gem 'elasticsearch-transport', git: 'git://github.com/elasticsearch/elasticsearch-ruby.git'
```
or install it from a source code checkout:
```
git clone https://github.com/elasticsearch/elasticsearch-ruby.git
cd elasticsearch-ruby/elasticsearch-transport
bundle install
rake install
```
[discrete]
[[transport-example-usage]]
==== Example usage
In the simplest form, connect to {es} running on http://localhost:9200 without
any configuration:
```ruby
require 'elasticsearch/transport'
client = Elasticsearch::Client.new
response = client.perform_request('GET', '_cluster/health')
# => #<Elasticsearch::Transport::Transport::Response:0x007fc5d506ce38 @status=200, @body={ ... } >
```
Full documentation is available at
http://rubydoc.info/gems/elasticsearch-transport.
[discrete]
[[transport-implementations]]
==== Transport implementations
By default, the client uses the https://rubygems.org/gems/faraday[Faraday] HTTP
library as a transport implementation.
It auto-detects and uses an adapter for Faraday based on gems loaded in your
code, preferring HTTP clients with support for persistent connections.
To use the https://github.com/toland/patron[Patron] HTTP, for example, require
it:
```
require 'patron'
```
Then, create a new client, and the Patron gem will be used as the "driver":
```ruby
client = Elasticsearch::Client.new
client.transport.connections.first.connection.builder.adapter
# => Faraday::Adapter::Patron
10.times do
client.nodes.stats(metric: 'http')['nodes'].values.each do |n|
puts "#{n['name']} : #{n['http']['total_opened']}"
end
end
# => Stiletoo : 24
# => Stiletoo : 24
# => Stiletoo : 24
# => ...
```
To use a specific adapter for Faraday, pass it as the `adapter` argument:
```ruby
client = Elasticsearch::Client.new adapter: :net_http_persistent
client.transport.connections.first.connection.builder.handlers
# => [Faraday::Adapter::NetHttpPersistent]
```
To pass options to the
https://github.com/lostisland/faraday/blob/master/lib/faraday/connection.rb[`Faraday::Connection`]
constructor, use the `transport_options` key:
```ruby
client = Elasticsearch::Client.new transport_options: {
request: { open_timeout: 1 },
headers: { user_agent: 'MyApp' },
params: { :format => 'yaml' },
ssl: { verify: false }
}
```
To configure the Faraday instance directly, use a block:
```ruby
require 'patron'
client = Elasticsearch::Client.new(host: 'localhost', port: '9200') do |f|
f.response :logger
f.adapter :patron
end
```
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:
```ruby
require 'patron'
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
# 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:
```ruby
# Set up the transport
#
faraday_configuration = lambda do |f|
f.instance_variable_set :@ssl, { verify: false }
f.adapter :excon
end
faraday_client = Elasticsearch::Transport::Transport::HTTP::Faraday.new \
hosts: [ { host: 'my-protected-host',
port: '443',
user: 'USERNAME',
password: 'PASSWORD',
scheme: 'https'
}],
&faraday_configuration
# Create a default client
#
client = Elasticsearch::Client.new
# Inject the transport to the client
#
client.transport = faraday_client
```
You can also use a bundled https://rubygems.org/gems/curb[Curb] based transport
implementation:
```ruby
require 'curb'
require 'elasticsearch/transport/transport/http/curb'
client = Elasticsearch::Client.new transport_class: Elasticsearch::Transport::Transport::HTTP::Curb
client.transport.connections.first.connection
# => #<Curl::Easy http://localhost:9200/>
```
It's possible to customize the Curb instance by passing a block to the
constructor as well (in this case, as an inline block):
```ruby
transport = Elasticsearch::Transport::Transport::HTTP::Curb.new \
hosts: [ { host: 'localhost', port: '9200' } ],
& lambda { |c| c.verbose = true }
client = Elasticsearch::Client.new transport: transport
```
You can write your own transport implementation by including the
{Elasticsearch::Transport::Transport::Base} module, implementing the required
contract, and passing it to the client as the `transport_class` parameter – or
by injecting it directly.
[discrete]
[[transport-architecture]]
==== Transport architecture
* `Elasticsearch::Transport::Client` is composed of
`Elasticsearch::Transport::Transport`.
* `Elasticsearch::Transport::Transport` is composed of
`Elasticsearch::Transport::Transport::Connections`, and an instance of logger,
tracer, serializer and sniffer.
* Logger and tracer can be any object conforming to Ruby logging interface, for
example, an instance of
https://ruby-doc.org/stdlib-1.9.3/libdoc/logger/rdoc/Logger.html[`Logger`],
https://rubygems.org/gems/log4r[log4r],
https://github.com/TwP/logging/[logging], and so on.
* The `Elasticsearch::Transport::Transport::Serializer::Base` implementations
handle converting data for {es} (for example, to JSON). You can implement your
own serializer.
* `Elasticsearch::Transport::Transport::Sniffer` allows to discover nodes in the
cluster and use them as connections.
* `Elasticsearch::Transport::Transport::Connections::Collection` is composed of
`Elasticsearch::Transport::Transport::Connections::Connection` instances and a
selector instance.
* `Elasticsearch::Transport::Transport::Connections::Connection` contains the
connection attributes such as hostname and port, as well as the concrete
persistent "session" connected to a specific node.
* The `Elasticsearch::Transport::Transport::Connections::Selector::Base`
implementations allow to choose connections from the pool, for example, in a
round-robin or random fashion. You can implement your own selector strategy.
|