logstash-output-elasticsearch 11.0.0-java → 11.0.4-java

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/docs/index.asciidoc +13 -13
  4. data/lib/logstash/outputs/elasticsearch/data_stream_support.rb +1 -1
  5. data/lib/logstash/outputs/elasticsearch/http_client/pool.rb +2 -28
  6. data/lib/logstash/outputs/elasticsearch/ilm.rb +2 -33
  7. data/lib/logstash/outputs/elasticsearch/license_checker.rb +12 -6
  8. data/lib/logstash/outputs/elasticsearch/template_manager.rb +1 -1
  9. data/lib/logstash/outputs/elasticsearch/templates/ecs-v1/elasticsearch-8x.json +1 -0
  10. data/lib/logstash/outputs/elasticsearch.rb +18 -15
  11. data/lib/logstash/plugin_mixins/elasticsearch/common.rb +2 -1
  12. data/logstash-output-elasticsearch.gemspec +2 -2
  13. data/spec/es_spec_helper.rb +4 -6
  14. data/spec/fixtures/_nodes/{5x_6x.json → 6x.json} +5 -5
  15. data/spec/integration/outputs/compressed_indexing_spec.rb +47 -46
  16. data/spec/integration/outputs/delete_spec.rb +49 -51
  17. data/spec/integration/outputs/ilm_spec.rb +230 -246
  18. data/spec/integration/outputs/index_spec.rb +5 -2
  19. data/spec/integration/outputs/index_version_spec.rb +78 -82
  20. data/spec/integration/outputs/ingest_pipeline_spec.rb +58 -60
  21. data/spec/integration/outputs/painless_update_spec.rb +74 -164
  22. data/spec/integration/outputs/parent_spec.rb +67 -75
  23. data/spec/integration/outputs/retry_spec.rb +2 -2
  24. data/spec/integration/outputs/sniffer_spec.rb +15 -53
  25. data/spec/integration/outputs/templates_spec.rb +79 -81
  26. data/spec/integration/outputs/update_spec.rb +99 -101
  27. data/spec/spec_helper.rb +1 -5
  28. data/spec/unit/outputs/elasticsearch/data_stream_support_spec.rb +0 -14
  29. data/spec/unit/outputs/elasticsearch/http_client/pool_spec.rb +30 -37
  30. data/spec/unit/outputs/elasticsearch/template_manager_spec.rb +9 -9
  31. data/spec/unit/outputs/elasticsearch_spec.rb +54 -18
  32. metadata +8 -22
  33. data/lib/logstash/outputs/elasticsearch/templates/ecs-disabled/elasticsearch-2x.json +0 -95
  34. data/lib/logstash/outputs/elasticsearch/templates/ecs-disabled/elasticsearch-5x.json +0 -46
  35. data/spec/fixtures/_nodes/2x_1x.json +0 -27
  36. data/spec/fixtures/scripts/groovy/scripted_update.groovy +0 -2
  37. data/spec/fixtures/scripts/groovy/scripted_update_nested.groovy +0 -2
  38. data/spec/fixtures/scripts/groovy/scripted_upsert.groovy +0 -2
  39. data/spec/integration/outputs/groovy_update_spec.rb +0 -150
  40. data/spec/integration/outputs/templates_5x_spec.rb +0 -98
@@ -1,116 +1,114 @@
1
1
  require_relative "../../../spec/es_spec_helper"
2
2
 
