fluent-plugin-opensearch 1.0.0

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 +37 -0
  5. data/.github/ISSUE_TEMPLATE/feature_request.md +24 -0
  6. data/.github/workflows/coverage.yaml +22 -0
  7. data/.github/workflows/issue-auto-closer.yml +12 -0
  8. data/.github/workflows/linux.yml +26 -0
  9. data/.github/workflows/macos.yml +26 -0
  10. data/.github/workflows/windows.yml +26 -0
  11. data/.gitignore +18 -0
  12. data/CONTRIBUTING.md +24 -0
  13. data/Gemfile +10 -0
  14. data/History.md +6 -0
  15. data/ISSUE_TEMPLATE.md +26 -0
  16. data/LICENSE.txt +201 -0
  17. data/PULL_REQUEST_TEMPLATE.md +9 -0
  18. data/README.OpenSearchGenID.md +116 -0
  19. data/README.OpenSearchInput.md +291 -0
  20. data/README.Troubleshooting.md +482 -0
  21. data/README.md +1556 -0
  22. data/Rakefile +37 -0
  23. data/fluent-plugin-opensearch.gemspec +38 -0
  24. data/gemfiles/Gemfile.elasticsearch.v6 +12 -0
  25. data/lib/fluent/log-ext.rb +64 -0
  26. data/lib/fluent/plugin/filter_opensearch_genid.rb +103 -0
  27. data/lib/fluent/plugin/in_opensearch.rb +351 -0
  28. data/lib/fluent/plugin/oj_serializer.rb +48 -0
  29. data/lib/fluent/plugin/opensearch_constants.rb +39 -0
  30. data/lib/fluent/plugin/opensearch_error.rb +31 -0
  31. data/lib/fluent/plugin/opensearch_error_handler.rb +166 -0
  32. data/lib/fluent/plugin/opensearch_fallback_selector.rb +36 -0
  33. data/lib/fluent/plugin/opensearch_index_template.rb +155 -0
  34. data/lib/fluent/plugin/opensearch_simple_sniffer.rb +36 -0
  35. data/lib/fluent/plugin/opensearch_tls.rb +96 -0
  36. data/lib/fluent/plugin/out_opensearch.rb +1124 -0
  37. data/lib/fluent/plugin/out_opensearch_data_stream.rb +214 -0
  38. data/test/helper.rb +61 -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 +493 -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 +689 -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 +3953 -0
  49. data/test/plugin/test_out_opensearch_data_stream.rb +474 -0
  50. data/test/plugin/test_template.json +23 -0
  51. data/test/test_log-ext.rb +61 -0
  52. metadata +262 -0
