fluent-plugin-elasticsearch 5.0.0 → 5.2.3

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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +6 -0
  3. data/.github/workflows/linux.yml +5 -2
  4. data/.github/workflows/macos.yml +5 -2
  5. data/.github/workflows/windows.yml +5 -2
  6. data/Gemfile +1 -1
  7. data/History.md +65 -1
  8. data/README.Troubleshooting.md +91 -0
  9. data/README.md +129 -4
  10. data/fluent-plugin-elasticsearch.gemspec +2 -1
  11. data/lib/fluent/plugin/elasticsearch_compat.rb +30 -0
  12. data/lib/fluent/plugin/elasticsearch_error_handler.rb +19 -4
  13. data/lib/fluent/plugin/elasticsearch_fallback_selector.rb +2 -2
  14. data/lib/fluent/plugin/elasticsearch_index_lifecycle_management.rb +18 -4
  15. data/lib/fluent/plugin/elasticsearch_index_template.rb +20 -4
  16. data/lib/fluent/plugin/elasticsearch_simple_sniffer.rb +2 -1
  17. data/lib/fluent/plugin/filter_elasticsearch_genid.rb +1 -1
  18. data/lib/fluent/plugin/in_elasticsearch.rb +2 -1
  19. data/lib/fluent/plugin/oj_serializer.rb +2 -1
  20. data/lib/fluent/plugin/out_elasticsearch.rb +80 -19
  21. data/lib/fluent/plugin/out_elasticsearch_data_stream.rb +132 -62
  22. data/lib/fluent/plugin/out_elasticsearch_dynamic.rb +3 -1
  23. data/test/plugin/mock_chunk.dat +0 -0
  24. data/test/plugin/test_elasticsearch_error_handler.rb +130 -23
  25. data/test/plugin/test_elasticsearch_fallback_selector.rb +16 -8
  26. data/test/plugin/test_elasticsearch_index_lifecycle_management.rb +55 -15
  27. data/test/plugin/test_filter_elasticsearch_genid.rb +16 -16
  28. data/test/plugin/test_in_elasticsearch.rb +20 -0
  29. data/test/plugin/test_out_elasticsearch.rb +795 -134
  30. data/test/plugin/test_out_elasticsearch_data_stream.rb +717 -117
  31. data/test/plugin/test_out_elasticsearch_dynamic.rb +150 -18
  32. metadata +21 -5
  33. data/.travis.yml +0 -40
  34. data/appveyor.yml +0 -20
@@ -28,6 +28,8 @@ module Fluent::Plugin
28
28
  @dynamic_config[key] = value.to_s
29
29
  }
30
30
  # end eval all configs
31
+
32
+ log.warn "Elasticsearch dynamic plugin will be deprecated and removed in the future. Please consider to use normal Elasticsearch plugin"
31
33
  end
32
34
 
33
35
  def create_meta_config_map
@@ -53,7 +55,7 @@ module Fluent::Plugin
53
55
  end
54
56
  headers = { 'Content-Type' => @content_type.to_s, }.merge(gzip_headers)
55
57
  ssl_options = { verify: @ssl_verify, ca_file: @ca_file}.merge(@ssl_version_options)
56
- transport = Elasticsearch::Transport::Transport::HTTP::Faraday.new(connection_options.merge(
58
+ transport = TRANSPORT_CLASS::Transport::HTTP::Faraday.new(connection_options.merge(
57
59
  options: {
58
60
  reload_connections: @reload_connections,
59
61
  reload_on_failure: @reload_on_failure,
Binary file
@@ -2,6 +2,7 @@ require_relative '../helper'
2
2
  require 'fluent/plugin/out_elasticsearch'
3
3
  require 'fluent/plugin/elasticsearch_error_handler'
4
4
  require 'json'
5
+ require 'msgpack'
5
6
 
6
7
  class TestElasticsearchErrorHandler < Test::Unit::TestCase
7
8
 
@@ -27,13 +28,18 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
27
28
  @error_events << {:tag => tag, :time=>time, :record=>record, :error=>e}
28
29
  end
29
30
 
30
- def process_message(tag, meta, header, time, record, extracted_values)
31
+ def process_message(tag, meta, header, time, record, affinity_target_indices, extracted_values)
31
32
  return [meta, header, record]
32
33
  end
33
34
 
35
+ def get_affinity_target_indices(chunk)
36
+ indices = Hash.new
37
+ indices
38
+ end
39
+
34
40
  def append_record_to_messages(op, meta, header, record, msgs)
35
41
  if record.has_key?('raise') && record['raise']
36
- raise Exception('process_message')
42
+ raise 'process_message'
37
43
  end
38
44
  return true
39
45
  end
@@ -49,6 +55,27 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
49
55
  end
50
56
  end
51
57
 
58
+ class MockMsgpackChunk
59
+ def initialize(chunk)
60
+ @chunk = chunk
61
+ @factory = MessagePack::Factory.new
62
+ @factory.register_type(Fluent::EventTime::TYPE, Fluent::EventTime)
63
+ end
64
+
65
+ def msgpack_each
66
+ @factory.unpacker(@chunk).each { |time, record| yield(time, record) }
67
+ end
68
+ end
69
+
70
+ class MockUnpackedMsg
71
+ def initialize(records)
72
+ @records = records
73
+ end
74
+ def each
75
+ @records.each { |item| yield({:time => item[:time], :record => item[:record]}) }
76
+ end
77
+ end
78
+
52
79
  def setup
53
80
  Fluent::Test.setup
54
81
  @log_device = Fluent::Test::DummyLogDevice.new
@@ -93,8 +120,9 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
93
120
  ]
94
121
  }))
95
122
  chunk = MockChunk.new(records)
123
+ unpacked_msg_arr = MockUnpackedMsg.new(records)
96
124
  dummy_extracted_values = []
97
- @handler.handle_error(response, 'atag', chunk, records.length, dummy_extracted_values)
125
+ @handler.handle_error(response, 'atag', chunk, records.length, dummy_extracted_values, unpacked_msg_arr)
98
126
  assert_equal(1, @plugin.error_events.size)
99
127
  expected_log = "failed to parse"
100
128
  exception_message = @plugin.error_events.first[:error].message
@@ -135,8 +163,9 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
135
163
  ]
