fluent-plugin-input-opensearch 1.1.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.editorconfig +9 -0
  4. data/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
  5. data/.github/ISSUE_TEMPLATE/feature_request.md +24 -0
  6. data/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +9 -0
  7. data/.github/workflows/coverage.yaml +22 -0
  8. data/.github/workflows/issue-auto-closer.yml +12 -0
  9. data/.github/workflows/linux.yml +26 -0
  10. data/.github/workflows/macos.yml +26 -0
  11. data/.github/workflows/windows.yml +26 -0
  12. data/.gitignore +18 -0
  13. data/CONTRIBUTING.md +24 -0
  14. data/Gemfile +10 -0
  15. data/History.md +67 -0
  16. data/LICENSE.txt +201 -0
  17. data/README.OpenSearchGenID.md +116 -0
  18. data/README.OpenSearchInput.md +314 -0
  19. data/README.Troubleshooting.md +482 -0
  20. data/README.md +1622 -0
  21. data/Rakefile +37 -0
  22. data/fluent-plugin-opensearch.gemspec +39 -0
  23. data/gemfiles/Gemfile.elasticsearch.v6 +12 -0
  24. data/lib/fluent/log-ext.rb +64 -0
  25. data/lib/fluent/plugin/filter_opensearch_genid.rb +103 -0
  26. data/lib/fluent/plugin/in_opensearch.rb +410 -0
  27. data/lib/fluent/plugin/oj_serializer.rb +48 -0
  28. data/lib/fluent/plugin/opensearch_constants.rb +39 -0
  29. data/lib/fluent/plugin/opensearch_error.rb +31 -0
  30. data/lib/fluent/plugin/opensearch_error_handler.rb +182 -0
  31. data/lib/fluent/plugin/opensearch_fallback_selector.rb +36 -0
  32. data/lib/fluent/plugin/opensearch_index_template.rb +155 -0
  33. data/lib/fluent/plugin/opensearch_simple_sniffer.rb +36 -0
  34. data/lib/fluent/plugin/opensearch_tls.rb +96 -0
  35. data/lib/fluent/plugin/out_opensearch.rb +1158 -0
  36. data/lib/fluent/plugin/out_opensearch_data_stream.rb +229 -0
  37. data/test/helper.rb +60 -0
  38. data/test/plugin/datastream_template.json +4 -0
  39. data/test/plugin/test_alias_template.json +9 -0
  40. data/test/plugin/test_filter_opensearch_genid.rb +241 -0
  41. data/test/plugin/test_in_opensearch.rb +500 -0
  42. data/test/plugin/test_index_alias_template.json +11 -0
  43. data/test/plugin/test_index_template.json +25 -0
  44. data/test/plugin/test_oj_serializer.rb +45 -0
  45. data/test/plugin/test_opensearch_error_handler.rb +770 -0
  46. data/test/plugin/test_opensearch_fallback_selector.rb +100 -0
  47. data/test/plugin/test_opensearch_tls.rb +171 -0
  48. data/test/plugin/test_out_opensearch.rb +3980 -0
  49. data/test/plugin/test_out_opensearch_data_stream.rb +746 -0
  50. data/test/plugin/test_template.json +23 -0
  51. data/test/test_log-ext.rb +61 -0
  52. metadata +291 -0
