elasticsearch-transport 2.0.2 → 5.0.0.pre

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
  SHA1:
3
- metadata.gz: 2130b4dc3b3535f12040bf6855c0818512ff278b
4
- data.tar.gz: ea2d71deae8bf8f7a02d55d83c6fa4b0dc5fdd48
3
+ metadata.gz: 568a5ed3db7d573112248d69314c74fd2a988c31
4
+ data.tar.gz: b453b165af67c3055f9d69029c50d502a87958b2
5
5
  SHA512:
6
- metadata.gz: f525b4b8f8d816cf1275dfbda0fc057944763ab8a131bb5e5052c89efb8111f835fbc454822eb5f4003449c79ab403cb2816b2da5d02542147426e72452c1d4b
7
- data.tar.gz: 7bf1a2f9167b63f89f2a9526040fbc69762d34110b95567ec5975d7501fa00e91375768690aea3261f40305ac564f61877f132abb2ecf09f7860892e0755c507
6
+ metadata.gz: 698088ec4e9741e569ee05e61ea4a3d8aee18cd48fdbb0fca04f595bc68d1711ec91d95e7166efcd75aec82a0d7aab07cbc5dfe3f1d055a464da6d57f5372744
7
+ data.tar.gz: 50a1533da40acedb10b2b310d29734ae27c0d3caabadd9844b1ef2b4d1093fd7bd15900895e925dfb47e66d2fef00f02575ecbbaeb8c139804aab9e5e65f7544
data/Gemfile CHANGED
@@ -7,7 +7,7 @@ if File.exist? File.expand_path("../../elasticsearch-api/elasticsearch-api.gemsp
7
7
  gem 'elasticsearch-api', :path => File.expand_path("../../elasticsearch-api", __FILE__), :require => false
8
8
  end
9
9
 
10
- if File.exist? File.expand_path("../../elasticsearch-extensions/elasticsearch-extensions.gemspec", __FILE__)
10
+ if File.exist? File.expand_path("../../elasticsearch-extensions", __FILE__)
11
11
  gem 'elasticsearch-extensions', :path => File.expand_path("../../elasticsearch-extensions", __FILE__), :require => false
12
12
  end
13
13
 
data/README.md CHANGED
@@ -16,7 +16,7 @@ data serialization and transport.
16
16
  It does not handle calling the Elasticsearch API;
17
17
  see the [`elasticsearch-api`](https://github.com/elasticsearch/elasticsearch-ruby/tree/master/elasticsearch-api) library.
18
18
 
19
- The library is compatible with Ruby 1.8.7 or higher and with Elasticsearch 0.90 and 1.0.
19
+ The library is compatible with Ruby 1.8.7 or higher and with all versions of Elasticsearch since 0.90.
20
20
 
21
21
  Features overview:
22
22
 
@@ -58,7 +58,7 @@ Gem::Specification.new do |s|
58
58
  # Prevent unit test failures on Ruby 1.8
59
59
  if defined?(RUBY_VERSION) && RUBY_VERSION < '1.9'
60
60
  s.add_development_dependency "test-unit", '~> 2'
61
- s.add_development_dependency "json"
61
+ s.add_development_dependency "json", '~> 1.8'
62
62
  end
63
63
 
64
64
  if defined?(RUBY_VERSION) && RUBY_VERSION > '1.9'
@@ -34,7 +34,6 @@ module Elasticsearch
34
34
  @hosts = arguments[:hosts] || []
35
35
  @options = arguments[:options] || {}
36
36
  @options[:http] ||= {}
37
- @options[:retry_on_status] ||= []
38
37
 
39
38
  @block = block
40
39
  @connections = __build_connections
@@ -50,9 +49,9 @@ module Elasticsearch
50
49
  @counter_mtx = Mutex.new
51
50
  @last_request_at = Time.now
52
51
  @reload_connections = options[:reload_connections]
53
- @reload_after = options[:reload_connections].is_a?(Integer) ? options[:reload_connections] : DEFAULT_RELOAD_AFTER
52
+ @reload_after = options[:reload_connections].is_a?(Fixnum) ? options[:reload_connections] : DEFAULT_RELOAD_AFTER
54
53
  @resurrect_after = options[:resurrect_after] || DEFAULT_RESURRECT_AFTER
55
- @max_retries = options[:retry_on_failure].is_a?(Integer) ? options[:retry_on_failure] : DEFAULT_MAX_RETRIES
54
+ @max_retries = options[:retry_on_failure].is_a?(Fixnum) ? options[:retry_on_failure] : DEFAULT_MAX_RETRIES
56
55
  @retry_on_status = Array(options[:retry_on_status]).map { |d| d.to_i }
57
56
  end
58
57
 
@@ -28,12 +28,12 @@ module Elasticsearch
28
28
 
29
29
  connection.connection.http(method.to_sym)
30
30
 
31
- headers = {}
32
- headers['content-type'] = 'application/json' if connection.connection.header_str =~ /\/json/
31
+ response_headers = {}
32
+ response_headers['content-type'] = 'application/json' if connection.connection.header_str =~ /\/json/
33
33
 
34
34
  Response.new connection.connection.response_code,
35
35
  connection.connection.body_str,
36
- headers
36
+ response_headers
37
37
  end
38
38
  end
39
39
 
@@ -18,11 +18,14 @@ module Elasticsearch
18
18
  #
19
19
  def perform_request(method, path, params={}, body=nil)
20
20
  super do |connection, url|
21
+ headers = connection.connection.headers
22
+
21
23
  response = connection.connection.run_request \
22
24
  method.downcase.to_sym,
23
25
  url,
24
26
  ( body ? __convert_to_json(body) : nil ),
25
- {}
27
+ headers
28
+
26
29
  Response.new response.status, response.body, response.headers
27
30
  end
28
31
  end
@@ -5,8 +5,7 @@ module Elasticsearch
5
5
  # Handles node discovery ("sniffing")
6
6
  #
7
7
  class Sniffer
8
- ES1_RE_URL = /\[([^\/]*)?\/?([^:]*):([0-9]+)\]/
9
- ES2_RE_URL = /([^\/]*)?\/?([^:]*):([0-9]+)/
8
+ PROTOCOL = 'http'
10
9
 
11
10
  attr_reader :transport
12
11
  attr_accessor :timeout
@@ -30,13 +29,18 @@ module Elasticsearch
30
29
  def hosts
31
30
  Timeout::timeout(timeout, SnifferTimeoutError) do
32
31
  nodes = transport.perform_request('GET', '_nodes/http').body
32
+
33
33
  hosts = nodes['nodes'].map do |id,info|
34
- addr_str = info["#{transport.protocol}_address"].to_s
35
- matches = addr_str.match(ES1_RE_URL) || addr_str.match(ES2_RE_URL)
36
- if matches
37
- host = matches[1].empty? ? matches[2] : matches[1]
38
- port = matches[3]
39
- info.merge :host => host, :port => port, :id => id
34
+ if info[PROTOCOL]
35
+ host, port = info[PROTOCOL]['publish_address'].split(':')
36
+
37
+ { :id => id,
38
+ :name => info['name'],
39
+ :version => info['version'],
40
+ :host => host,
41
+ :port => port,
42
+ :roles => info['roles'],
43
+ :attributes => info['attributes'] }
40
44
  end
41
45
  end.compact
42
46
 
@@ -1,5 +1,5 @@
1
1
  module Elasticsearch
2
2
  module Transport
3
- VERSION = "2.0.2"
3
+ VERSION = "5.0.0.pre"
4
4
  end
5
5
  end
@@ -17,7 +17,7 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
17
17
 
18
18
  setup do
19
19
  @port = (ENV['TEST_CLUSTER_PORT'] || 9250).to_i
20
- system "curl -X DELETE http://localhost:#{@port}/_all > /dev/null 2>&1"
20
+ system "curl -X DELETE http://127.0.0.1:#{@port}/_all > /dev/null 2>&1"
21
21
 
22
22
  @logger = Logger.new(STDERR)
23
23
  @logger.formatter = proc do |severity, datetime, progname, msg|
@@ -30,7 +30,7 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
30
30
  ANSI.ansi(severity[0] + ' ', color, :faint) + ANSI.ansi(msg, :white, :faint) + "\n"
31
31
  end
32
32
 
33
- @client = Elasticsearch::Client.new host: "localhost:#{@port}"
33
+ @client = Elasticsearch::Client.new host: "127.0.0.1:#{@port}"
34
34
  end
35
35
 
36
36
  should "connect to the cluster" do
@@ -55,32 +55,35 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
55
55
 
56
56
  should "pass options to the transport" do
57
57
  @client = Elasticsearch::Client.new \
58
- host: "localhost:#{@port}",
58
+ host: "127.0.0.1:#{@port}",
59
59
  logger: (ENV['QUIET'] ? nil : @logger),
60
- transport_options: { headers: { content_type: 'application/yaml' } }
60
+ transport_options: { headers: { accept: 'application/yaml', content_type: 'application/yaml' } }
61
61
 
62
62
  response = @client.perform_request 'GET', '_cluster/health'
63
- assert_match /---\ncluster_name:/, response.body.to_s
63
+
64
+ assert response.body.to_s.start_with?("---\n"), "Response body should be YAML: #{response.body.inspect}"
65
+ assert_equal 'application/yaml', response.headers['content-type']
64
66
  end
65
67
 
66
68
  should "pass options to the Faraday::Connection with a block" do
67
69
  @client = Elasticsearch::Client.new(
68
- host: "localhost:#{@port}",
70
+ host: "127.0.0.1:#{@port}",
69
71
  logger: (ENV['QUIET'] ? nil : @logger)
70
72
  ) do |client|
71
- client.headers['Content-Type'] = 'application/yaml'
73
+ client.headers['Content-Type'] = 'application/yaml' # For ES 2.x
74
+ client.headers['Accept'] = 'application/yaml' # For ES 5.x
72
75
  end
73
76
 
74
77
  response = @client.perform_request 'GET', '_cluster/health'
75
78
 
76
- assert response.body.start_with?("---\n"), "Response body should be YAML: #{response.body.inspect}"
79
+ assert response.body.to_s.start_with?("---\n"), "Response body should be YAML: #{response.body.inspect}"
77
80
  assert_equal 'application/yaml', response.headers['content-type']
78
81
  end
79
82
 
80
83
  context "with round robin selector" do
81
84
  setup do
82
85
  @client = Elasticsearch::Client.new \
83
- hosts: ["localhost:#{@port}", "localhost:#{@port+1}" ],
86
+ hosts: ["127.0.0.1:#{@port}", "127.0.0.1:#{@port+1}" ],
84
87
  logger: (ENV['QUIET'] ? nil : @logger)
85
88
  end
86
89
 
@@ -103,7 +106,7 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
103
106
  setup do
104
107
  @port = (ENV['TEST_CLUSTER_PORT'] || 9250).to_i
105
108
  @client = Elasticsearch::Client.new \
106
- hosts: ["localhost:#{@port}", "foobar1"],
109
+ hosts: ["127.0.0.1:#{@port}", "foobar1"],
107
110
  logger: (ENV['QUIET'] ? nil : @logger),
108
111
  retry_on_failure: true
109
112
  end
@@ -116,7 +119,7 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
116
119
 
117
120
  should "raise exception when it cannot get any healthy server" do
118
121
  @client = Elasticsearch::Client.new \
119
- hosts: ["localhost:#{@port}", "foobar1", "foobar2", "foobar3"],
122
+ hosts: ["127.0.0.1:#{@port}", "foobar1", "foobar2", "foobar3"],
120
123
  logger: (ENV['QUIET'] ? nil : @logger),
121
124
  retry_on_failure: 1
122
125
 
@@ -135,7 +138,7 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
135
138
  context "with a sick node and reloading on failure" do
136
139
  setup do
137
140
  @client = Elasticsearch::Client.new \
138
- hosts: ["localhost:#{@port}", "foobar1", "foobar2"],
141
+ hosts: ["127.0.0.1:#{@port}", "foobar1", "foobar2"],
139
142
  logger: (ENV['QUIET'] ? nil : @logger),
140
143
  reload_on_failure: true
141
144
  end
@@ -152,7 +155,7 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
152
155
  context "with retrying on status" do
153
156
  should "retry when the status does match" do
154
157
  @client = Elasticsearch::Client.new \
155
- hosts: ["localhost:#{@port}"],
158
+ hosts: ["127.0.0.1:#{@port}"],
156
159
  logger: (ENV['QUIET'] ? nil : @logger),
157
160
  retry_on_status: 400
158
161
 
@@ -170,7 +173,7 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
170
173
  context "when reloading connections" do
171
174
  should "keep existing connections" do
172
175
  require 'patron' # We need a client with keep-alive
173
- client = Elasticsearch::Transport::Client.new host: "localhost:#{@port}", adapter: :patron, logger: @logger
176
+ client = Elasticsearch::Transport::Client.new host: "127.0.0.1:#{@port}", adapter: :patron, logger: @logger
174
177
 
175
178
  assert_equal 'Faraday::Adapter::Patron',
176
179
  client.transport.connections.first.connection.builder.handlers.first.name
@@ -192,7 +195,7 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
192
195
  should "set the adapter with a block" do
193
196
  require 'net/http/persistent'
194
197
 
195
- client = Elasticsearch::Transport::Client.new url: "localhost:#{@port}" do |f|
198
+ client = Elasticsearch::Transport::Client.new url: "127.0.0.1:#{@port}" do |f|
196
199
  f.adapter :net_http_persistent
197
200
  end
198
201
 
@@ -207,7 +210,7 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
207
210
  teardown { begin; Object.send(:remove_const, :Patron); rescue NameError; end }
208
211
 
209
212
  require 'patron'
210
- client = Elasticsearch::Transport::Client.new host: "localhost:#{@port}"
213
+ client = Elasticsearch::Transport::Client.new host: "127.0.0.1:#{@port}"
211
214
 
212
215
  assert_equal 'Faraday::Adapter::Patron',
213
216
  client.transport.connections.first.connection.builder.handlers.first.name
@@ -11,6 +11,38 @@ class Elasticsearch::Transport::Transport::SnifferTest < Test::Unit::TestCase
11
11
  Elasticsearch::Transport::Transport::Response.new 200, MultiJson.load(json)
12
12
  end
13
13
 
14
+ DEFAULT_NODES_INFO_RESPONSE = <<-JSON
15
+ {
16
+ "cluster_name" : "elasticsearch_test",
17
+ "nodes" : {
18
+ "N1" : {
19
+ "name" : "Node 1",
20
+ "transport_address" : "127.0.0.1:9300",
21
+ "host" : "testhost1",
22
+ "ip" : "127.0.0.1",
23
+ "version" : "5.0.0",
24
+ "roles": [
25
+ "master",
26
+ "data",
27
+ "ingest"
28
+ ],
29
+ "attributes": {
30
+ "testattr": "test"
31
+ },
32
+ "http": {
33
+ "bound_address": [
34
+ "[fe80::1]:9250",
35
+ "[::1]:9250",
36
+ "127.0.0.1:9250"
37
+ ],
38
+ "publish_address": "127.0.0.1:9250",
39
+ "max_content_length_in_bytes": 104857600
40
+ }
41
+ }
42
+ }
43
+ }
44
+ JSON
45
+
14
46
  context "Sniffer" do
15
47
  setup do
16
48
  @transport = DummyTransport.new
@@ -21,47 +53,25 @@ class Elasticsearch::Transport::Transport::SnifferTest < Test::Unit::TestCase
21
53
  assert_equal @transport, @sniffer.transport
22
54
  end
23
55
 
24
- should "return an array of hosts as hashes with Elasticsearch 1.x syntax" do
25
- @transport.expects(:perform_request).returns __nodes_info <<-JSON
26
- {
27
- "ok" : true,
28
- "cluster_name" : "elasticsearch_test",
29
- "nodes" : {
30
- "N1" : {
31
- "name" : "Node 1",
32
- "transport_address" : "inet[/192.168.1.23:9300]",
33
- "hostname" : "testhost1",
34
- "version" : "0.20.6",
35
- "http_address" : "inet[/192.168.1.23:9200]",
36
- "thrift_address" : "/192.168.1.23:9500",
37
- "memcached_address" : "inet[/192.168.1.23:11211]"
38
- }
39
- }
40
- }
41
- JSON
56
+ should "return an array of hosts as hashes" do
57
+ @transport.expects(:perform_request).returns __nodes_info(DEFAULT_NODES_INFO_RESPONSE)
42
58
 
43
59
  hosts = @sniffer.hosts
44
60
 
45
61
  assert_equal 1, hosts.size
46
- assert_equal '192.168.1.23', hosts.first[:host]
47
- assert_equal '9200', hosts.first[:port]
48
- assert_equal 'Node 1', hosts.first['name']
62
+ assert_equal '127.0.0.1', hosts.first[:host]
63
+ assert_equal '9250', hosts.first[:port]
64
+ assert_equal 'Node 1', hosts.first[:name]
49
65
  end
50
66
 
51
- should "return an array of hosts as hashes with Elasticsearch 2.0 syntax" do
67
+ should "return an array of hosts as hostnames when a hostname is returned" do
52
68
  @transport.expects(:perform_request).returns __nodes_info <<-JSON
53
69
  {
54
- "ok" : true,
55
- "cluster_name" : "elasticsearch_test",
56
70
  "nodes" : {
57
71
  "N1" : {
58
- "name" : "Node 1",
59
- "transport_address" : "192.168.1.23:9300",
60
- "hostname" : "testhost1",
61
- "version" : "0.20.6",
62
- "http_address" : "192.168.1.23:9200",
63
- "thrift_address" : "192.168.1.23:9500",
64
- "memcached_address" : "192.168.1.23:11211"
72
+ "http": {
73
+ "publish_address": "testhost1.com:9250"
74
+ }
65
75
  }
66
76
  }
67
77
  }
@@ -70,66 +80,36 @@ class Elasticsearch::Transport::Transport::SnifferTest < Test::Unit::TestCase
70
80
  hosts = @sniffer.hosts
71
81
 
72
82
  assert_equal 1, hosts.size
73
- assert_equal '192.168.1.23', hosts.first[:host]
74
- assert_equal '9200', hosts.first[:port]
75
- assert_equal 'Node 1', hosts.first['name']
83
+ assert_equal 'testhost1.com', hosts.first[:host]
84
+ assert_equal '9250', hosts.first[:port]
76
85
  end
77
86
 
78
- should "return an array of hosts as hostnames when a hostname is returned" do
79
- @transport.expects(:perform_request).returns __nodes_info <<-JSON
80
- {
81
- "ok" : true,
82
- "cluster_name" : "elasticsearch_test",
83
- "nodes" : {
84
- "N1" : {
85
- "name" : "Node 1",
86
- "transport_address" : "inet[/192.168.1.23:9300]",
87
- "hostname" : "testhost1",
88
- "version" : "0.20.6",
89
- "http_address" : "inet[testhost1.com/192.168.1.23:9200]",
90
- "thrift_address" : "/192.168.1.23:9500",
91
- "memcached_address" : "inet[/192.168.1.23:11211]"
92
- }
93
- }
94
- }
95
- JSON
87
+ should "return HTTP hosts for the HTTPS protocol in the transport" do
88
+ @transport = DummyTransport.new :options => { :protocol => 'https' }
89
+ @sniffer = Elasticsearch::Transport::Transport::Sniffer.new @transport
96
90
 
97
- hosts = @sniffer.hosts
91
+ @transport.expects(:perform_request).returns __nodes_info(DEFAULT_NODES_INFO_RESPONSE)
98
92
 
99
- assert_equal 1, hosts.size
100
- assert_equal 'testhost1.com', hosts.first[:host]
101
- assert_equal '9200', hosts.first[:port]
102
- assert_equal 'Node 1', hosts.first['name']
93
+ assert_equal 1, @sniffer.hosts.size
103
94
  end
104
95
 
105
96
  should "skip hosts without a matching transport protocol" do
106
- @transport = DummyTransport.new :options => { :protocol => 'memcached' }
97
+ @transport = DummyTransport.new
107
98
  @sniffer = Elasticsearch::Transport::Transport::Sniffer.new @transport
108
99
 
109
100
  @transport.expects(:perform_request).returns __nodes_info <<-JSON
110
101
  {
111
- "ok" : true,
112
- "cluster_name" : "elasticsearch_test",
113
102
  "nodes" : {
114
103
  "N1" : {
115
- "name" : "Memcached Node",
116
- "http_address" : "inet[/192.168.1.23:9200]",
117
- "memcached_address" : "inet[/192.168.1.23:11211]"
118
- },
119
- "N2" : {
120
- "name" : "HTTP Node",
121
- "http_address" : "inet[/192.168.1.23:9200]"
104
+ "foobar": {
105
+ "publish_address": "foobar:1234"
106
+ }
122
107
  }
123
108
  }
124
109
  }
125
110
  JSON
126
111
 
127
- hosts = @sniffer.hosts
128
-
129
- assert_equal 1, hosts.size
130
- assert_equal '192.168.1.23', hosts.first[:host]
131
- assert_equal '11211', hosts.first[:port]
132
- assert_equal 'Memcached Node', hosts.first['name']
112
+ assert_empty @sniffer.hosts
133
113
  end
134
114
 
135
115
  should "have configurable timeout" do
@@ -55,7 +55,7 @@ else
55
55
  @transport.perform_request 'POST', '/', {}, '{"foo":"bar"}'
56
56
  end
57
57
 
58
- should "set application/json header" do
58
+ should "set application/json response header" do
59
59
  @transport.connections.first.connection.expects(:http).with(:GET).returns(stub_everything)
60
60
  @transport.connections.first.connection.expects(:body_str).returns('{"foo":"bar"}')
61
61
  @transport.connections.first.connection.expects(:header_str).returns('HTTP/1.1 200 OK\r\nContent-Type: application/json; charset=UTF-8\r\nContent-Length: 311\r\n\r\n')
@@ -33,8 +33,12 @@ class Elasticsearch::Transport::Transport::HTTP::FaradayTest < Test::Unit::TestC
33
33
 
34
34
  should "properly prepare the request" do
35
35
  @transport.connections.first.connection.expects(:run_request).with do |method, url, body, headers|
36
- :post == method && '{"foo":"bar"}' == body
36
+ assert_equal :post, method
37
+ assert_equal '{"foo":"bar"}', body
38
+ assert_nil headers['Accept']
39
+ true
37
40
  end.returns(stub_everything)
41
+
38
42
  @transport.perform_request 'POST', '/', {}, {:foo => 'bar'}
39
43
  end
40
44
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elasticsearch-transport
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 5.0.0.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Karel Minarik
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-07 00:00:00.000000000 Z
11
+ date: 2016-10-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: multi_json
@@ -410,12 +410,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
410
410
  version: '0'
411
411
  required_rubygems_version: !ruby/object:Gem::Requirement
412
412
  requirements:
413
- - - ">="
413
+ - - ">"
414
414
  - !ruby/object:Gem::Version
415
- version: '0'
415
+ version: 1.3.1
416
416
  requirements: []
417
417
  rubyforge_project:
418
- rubygems_version: 2.6.10
418
+ rubygems_version: 2.5.1
419
419
  signing_key:
420
420
  specification_version: 4
421
421
  summary: Ruby client for Elasticsearch.