3
- if ESHelper.es_version_satisfies?(">= 2")
4
- describe "Update actions without scripts", :integration => true do
5
- require "logstash/outputs/elasticsearch"
6
-
7
- def get_es_output( options={} )
8
- settings = {
9
- "manage_template" => true,
10
- "index" => "logstash-update",
11
- "template_overwrite" => true,
12
- "hosts" => get_host_port(),
13
- "action" => "update"
14
- }
15
- LogStash::Outputs::ElasticSearch.new(settings.merge!(options))
3
+ describe "Update actions without scripts", :integration => true do
4
+ require "logstash/outputs/elasticsearch"
5
+
6
+ def get_es_output( options={} )
7
+ settings = {
8
+ "manage_template" => true,
9
+ "index" => "logstash-update",
10
+ "template_overwrite" => true,
11
+ "hosts" => get_host_port(),
12
+ "action" => "update"
13
+ }
14
+ LogStash::Outputs::ElasticSearch.new(settings.merge!(options))
15
+ end
16
+
17
+ before :each do
18
+ @es = get_client
19
+ # Delete all templates first.
20
+ # Clean ES of data before we start.
21
+ @es.indices.delete_template(:name => "*")
22
+ # This can fail if there are no indexes, ignore failure.
23
+ @es.indices.delete(:index => "*") rescue nil
24
+ @es.index(
25
+ :index => 'logstash-update',
26
+ :type => doc_type,
27
+ :id => "123",
28
+ :body => { :message => 'Test', :counter => 1 }
29
+ )
30
+ @es.indices.refresh
31
+ end
32
+
33
+ it "should fail without a document_id" do
34
+ subject = get_es_output
35
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError)
36
+ end
37
+
38
+ context "when update only" do
39
+ it "should not create new document" do
40
+ subject = get_es_output({ 'document_id' => "456" } )
41
+ subject.register
42
+ subject.multi_receive([LogStash::Event.new("message" => "sample message here")])
43
+ expect {@es.get(:index => 'logstash-update', :type => doc_type, :id => "456", :refresh => true)}.to raise_error(Elasticsearch::Transport::Transport::Errors::NotFound)
44
+ end
45
+
46
+ it "should update existing document" do
47
+ subject = get_es_output({ 'document_id' => "123" })
48
+ subject.register
49
+ subject.multi_receive([LogStash::Event.new("message" => "updated message here")])
50
+ r = @es.get(:index => 'logstash-update', :type => doc_type, :id => "123", :refresh => true)
51
+ expect(r["_source"]["message"]).to eq('updated message here')
52
+ end
53
+
54
+ # The es ruby client treats the data field differently. Make sure this doesn't
55
+ # raise an exception
56
+ it "should update an existing document that has a 'data' field" do
57
+ subject = get_es_output({ 'document_id' => "123" })
58
+ subject.register
59
+ subject.multi_receive([LogStash::Event.new("data" => "updated message here", "message" => "foo")])
60
+ r = @es.get(:index => 'logstash-update', :type => doc_type, :id => "123", :refresh => true)
61
+ expect(r["_source"]["data"]).to eq('updated message here')
62
+ expect(r["_source"]["message"]).to eq('foo')
63
+ end
64
+
65
+ it "should allow default (internal) version" do
66
+ subject = get_es_output({ 'document_id' => "123", "version" => "99" })
67
+ subject.register
16
68
  end
17
69
 
18
- before :each do
19
- @es = get_client
20
- # Delete all templates first.
21
- # Clean ES of data before we start.
22
- @es.indices.delete_template(:name => "*")
23
- # This can fail if there are no indexes, ignore failure.
24
- @es.indices.delete(:index => "*") rescue nil
25
- @es.index(
26
- :index => 'logstash-update',
27
- :type => doc_type,
28
- :id => "123",
29
- :body => { :message => 'Test', :counter => 1 }
30
- )
31
- @es.indices.refresh
70
+ it "should allow internal version" do
71
+ subject = get_es_output({ 'document_id' => "123", "version" => "99", "version_type" => "internal" })
72
+ subject.register
32
73
  end
33
74
 
34
- it "should fail without a document_id" do
35
- subject = get_es_output
75
+ it "should not allow external version" do
76
+ subject = get_es_output({ 'document_id' => "123", "version" => "99", "version_type" => "external" })
36
77
  expect { subject.register }.to raise_error(LogStash::ConfigurationError)
37
78
  end
38
79
 
