logstash-output-elasticsearch-test 10.3.0-x86_64-linux

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.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +397 -0
  3. data/CONTRIBUTORS +33 -0
  4. data/Gemfile +15 -0
  5. data/LICENSE +13 -0
  6. data/NOTICE.TXT +5 -0
  7. data/README.md +106 -0
  8. data/docs/index.asciidoc +899 -0
  9. data/lib/logstash/outputs/elasticsearch/common.rb +441 -0
  10. data/lib/logstash/outputs/elasticsearch/common_configs.rb +167 -0
  11. data/lib/logstash/outputs/elasticsearch/default-ilm-policy.json +14 -0
  12. data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es2x.json +95 -0
  13. data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es5x.json +46 -0
  14. data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es6x.json +45 -0
  15. data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es7x.json +44 -0
  16. data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es8x.json +44 -0
  17. data/lib/logstash/outputs/elasticsearch/http_client/manticore_adapter.rb +131 -0
  18. data/lib/logstash/outputs/elasticsearch/http_client/pool.rb +495 -0
  19. data/lib/logstash/outputs/elasticsearch/http_client.rb +432 -0
  20. data/lib/logstash/outputs/elasticsearch/http_client_builder.rb +159 -0
  21. data/lib/logstash/outputs/elasticsearch/ilm.rb +113 -0
  22. data/lib/logstash/outputs/elasticsearch/template_manager.rb +61 -0
  23. data/lib/logstash/outputs/elasticsearch.rb +263 -0
  24. data/logstash-output-elasticsearch.gemspec +33 -0
  25. data/spec/es_spec_helper.rb +189 -0
  26. data/spec/fixtures/_nodes/2x_1x.json +27 -0
  27. data/spec/fixtures/_nodes/5x_6x.json +81 -0
  28. data/spec/fixtures/_nodes/7x.json +92 -0
  29. data/spec/fixtures/htpasswd +2 -0
  30. data/spec/fixtures/nginx_reverse_proxy.conf +22 -0
  31. data/spec/fixtures/scripts/groovy/scripted_update.groovy +2 -0
  32. data/spec/fixtures/scripts/groovy/scripted_update_nested.groovy +2 -0
  33. data/spec/fixtures/scripts/groovy/scripted_upsert.groovy +2 -0
  34. data/spec/fixtures/scripts/painless/scripted_update.painless +2 -0
  35. data/spec/fixtures/scripts/painless/scripted_update_nested.painless +1 -0
  36. data/spec/fixtures/scripts/painless/scripted_upsert.painless +1 -0
  37. data/spec/fixtures/template-with-policy-es6x.json +48 -0
  38. data/spec/fixtures/template-with-policy-es7x.json +45 -0
  39. data/spec/fixtures/test_certs/ca/ca.crt +32 -0
  40. data/spec/fixtures/test_certs/ca/ca.key +51 -0
  41. data/spec/fixtures/test_certs/test.crt +36 -0
  42. data/spec/fixtures/test_certs/test.key +51 -0
  43. data/spec/integration/outputs/compressed_indexing_spec.rb +69 -0
  44. data/spec/integration/outputs/create_spec.rb +67 -0
  45. data/spec/integration/outputs/delete_spec.rb +65 -0
  46. data/spec/integration/outputs/groovy_update_spec.rb +150 -0
  47. data/spec/integration/outputs/ilm_spec.rb +531 -0
  48. data/spec/integration/outputs/index_spec.rb +178 -0
  49. data/spec/integration/outputs/index_version_spec.rb +102 -0
  50. data/spec/integration/outputs/ingest_pipeline_spec.rb +74 -0
  51. data/spec/integration/outputs/metrics_spec.rb +70 -0
  52. data/spec/integration/outputs/no_es_on_startup_spec.rb +58 -0
  53. data/spec/integration/outputs/painless_update_spec.rb +189 -0
  54. data/spec/integration/outputs/parent_spec.rb +102 -0
  55. data/spec/integration/outputs/retry_spec.rb +169 -0
  56. data/spec/integration/outputs/routing_spec.rb +61 -0
  57. data/spec/integration/outputs/sniffer_spec.rb +133 -0
  58. data/spec/integration/outputs/templates_5x_spec.rb +98 -0
  59. data/spec/integration/outputs/templates_spec.rb +98 -0
  60. data/spec/integration/outputs/update_spec.rb +116 -0
  61. data/spec/support/elasticsearch/api/actions/delete_ilm_policy.rb +19 -0
  62. data/spec/support/elasticsearch/api/actions/get_alias.rb +18 -0
  63. data/spec/support/elasticsearch/api/actions/get_ilm_policy.rb +18 -0
  64. data/spec/support/elasticsearch/api/actions/put_alias.rb +24 -0
  65. data/spec/support/elasticsearch/api/actions/put_ilm_policy.rb +25 -0
  66. data/spec/unit/http_client_builder_spec.rb +185 -0
  67. data/spec/unit/outputs/elasticsearch/http_client/manticore_adapter_spec.rb +149 -0
  68. data/spec/unit/outputs/elasticsearch/http_client/pool_spec.rb +274 -0
  69. data/spec/unit/outputs/elasticsearch/http_client_spec.rb +250 -0
  70. data/spec/unit/outputs/elasticsearch/template_manager_spec.rb +25 -0
  71. data/spec/unit/outputs/elasticsearch_proxy_spec.rb +72 -0
  72. data/spec/unit/outputs/elasticsearch_spec.rb +675 -0
  73. data/spec/unit/outputs/elasticsearch_ssl_spec.rb +82 -0
  74. data/spec/unit/outputs/error_whitelist_spec.rb +54 -0
  75. metadata +300 -0