136
164
  }))
137
165
  chunk = MockChunk.new(records)
166
+ unpacked_msg_arr = MockUnpackedMsg.new(records)
138
167
  dummy_extracted_values = []
139
- @handler.handle_error(response, 'atag', chunk, records.length, dummy_extracted_values)
168
+ @handler.handle_error(response, 'atag', chunk, records.length, dummy_extracted_values, unpacked_msg_arr)
140
169
  assert_equal(1, @plugin.error_events.size)
141
170
  expected_log = "failed to parse"
142
171
  exception_message = @plugin.error_events.first[:error].message
@@ -154,8 +183,9 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
154
183
  "items" : [{}]
155
184
  }))
156
185
  chunk = MockChunk.new(records)
186
+ unpacked_msg_arr = MockUnpackedMsg.new(records)
157
187
  dummy_extracted_values = []
158
- @handler.handle_error(response, 'atag', chunk, records.length, dummy_extracted_values)
188
+ @handler.handle_error(response, 'atag', chunk, records.length, dummy_extracted_values, unpacked_msg_arr)
159
189
  assert_equal(0, @plugin.error_events.size)
160
190
  assert_nil(@plugin.error_events[0])
161
191
  end
@@ -176,8 +206,9 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
176
206
  ]
177
207
  }))
178
208
  chunk = MockChunk.new(records)
209
+ unpacked_msg_arr = MockUnpackedMsg.new(records)
179
210
  dummy_extracted_values = []
180
- @handler.handle_error(response, 'atag', chunk, records.length, dummy_extracted_values)
211
+ @handler.handle_error(response, 'atag', chunk, records.length, dummy_extracted_values, unpacked_msg_arr)
181
212
  assert_equal(1, @plugin.error_events.size)
182
213
  assert_true(@plugin.error_events[0][:error].respond_to?(:backtrace))
183
214
  end
@@ -199,8 +230,9 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
199
230
  ]
200
231
  }))
201
232
  chunk = MockChunk.new(records)
233
+ unpacked_msg_arr = MockUnpackedMsg.new(records)
202
234
  dummy_extracted_values = []
203
- @handler.handle_error(response, 'atag', chunk, records.length, dummy_extracted_values)
235
+ @handler.handle_error(response, 'atag', chunk, records.length, dummy_extracted_values, unpacked_msg_arr)
204
236
  assert_equal(1, @plugin.error_events.size)
205
237
  assert_true(@plugin.error_events[0][:error].respond_to?(:backtrace))
206
238
  end
@@ -225,10 +257,11 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
225
257
  ]
226
258
  }))
227
259
 
228
- chunk = MockChunk.new(records)
229
- dummy_extracted_values = []
260
+ chunk = MockChunk.new(records)
261
+ unpacked_msg_arr = MockUnpackedMsg.new(records)
262
+ dummy_extracted_values = []
230
263
  assert_raise(Fluent::Plugin::ElasticsearchErrorHandler::ElasticsearchRequestAbortError) do
231
- @handler.handle_error(response, 'atag', chunk, records.length, dummy_extracted_values)
264
+ @handler.handle_error(response, 'atag', chunk, records.length, dummy_extracted_values, unpacked_msg_arr)
232
265
  end
233
266
  end
234
267
 
@@ -252,10 +285,11 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
252
285
  ]
253
286
  }))
254
287
 