39
- context "when update only" do
40
- it "should not create new document" do
41
- subject = get_es_output({ 'document_id' => "456" } )
42
- subject.register
43
- subject.multi_receive([LogStash::Event.new("message" => "sample message here")])
44
- expect {@es.get(:index => 'logstash-update', :type => doc_type, :id => "456", :refresh => true)}.to raise_error(Elasticsearch::Transport::Transport::Errors::NotFound)
45
- end
46
-
47
- it "should update existing document" do
48
- subject = get_es_output({ 'document_id' => "123" })
49
- subject.register
50
- subject.multi_receive([LogStash::Event.new("message" => "updated message here")])
51
- r = @es.get(:index => 'logstash-update', :type => doc_type, :id => "123", :refresh => true)
52
- expect(r["_source"]["message"]).to eq('updated message here')
53
- end
54
-
55
- # The es ruby client treats the data field differently. Make sure this doesn't
56
- # raise an exception
57
- it "should update an existing document that has a 'data' field" do
58
- subject = get_es_output({ 'document_id' => "123" })
59
- subject.register
60
- subject.multi_receive([LogStash::Event.new("data" => "updated message here", "message" => "foo")])
61
- r = @es.get(:index => 'logstash-update', :type => doc_type, :id => "123", :refresh => true)
62
- expect(r["_source"]["data"]).to eq('updated message here')
63
- expect(r["_source"]["message"]).to eq('foo')
64
- end
65
-
66
- it "should allow default (internal) version" do
67
- subject = get_es_output({ 'document_id' => "123", "version" => "99" })
68
- subject.register
69
- end
70
-
71
- it "should allow internal version" do
72
- subject = get_es_output({ 'document_id' => "123", "version" => "99", "version_type" => "internal" })
73
- subject.register
74
- end
75
-
76
- it "should not allow external version" do
77
- subject = get_es_output({ 'document_id' => "123", "version" => "99", "version_type" => "external" })
78
- expect { subject.register }.to raise_error(LogStash::ConfigurationError)
79
- end
80
-
81
- it "should not allow external_gt version" do
82
- subject = get_es_output({ 'document_id' => "123", "version" => "99", "version_type" => "external_gt" })
83
- expect { subject.register }.to raise_error(LogStash::ConfigurationError)
84
- end
85
-
86
- it "should not allow external_gte version" do
87
- subject = get_es_output({ 'document_id' => "123", "version" => "99", "version_type" => "external_gte" })
88
- expect { subject.register }.to raise_error(LogStash::ConfigurationError)
89
- end
80
+ it "should not allow external_gt version" do
81
+ subject = get_es_output({ 'document_id' => "123", "version" => "99", "version_type" => "external_gt" })
82
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError)
83
+ end
90
84
 
85
+ it "should not allow external_gte version" do
86
+ subject = get_es_output({ 'document_id' => "123", "version" => "99", "version_type" => "external_gte" })
87
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError)
91
88
  end
92
89
 
93
- context "when update with upsert" do
94
- it "should create new documents with provided upsert" do
95
- subject = get_es_output({ 'document_id' => "456", 'upsert' => '{"message": "upsert message"}' })
96
- subject.register
97
- subject.multi_receive([LogStash::Event.new("message" => "sample message here")])
98
- r = @es.get(:index => 'logstash-update', :type => doc_type, :id => "456", :refresh => true)
99
- expect(r["_source"]["message"]).to eq('upsert message')
100
- end
101
-
102
- it "should create new documents with event/doc as upsert" do
103
- subject = get_es_output({ 'document_id' => "456", 'doc_as_upsert' => true })
104
- subject.register
105
- subject.multi_receive([LogStash::Event.new("message" => "sample message here")])
106
- r = @es.get(:index => 'logstash-update', :type => doc_type, :id => "456", :refresh => true)
107
- expect(r["_source"]["message"]).to eq('sample message here')
108
- end
109
-
110
- it "should fail on documents with event/doc as upsert at external version" do
111
- subject = get_es_output({ 'document_id' => "456", 'doc_as_upsert' => true, 'version' => 999, "version_type" => "external" })
112
- expect { subject.register }.to raise_error(LogStash::ConfigurationError)
113
- end
90
+ end
91
+
92
+ context "when update with upsert" do
93
+ it "should create new documents with provided upsert" do
94
+ subject = get_es_output({ 'document_id' => "456", 'upsert' => '{"message": "upsert message"}' })
95
+ subject.register
96
+ subject.multi_receive([LogStash::Event.new("message" => "sample message here")])
97
+ r = @es.get(:index => 'logstash-update', :type => doc_type, :id => "456", :refresh => true)
98
+ expect(r["_source"]["message"]).to eq('upsert message')
99
+ end
100
+
101
+ it "should create new documents with event/doc as upsert" do
102
+ subject = get_es_output({ 'document_id' => "456", 'doc_as_upsert' => true })
103
+ subject.register
104
+ subject.multi_receive([LogStash::Event.new("message" => "sample message here")])
105
+ r = @es.get(:index => 'logstash-update', :type => doc_type, :id => "456", :refresh => true)
106
+ expect(r["_source"]["message"]).to eq('sample message here')
107
+ end
108
+
109
+ it "should fail on documents with event/doc as upsert at external version" do
110
+ subject = get_es_output({ 'document_id' => "456", 'doc_as_upsert' => true, 'version' => 999, "version_type" => "external" })
111
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError)
114
112
  end
115
113
  end
116
114
  end
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,5 @@
1
1
  require "logstash/devutils/rspec/spec_helper"
2
2
 