@@ -0,0 +1,274 @@
1
+ require "logstash/devutils/rspec/spec_helper"
2
+ require "logstash/outputs/elasticsearch/http_client"
3
+ require "json"
4
+
5
+ describe LogStash::Outputs::ElasticSearch::HttpClient::Pool do
6
+ let(:logger) { Cabin::Channel.get }
7
+ let(:adapter) { LogStash::Outputs::ElasticSearch::HttpClient::ManticoreAdapter.new(logger) }
8
+ let(:initial_urls) { [::LogStash::Util::SafeURI.new("http://localhost:9200")] }
9
+ let(:options) { {:resurrect_delay => 2, :url_normalizer => proc {|u| u}} } # Shorten the delay a bit to speed up tests
10
+ let(:es_node_versions) { [ "0.0.0" ] }
11
+ let(:oss) { true }
12
+ let(:valid_license) { true }
13
+
14
+ subject { described_class.new(logger, adapter, initial_urls, options) }
15
+
16
+ let(:manticore_double) { double("manticore a") }
17
+ before(:each) do
18
+
19
+ allow(::LogStash::Outputs::ElasticSearch).to receive(:oss?).and_return(oss)
20
+ response_double = double("manticore response").as_null_object
21
+ # Allow healtchecks
22
+ allow(manticore_double).to receive(:head).with(any_args).and_return(response_double)
23
+ allow(manticore_double).to receive(:get).with(any_args).and_return(response_double)
24
+ allow(manticore_double).to receive(:close)
25
+
26
+ allow(::Manticore::Client).to receive(:new).and_return(manticore_double)
27
+
28
+ allow(subject).to receive(:get_es_version).with(any_args).and_return(*es_node_versions)
29
+ allow(subject).to receive(:oss?).and_return(oss)
30
+ allow(subject).to receive(:valid_es_license?).and_return(valid_license)
31
+ end
32
+
33
+ after do
34
+ subject.close
35
+ end
36
+
37
+ describe "initialization" do
38
+ it "should be successful" do
39
+ expect { subject }.not_to raise_error
40
+ subject.start
41
+ end
42
+ end
43
+
44
+ describe "the resurrectionist" do
45
+ before(:each) { subject.start }
46
+ it "should start the resurrectionist when created" do
47
+ expect(subject.resurrectionist_alive?).to eql(true)
48
+ end
49
+
50
+ it "should attempt to resurrect connections after the ressurrect delay" do
51
+ expect(subject).to receive(:healthcheck!).once
52
+ sleep(subject.resurrect_delay + 1)
53
+ end
54
+
55
+ describe "healthcheck url handling" do
56
+ let(:initial_urls) { [::LogStash::Util::SafeURI.new("http://localhost:9200")] }
57
+
58
+ context "and not setting healthcheck_path" do
59
+ it "performs the healthcheck to the root" do
60
+ expect(adapter).to receive(:perform_request) do |url, method, req_path, _, _|
61
+ expect(method).to eq(:head)
62
+ expect(url.path).to be_empty
63
+ expect(req_path).to eq("/")
64
+ end
65
+ subject.healthcheck!
66
+ end
67
+ end
68
+
69
+ context "and setting healthcheck_path" do
70
+ let(:healthcheck_path) { "/my/health" }
71
+ let(:options) { super.merge(:healthcheck_path => healthcheck_path) }
72
+ it "performs the healthcheck to the healthcheck_path" do
73
+ expect(adapter).to receive(:perform_request) do |url, method, req_path, _, _|
74
+ expect(method).to eq(:head)
75
+ expect(url.path).to be_empty
76
+ expect(req_path).to eq(healthcheck_path)
77
+ end
78
+ subject.healthcheck!
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ describe 'resolving the address from Elasticsearch node info' do
85
+ let(:host) { "node.elastic.co"}
86
+ let(:ip_address) { "192.168.1.0"}
87
+ let(:port) { 9200 }
88
+
89
+ context 'in Elasticsearch 1.x format' do
90
+ context 'with host and ip address' do
91
+ let(:publish_address) { "inet[#{host}/#{ip_address}:#{port}]"}
92
+ it 'should correctly extract the host' do
93
+ expect(subject.address_str_to_uri(publish_address)).to eq (LogStash::Util::SafeURI.new("#{host}:#{port}"))
94
+ end
95
+ end
96
+ context 'with ip address' do
97
+ let(:publish_address) { "inet[/#{ip_address}:#{port}]"}
98
+ it 'should correctly extract the ip address' do
99
+ expect(subject.address_str_to_uri(publish_address)).to eq (LogStash::Util::SafeURI.new("#{ip_address}:#{port}"))
100
+ end
101
+ end
102
+ end
103
+
104
+ context 'in Elasticsearch 2.x-6.x format' do
105
+ let(:publish_address) { "#{ip_address}:#{port}"}
106
+ it 'should correctly extract the ip address' do
107
+ expect(subject.address_str_to_uri(publish_address)).to eq (LogStash::Util::SafeURI.new("//#{ip_address}:#{port}"))
108
+ end
109
+ end
110
+
111
+ context 'in Elasticsearch 7.x'
112
+ context 'with host and ip address' do
113
+ let(:publish_address) { "#{host}/#{ip_address}:#{port}"}
114
+ it 'should correctly extract the host' do
115
+ expect(subject.address_str_to_uri(publish_address)).to eq (LogStash::Util::SafeURI.new("#{host}:#{port}"))
116
+ end
117
+ end
118
+ context 'with ip address' do
119
+ let(:publish_address) { "#{ip_address}:#{port}"}
120
+ it 'should correctly extract the ip address' do
121
+ expect(subject.address_str_to_uri(publish_address)).to eq (LogStash::Util::SafeURI.new("#{ip_address}:#{port}"))
122
+ end
123
+ end
124
+ end
125
+
126
+ describe "the sniffer" do
127
+ before(:each) { subject.start }
128
+ it "should not start the sniffer by default" do
129
+ expect(subject.sniffer_alive?).to eql(nil)
130
+ end
131
+
132
+ context "when enabled" do
133
+ let(:options) { super.merge(:sniffing => true)}
134
+
135
+ it "should start the sniffer" do
136
+ expect(subject.sniffer_alive?).to eql(true)
137
+ end
138
+ end
139
+ end
140
+
141
+ describe "closing" do
142
+ before do
143
+ subject.start
144
+ # Simulate a single in use connection on the first check of this
145
+ allow(adapter).to receive(:close).and_call_original
146
+ allow(subject).to receive(:wait_for_in_use_connections).and_call_original
147
+ allow(subject).to receive(:in_use_connections).and_return([subject.empty_url_meta()],[])
148
+ allow(subject).to receive(:start)
149
+ subject.close
150
+ end
151
+
152
+ it "should close the adapter" do
153
+ expect(adapter).to have_received(:close)
154
+ end
155
+
156
+ it "should stop the resurrectionist" do
157
+ expect(subject.resurrectionist_alive?).to eql(false)
158
+ end
159
+
160
+ it "should stop the sniffer" do
161
+ # If no sniffer (the default) returns nil
162
+ expect(subject.sniffer_alive?).to be_falsey
163
+ end
164
+
165
+ it "should wait for in use connections to terminate" do
166
+ expect(subject).to have_received(:wait_for_in_use_connections).once
167
+ expect(subject).to have_received(:in_use_connections).twice
168
+ end
169
+ end
170
+
171
+ describe "connection management" do
172
+ before(:each) { subject.start }
173
+ context "with only one URL in the list" do
174
+ it "should use the only URL in 'with_connection'" do
175
+ subject.with_connection do |c|
176
+ expect(c).to eq(initial_urls.first)
177
+ end
178
+ end
179
+ end
180
+
181
+ context "with multiple URLs in the list" do
182
+ before :each do
183
+ allow(adapter).to receive(:perform_request).with(anything, :head, subject.healthcheck_path, {}, nil)
184
+ end
185
+ let(:initial_urls) { [ ::LogStash::Util::SafeURI.new("http://localhost:9200"), ::LogStash::Util::SafeURI.new("http://localhost:9201"), ::LogStash::Util::SafeURI.new("http://localhost:9202") ] }
186
+
187
+ it "should minimize the number of connections to a single URL" do
188
+ connected_urls = []
189
+
190
+ # If we make 2x the number requests as we have URLs we should
191
+ # connect to each URL exactly 2 times
192
+ (initial_urls.size*2).times do
193
+ u, meta = subject.get_connection
194
+ connected_urls << u
195
+ end
196
+
197
+ connected_urls.each {|u| subject.return_connection(u) }
198
+ initial_urls.each do |url|
199
+ conn_count = connected_urls.select {|u| u == url}.size
200
+ expect(conn_count).to eql(2)
201
+ end
202
+ end
203
+
204
+ it "should correctly resurrect the dead" do
205
+ u,m = subject.get_connection
206
+
207
+ # The resurrectionist will call this to check on the backend
208
+ response = double("response")
209
+ expect(adapter).to receive(:perform_request).with(u, :head, subject.healthcheck_path, {}, nil).and_return(response)
210
+
211
+ subject.return_connection(u)
212
+ subject.mark_dead(u, Exception.new)
213
+
214
+ expect(subject.url_meta(u)[:state]).to eql(:dead)
215
+ sleep subject.resurrect_delay + 1
216
+ expect(subject.url_meta(u)[:state]).to eql(:alive)
217
+ end
218
+ end
219
+ end
220
+
221
+ describe "version tracking" do
222
+ let(:initial_urls) { [
223
+ ::LogStash::Util::SafeURI.new("http://somehost:9200"),
224
+ ::LogStash::Util::SafeURI.new("http://otherhost:9201")
225
+ ] }
226
+
227
+ before(:each) do
228
+ allow(subject).to receive(:perform_request_to_url).and_return(nil)
229
+ subject.start
230
+ end
231
+
232
+ it "picks the largest major version" do
233
+ expect(subject.maximum_seen_major_version).to eq(0)
234
+ end
235
+
236
+ context "if there are nodes with multiple major versions" do
237
+ let(:es_node_versions) { [ "0.0.0", "6.0.0" ] }
238
+ it "picks the largest major version" do
239
+ expect(subject.maximum_seen_major_version).to eq(6)
240
+ end
241
+ end
242
+ end
243
+
244
+ describe "license checking" do
245
+ before(:each) do
246
+ allow(subject).to receive(:health_check_request)
247
+ end
248
+ context "when using default logstash distribution" do
249
+ let(:oss) { false }
250
+ context "if ES doesn't return a valid license" do
251
+ let(:valid_license) { false }
252
+ it "marks the url as active" do
253
+ subject.update_initial_urls
254
+ expect(subject.alive_urls_count).to eq(1)
255
+ end
256
+ it "logs a warning" do
257
+ expect(subject).to receive(:log_license_deprecation_warn).once
258
+ subject.update_initial_urls
259
+ end
260
+ end
261
+ context "if ES returns a valid license" do
262
+ let(:valid_license) { true }
263
+ it "marks the url as active" do
264
+ subject.update_initial_urls
265
+ expect(subject.alive_urls_count).to eq(1)
266
+ end
267
+ it "does not log a warning" do
268
+ expect(subject).to_not receive(:log_license_deprecation_warn)
269
+ subject.update_initial_urls
270
+ end
271
+ end
272
+ end
273
+ end
274
+ end
@@ -0,0 +1,250 @@
1
+ require "logstash/devutils/rspec/spec_helper"
2
+ require "logstash/outputs/elasticsearch/http_client"
3
+ require "java"
4
+
5
+ describe LogStash::Outputs::ElasticSearch::HttpClient do
6
+ let(:ssl) { nil }
7
+ let(:base_options) do
8
+ opts = {
9
+ :hosts => [::LogStash::Util::SafeURI.new("127.0.0.1")],
10
+ :logger => Cabin::Channel.get,
11
+ :metric => ::LogStash::Instrument::NullMetric.new(:dummy).namespace(:alsodummy)
12
+ }
13
+
14
+ if !ssl.nil? # Shortcut to set this
15
+ opts[:client_settings] = {:ssl => {:enabled => ssl}}
16
+ end
17
+
18
+ opts
19
+ end
20
+
21
+ describe "Host/URL Parsing" do
22
+ subject { described_class.new(base_options) }
23
+
24
+ let(:true_hostname) { "my-dash.hostname" }
25
+ let(:ipv6_hostname) { "[::1]" }
26
+ let(:ipv4_hostname) { "127.0.0.1" }
27
+ let(:port) { 9202 }
28
+ let(:hostname_port) { "#{hostname}:#{port}" }
29
+ let(:hostname_port_uri) { ::LogStash::Util::SafeURI.new("//#{hostname_port}") }
30
+ let(:http_hostname_port) { ::LogStash::Util::SafeURI.new("http://#{hostname_port}") }
31
+ let(:https_hostname_port) { ::LogStash::Util::SafeURI.new("https://#{hostname_port}") }
32
+ let(:http_hostname_port_path) { ::LogStash::Util::SafeURI.new("http://#{hostname_port}/path") }
33
+
34
+ shared_examples("proper host handling") do
35
+ it "should properly transform a host:port string to a URL" do
36
+ expect(subject.host_to_url(hostname_port_uri).to_s).to eq(http_hostname_port.to_s + "/")
37
+ end
38
+
39
+ it "should not raise an error with a / for a path" do
40
+ expect(subject.host_to_url(::LogStash::Util::SafeURI.new("#{http_hostname_port}/"))).to eq(LogStash::Util::SafeURI.new("#{http_hostname_port}/"))
41
+ end
42
+
43
+ it "should parse full URLs correctly" do
44
+ expect(subject.host_to_url(http_hostname_port).to_s).to eq(http_hostname_port.to_s + "/")
45
+ end
46
+
47
+ describe "ssl" do
48
+ context "when SSL is true" do
49
+ let(:ssl) { true }
50
+ let(:base_options) { super.merge(:hosts => [http_hostname_port]) }
51
+
52
+ it "should refuse to handle an http url" do
53
+ expect {
54
+ subject.host_to_url(http_hostname_port)
55
+ }.to raise_error(LogStash::ConfigurationError)
56
+ end
57
+ end
58
+
59
+ context "when SSL is false" do
60
+ let(:ssl) { false }
61
+ let(:base_options) { super.merge(:hosts => [https_hostname_port]) }
62
+
63
+ it "should refuse to handle an https url" do
64
+ expect {
65
+ subject.host_to_url(https_hostname_port)
66
+ }.to raise_error(LogStash::ConfigurationError)
67
+ end
68
+ end
69
+
70
+ describe "ssl is nil" do
71
+ let(:base_options) { super.merge(:hosts => [https_hostname_port]) }
72
+ it "should handle an ssl url correctly when SSL is nil" do
73
+ subject
74
+ expect(subject.host_to_url(https_hostname_port).to_s).to eq(https_hostname_port.to_s + "/")
75
+ end
76
+ end
77
+ end
78
+
79
+ describe "path" do
80
+ let(:url) { http_hostname_port_path }
81
+ let(:base_options) { super.merge(:hosts => [url]) }
82
+
83
+ it "should allow paths in a url" do
84
+ expect(subject.host_to_url(url)).to eq(url)
85
+ end
86
+
87
+ context "with the path option set" do
88
+ let(:base_options) { super.merge(:client_settings => {:path => "/otherpath"}) }
89
+
90
+ it "should not allow paths in two places" do
91
+ expect {
92
+ subject.host_to_url(url)
93
+ }.to raise_error(LogStash::ConfigurationError)
94
+ end
95
+ end
96
+
97
+ context "with a path missing a leading /" do
98
+ let(:url) { http_hostname_port }
99
+ let(:base_options) { super.merge(:client_settings => {:path => "otherpath"}) }
100
+
101
+
102
+ it "should automatically insert a / in front of path overlays" do
103
+ expected = url.clone
104
+ expected.path = url.path + "/otherpath"
105
+ expect(subject.host_to_url(url)).to eq(expected)
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ describe "an regular hostname" do
112
+ let(:hostname) { true_hostname }
113
+ include_examples("proper host handling")
114
+ end
115
+
116
+ describe "an ipv4 host" do
117
+ let(:hostname) { ipv4_hostname }
118
+ include_examples("proper host handling")
119
+ end
120
+
121
+ describe "an ipv6 host" do
122
+ let(:hostname) { ipv6_hostname }
123
+ include_examples("proper host handling")
124
+ end
125
+ end
126
+
127
+ describe "get" do
128
+ subject { described_class.new(base_options) }
129
+ let(:body) { "foobar" }
130
+ let(:path) { "/hello-id" }
131
+ let(:get_response) {
132
+ double("response", :body => LogStash::Json::dump( { "body" => body }))
133
+ }
134
+
135
+ it "returns the hash response" do
136
+ expect(subject.pool).to receive(:get).with(path, nil).and_return(get_response)
137
+ expect(subject.get(path)["body"]).to eq(body)
138
+ end
139
+ end
140
+
141
+ describe "join_bulk_responses" do
142
+ subject { described_class.new(base_options) }
143
+
144
+ context "when items key is available" do
145
+ require "json"
146
+ let(:bulk_response) {
147
+ LogStash::Json.load ('[{
148
+ "items": [{
149
+ "delete": {
150
+ "_index": "website",
151
+ "_type": "blog",
152
+ "_id": "123",
153
+ "_version": 2,
154
+ "status": 200,
155
+ "found": true
156
+ }
157
+ }],
158
+ "errors": false
159
+ }]')
160
+ }
161
+ it "should be handled properly" do
162
+ s = subject.send(:join_bulk_responses, bulk_response)
163
+ expect(s["errors"]).to be false
164
+ expect(s["items"].size).to be 1
165
+ end
166
+ end
167
+
168
+ context "when items key is not available" do
169
+ require "json"
170
+ let(:bulk_response) {
171
+ JSON.parse ('[{
172
+ "took": 4,
173
+ "errors": false
174
+ }]')
175
+ }
176
+ it "should be handled properly" do
177
+ s = subject.send(:join_bulk_responses, bulk_response)
178
+ expect(s["errors"]).to be false
179
+ expect(s["items"].size).to be 0
180
+ end
181
+ end
182
+ end
183
+
184
+ describe "#bulk" do
185
+ subject { described_class.new(base_options) }
186
+
187
+ require "json"
188
+ let(:message) { "hey" }
189
+ let(:actions) { [
190
+ ["index", {:_id=>nil, :_index=>"logstash"}, {"message"=> message}],
191
+ ]}
192
+
193
+ context "if a message is over TARGET_BULK_BYTES" do
194
+ let(:target_bulk_bytes) { LogStash::Outputs::ElasticSearch::TARGET_BULK_BYTES }
195
+ let(:message) { "a" * (target_bulk_bytes + 1) }
196
+
197
+ it "should be handled properly" do
198
+ allow(subject).to receive(:join_bulk_responses)
199
+ expect(subject).to receive(:bulk_send).once do |data|
200
+ expect(data.size).to be > target_bulk_bytes
201
+ end
202
+ s = subject.send(:bulk, actions)
203
+ end
204
+ end
205
+
206
+ context "with two messages" do
207
+ let(:message1) { "hey" }
208
+ let(:message2) { "you" }
209
+ let(:actions) { [
210
+ ["index", {:_id=>nil, :_index=>"logstash"}, {"message"=> message1}],
211
+ ["index", {:_id=>nil, :_index=>"logstash"}, {"message"=> message2}],
212
+ ]}
213
+ it "executes one bulk_send operation" do
214
+ allow(subject).to receive(:join_bulk_responses)
215
+ expect(subject).to receive(:bulk_send).once
216
+ s = subject.send(:bulk, actions)
217
+ end
218
+
219
+ context "if one exceeds TARGET_BULK_BYTES" do
220
+ let(:target_bulk_bytes) { LogStash::Outputs::ElasticSearch::TARGET_BULK_BYTES }
221
+ let(:message1) { "a" * (target_bulk_bytes + 1) }
222
+ it "executes two bulk_send operations" do
223
+ allow(subject).to receive(:join_bulk_responses)
224
+ expect(subject).to receive(:bulk_send).twice
225
+ s = subject.send(:bulk, actions)
226
+ end
227
+ end
228
+ end
229
+ end
230
+
231
+ describe "sniffing" do
232
+ let(:client) { LogStash::Outputs::ElasticSearch::HttpClient.new(base_options.merge(client_opts)) }
233
+
234
+ context "with sniffing enabled" do
235
+ let(:client_opts) { {:sniffing => true, :sniffing_delay => 1 } }
236
+
237
+ it "should start the sniffer" do
238
+ expect(client.pool.sniffing).to be_truthy
239
+ end
240
+ end
241
+
242
+ context "with sniffing disabled" do
243
+ let(:client_opts) { {:sniffing => false} }
244
+
245
+ it "should not start the sniffer" do
246
+ expect(client.pool.sniffing).to be_falsey
247
+ end
248
+ end
249
+ end
250
+ end
@@ -0,0 +1,25 @@
1
+ require "logstash/devutils/rspec/spec_helper"
2
+ require "logstash/outputs/elasticsearch/http_client"
3
+ require "java"
4
+ require "json"
5
+
6
+ describe LogStash::Outputs::ElasticSearch::TemplateManager do
7
+
8
+ describe ".default_template_path" do
9
+ context "elasticsearch 1.x" do
10
+ it "chooses the 2x template" do
11
+ expect(described_class.default_template_path(1)).to match(/elasticsearch-template-es2x.json/)
12
+ end
13
+ end
14
+ context "elasticsearch 2.x" do
15
+ it "chooses the 2x template" do
16
+ expect(described_class.default_template_path(2)).to match(/elasticsearch-template-es2x.json/)
17
+ end
18
+ end
19
+ context "elasticsearch 5.x" do
20
+ it "chooses the 5x template" do
21
+ expect(described_class.default_template_path(5)).to match(/elasticsearch-template-es5x.json/)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,72 @@
1
+ require_relative "../../../spec/es_spec_helper"
2
+ require 'stud/temporary'
3
+ require "logstash/outputs/elasticsearch"
4
+ require 'manticore/client'
5
+
6
+ describe "Proxy option" do
7
+ let(:settings) { { "hosts" => "node01" } }
8
+ subject {
9
+ LogStash::Outputs::ElasticSearch.new(settings)
10
+ }
11
+
12
+ before do
13
+ allow(::Manticore::Client).to receive(:new).with(any_args).and_call_original
14
+ end
15
+
16
+ describe "valid configs" do
17
+ before do
18
+ subject.register
19
+ end
20
+
21
+ after do
22
+ subject.close
23
+ end
24
+
25
+ context "when specified as a URI" do
26
+ shared_examples("hash conversion") do |hash|
27
+ let(:settings) { super.merge("proxy" => proxy)}
28
+
29
+ it "should set the proxy to the correct hash value" do
30
+ expect(::Manticore::Client).to have_received(:new) do |options|
31
+ expect(options[:proxy]).to eq(hash)
32
+ end
33
+ end
34
+ end
35
+
36
+ describe "simple proxy" do
37
+ let(:proxy) { LogStash::Util::SafeURI.new("http://127.0.0.1:1234") }
38
+
39
+ include_examples("hash conversion",
40
+ {
41
+ :host => "127.0.0.1",
42
+ :scheme => "http",
43
+ :port => 1234
44
+ }
45
+ )
46
+ end
47
+
48
+
49
+ describe "a secure authed proxy" do
50
+ let(:proxy) { LogStash::Util::SafeURI.new("https://myuser:mypass@127.0.0.1:1234") }
51
+
52
+ include_examples("hash conversion",
53
+ {
54
+ :host => "127.0.0.1",
55
+ :scheme => "https",
56
+ :user => "myuser",
57
+ :password => "mypass",
58
+ :port => 1234
59
+ }
60
+ )
61
+ end
62
+ end
63
+
64
+ context "when not specified" do
65
+ it "should not send the proxy option to manticore" do
66
+ expect(::Manticore::Client).to have_received(:new) do |options|
67
+ expect(options).not_to include(:proxy)
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end