255
- chunk = MockChunk.new(records)
256
- dummy_extracted_values = []
288
+ chunk = MockChunk.new(records)
289
+ unpacked_msg_arr = MockUnpackedMsg.new(records)
290
+ dummy_extracted_values = []
257
291
  assert_raise(Fluent::Plugin::ElasticsearchErrorHandler::ElasticsearchRequestAbortError) do
258
- @handler.handle_error(response, 'atag', chunk, records.length, dummy_extracted_values)
292
+ @handler.handle_error(response, 'atag', chunk, records.length, dummy_extracted_values, unpacked_msg_arr)
259
293
  end
260
294
  end
261
295
 
@@ -285,8 +319,9 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
285
319
  begin
286
320
  failed = false
287
321
  chunk = MockChunk.new(records)
322
+ unpacked_msg_arr = MockUnpackedMsg.new(records)
288
323
  dummy_extracted_values = []
289
- handler.handle_error(response, 'atag', chunk, response['items'].length, dummy_extracted_values)
324
+ handler.handle_error(response, 'atag', chunk, response['items'].length, dummy_extracted_values, unpacked_msg_arr)
290
325
  rescue Fluent::Plugin::ElasticsearchErrorHandler::ElasticsearchRequestAbortError, Fluent::Plugin::ElasticsearchOutput::RetryStreamError=>e
291
326
  failed = true
292
327
  records = [].tap do |records|
@@ -302,11 +337,12 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
302
337
  def test_retry_error
303
338
  records = []
304
339
  error_records = Hash.new(false)
305
- error_records.merge!({0=>true, 4=>true, 9=>true})
340
+ error_records.merge!({0=>true, 4=>true})
306
341
  10.times do |i|
307
342
  records << {time: 12345, record: {"message"=>"record #{i}","_id"=>i,"raise"=>error_records[i]}}
308
343
  end
309
344
  chunk = MockChunk.new(records)
345
+ unpacked_msg_arr = MockUnpackedMsg.new(records)
310
346
 
311
347
  response = parse_response(%({
312
348
  "took" : 1,
@@ -386,6 +422,18 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
386
422
  "reason":"unrecognized error"
387
423
  }
388
424
  }
425
+ },
426
+ {
427
+ "create" : {
428
+ "_index" : "foo",
429
+ "_type" : "bar",
430
+ "_id" : "9",
431
+ "status" : 500,
432
+ "error" : {
433
+ "type" : "json_parse_exception",
434
+ "reason":"Invalid UTF-8 start byte 0x92\\n at [Source: org.elasticsearch.transport.netty4.ByteBufStreamInput@204fe9c9; line: 1, column: 81]"
435
+ }
436
+ }
389
437
  }
390
438
  ]
391
439
  }))
@@ -393,19 +441,19 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
393
441
  begin
394
442
  failed = false
395
443
  dummy_extracted_values = []
396
- @handler.handle_error(response, 'atag', chunk, response['items'].length, dummy_extracted_values)
444
+ @handler.handle_error(response, 'atag', chunk, response['items'].length, dummy_extracted_values, unpacked_msg_arr)
397
445
  rescue Fluent::Plugin::ElasticsearchErrorHandler::ElasticsearchRequestAbortError, Fluent::Plugin::ElasticsearchOutput::RetryStreamError=>e
398
446
  failed = true
399
447
  records = [].tap do |records|
400
448
  next unless e.respond_to?(:retry_stream)
401
449
  e.retry_stream.each {|time, record| records << record}
402
450
  end
403
- assert_equal 2, records.length
404
- assert_equal 2, records[0]['_id']
405
- assert_equal 8, records[1]['_id']
451
+ assert_equal 2, records.length, "Exp. retry_stream to contain records"
452
+ assert_equal 2, records[0]['_id'], "Exp record with given ID to in retry_stream"
453
+ assert_equal 8, records[1]['_id'], "Exp record with given ID to in retry_stream"
406
454
  error_ids = @plugin.error_events.collect {|h| h[:record]['_id']}
407
- assert_equal 3, error_ids.length
408
- assert_equal [5, 6, 7], error_ids
455
+ assert_equal 4, error_ids.length, "Exp. a certain number of records to be dropped from retry_stream"
456
+ assert_equal [5, 6, 7, 9], error_ids, "Exp. specific records to be dropped from retry_stream"
409
457
  @plugin.error_events.collect {|h| h[:error]}.each do |e|
410
458
  assert_true e.respond_to?(:backtrace)
411
459
  end
@@ -422,6 +470,7 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
422
470
  records << {time: 12345, record: {"message"=>"record #{i}","_id"=>i,"raise"=>error_records[i]}}
423
471
  end
424
472
  chunk = MockChunk.new(records)
473
+ unpacked_msg_arr = MockUnpackedMsg.new(records)
425
474
 