3
- unless defined?(LogStash::OSS)
4
- LogStash::OSS = ENV['DISTRIBUTION'] != "default"
5
- end
6
-
7
3
  require "logstash/outputs/elasticsearch"
8
4
 
9
5
  module LogStash::Outputs::ElasticSearch::SpecHelper
@@ -11,4 +7,4 @@ end
11
7
 
12
8
  RSpec.configure do |config|
13
9
  config.include LogStash::Outputs::ElasticSearch::SpecHelper
14
- end
10
+ end
@@ -31,18 +31,12 @@ describe LogStash::Outputs::ElasticSearch::DataStreamSupport do
31
31
  # end
32
32
  end
33
33
 
34
- @@logstash_oss = LogStash::OSS
35
-
36
34
  before(:each) do
37
- change_constant :OSS, false, target: LogStash # assume non-OSS by default
38
-
39
35
  stub_plugin_register! if do_register
40
36
  end
41
37
 
42
38
  after(:each) do
43
39
  subject.close if do_register
44
-
45
- change_constant :OSS, @@logstash_oss, target: LogStash
46
40
  end
47
41
 
48
42
  context "default configuration" do
@@ -115,14 +109,6 @@ describe LogStash::Outputs::ElasticSearch::DataStreamSupport do
115
109
  end
116
110
  end
117
111
 
118
- it "uses data-streams on LS 8.0 (OSS)" do
119
- change_constant :LOGSTASH_VERSION, '8.0.1' do
120
- change_constant :OSS, true, target: LogStash do
121
- expect( subject.data_stream_config? ).to be true
122
- end
123
- end
124
- end
125
-
126
112
  context 'old ES' do
127
113
 
128
114
  let(:es_version) { '7.8.1' }
@@ -8,15 +8,12 @@ describe LogStash::Outputs::ElasticSearch::HttpClient::Pool do
8
8
  let(:initial_urls) { [::LogStash::Util::SafeURI.new("http://localhost:9200")] }
9
9
  let(:options) { {:resurrect_delay => 2, :url_normalizer => proc {|u| u}} } # Shorten the delay a bit to speed up tests
10
10
  let(:es_node_versions) { [ "0.0.0" ] }
11
- let(:oss) { true }
12
11
  let(:license_status) { 'active' }
13
12
 
14
13
  subject { described_class.new(logger, adapter, initial_urls, options) }
15
14
 
16
15
  let(:manticore_double) { double("manticore a") }
17
16
  before(:each) do
18
- stub_const('LogStash::OSS', oss)
19
-
20
17
  response_double = double("manticore response").as_null_object
21
18
  # Allow healtchecks
22
19
  allow(manticore_double).to receive(:head).with(any_args).and_return(response_double)
@@ -278,50 +275,46 @@ describe LogStash::Outputs::ElasticSearch::HttpClient::Pool do
278
275
  allow(subject).to receive(:health_check_request)
279
276
  end
280
277
 
281
- context "when using default logstash distribution" do
282
- let(:oss) { false }
283
-
284
- context "if ES doesn't return a valid license" do
285
- let(:license_status) { nil }
278
+ context "if ES doesn't return a valid license" do
279
+ let(:license_status) { nil }
286
280
 
287
- it "marks the url as dead" do
288
- subject.update_initial_urls
289
- expect(subject.alive_urls_count).to eq(0)
290
- end
281
+ it "marks the url as dead" do
282
+ subject.update_initial_urls
283
+ expect(subject.alive_urls_count).to eq(0)
284
+ end
291
285
 
292
- it "logs a warning" do
293
- expect(subject.license_checker).to receive(:warn_no_license).once.and_call_original
294
- subject.update_initial_urls
295
- end
286
+ it "logs a warning" do
287
+ expect(subject.license_checker).to receive(:warn_no_license).once.and_call_original
288
+ subject.update_initial_urls
296
289
  end
290
+ end
297
291
 
298
- context "if ES returns a valid license" do
299
- let(:license_status) { 'active' }
292
+ context "if ES returns a valid license" do
293
+ let(:license_status) { 'active' }
300
294
 
301
- it "marks the url as active" do
302
- subject.update_initial_urls
303
- expect(subject.alive_urls_count).to eq(1)
304
- end
295
+ it "marks the url as active" do
296
+ subject.update_initial_urls
297
+ expect(subject.alive_urls_count).to eq(1)
298
+ end
305
299
 