@@ -0,0 +1,500 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ #
3
+ # The fluent-plugin-opensearch Contributors require contributions made to
4
+ # this file be licensed under the Apache-2.0 license or a
5
+ # compatible open source license.
6
+ #
7
+ # Modifications Copyright fluent-plugin-opensearch Contributors. See
8
+ # GitHub history for details.
9
+ #
10
+ # Licensed to Uken Inc. under one or more contributor
11
+ # license agreements. See the NOTICE file distributed with
12
+ # this work for additional information regarding copyright
13
+ # ownership. Uken Inc. licenses this file to you under
14
+ # the Apache License, Version 2.0 (the "License"); you may
15
+ # not use this file except in compliance with the License.
16
+ # You may obtain a copy of the License at
17
+ #
18
+ # http://www.apache.org/licenses/LICENSE-2.0
19
+ #
20
+ # Unless required by applicable law or agreed to in writing,
21
+ # software distributed under the License is distributed on an
22
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
23
+ # KIND, either express or implied. See the License for the
24
+ # specific language governing permissions and limitations
25
+ # under the License.
26
+
27
+ require_relative '../helper'
28
+ require 'date'
29
+ require 'fluent/test/helpers'
30
+ require 'json'
31
+ require 'fluent/test/driver/input'
32
+ require 'flexmock/test_unit'
33
+ require 'fluent/plugin/in_opensearch'
34
+
35
+ class OpenSearchInputTest < Test::Unit::TestCase
36
+ include FlexMock::TestCase
37
+ include Fluent::Test::Helpers
38
+
39
+ CONFIG = %[
40
+ tag raw.opensearch
41
+ interval 2
42
+ infinite_check_connection false
43
+ ]
44
+
45
+ def setup
46
+ Fluent::Test.setup
47
+ @driver = nil
48
+ log = Fluent::Engine.log
49
+ log.out.logs.slice!(0, log.out.logs.length)
50
+ @http_method = :post
51
+ end
52
+
53
+ def driver(conf='')
54
+ @driver ||= Fluent::Test::Driver::Input.new(Fluent::Plugin::OpenSearchInput).configure(conf)
55
+ end
56
+
57
+ def stub_elastic_info(url="http://localhost:9200/", version="1.2.2")
58
+ body ="{\"version\":{\"number\":\"#{version}\", \"distribution\":\"opensearch\"},\"tagline\":\"The OpenSearch Project: https://opensearch.org/\"}"
59
+ stub_request(:get, url).to_return({:status => 200, :body => body, :headers => { 'Content-Type' => 'json' } })
60
+ end
61
+
62
+ def sample_response(index_name="fluentd")
63
+ {
64
+ "took"=>4,
65
+ "timed_out"=>false,
66
+ "_shards"=>{
67
+ "total"=>2,
68
+ "successful"=>2,
69
+ "skipped"=>0,
70
+ "failed"=>0
71
+ },
72
+ "hits"=>{
73
+ "total"=>{
74
+ "value"=>1,
75
+ "relation"=>"eq"
76
+ },
77
+ "max_score"=>1,
78
+ "hits"=>[
79
+ {
80
+ "_index"=>"#{index_name}-2019.11.14",
81
+ "_type"=>"_doc",
82
+ "_id"=>"MJ_faG4B16RqUMOji_nH",
83
+ "_score"=>1,
84
+ "_source"=>{
85
+ "message"=>"Hi from Fluentd!",
86
+ "@timestamp"=>"2019-11-14T16:45:10.559841000+09:00"
87
+ }
88
+ }
89
+ ]
90
+ }
91
+ }.to_json
92
+ end
93
+
94
+ def sample_scroll_response
95
+ {
96
+ "_scroll_id"=>"WomkoUKG0QPB679Ulo6TqQgh3pIGRUmrl9qXXGK3EeiQh9rbYNasTkspZQcJ01uz",
97
+ "took"=>0,
98
+ "timed_out"=>false,
99
+ "_shards"=>{
100
+ "total"=>1,
101
+ "successful"=>1,
102
+ "skipped"=>0,
103
+ "failed"=>0
104
+ },
105
+ "hits"=>{
106
+ "total"=>{
107
+ "value"=>7,
108
+ "relation"=>"eq"
109
+ },
110
+ "max_score"=>nil,
111
+ "hits"=>[
112
+ {
113
+ "_index"=>"fluentd-2019.11.14",
114
+ "_type"=>"_doc",
115
+ "_id"=>"MJ_faG4B16RqUMOji_nH",
116
+ "_score"=>1,
117
+ "_source"=>{
118
+ "message"=>"Hi from Fluentd!",
119
+ "@timestamp"=>"2019-11-14T16:45:10.559841000+09:00"
120
+ },
121
+ "sort"=>[0]
122
+ }
123
+ ]
124
+ }
125
+ }.to_json
126
+ end
127
+
128
+ def sample_scroll_response_2
129
+ {
130
+ "_scroll_id"=>"WomkoUKG0QPB679Ulo6TqQgh3pIGRUmrl9qXXGK3EeiQh9rbYNasTkspZQcJ01uz",
131
+ "took"=>0,
132
+ "timed_out"=>false,
133
+ "_shards"=>{
134
+ "total"=>1,
135
+ "successful"=>1,
136
+ "skipped"=>0,
137
+ "failed"=>0
138
+ },
139
+ "hits"=>{
140
+ "total"=>{
141
+ "value"=>7,
142
+ "relation"=>"eq"
143
+ },
144
+ "max_score"=>nil,
145
+ "hits"=>[
146
+ {
147
+ "_index"=>"fluentd-2019.11.14",
148
+ "_type"=>"_doc",
149
+ "_id"=>"L5-saG4B16RqUMOjw_kb",
150
+ "_score"=>1,
151
+ "_source"=>{
152
+ "message"=>"Yaaaaaaay from Fluentd!",
153
+ "@timestamp"=>"2019-11-14T15:49:41.112023000+09:00"
154
+ },
155
+ "sort"=>[1]
156
+ }
157
+ ]
158
+ }
159
+ }.to_json
160
+ end
161
+
162
+ def sample_scroll_response_terminate
163
+ {
164
+ "_scroll_id"=>"WomkoUKG0QPB679Ulo6TqQgh3pIGRUmrl9qXXGK3EeiQh9rbYNasTkspZQcJ01uz",
165
+ "took"=>1,
166
+ "timed_out"=>false,
167
+ "terminated_early"=>true,
168
+ "_shards"=>{
169
+ "total"=>1,
170
+ "successful"=>1,
171
+ "skipped"=>0,
172
+ "failed"=>0
173
+ },
174
+ "hits"=>{
175
+ "total"=>{
176
+ "value"=>7,
177
+ "relation"=>"eq"
178
+ },
179
+ "max_score"=>nil,
180
+ "hits"=>[]
181
+ }
182
+ }.to_json
183
+ end
184
+
185
+ def test_configure
186
+ config = %{
187
+ host logs.google.com
188
+ port 777
189
+ scheme https
190
+ path /es/
191
+ user john
192
+ password doe
193
+ tag raw.opensearch
194
+ infinite_check_connection false
195
+ }
196
+ instance = driver(config).instance
197
+
198
+ expected_query = { "sort" => [ "_doc" ]}
199
+ assert_equal 'logs.google.com', instance.host
200
+ assert_equal 777, instance.port
201
+ assert_equal :https, instance.scheme
202
+ assert_equal '/es/', instance.path
203
+ assert_equal 'john', instance.user
204
+ assert_equal 'doe', instance.password
205
+ assert_equal 'raw.opensearch', instance.tag
206
+ assert_equal :TLSv1_2, instance.ssl_version
207
+ assert_equal 'fluentd', instance.index_name
208
+ assert_equal expected_query, instance.query
209
+ assert_equal '1m', instance.scroll
210
+ assert_equal 1000, instance.size
211
+ assert_equal 1, instance.num_slices
212
+ assert_equal 5, instance.interval
213
+ assert_true instance.repeat
214
+ assert_nil instance.client_key
215
+ assert_nil instance.client_cert
216
+ assert_nil instance.client_key_pass
217
+ assert_nil instance.ca_file
218
+ assert_false instance.with_transporter_log
219
+ assert_equal :excon, instance.http_backend
220
+ assert_nil instance.sniffer_class_name
221
+ assert_true instance.custom_headers.empty?
222
+ assert_equal ['_index', '_type', '_id'], instance.docinfo_fields
223
+ assert_equal '@metadata', instance.docinfo_target
224
+ assert_false instance.docinfo
225
+ end
226
+
227
+ def test_single_host_params_and_defaults
228
+ config = %{
229
+ host logs.google.com
230
+ user john
231
+ password doe
232
+ tag raw.opensearch
233
+ infinite_check_connection false
234
+ }
235
+ instance = driver(config).instance
236
+
237
+ assert_equal 1, instance.get_connection_options[:hosts].length
238
+ host1 = instance.get_connection_options[:hosts][0]
239
+
240
+ assert_equal 'logs.google.com', host1[:host]
241
+ assert_equal 9200, host1[:port]
242
+ assert_equal 'http', host1[:scheme]
243
+ assert_equal 'john', host1[:user]
244
+ assert_equal 'doe', host1[:password]
245
+ assert_equal nil, host1[:path]
246
+ assert_equal 'raw.opensearch', instance.tag
247
+ end
248
+
249
+ def test_single_host_params_and_defaults_with_escape_placeholders
250
+ config = %{
251
+ host logs.google.com
252
+ user %{j+hn}
253
+ password %{d@e}
254
+ tag raw.opensearch
255
+ infinite_check_connection false
256
+ }
257
+ instance = driver(config).instance
258
+
259
+ assert_equal 1, instance.get_connection_options[:hosts].length
260
+ host1 = instance.get_connection_options[:hosts][0]
261
+
262
+ assert_equal 'logs.google.com', host1[:host]
263
+ assert_equal 9200, host1[:port]
264
+ assert_equal 'http', host1[:scheme]
265
+ assert_equal 'j%2Bhn', host1[:user]
266
+ assert_equal 'd%40e', host1[:password]
267
+ assert_equal nil, host1[:path]
268
+ assert_equal 'raw.opensearch', instance.tag
269
+ end
270
+
271
+ def test_legacy_hosts_list
272
+ config = %{
273
+ hosts host1:50,host2:100,host3
274
+ scheme https
275
+ path /es/
276
+ port 123
277
+ tag raw.opensearch
278
+ infinite_check_connection false
279
+ }
280
+ instance = driver(config).instance
281
+
282
+ assert_equal 3, instance.get_connection_options[:hosts].length
283
+ host1, host2, host3 = instance.get_connection_options[:hosts]
284
+
285
+ assert_equal 'host1', host1[:host]
286
+ assert_equal 50, host1[:port]
287
+ assert_equal 'https', host1[:scheme]
288
+ assert_equal '/es/', host2[:path]
289
+ assert_equal 'host3', host3[:host]
290
+ assert_equal 123, host3[:port]
291
+ assert_equal 'https', host3[:scheme]
292
+ assert_equal '/es/', host3[:path]
293
+ assert_equal 'raw.opensearch', instance.tag
294
+ end
295
+
296
+ def test_hosts_list
297
+ config = %{
298
+ hosts https://john:password@host1:443/elastic/,http://host2
299
+ path /default_path
300
+ user default_user
301
+ password default_password
302
+ tag raw.opensearch
303
+ infinite_check_connection false
304
+ }
305
+ instance = driver(config).instance
306
+
307
+ assert_equal 2, instance.get_connection_options[:hosts].length
308
+ host1, host2 = instance.get_connection_options[:hosts]
309
+
310
+ assert_equal 'host1', host1[:host]
311
+ assert_equal 443, host1[:port]
312
+ assert_equal 'https', host1[:scheme]
313
+ assert_equal 'john', host1[:user]
314
+ assert_equal 'password', host1[:password]
315
+ assert_equal '/elastic/', host1[:path]
316
+
317
+ assert_equal 'host2', host2[:host]
318
+ assert_equal 'http', host2[:scheme]
319
+ assert_equal 'default_user', host2[:user]
320
+ assert_equal 'default_password', host2[:password]
321
+ assert_equal '/default_path', host2[:path]
322
+ assert_equal 'raw.opensearch', instance.tag
323
+ end
324
+
325
+ def test_hosts_list_with_escape_placeholders
326
+ config = %{
327
+ hosts https://%{j+hn}:%{passw@rd}@host1:443/elastic/,http://host2
328
+ path /default_path
329
+ user default_user
330
+ password default_password
331
+ tag raw.opensearch
332
+ infinite_check_connection false
333
+ }
334
+ instance = driver(config).instance
335
+
336
+ assert_equal 2, instance.get_connection_options[:hosts].length
337
+ host1, host2 = instance.get_connection_options[:hosts]
338
+
339
+ assert_equal 'host1', host1[:host]
340
+ assert_equal 443, host1[:port]
341
+ assert_equal 'https', host1[:scheme]
342
+ assert_equal 'j%2Bhn', host1[:user]
343
+ assert_equal 'passw%40rd', host1[:password]
344
+ assert_equal '/elastic/', host1[:path]
345
+
346
+ assert_equal 'host2', host2[:host]
347
+ assert_equal 'http', host2[:scheme]
348
+ assert_equal 'default_user', host2[:user]
349
+ assert_equal 'default_password', host2[:password]
350
+ assert_equal '/default_path', host2[:path]
351
+ assert_equal 'raw.opensearch', instance.tag
352
+ end
353
+
354
+ def test_emit
355
+ stub_request(@http_method, "http://localhost:9200/fluentd/_search?scroll=1m&size=1000").
356
+ with(body: "{\"sort\":[\"_doc\"]}").
357
+ to_return(status: 200, body: sample_response.to_s,
358
+ headers: {'Content-Type' => 'application/json'})
359
+ stub_elastic_info
360
+
361
+ driver(CONFIG)
362
+ driver.run(expect_emits: 1, timeout: 10)
363
+ expected = {"message" => "Hi from Fluentd!",
364
+ "@timestamp" => "2019-11-14T16:45:10.559841000+09:00"}
365
+ event = driver.events.map {|e| e.last}.last
366
+ assert_equal expected, event
367
+ end
368
+
369
+ def test_emit_with_custom_index_name
370
+ index_name = "logstash"
371
+ stub_request(@http_method, "http://localhost:9200/#{index_name}/_search?scroll=1m&size=1000").
372
+ with(body: "{\"sort\":[\"_doc\"]}").
373
+ to_return(status: 200, body: sample_response(index_name).to_s,
374
+ headers: {'Content-Type' => 'application/json'})
375
+ stub_elastic_info
376
+
377
+ driver(CONFIG + %[index_name #{index_name}])
378
+ driver.run(expect_emits: 1, timeout: 10)
379
+ expected = {"message" => "Hi from Fluentd!",
380
+ "@timestamp" => "2019-11-14T16:45:10.559841000+09:00"}
381
+ event = driver.events.map {|e| e.last}.last
382
+ assert_equal expected, event
383
+ end
384
+
385
+ def test_emit_with_parse_timestamp
386
+ index_name = "fluentd"
387
+ stub_request(@http_method, "http://localhost:9200/#{index_name}/_search?scroll=1m&size=1000").
388
+ with(body: "{\"sort\":[\"_doc\"]}").
389
+ to_return(status: 200, body: sample_response(index_name).to_s,
390
+ headers: {'Content-Type' => 'application/json'})
391
+ stub_elastic_info
392
+
393
+ driver(CONFIG + %[parse_timestamp])
394
+ driver.run(expect_emits: 1, timeout: 10)
395
+ expected = {"message" => "Hi from Fluentd!",
396
+ "@timestamp" => "2019-11-14T16:45:10.559841000+09:00"}
397
+ event = driver.events.map {|e| e.last}.last
398
+ time = driver.events.map {|e| e[1]}.last
399
+ expected_time = event_time("2019-11-14T16:45:10.559841000+09:00")
400
+ assert_equal expected_time.to_time, time.to_time
401
+ assert_equal expected, event
402
+ end
403
+
404
+ def test_emit_with_parse_timestamp_and_timstamp_format
405
+ index_name = "fluentd"
406
+ stub_request(@http_method, "http://localhost:9200/#{index_name}/_search?scroll=1m&size=1000").
407
+ with(body: "{\"sort\":[\"_doc\"]}").
408
+ to_return(status: 200, body: sample_response(index_name).to_s,
409
+ headers: {'Content-Type' => 'application/json'})
410
+ stub_elastic_info
411
+
412
+ driver(CONFIG + %[parse_timestamp true
413
+ timestamp_key_format %Y-%m-%dT%H:%M:%S.%N%z
414
+ ])
415
+ driver.run(expect_emits: 1, timeout: 10)
416
+ expected = {"message" => "Hi from Fluentd!",
417
+ "@timestamp" => "2019-11-14T16:45:10.559841000+09:00"}
418
+ event = driver.events.map {|e| e.last}.last
419
+ time = driver.events.map {|e| e[1]}.last
420
+ expected_time = event_time("2019-11-14T16:45:10.559841000+09:00")
421
+ assert_equal expected_time.to_time, time.to_time
422
+ assert_equal expected, event
423
+ end
424
+
425
+ def test_emit_with_docinfo
426
+ stub_request(@http_method, "http://localhost:9200/fluentd/_search?scroll=1m&size=1000").
427
+ with(body: "{\"sort\":[\"_doc\"]}").
428
+ to_return(status: 200, body: sample_response.to_s,
429
+ headers: {'Content-Type' => 'application/json'})
430
+ stub_elastic_info
431
+
432
+ driver(CONFIG + %[docinfo true])
433
+ driver.run(expect_emits: 1, timeout: 10)
434
+ expected = {"message" => "Hi from Fluentd!",
435
+ "@timestamp" => "2019-11-14T16:45:10.559841000+09:00"}
436
+ expected.merge!({"@metadata"=>
437
+ {"_id"=>"MJ_faG4B16RqUMOji_nH",
438
+ "_index"=>"fluentd-2019.11.14",
439
+ "_type"=>"_doc"}
440
+ })
441
+ event = driver.events.map {|e| e.last}.last
442
+ assert_equal expected, event
443
+ end
444
+
445
+ def test_emit_with_slices
446
+ stub_request(@http_method, "http://localhost:9200/fluentd/_search?scroll=1m&size=1000").
447
+ with(body: "{\"sort\":[\"_doc\"],\"slice\":{\"id\":0,\"max\":2}}").
448
+ to_return(status: 200, body: sample_response.to_s,
449
+ headers: {'Content-Type' => 'application/json'})
450
+ stub_request(@http_method, "http://localhost:9200/fluentd/_search?scroll=1m&size=1000").
451
+ with(body: "{\"sort\":[\"_doc\"],\"slice\":{\"id\":1,\"max\":2}}").
452
+ to_return(status: 200, body: sample_response.to_s,
453
+ headers: {'Content-Type' => 'application/json'})
454
+ stub_elastic_info
455
+
456
+ driver(CONFIG + %[num_slices 2])
457
+ driver.run(expect_emits: 1, timeout: 10)
458
+ expected = [
459
+ {"message"=>"Hi from Fluentd!", "@timestamp"=>"2019-11-14T16:45:10.559841000+09:00"},
460
+ {"message"=>"Hi from Fluentd!", "@timestamp"=>"2019-11-14T16:45:10.559841000+09:00"},
461
+ ]
462
+ events = driver.events.map {|e| e.last}
463
+ assert_equal expected, events
464
+ end
465
+
466
+ def test_emit_with_size
467
+ stub_request(@http_method, "http://localhost:9200/fluentd/_search?scroll=1m&size=1").
468
+ with(body: "{\"sort\":[\"_doc\"]}").
469
+ to_return(status: 200, body: sample_scroll_response.to_s,
470
+ headers: {'Content-Type' => 'application/json'})
471
+ connection = 0
472
+ scroll_request = stub_request(@http_method, "http://localhost:9200/_search/scroll?scroll=1m").
473
+ with(
474
+ body: "{\"scroll_id\":\"WomkoUKG0QPB679Ulo6TqQgh3pIGRUmrl9qXXGK3EeiQh9rbYNasTkspZQcJ01uz\"}") do
475
+ connection += 1
476
+ end
477
+ stub_elastic_info
478
+ scroll_request.to_return(lambda do |req|
479
+ if connection <= 1
480
+ {status: 200, body: sample_scroll_response_2.to_s,
481
+ headers: {'Content-Type' => 'application/json'}}
482
+ else
483
+ {status: 200, body: sample_scroll_response_terminate.to_s,
484
+ headers: {'Content-Type' => 'application/json'}}
485
+ end
486
+ end)
487
+ stub_request(:delete, "http://localhost:9200/_search/scroll/WomkoUKG0QPB679Ulo6TqQgh3pIGRUmrl9qXXGK3EeiQh9rbYNasTkspZQcJ01uz").
488
+ to_return(status: 200, body: "", headers: {})
489
+
490
+ driver(CONFIG + %[size 1])
491
+ driver.run(expect_emits: 1, timeout: 10)
492
+ expected = [
493
+ {"message"=>"Hi from Fluentd!", "@timestamp"=>"2019-11-14T16:45:10.559841000+09:00"},
494
+ {"message"=>"Yaaaaaaay from Fluentd!", "@timestamp"=>"2019-11-14T15:49:41.112023000+09:00"}
495
+ ]
496
+ events = driver.events.map{|e| e.last}
497
+ assert_equal expected, events
498
+ end
499
+
500
+ end
@@ -0,0 +1,11 @@
1
+ {
2
+ "priority": 105,
3
+ "index_patterns": "--index_prefix-----appid---*",
4
+ "template" : {
5
+ "settings": {},
6
+ "mappings": {},
7
+ "aliases": {
8
+ "--appid---alias": {}
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "index_patterns": "te*",
3
+ "template": {
4
+ "settings": {
5
+ "number_of_shards": 1
6
+ },
7
+ "mappings": {
8
+ "type1": {
9
+ "_source": {
10
+ "enabled": false
11
+ },
12
+ "properties": {
13
+ "host_name": {
14
+ "type": "string",
15
+ "index": "not_analyzed"
16
+ },
17
+ "created_at": {
18
+ "type": "date",
19
+ "format": "EEE MMM dd HH:mm:ss Z YYYY"
20
+ }
21
+ }
22
+ }
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,45 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ #
3
+ # The fluent-plugin-opensearch Contributors require contributions made to
4
+ # this file be licensed under the Apache-2.0 license or a
5
+ # compatible open source license.
6
+ #
7
+ # Modifications Copyright fluent-plugin-opensearch Contributors. See
8
+ # GitHub history for details.
9
+ #
10
+ # Licensed to Uken Inc. under one or more contributor
11
+ # license agreements. See the NOTICE file distributed with
12
+ # this work for additional information regarding copyright
13
+ # ownership. Uken Inc. licenses this file to you under
14
+ # the Apache License, Version 2.0 (the "License"); you may
15
+ # not use this file except in compliance with the License.
16
+ # You may obtain a copy of the License at
17
+ #
18
+ # http://www.apache.org/licenses/LICENSE-2.0
19
+ #
20
+ # Unless required by applicable law or agreed to in writing,
21
+ # software distributed under the License is distributed on an
22
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
23
+ # KIND, either express or implied. See the License for the
24
+ # specific language governing permissions and limitations
25
+ # under the License.
26
+
27
+ require_relative '../helper'
28
+ require 'opensearch'
29
+
30
+ class OjSerializerTest < Test::Unit::TestCase
31
+ def setup
32
+ begin
33
+ require 'fluent/plugin/oj_serializer'
34
+ rescue LoadError
35
+ omit "OjSerializer testcase needs oj gem."
36
+ end
37
+ @serializer = Fluent::Plugin::Serializer::Oj.new
38
+ end
39
+
40
+ def test_serializer
41
+ data = {"message" => "Hi"}
42
+ assert_equal data.to_json, @serializer.dump(data)
43
+ assert_equal data, @serializer.load(data.to_json)
44
+ end
45
+ end