@@ -0,0 +1,493 @@
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
+ ]
43
+
44
+ def setup
45
+ Fluent::Test.setup
46
+ @driver = nil
47
+ log = Fluent::Engine.log
48
+ log.out.logs.slice!(0, log.out.logs.length)
49
+ @http_method = :post
50
+ end
51
+
52
+ def driver(conf='')
53
+ @driver ||= Fluent::Test::Driver::Input.new(Fluent::Plugin::OpenSearchInput).configure(conf)
54
+ end
55
+
56
+ def stub_elastic_info(url="http://localhost:9200/", version="1.2.2")
57
+ body ="{\"version\":{\"number\":\"#{version}\", \"distribution\":\"opensearch\"},\"tagline\":\"The OpenSearch Project: https://opensearch.org/\"}"
58
+ stub_request(:get, url).to_return({:status => 200, :body => body, :headers => { 'Content-Type' => 'json' } })
59
+ end
60
+
61
+ def sample_response(index_name="fluentd")
62
+ {
63
+ "took"=>4,
64
+ "timed_out"=>false,
65
+ "_shards"=>{
66
+ "total"=>2,
67
+ "successful"=>2,
68
+ "skipped"=>0,
69
+ "failed"=>0
70
+ },
71
+ "hits"=>{
72
+ "total"=>{
73
+ "value"=>1,
74
+ "relation"=>"eq"
75
+ },
76
+ "max_score"=>1,
77
+ "hits"=>[
78
+ {
79
+ "_index"=>"#{index_name}-2019.11.14",
80
+ "_type"=>"_doc",
81
+ "_id"=>"MJ_faG4B16RqUMOji_nH",
82
+ "_score"=>1,
83
+ "_source"=>{
84
+ "message"=>"Hi from Fluentd!",
85
+ "@timestamp"=>"2019-11-14T16:45:10.559841000+09:00"
86
+ }
87
+ }
88
+ ]
89
+ }
90
+ }.to_json
91
+ end
92
+
93
+ def sample_scroll_response
94
+ {
95
+ "_scroll_id"=>"WomkoUKG0QPB679Ulo6TqQgh3pIGRUmrl9qXXGK3EeiQh9rbYNasTkspZQcJ01uz",
96
+ "took"=>0,
97
+ "timed_out"=>false,
98
+ "_shards"=>{
99
+ "total"=>1,
100
+ "successful"=>1,
101
+ "skipped"=>0,
102
+ "failed"=>0
103
+ },
104
+ "hits"=>{
105
+ "total"=>{
106
+ "value"=>7,
107
+ "relation"=>"eq"
108
+ },
109
+ "max_score"=>nil,
110
+ "hits"=>[
111
+ {
112
+ "_index"=>"fluentd-2019.11.14",
113
+ "_type"=>"_doc",
114
+ "_id"=>"MJ_faG4B16RqUMOji_nH",
115
+ "_score"=>1,
116
+ "_source"=>{
117
+ "message"=>"Hi from Fluentd!",
118
+ "@timestamp"=>"2019-11-14T16:45:10.559841000+09:00"
119
+ },
120
+ "sort"=>[0]
121
+ }
122
+ ]
123
+ }
124
+ }.to_json
125
+ end
126
+
127
+ def sample_scroll_response_2
128
+ {
129
+ "_scroll_id"=>"WomkoUKG0QPB679Ulo6TqQgh3pIGRUmrl9qXXGK3EeiQh9rbYNasTkspZQcJ01uz",
130
+ "took"=>0,
131
+ "timed_out"=>false,
132
+ "_shards"=>{
133
+ "total"=>1,
134
+ "successful"=>1,
135
+ "skipped"=>0,
136
+ "failed"=>0
137
+ },
138
+ "hits"=>{
139
+ "total"=>{
140
+ "value"=>7,
141
+ "relation"=>"eq"
142
+ },
143
+ "max_score"=>nil,
144
+ "hits"=>[
145
+ {
146
+ "_index"=>"fluentd-2019.11.14",
147
+ "_type"=>"_doc",
148
+ "_id"=>"L5-saG4B16RqUMOjw_kb",
149
+ "_score"=>1,
150
+ "_source"=>{
151
+ "message"=>"Yaaaaaaay from Fluentd!",
152
+ "@timestamp"=>"2019-11-14T15:49:41.112023000+09:00"
153
+ },
154
+ "sort"=>[1]
155
+ }
156
+ ]
157
+ }
158
+ }.to_json
159
+ end
160
+
161
+ def sample_scroll_response_terminate
162
+ {
163
+ "_scroll_id"=>"WomkoUKG0QPB679Ulo6TqQgh3pIGRUmrl9qXXGK3EeiQh9rbYNasTkspZQcJ01uz",
164
+ "took"=>1,
165
+ "timed_out"=>false,
166
+ "terminated_early"=>true,
167
+ "_shards"=>{
168
+ "total"=>1,
169
+ "successful"=>1,
170
+ "skipped"=>0,
171
+ "failed"=>0
172
+ },
173
+ "hits"=>{
174
+ "total"=>{
175
+ "value"=>7,
176
+ "relation"=>"eq"
177
+ },
178
+ "max_score"=>nil,
179
+ "hits"=>[]
180
+ }
181
+ }.to_json
182
+ end
183
+
184
+ def test_configure
185
+ config = %{
186
+ host logs.google.com
187
+ port 777
188
+ scheme https
189
+ path /es/
190
+ user john
191
+ password doe
192
+ tag raw.opensearch
193
+ }
194
+ instance = driver(config).instance
195
+
196
+ expected_query = { "sort" => [ "_doc" ]}
197
+ assert_equal 'logs.google.com', instance.host
198
+ assert_equal 777, instance.port
199
+ assert_equal :https, instance.scheme
200
+ assert_equal '/es/', instance.path
201
+ assert_equal 'john', instance.user
202
+ assert_equal 'doe', instance.password
203
+ assert_equal 'raw.opensearch', instance.tag
204
+ assert_equal :TLSv1_2, instance.ssl_version
205
+ assert_equal 'fluentd', instance.index_name
206
+ assert_equal expected_query, instance.query
207
+ assert_equal '1m', instance.scroll
208
+ assert_equal 1000, instance.size
209
+ assert_equal 1, instance.num_slices
210
+ assert_equal 5, instance.interval
211
+ assert_true instance.repeat
212
+ assert_nil instance.client_key
213
+ assert_nil instance.client_cert
214
+ assert_nil instance.client_key_pass
215
+ assert_nil instance.ca_file
216
+ assert_false instance.with_transporter_log
217
+ assert_equal :excon, instance.http_backend
218
+ assert_nil instance.sniffer_class_name
219
+ assert_true instance.custom_headers.empty?
220
+ assert_equal ['_index', '_type', '_id'], instance.docinfo_fields
221
+ assert_equal '@metadata', instance.docinfo_target
222
+ assert_false instance.docinfo
223
+ end
224
+
225
+ def test_single_host_params_and_defaults
226
+ config = %{
227
+ host logs.google.com
228
+ user john
229
+ password doe
230
+ tag raw.opensearch
231
+ }
232
+ instance = driver(config).instance
233
+
234
+ assert_equal 1, instance.get_connection_options[:hosts].length
235
+ host1 = instance.get_connection_options[:hosts][0]
236
+
237
+ assert_equal 'logs.google.com', host1[:host]
238
+ assert_equal 9200, host1[:port]
239
+ assert_equal 'http', host1[:scheme]
240
+ assert_equal 'john', host1[:user]
241
+ assert_equal 'doe', host1[:password]
242
+ assert_equal nil, host1[:path]
243
+ assert_equal 'raw.opensearch', instance.tag
244
+ end
245
+
246
+ def test_single_host_params_and_defaults_with_escape_placeholders
247
+ config = %{
248
+ host logs.google.com
249
+ user %{j+hn}
250
+ password %{d@e}
251
+ tag raw.opensearch
252
+ }
253
+ instance = driver(config).instance
254
+
255
+ assert_equal 1, instance.get_connection_options[:hosts].length
256
+ host1 = instance.get_connection_options[:hosts][0]
257
+
258
+ assert_equal 'logs.google.com', host1[:host]
259
+ assert_equal 9200, host1[:port]
260
+ assert_equal 'http', host1[:scheme]
261
+ assert_equal 'j%2Bhn', host1[:user]
262
+ assert_equal 'd%40e', host1[:password]
263
+ assert_equal nil, host1[:path]
264
+ assert_equal 'raw.opensearch', instance.tag
265
+ end
266
+
267
+ def test_legacy_hosts_list
268
+ config = %{
269
+ hosts host1:50,host2:100,host3
270
+ scheme https
271
+ path /es/
272
+ port 123
273
+ tag raw.opensearch
274
+ }
275
+ instance = driver(config).instance
276
+
277
+ assert_equal 3, instance.get_connection_options[:hosts].length
278
+ host1, host2, host3 = instance.get_connection_options[:hosts]
279
+
280
+ assert_equal 'host1', host1[:host]
281
+ assert_equal 50, host1[:port]
282
+ assert_equal 'https', host1[:scheme]
283
+ assert_equal '/es/', host2[:path]
284
+ assert_equal 'host3', host3[:host]
285
+ assert_equal 123, host3[:port]
286
+ assert_equal 'https', host3[:scheme]
287
+ assert_equal '/es/', host3[:path]
288
+ assert_equal 'raw.opensearch', instance.tag
289
+ end
290
+
291
+ def test_hosts_list
292
+ config = %{
293
+ hosts https://john:password@host1:443/elastic/,http://host2
294
+ path /default_path
295
+ user default_user
296
+ password default_password
297
+ tag raw.opensearch
298
+ }
299
+ instance = driver(config).instance
300
+
301
+ assert_equal 2, instance.get_connection_options[:hosts].length
302
+ host1, host2 = instance.get_connection_options[:hosts]
303
+
304
+ assert_equal 'host1', host1[:host]
305
+ assert_equal 443, host1[:port]
306
+ assert_equal 'https', host1[:scheme]
307
+ assert_equal 'john', host1[:user]
308
+ assert_equal 'password', host1[:password]
309
+ assert_equal '/elastic/', host1[:path]
310
+
311
+ assert_equal 'host2', host2[:host]
312
+ assert_equal 'http', host2[:scheme]
313
+ assert_equal 'default_user', host2[:user]
314
+ assert_equal 'default_password', host2[:password]
315
+ assert_equal '/default_path', host2[:path]
316
+ assert_equal 'raw.opensearch', instance.tag
317
+ end
318
+
319
+ def test_hosts_list_with_escape_placeholders
320
+ config = %{
321
+ hosts https://%{j+hn}:%{passw@rd}@host1:443/elastic/,http://host2
322
+ path /default_path
323
+ user default_user
324
+ password default_password
325
+ tag raw.opensearch
326
+ }
327
+ instance = driver(config).instance
328
+
329
+ assert_equal 2, instance.get_connection_options[:hosts].length
330
+ host1, host2 = instance.get_connection_options[:hosts]
331
+
332
+ assert_equal 'host1', host1[:host]
333
+ assert_equal 443, host1[:port]
334
+ assert_equal 'https', host1[:scheme]
335
+ assert_equal 'j%2Bhn', host1[:user]
336
+ assert_equal 'passw%40rd', host1[:password]
337
+ assert_equal '/elastic/', host1[:path]
338
+
339
+ assert_equal 'host2', host2[:host]
340
+ assert_equal 'http', host2[:scheme]
341
+ assert_equal 'default_user', host2[:user]
342
+ assert_equal 'default_password', host2[:password]
343
+ assert_equal '/default_path', host2[:path]
344
+ assert_equal 'raw.opensearch', instance.tag
345
+ end
346
+
347
+ def test_emit
348
+ stub_request(@http_method, "http://localhost:9200/fluentd/_search?scroll=1m&size=1000").
349
+ with(body: "{\"sort\":[\"_doc\"]}").
350
+ to_return(status: 200, body: sample_response.to_s,
351
+ headers: {'Content-Type' => 'application/json'})
352
+ stub_elastic_info
353
+
354
+ driver(CONFIG)
355
+ driver.run(expect_emits: 1, timeout: 10)
356
+ expected = {"message" => "Hi from Fluentd!",
357
+ "@timestamp" => "2019-11-14T16:45:10.559841000+09:00"}
358
+ event = driver.events.map {|e| e.last}.last
359
+ assert_equal expected, event
360
+ end
361
+
362
+ def test_emit_with_custom_index_name
363
+ index_name = "logstash"
364
+ stub_request(@http_method, "http://localhost:9200/#{index_name}/_search?scroll=1m&size=1000").
365
+ with(body: "{\"sort\":[\"_doc\"]}").
366
+ to_return(status: 200, body: sample_response(index_name).to_s,
367
+ headers: {'Content-Type' => 'application/json'})
368
+ stub_elastic_info
369
+
370
+ driver(CONFIG + %[index_name #{index_name}])
371
+ driver.run(expect_emits: 1, timeout: 10)
372
+ expected = {"message" => "Hi from Fluentd!",
373
+ "@timestamp" => "2019-11-14T16:45:10.559841000+09:00"}
374
+ event = driver.events.map {|e| e.last}.last
375
+ assert_equal expected, event
376
+ end
377
+
378
+ def test_emit_with_parse_timestamp
379
+ index_name = "fluentd"
380
+ stub_request(@http_method, "http://localhost:9200/#{index_name}/_search?scroll=1m&size=1000").
381
+ with(body: "{\"sort\":[\"_doc\"]}").
382
+ to_return(status: 200, body: sample_response(index_name).to_s,
383
+ headers: {'Content-Type' => 'application/json'})
384
+ stub_elastic_info
385
+
386
+ driver(CONFIG + %[parse_timestamp])
387
+ driver.run(expect_emits: 1, timeout: 10)
388
+ expected = {"message" => "Hi from Fluentd!",
389
+ "@timestamp" => "2019-11-14T16:45:10.559841000+09:00"}
390
+ event = driver.events.map {|e| e.last}.last
391
+ time = driver.events.map {|e| e[1]}.last
392
+ expected_time = event_time("2019-11-14T16:45:10.559841000+09:00")
393
+ assert_equal expected_time.to_time, time.to_time
394
+ assert_equal expected, event
395
+ end
396
+
397
+ def test_emit_with_parse_timestamp_and_timstamp_format
398
+ index_name = "fluentd"
399
+ stub_request(@http_method, "http://localhost:9200/#{index_name}/_search?scroll=1m&size=1000").
400
+ with(body: "{\"sort\":[\"_doc\"]}").
401
+ to_return(status: 200, body: sample_response(index_name).to_s,
402
+ headers: {'Content-Type' => 'application/json'})
403
+ stub_elastic_info
404
+
405
+ driver(CONFIG + %[parse_timestamp true
406
+ timestamp_key_format %Y-%m-%dT%H:%M:%S.%N%z
407
+ ])
408
+ driver.run(expect_emits: 1, timeout: 10)
409
+ expected = {"message" => "Hi from Fluentd!",
410
+ "@timestamp" => "2019-11-14T16:45:10.559841000+09:00"}
411
+ event = driver.events.map {|e| e.last}.last
412
+ time = driver.events.map {|e| e[1]}.last
413
+ expected_time = event_time("2019-11-14T16:45:10.559841000+09:00")
414
+ assert_equal expected_time.to_time, time.to_time
415
+ assert_equal expected, event
416
+ end
417
+
418
+ def test_emit_with_docinfo
419
+ stub_request(@http_method, "http://localhost:9200/fluentd/_search?scroll=1m&size=1000").
420
+ with(body: "{\"sort\":[\"_doc\"]}").
421
+ to_return(status: 200, body: sample_response.to_s,
422
+ headers: {'Content-Type' => 'application/json'})
423
+ stub_elastic_info
424
+
425
+ driver(CONFIG + %[docinfo true])
426
+ driver.run(expect_emits: 1, timeout: 10)
427
+ expected = {"message" => "Hi from Fluentd!",
428
+ "@timestamp" => "2019-11-14T16:45:10.559841000+09:00"}
429
+ expected.merge!({"@metadata"=>
430
+ {"_id"=>"MJ_faG4B16RqUMOji_nH",
431
+ "_index"=>"fluentd-2019.11.14",
432
+ "_type"=>"_doc"}
433
+ })
434
+ event = driver.events.map {|e| e.last}.last
435
+ assert_equal expected, event
436
+ end
437
+
438
+ def test_emit_with_slices
439
+ stub_request(@http_method, "http://localhost:9200/fluentd/_search?scroll=1m&size=1000").
440
+ with(body: "{\"sort\":[\"_doc\"],\"slice\":{\"id\":0,\"max\":2}}").
441
+ to_return(status: 200, body: sample_response.to_s,
442
+ headers: {'Content-Type' => 'application/json'})
443
+ stub_request(@http_method, "http://localhost:9200/fluentd/_search?scroll=1m&size=1000").
444
+ with(body: "{\"sort\":[\"_doc\"],\"slice\":{\"id\":1,\"max\":2}}").
445
+ to_return(status: 200, body: sample_response.to_s,
446
+ headers: {'Content-Type' => 'application/json'})
447
+ stub_elastic_info
448
+
449
+ driver(CONFIG + %[num_slices 2])
450
+ driver.run(expect_emits: 1, timeout: 10)
451
+ expected = [
452
+ {"message"=>"Hi from Fluentd!", "@timestamp"=>"2019-11-14T16:45:10.559841000+09:00"},
453
+ {"message"=>"Hi from Fluentd!", "@timestamp"=>"2019-11-14T16:45:10.559841000+09:00"},
454
+ ]
455
+ events = driver.events.map {|e| e.last}
456
+ assert_equal expected, events
457
+ end
458
+
459
+ def test_emit_with_size
460
+ stub_request(@http_method, "http://localhost:9200/fluentd/_search?scroll=1m&size=1").
461
+ with(body: "{\"sort\":[\"_doc\"]}").
462
+ to_return(status: 200, body: sample_scroll_response.to_s,
463
+ headers: {'Content-Type' => 'application/json'})
464
+ connection = 0
465
+ scroll_request = stub_request(@http_method, "http://localhost:9200/_search/scroll?scroll=1m").
466
+ with(
467
+ body: "{\"scroll_id\":\"WomkoUKG0QPB679Ulo6TqQgh3pIGRUmrl9qXXGK3EeiQh9rbYNasTkspZQcJ01uz\"}") do
468
+ connection += 1
469
+ end
470
+ stub_elastic_info
471
+ scroll_request.to_return(lambda do |req|
472
+ if connection <= 1
473
+ {status: 200, body: sample_scroll_response_2.to_s,
474
+ headers: {'Content-Type' => 'application/json'}}
475
+ else
476
+ {status: 200, body: sample_scroll_response_terminate.to_s,
477
+ headers: {'Content-Type' => 'application/json'}}
478
+ end
479
+ end)
480
+ stub_request(:delete, "http://localhost:9200/_search/scroll/WomkoUKG0QPB679Ulo6TqQgh3pIGRUmrl9qXXGK3EeiQh9rbYNasTkspZQcJ01uz").
481
+ to_return(status: 200, body: "", headers: {})
482
+
483
+ driver(CONFIG + %[size 1])
484
+ driver.run(expect_emits: 1, timeout: 10)
485
+ expected = [
486
+ {"message"=>"Hi from Fluentd!", "@timestamp"=>"2019-11-14T16:45:10.559841000+09:00"},
487
+ {"message"=>"Yaaaaaaay from Fluentd!", "@timestamp"=>"2019-11-14T15:49:41.112023000+09:00"}
488
+ ]
489
+ events = driver.events.map{|e| e.last}
490
+ assert_equal expected, events
491
+ end
492
+
493
+ 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