306
- it "does not log a warning" do
307
- expect(subject.license_checker).to_not receive(:warn_no_license)
308
- expect(subject.license_checker).to_not receive(:warn_invalid_license)
309
- subject.update_initial_urls
310
- end
300
+ it "does not log a warning" do
301
+ expect(subject.license_checker).to_not receive(:warn_no_license)
302
+ expect(subject.license_checker).to_not receive(:warn_invalid_license)
303
+ subject.update_initial_urls
311
304
  end
305
+ end
312
306
 
313
- context "if ES returns an invalid license" do
314
- let(:license_status) { 'invalid' }
307
+ context "if ES returns an invalid license" do
308
+ let(:license_status) { 'invalid' }
315
309
 
316
- it "marks the url as active" do
317
- subject.update_initial_urls
318
- expect(subject.alive_urls_count).to eq(1)
319
- end
310
+ it "marks the url as active" do
311
+ subject.update_initial_urls
312
+ expect(subject.alive_urls_count).to eq(1)
313
+ end
320
314
 
321
- it "logs a warning" do
322
- expect(subject.license_checker).to receive(:warn_invalid_license).and_call_original
323
- subject.update_initial_urls
324
- end
315
+ it "logs a warning" do
316
+ expect(subject.license_checker).to receive(:warn_invalid_license).and_call_original
317
+ subject.update_initial_urls
325
318
  end
326
319
  end
327
320
  end
@@ -4,19 +4,19 @@ require "logstash/outputs/elasticsearch/template_manager"
4
4
  describe LogStash::Outputs::ElasticSearch::TemplateManager do
5
5
 
6
6
  describe ".default_template_path" do
7
- context "elasticsearch 1.x" do
8
- it "chooses the 2x template" do
9
- expect(described_class.default_template_path(1)).to end_with("/templates/ecs-disabled/elasticsearch-2x.json")
7
+ context "elasticsearch 6.x" do
8
+ it "chooses the 6x template" do
9
+ expect(described_class.default_template_path(6)).to end_with("/templates/ecs-disabled/elasticsearch-6x.json")
10
10
  end
11
11
  end
12
- context "elasticsearch 2.x" do
13
- it "chooses the 2x template" do
14
- expect(described_class.default_template_path(2)).to end_with("/templates/ecs-disabled/elasticsearch-2x.json")
12
+ context "elasticsearch 7.x" do
13
+ it "chooses the 7x template" do
14
+ expect(described_class.default_template_path(7)).to end_with("/templates/ecs-disabled/elasticsearch-7x.json")
15
15
  end
16
16
  end
17
- context "elasticsearch 5.x" do
18
- it "chooses the 5x template" do
19
- expect(described_class.default_template_path(5)).to end_with("/templates/ecs-disabled/elasticsearch-5x.json")
17
+ context "elasticsearch 8.x" do
18
+ it "chooses the 8x template" do
19
+ expect(described_class.default_template_path(8)).to end_with("/templates/ecs-disabled/elasticsearch-8x.json")
20
20
  end
21
21
  end
22
22
  end
@@ -7,7 +7,7 @@ require "logstash/outputs/elasticsearch"
7
7
  describe LogStash::Outputs::ElasticSearch do
8
8
  subject(:elasticsearch_output_instance) { described_class.new(options) }
9
9
  let(:options) { {} }
10
- let(:maximum_seen_major_version) { [1,2,5,6,7,8].sample }
10
+ let(:maximum_seen_major_version) { [6,7,8].sample }
11
11
 
12
12
  let(:do_register) { true }
13
13
 
@@ -79,13 +79,6 @@ describe LogStash::Outputs::ElasticSearch do
79
79
  expect(subject.send(:get_event_type, LogStash::Event.new("type" => "foo"))).to eql("doc")
80
80
  end
81
81
  end
82
-
83
- context "for < 6.0 elasticsearch clusters" do
84
- let(:maximum_seen_major_version) { 5 }
85
- it "should get the type from the event" do
86
- expect(subject.send(:get_event_type, LogStash::Event.new("type" => "foo"))).to eql("foo")
87
- end
88
- end
89
82
  end
90
83
 
91
84
  context "with 'document type set'" do
@@ -343,7 +336,7 @@ describe LogStash::Outputs::ElasticSearch do
343
336
  }
344
337
  }]
345
338
  }
346
- end
339
+ end
347
340
 
348
341
  before(:each) do
349
342
  allow(subject.client).to receive(:bulk_send).with(instance_of(StringIO), instance_of(Array)) do |stream, actions|
@@ -771,9 +764,9 @@ describe LogStash::Outputs::ElasticSearch do
771
764
 
772
765
  context 'when getting any other exception' do