426
475
  response = parse_response(%({
427
476
  "took" : 1,
@@ -509,7 +558,7 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
509
558
  begin
510
559
  failed = false
511
560
  dummy_extracted_values = []
512
- @handler.handle_error(response, 'atag', chunk, response['items'].length, dummy_extracted_values)
561
+ @handler.handle_error(response, 'atag', chunk, response['items'].length, dummy_extracted_values, unpacked_msg_arr)
513
562
  rescue Fluent::Plugin::ElasticsearchErrorHandler::ElasticsearchRequestAbortError, Fluent::Plugin::ElasticsearchOutput::RetryStreamError=>e
514
563
  failed = true
515
564
  records = [].tap do |records|
@@ -532,6 +581,7 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
532
581
  records << {time: 12345, record: {"message"=>"record #{i}","_id"=>i,"raise"=>error_records[i]}}
533
582
  end
534
583
  chunk = MockChunk.new(records)
584
+ unpacked_msg_arr = MockUnpackedMsg.new(records)
535
585
 
536
586
  response = parse_response(%({
537
587
  "took" : 1,
@@ -622,7 +672,7 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
622
672
  begin
623
673
  failed = false
624
674
  dummy_extracted_values = []
625
- @handler.handle_error(response, 'atag', chunk, response['items'].length, dummy_extracted_values)
675
+ @handler.handle_error(response, 'atag', chunk, response['items'].length, dummy_extracted_values, unpacked_msg_arr)
626
676
  rescue Fluent::Plugin::ElasticsearchErrorHandler::ElasticsearchRequestAbortError, Fluent::Plugin::ElasticsearchOutput::RetryStreamError=>e
627
677
  failed = true
628
678
  records = [].tap do |records|
@@ -643,4 +693,61 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
643
693
  end
644
694
  assert_true failed
645
695
  end
696
+
697
+ def test_nested_msgpack_each
698
+ cwd = File.dirname(__FILE__)
699
+ chunk_path = File.join(cwd, 'mock_chunk.dat')
700
+ chunk_file = File.open(chunk_path, 'rb', 0644)
701
+ chunk_file.seek(0, IO::SEEK_SET)
702
+
703
+ chunk = MockMsgpackChunk.new(chunk_file)
704
+
705
+ unpacked_msg_arr = []
706
+ msg_count = 0
707
+ count_to_trigger_error_handle = 0
708
+ chunk.msgpack_each do |time, record|
709
+ next unless record.is_a? Hash
710
+
711
+ unpacked_msg_arr << {:time => time, :record => record}
712
+ msg_count += 1
713
+
714
+ record.each_key do |k|
715
+ if k != 'aaa' && k != 'bbb' && k != 'ccc' && k != 'log_path'
716
+ assert_equal(:impossible, k)
717
+ end
718
+ end
719
+
720
+ if msg_count % 55 == 0
721
+ if count_to_trigger_error_handle == 1
722
+ begin
723
+ response = {}
724
+ response['errors'] = true
725
+ response['items'] = []
726
+ item = {}
727
+ item['index'] = {}
728
+ item['index']['status'] = 429
729
+ item['index']['error'] = {}
730
+ item['index']['error']['type'] = "es_rejected_execution_exception"
731
+ abc = 0
732
+ while abc < unpacked_msg_arr.length
733
+ abc += 1
734
+ response['items'] << item
735
+ end
736
+
737
+ dummy_extracted_values = []
738
+ @handler.handle_error(response, 'atag', chunk, unpacked_msg_arr.length, dummy_extracted_values, unpacked_msg_arr)
739
+ assert_equal(0, @plugin.error_events.size)
740
+ assert_nil(@plugin.error_events[0])
741
+ rescue => e
742
+ # capture ElasticsearchRequestAbortError, beacuse es_rejected_execution_exception is unrecoverable.
743
+ end
744
+ end
745
+
746
+ count_to_trigger_error_handle += 1
747
+ unpacked_msg_arr.clear
748
+ end # end if
749
+ end # end chunk.msgpack_each
750
+
751
+ chunk_file.close
752
+ end
646
753
  end
@@ -18,17 +18,25 @@ class ElasticsearchFallbackSelectorTest < Test::Unit::TestCase
18
18
  end
19
19
  end
20
20
 
21
- def stub_elastic_info(url="http://localhost:9200/", version="6.4.2")
22
- body ="{\"version\":{\"number\":\"#{version}\"}}"
23
- stub_request(:get, url).to_return({:status => 200, :body => body, :headers => { 'Content-Type' => 'json' } })
21
+ def elasticsearch_version
22
+ if Gem::Version.new(TRANSPORT_CLASS::VERSION) >= Gem::Version.new("7.14.0")
23
+ TRANSPORT_CLASS::VERSION
24
+ else
25
+ '6.4.2'.freeze
26
+ end
27
+ end
28
+
29
+ def stub_elastic_info(url="http://localhost:9200/", version=elasticsearch_version)
30
+ body ="{\"version\":{\"number\":\"#{version}\", \"build_flavor\":\"default\"},\"tagline\" : \"You Know, for Search\"}"
31
+ stub_request(:get, url).to_return({:status => 200, :body => body, :headers => { 'Content-Type' => 'json', 'x-elastic-product' => 'Elasticsearch' } })
24
32
  end
25
33
 
26
- def stub_elastic_info_not_found(url="http://localhost:9200/", version="6.4.2")
27
- stub_request(:get, url).to_return(:status => [404, "Not Found"])
34
+ def stub_elastic_info_not_found(url="http://localhost:9200/", version=elasticsearch_version)
35
+ stub_request(:get, url).to_return(:status => [404, "Not Found"], headers: {'x-elastic-product' => 'Elasticsearch' })
28
36
  end
29
37
 
30
- def stub_elastic_info_unavailable(url="http://localhost:9200/", version="6.4.2")
31
- stub_request(:get, url).to_return(:status => [503, "Service Unavailable"])
38
+ def stub_elastic_info_unavailable(url="http://localhost:9200/", version=elasticsearch_version)
39
+ stub_request(:get, url).to_return(:status => [503, "Service Unavailable"], headers: {'x-elastic-product' => 'Elasticsearch' })
32
40
  end
33
41
 
34
42
  def sample_record(content={})
@@ -60,7 +68,7 @@ class ElasticsearchFallbackSelectorTest < Test::Unit::TestCase
60
68
  reload_after 10
61
69
  catch_transport_exception_on_retry false # For fallback testing
62
70
  ]
63
- assert_raise(Elasticsearch::Transport::Transport::Errors::NotFound) do
71
+ assert_raise(TRANSPORT_CLASS::Transport::Errors::NotFound) do
64
72
  driver(config)
65
73
  end
66
74
  driver.run(default_tag: 'test') do
@@ -6,12 +6,14 @@ class TestElasticsearchIndexLifecycleManagement < Test::Unit::TestCase
6
6
  include Fluent::Plugin::ElasticsearchIndexLifecycleManagement
7
7
 
8
8
  def setup
9
- begin
10
- require "elasticsearch/xpack"
11
- rescue LoadError
12
- omit "ILM testcase needs elasticsearch-xpack gem."
9
+ if Gem::Version.new(Elasticsearch::VERSION) < Gem::Version.new("7.14.0")
10
+ begin
11
+ require "elasticsearch/xpack"
12
+ rescue LoadError
13
+ omit "ILM testcase needs elasticsearch-xpack gem."
14
+ end
13
15
  end
14
- if Gem::Version.create(::Elasticsearch::Transport::VERSION) < Gem::Version.create("7.4.0")
16
+ if Gem::Version.create(::TRANSPORT_CLASS::VERSION) < Gem::Version.create("7.4.0")
15
17
  omit "elastisearch-ruby v7.4.0 or later is needed for ILM."
16
18
  end
17
19
  Fluent::Plugin::ElasticsearchIndexLifecycleManagement.module_eval(<<-CODE)
@@ -27,40 +29,78 @@ class TestElasticsearchIndexLifecycleManagement < Test::Unit::TestCase
27
29
  CODE
28
30
  end
29
31
 
32
+ def elasticsearch_version
33
+ if Gem::Version.new(TRANSPORT_CLASS::VERSION) >= Gem::Version.new("8.0.0")
34
+ TRANSPORT_CLASS::VERSION
35
+ else
36
+ '6.4.2'.freeze
37
+ end
38
+ end
39
+
40
+ def ilm_existence_endpoint(policy_id)
41
+ if Gem::Version.new(TRANSPORT_CLASS::VERSION) >= Gem::Version.new("8.0.0")
42
+ "_enrich/policy/#{policy_id}"
43
+ else
44
+ "_ilm/policy/%7B:policy_id=%3E%22#{policy_id}%22%7D"
45
+ end
46
+ end
47
+
48
+ def ilm_creation_endpoint(policy_id)
49
+ if Gem::Version.new(TRANSPORT_CLASS::VERSION) >= Gem::Version.new("8.0.0")
50
+ "_enrich/policy/#{policy_id}"
51
+ else
52
+ "_ilm/policy/#{policy_id}"
53
+ end
54
+ end
55
+
56
+ def stub_elastic_info(url="http://localhost:9200/", version=elasticsearch_version)
57
+ body ="{\"version\":{\"number\":\"#{version}\", \"build_flavor\":\"default\"},\"tagline\" : \"You Know, for Search\"}"
58
+ stub_request(:get, url).to_return({:status => 200, :body => body, :headers => { 'Content-Type' => 'json', 'x-elastic-product' => 'Elasticsearch' } })
59
+ end
60
+
30
61
  def test_xpack_info
31
62
  stub_request(:get, "http://localhost:9200/_xpack").
32
- to_return(:status => 200, :body => '{"features":{"ilm":{"available":true,"enabled":true}}}', :headers => {"Content-Type"=> "application/json"})
63
+ to_return(:status => 200, :body => '{"features":{"ilm":{"available":true,"enabled":true}}}', :headers => {"Content-Type"=> "application/json" })
64
+ stub_elastic_info
33
65
  expected = {"features"=>{"ilm"=>{"available"=>true, "enabled"=>true}}}
34
- assert_equal(expected, xpack_info)
66
+ if xpack_info.is_a?(Elasticsearch::API::Response)
67
+ assert_equal(expected, xpack_info.body)
68
+ else
69
+ assert_equal(expected, xpack_info)
70
+ end
35
71
  end
36
72
 
37
73
  def test_verify_ilm_working
38
74
  stub_request(:get, "http://localhost:9200/_xpack").
39
- to_return(:status => 200, :body => '{"features":{"ilm":{"available":true,"enabled":true}}}', :headers => {"Content-Type"=> "application/json"})
75
+ to_return(:status => 200, :body => '{"features":{"ilm":{"available":true,"enabled":true}}}', :headers => {"Content-Type"=> "application/json" })
76
+ stub_elastic_info
40
77
  assert_nothing_raised { verify_ilm_working }
41
78
  end
42
79
 
43
80
  def test_ilm_policy_doesnt_exists
44
- stub_request(:get, "http://localhost:9200/_ilm/policy/%7B:policy_id=%3E%22fluentd-policy%22%7D").
81
+ stub_request(:get, "http://localhost:9200/#{ilm_existence_endpoint("fluentd-policy")}").
45
82
  to_return(:status => 404, :body => "", :headers => {})
46
- assert_false(ilm_policy_exists?(policy_id: "fluentd-policy"))
83
+ stub_elastic_info
84
+ assert_false(ilm_policy_exists?("fluentd-policy"))
47
85
  end
48
86
 
49
87
  def test_ilm_policy_exists
50
- stub_request(:get, "http://localhost:9200/_ilm/policy/%7B:policy_id=%3E%22fluent-policy%22%7D").
88
+ stub_request(:get, "http://localhost:9200/#{ilm_existence_endpoint("fluent-policy")}").
51
89
  to_return(:status => 200, :body => "", :headers => {})
52
- assert_true(ilm_policy_exists?(policy_id: "fluent-policy"))
90
+ stub_elastic_info
91
+ assert_true(ilm_policy_exists?("fluent-policy"))
53
92
  end
54
93
 
55
94
  def test_create_ilm_policy
56
- stub_request(:get, "http://localhost:9200/_ilm/policy/fluent-policy").
95
+ stub_request(:get, "http://localhost:9200/#{ilm_creation_endpoint("fluent-policy")}").
57
96
  to_return(:status => 404, :body => "", :headers => {})
58
- stub_request(:put, "http://localhost:9200/_ilm/policy/fluent-policy").
97
+ stub_request(:put, "http://localhost:9200/#{ilm_creation_endpoint("fluent-policy")}").
59
98
  with(:body => "{\"policy\":{\"phases\":{\"hot\":{\"actions\":{\"rollover\":{\"max_size\":\"50gb\",\"max_age\":\"30d\"}}}}}}",
60
99
  :headers => {'Content-Type'=>'application/json'}).
61
100
  to_return(:status => 200, :body => "", :headers => {})
101
+ stub_elastic_info
62
102
  create_ilm_policy("fluent-policy")
63
103
 
64
- assert_requested(:put, "http://localhost:9200/_ilm/policy/fluent-policy", times: 1)
104
+ assert_requested(:put, "http://localhost:9200/#{ilm_creation_endpoint("fluent-policy")}", times: 1)
65
105
  end
66
106
  end
@@ -132,10 +132,10 @@ class ElasticsearchGenidFilterTest < Test::Unit::TestCase
132
132
  end
133
133
 
134
134
  class UseEntireRecordAsSeedTest < self
135
- data("md5" => ["md5", "MuMU0gHOP1cWvvg/J4aEFg=="],
136
- "sha1" => ["sha1", "GZ6Iup9Ywyk5spCWtPQbtZnfK0U="],
137
- "sha256" => ["sha256", "O4YN0RiXCUAYeaR97UUULRLxgra/R2dvTV47viir5l4="],
138
- "sha512" => ["sha512", "FtbwO1xsLUq0KcO0mj0l80rbwFH5rGE3vL+Vgh90+4R/9j+/Ni/ipwhiOoUcetDxj1r5Vf/92B54La+QTu3eMA=="],)
135
+ data("md5" => ["md5", "OAod7J0DR9s9/rOQnkeSFw=="],
136
+ "sha1" => ["sha1", "0CT4aMJ4gxMT3TKaYPCYApiVsq8="],
137
+ "sha256" => ["sha256", "mbAuKF5can0TTj/JBk71AXtOyoVqw5W5gMPUxx6pxLk="],
138
+ "sha512" => ["sha512", "f7kz5KVuDy+riENePDzqBjGQfbuRNpRBSQMzT2/6hrljXbYtBy3YFmxB86ofIf3zz4ZBao2QM2W7YvcwbRtK1w=="],)
139
139
  def test_record
140
140
  hash_type, expected = data
141
141
  d = create_driver(%[
@@ -151,10 +151,10 @@ class ElasticsearchGenidFilterTest < Test::Unit::TestCase
151
151
  d.filtered.map {|e| e.last}.first[d.instance.hash_id_key])
152
152
  end
153
153
 
154
- data("md5" => ["md5", "GJfpWe8ofiGzn97bc9Gh0Q=="],
155
- "sha1" => ["sha1", "AVaK67Tz0bEJ8xNEzjOQ6r9fAu4="],
156
- "sha256" => ["sha256", "WIXWAuf/Z94Uw95mudloo2bgjhSsSduQIwkKTQsNFgU="],
157
- "sha512" => ["sha512", "yjMGGxy8uc7gCrPgm8W6MzJGLFk0GtUwJ6w/91laf6WNywuvG/7T6kNHLagAV8rSW8xzxmtEfyValBO5scuoKw=="],)
154
+ data("md5" => ["md5", "Hb0jwxofNQP+ufQTKK1U4g=="],
155
+ "sha1" => ["sha1", "BakTtlotl/u+yOON6YcViTz6nms="],
156
+ "sha256" => ["sha256", "eLuTCsFqDlk6PfABNyD39r36+yNIBeDTHyNKfJ8fZQw="],
157
+ "sha512" => ["sha512", "PhPCNGalM4H4xT19DnCBnpwr56lbvCo8wJGyCiH9dWcyhn1nA5l1diYSZlF2fNiq1+wzMqfGvJILIjgQrlAPcg=="],)
158
158
  def test_record_with_tag
159
159
  hash_type, expected = data
160
160
  d = create_driver(%[
@@ -171,10 +171,10 @@ class ElasticsearchGenidFilterTest < Test::Unit::TestCase
171
171
  d.filtered.map {|e| e.last}.first[d.instance.hash_id_key])
172
172
  end
173
173
 
174
- data("md5" => ["md5", "5nQSaJ4F1p9rDFign13Lfg=="],
175
- "sha1" => ["sha1", "hyo9+0ZFBpizKl2NShs3C8yQcGw="],
176
- "sha256" => ["sha256", "romVsZSIksbqYsOSnUzolZQw76ankcy0DgvDZ3CayTo="],
177
- "sha512" => ["sha512", "RPU7K2Pt0iVyvV7p5usqcUIIOmfTajD1aa7pkR9qZ89UARH/lpm6ESY9iwuYJj92lxOUuF5OxlEwvV7uXJ07iA=="],)
174
+ data("md5" => ["md5", "C8vfhC4kecNCNutFCuC6MA=="],
175
+ "sha1" => ["sha1", "+YWVqUEL90wpKJRrionUJwNgXHg="],
176
+ "sha256" => ["sha256", "eSqGZqjnO6Uum/4CNfJaolX49+2XKogiGMHGNHiO91Q="],
177
+ "sha512" => ["sha512", "iVmuD0D+i/WtBwNza09ZXSIW8Xg8/yrUwK/M/EZaCMjz/x5FyyCiVkb1VVKsgNnJy0SYt4w21dhHewu1aXM6HA=="],)
178
178
  def test_record_with_time
179
179
  hash_type, expected = data
180
180
  d = create_driver(%[
@@ -191,10 +191,10 @@ class ElasticsearchGenidFilterTest < Test::Unit::TestCase
191
191
  d.filtered.map {|e| e.last}.first[d.instance.hash_id_key])
192
192
  end
193
193
 
194
- data("md5" => ["md5", "zGQF35KlMUibJAcgkgQDtw=="],
195
- "sha1" => ["sha1", "1x9RZO1xEuWps090qq4DUIsU9x8="],
196
- "sha256" => ["sha256", "eulMz0eF56lBEf31aIs0OG2TGCH/aoPfZbRqfEOkAwk="],
197
- "sha512" => ["sha512", "mIiYATtpdUFEFCIZg1FdKssIs7oWY0gJjhSSbet0ddUmqB+CiQAcAMTmrXO6AVSH0vsMvao/8vtC8AsIPfF1fA=="],)
194
+ data("md5" => ["md5", "lU7d4EiF+2M1zxWcsmBbjg=="],
195
+ "sha1" => ["sha1", "nghmz1y3KTEFxalfS2/Oe4n4yfQ="],
196
+ "sha256" => ["sha256", "d0le9UOnUeuGPF/2yEBRM1YzOYeHtxYOE1UU6JgJrvU="],
197
+ "sha512" => ["sha512", "n7rhisGHUBne6c4Cs9DRMbPror8O5Y/vYajDqAtOaiUTys/Z1EKBMnZQA0iVNFw7joX33cenBW3Yyccct3xSew=="],)
198
198
  def test_record_with_tag_and_time
199
199
  hash_type, expected = data
200
200
  d = create_driver(%[
@@ -31,6 +31,19 @@ class ElasticsearchInputTest < Test::Unit::TestCase
31
31
  @driver ||= Fluent::Test::Driver::Input.new(Fluent::Plugin::ElasticsearchInput).configure(conf)
32
32
  end
33
33
 
34
+ def elasticsearch_version
35
+ if Gem::Version.new(TRANSPORT_CLASS::VERSION) >= Gem::Version.new("7.14.0")
36
+ TRANSPORT_CLASS::VERSION
37
+ else
38
+ '7.9.0'.freeze
39
+ end
40
+ end
41
+
42
+ def stub_elastic_info(url="http://localhost:9200/", version=elasticsearch_version)
43
+ body ="{\"version\":{\"number\":\"#{version}\", \"build_flavor\":\"default\"},\"tagline\" : \"You Know, for Search\"}"
44
+ stub_request(:get, url).to_return({:status => 200, :body => body, :headers => { 'Content-Type' => 'json', 'x-elastic-product' => 'Elasticsearch' } })
45
+ end
46
+
34
47
  def sample_response(index_name="fluentd")
35
48
  {
36
49
  "took"=>4,
@@ -322,6 +335,7 @@ class ElasticsearchInputTest < Test::Unit::TestCase
322
335
  with(body: "{\"sort\":[\"_doc\"]}").
323
336
  to_return(status: 200, body: sample_response.to_s,
324
337
  headers: {'Content-Type' => 'application/json'})
338
+ stub_elastic_info
325
339
 
326
340
  driver(CONFIG)
327
341
  driver.run(expect_emits: 1, timeout: 10)
@@ -337,6 +351,7 @@ class ElasticsearchInputTest < Test::Unit::TestCase
337
351
  with(body: "{\"sort\":[\"_doc\"]}").
338
352
  to_return(status: 200, body: sample_response(index_name).to_s,
339
353
  headers: {'Content-Type' => 'application/json'})
354
+ stub_elastic_info
340
355
 
341
356
  driver(CONFIG + %[index_name #{index_name}])
342
357
  driver.run(expect_emits: 1, timeout: 10)
@@ -352,6 +367,7 @@ class ElasticsearchInputTest < Test::Unit::TestCase
352
367
  with(body: "{\"sort\":[\"_doc\"]}").
353
368
  to_return(status: 200, body: sample_response(index_name).to_s,
354
369
  headers: {'Content-Type' => 'application/json'})
370
+ stub_elastic_info
355
371
 
356
372
  driver(CONFIG + %[parse_timestamp])
357
373
  driver.run(expect_emits: 1, timeout: 10)
@@ -370,6 +386,7 @@ class ElasticsearchInputTest < Test::Unit::TestCase
370
386
  with(body: "{\"sort\":[\"_doc\"]}").
371
387
  to_return(status: 200, body: sample_response(index_name).to_s,
372
388
  headers: {'Content-Type' => 'application/json'})
389
+ stub_elastic_info
373
390
 
374
391
  driver(CONFIG + %[parse_timestamp true
375
392
  timestamp_key_format %Y-%m-%dT%H:%M:%S.%N%z
@@ -389,6 +406,7 @@ class ElasticsearchInputTest < Test::Unit::TestCase
389
406
  with(body: "{\"sort\":[\"_doc\"]}").
390
407
  to_return(status: 200, body: sample_response.to_s,
391
408
  headers: {'Content-Type' => 'application/json'})
409
+ stub_elastic_info
392
410
 
393
411
  driver(CONFIG + %[docinfo true])
394
412
  driver.run(expect_emits: 1, timeout: 10)
@@ -412,6 +430,7 @@ class ElasticsearchInputTest < Test::Unit::TestCase
412
430
  with(body: "{\"sort\":[\"_doc\"],\"slice\":{\"id\":1,\"max\":2}}").
413
431
  to_return(status: 200, body: sample_response.to_s,
414
432
  headers: {'Content-Type' => 'application/json'})
433
+ stub_elastic_info
415
434
 
416
435
  driver(CONFIG + %[num_slices 2])
417
436
  driver.run(expect_emits: 1, timeout: 10)
@@ -434,6 +453,7 @@ class ElasticsearchInputTest < Test::Unit::TestCase
434
453
  body: "{\"scroll_id\":\"WomkoUKG0QPB679Ulo6TqQgh3pIGRUmrl9qXXGK3EeiQh9rbYNasTkspZQcJ01uz\"}") do
435
454
  connection += 1
436
455
  end
456
+ stub_elastic_info
437
457
  scroll_request.to_return(lambda do |req|
438
458
  if connection <= 1
439
459
  {status: 200, body: sample_scroll_response_2.to_s,