773
766
  it 'should log at WARN level' do
774
- dlog = double_logger = double("logger").as_null_object
775
- subject.instance_variable_set(:@logger, dlog)
776
- expect(dlog).to receive(:warn).with(/Could not index/, hash_including(:status, :action, :response))
767
+ logger = double("logger").as_null_object
768
+ subject.instance_variable_set(:@logger, logger)
769
+ expect(logger).to receive(:warn).with(/Could not index/, hash_including(:status, :action, :response))
777
770
  mock_response = { 'index' => { 'error' => { 'type' => 'illegal_argument_exception' } } }
778
771
  subject.handle_dlq_status("Could not index event to Elasticsearch.",
779
772
  [:action, :params, :event], :some_status, mock_response)
@@ -782,9 +775,9 @@ describe LogStash::Outputs::ElasticSearch do
782
775
 
783
776
  context 'when the response does not include [error]' do
784
777
  it 'should not fail, but just log a warning' do
785
- dlog = double_logger = double("logger").as_null_object
786
- subject.instance_variable_set(:@logger, dlog)
787
- expect(dlog).to receive(:warn).with(/Could not index/, hash_including(:status, :action, :response))
778
+ logger = double("logger").as_null_object
779
+ subject.instance_variable_set(:@logger, logger)
780
+ expect(logger).to receive(:warn).with(/Could not index/, hash_including(:status, :action, :response))
788
781
  mock_response = { 'index' => {} }
789
782
  expect do
790
783
  subject.handle_dlq_status("Could not index event to Elasticsearch.",
@@ -804,12 +797,55 @@ describe LogStash::Outputs::ElasticSearch do
804
797
  # We should still log when sending to the DLQ.
805
798
  # This shall be solved by another issue, however: logstash-output-elasticsearch#772
806
799
  it 'should send the event to the DLQ instead, and not log' do
807
- expect(dlq_writer).to receive(:write).once.with(:event, /Could not index/)
800
+ event = LogStash::Event.new("foo" => "bar")
801
+ expect(dlq_writer).to receive(:write).once.with(event, /Could not index/)
808
802
  mock_response = { 'index' => { 'error' => { 'type' => 'illegal_argument_exception' } } }
809
- subject.handle_dlq_status("Could not index event to Elasticsearch.",
810
- [:action, :params, :event], :some_status, mock_response)
803
+ action = LogStash::Outputs::ElasticSearch::EventActionTuple.new(:action, :params, event)
804
+ subject.handle_dlq_status("Could not index event to Elasticsearch.", action, 404, mock_response)
811
805
  end
812
806
  end
807
+
808
+ context 'with response status 400' do
809
+
810
+ let(:options) { super().merge 'document_id' => '%{foo}' }
811
+
812
+ let(:events) { [ LogStash::Event.new("foo" => "bar") ] }
813
+
814
+ let(:dlq_writer) { subject.instance_variable_get(:@dlq_writer) }
815
+
816
+ let(:bulk_response) do
817
+ {
818
+ "took"=>1, "ingest_took"=>11, "errors"=>true, "items"=>
819
+ [{
820
+ "index"=>{"_index"=>"bar", "_type"=>"_doc", "_id"=>'bar', "status"=>400,
821
+ "error"=>{"type" => "illegal_argument_exception", "reason" => "TEST" }
822
+ }
823
+ }]
824
+ }
825
+ end
826
+
827
+ before(:each) do
828
+ allow(subject.client).to receive(:bulk_send).and_return(bulk_response)
829
+ end
830
+
831
+ it "should write event to DLQ" do
832
+ expect(dlq_writer).to receive(:write).and_wrap_original do |method, *args|
833
+ expect( args.size ).to eql 2
834
+
835
+ event, reason = *args
836
+ expect( event ).to be_a LogStash::Event
837
+ expect( event ).to be events.first
838
+ expect( reason ).to start_with 'Could not index event to Elasticsearch. status: 400, action: ["index"'
839
+ expect( reason ).to match /_id=>"bar".*"foo"=>"bar".*response:.*"reason"=>"TEST"/
840
+
841
+ method.call(*args) # won't hurt to call LogStash::Util::DummyDeadLetterQueueWriter
842
+ end.once
843
+
844
+ event_action_tuples = subject.map_events(events)
845
+ subject.send(:submit, event_action_tuples)
846
+ end
847
+
848
+ end if LOGSTASH_VERSION > '7.0'
813
849
  end
814
850
 
815
851
  describe "custom headers" do