fluent-plugin-input-opensearch 1.2.4 → 1.2.5
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.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/lib/fluent/plugin/in_opensearch.rb +3 -3
- data/lib/fluent/plugin/out_opensearch.rb +5 -1
- metadata +5 -55
- data/.coveralls.yml +0 -1
- data/.editorconfig +0 -9
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -29
- data/.github/ISSUE_TEMPLATE/feature_request.md +0 -24
- data/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -9
- data/.github/workflows/coverage.yaml +0 -22
- data/.github/workflows/issue-auto-closer.yml +0 -12
- data/.github/workflows/linux.yml +0 -26
- data/.github/workflows/macos.yml +0 -26
- data/.github/workflows/windows.yml +0 -26
- data/.gitignore +0 -18
- data/CONTRIBUTING.md +0 -24
- data/Gemfile +0 -10
- data/History.md +0 -67
- data/README.OpenSearchGenID.md +0 -116
- data/README.OpenSearchInput.md +0 -396
- data/README.Troubleshooting.md +0 -482
- data/Rakefile +0 -37
- data/fluent-plugin-opensearch.gemspec +0 -39
- data/gemfiles/Gemfile.elasticsearch.v6 +0 -12
- data/test/helper.rb +0 -60
- data/test/plugin/datastream_template.json +0 -4
- data/test/plugin/test_alias_template.json +0 -9
- data/test/plugin/test_filter_opensearch_genid.rb +0 -241
- data/test/plugin/test_in_opensearch.rb +0 -500
- data/test/plugin/test_index_alias_template.json +0 -11
- data/test/plugin/test_index_template.json +0 -25
- data/test/plugin/test_oj_serializer.rb +0 -45
- data/test/plugin/test_opensearch_error_handler.rb +0 -770
- data/test/plugin/test_opensearch_fallback_selector.rb +0 -100
- data/test/plugin/test_opensearch_tls.rb +0 -171
- data/test/plugin/test_out_opensearch.rb +0 -3980
- data/test/plugin/test_out_opensearch_data_stream.rb +0 -746
- data/test/plugin/test_template.json +0 -23
- data/test/test_log-ext.rb +0 -61
@@ -1,3980 +0,0 @@
|
|
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/output'
|
32
|
-
require 'flexmock/test_unit'
|
33
|
-
require 'fluent/plugin/out_opensearch'
|
34
|
-
|
35
|
-
class OpenSearchOutputTest < Test::Unit::TestCase
|
36
|
-
include FlexMock::TestCase
|
37
|
-
include Fluent::Test::Helpers
|
38
|
-
|
39
|
-
attr_accessor :index_cmds, :index_command_counts, :index_cmds_all_requests
|
40
|
-
|
41
|
-
def setup
|
42
|
-
Fluent::Test.setup
|
43
|
-
@driver = nil
|
44
|
-
log = Fluent::Engine.log
|
45
|
-
log.out.logs.slice!(0, log.out.logs.length)
|
46
|
-
end
|
47
|
-
|
48
|
-
def driver(conf='', os_version=1, client_version="\"1.2\"")
|
49
|
-
# For request stub to detect compatibility.
|
50
|
-
@os_version ||= os_version
|
51
|
-
@client_version ||= client_version
|
52
|
-
if @os_version
|
53
|
-
Fluent::Plugin::OpenSearchOutput.module_eval(<<-CODE)
|
54
|
-
def detect_os_major_version
|
55
|
-
#{@os_version}
|
56
|
-
end
|
57
|
-
CODE
|
58
|
-
end
|
59
|
-
Fluent::Plugin::OpenSearchOutput.module_eval(<<-CODE)
|
60
|
-
def client_library_version
|
61
|
-
#{@client_version}
|
62
|
-
end
|
63
|
-
CODE
|
64
|
-
@driver ||= Fluent::Test::Driver::Output.new(Fluent::Plugin::OpenSearchOutput) {
|
65
|
-
# v0.12's test driver assume format definition. This simulates ObjectBufferedOutput format
|
66
|
-
if !defined?(Fluent::Plugin::Output)
|
67
|
-
def format(tag, time, record)
|
68
|
-
[time, record].to_msgpack
|
69
|
-
end
|
70
|
-
end
|
71
|
-
}.configure(conf)
|
72
|
-
end
|
73
|
-
|
74
|
-
def default_type_name
|
75
|
-
Fluent::Plugin::OpenSearchOutput::DEFAULT_TYPE_NAME
|
76
|
-
end
|
77
|
-
|
78
|
-
def sample_record(content={})
|
79
|
-
{'age' => 26, 'request_id' => '42', 'parent_id' => 'parent', 'routing_id' => 'routing'}.merge(content)
|
80
|
-
end
|
81
|
-
|
82
|
-
def nested_sample_record
|
83
|
-
{'nested' =>
|
84
|
-
{'age' => 26, 'parent_id' => 'parent', 'routing_id' => 'routing', 'request_id' => '42'}
|
85
|
-
}
|
86
|
-
end
|
87
|
-
|
88
|
-
def stub_opensearch_info(url="http://localhost:9200/", version="1.2.2")
|
89
|
-
body ="{\"version\":{\"number\":\"#{version}\", \"distribution\":\"opensearch\"},\"tagline\":\"The OpenSearch Project: https://opensearch.org/\"}"
|
90
|
-
stub_request(:get, url).to_return({:status => 200, :body => body, :headers => { 'Content-Type' => 'json' } })
|
91
|
-
end
|
92
|
-
|
93
|
-
def stub_opensearch(url="http://localhost:9200/_bulk")
|
94
|
-
stub_request(:post, url).with do |req|
|
95
|
-
@index_cmds = req.body.split("\n").map {|r| JSON.parse(r) }
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def stub_opensearch_all_requests(url="http://localhost:9200/_bulk")
|
100
|
-
@index_cmds_all_requests = Array.new
|
101
|
-
stub_request(:post, url).with do |req|
|
102
|
-
@index_cmds = req.body.split("\n").map {|r| JSON.parse(r) }
|
103
|
-
@index_cmds_all_requests << @index_cmds
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
def stub_opensearch_unavailable(url="http://localhost:9200/_bulk")
|
108
|
-
stub_request(:post, url).to_return(:status => [503, "Service Unavailable"])
|
109
|
-
end
|
110
|
-
|
111
|
-
def stub_opensearch_timeout(url="http://localhost:9200/_bulk")
|
112
|
-
stub_request(:post, url).to_timeout
|
113
|
-
end
|
114
|
-
|
115
|
-
def stub_opensearch_with_store_index_command_counts(url="http://localhost:9200/_bulk")
|
116
|
-
if @index_command_counts == nil
|
117
|
-
@index_command_counts = {}
|
118
|
-
@index_command_counts.default = 0
|
119
|
-
end
|
120
|
-
|
121
|
-
stub_request(:post, url).with do |req|
|
122
|
-
index_cmds = req.body.split("\n").map {|r| JSON.parse(r) }
|
123
|
-
@index_command_counts[url] += index_cmds.size
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
def make_response_body(req, error_el = nil, error_status = nil, error = nil)
|
128
|
-
req_index_cmds = req.body.split("\n").map { |r| JSON.parse(r) }
|
129
|
-
items = []
|
130
|
-
count = 0
|
131
|
-
ids = 1
|
132
|
-
op = nil
|
133
|
-
index = nil
|
134
|
-
type = nil
|
135
|
-
id = nil
|
136
|
-
req_index_cmds.each do |cmd|
|
137
|
-
if count.even?
|
138
|
-
op = cmd.keys[0]
|
139
|
-
index = cmd[op]['_index']
|
140
|
-
type = cmd[op]['_type']
|
141
|
-
if cmd[op].has_key?('_id')
|
142
|
-
id = cmd[op]['_id']
|
143
|
-
else
|
144
|
-
# Note: this appears to be an undocumented feature of OpenSearch (and Elasticsearch)
|
145
|
-
# https://www.elastic.co/guide/en/elasticsearch/reference/2.4/docs-bulk.html
|
146
|
-
# When you submit an "index" write_operation, with no "_id" field in the
|
147
|
-
# metadata header, OpenSearch will turn this into a "create"
|
148
|
-
# operation in the response.
|
149
|
-
if "index" == op
|
150
|
-
op = "create"
|
151
|
-
end
|
152
|
-
id = ids
|
153
|
-
ids += 1
|
154
|
-
end
|
155
|
-
else
|
156
|
-
item = {
|
157
|
-
op => {
|
158
|
-
'_index' => index, '_type' => type, '_id' => id, '_version' => 1,
|
159
|
-
'_shards' => { 'total' => 1, 'successful' => 1, 'failed' => 0 },
|
160
|
-
'status' => op == 'create' ? 201 : 200
|
161
|
-
}
|
162
|
-
}
|
163
|
-
items.push(item)
|
164
|
-
end
|
165
|
-
count += 1
|
166
|
-
end
|
167
|
-
if !error_el.nil? && !error_status.nil? && !error.nil?
|
168
|
-
op = items[error_el].keys[0]
|
169
|
-
items[error_el][op].delete('_version')
|
170
|
-
items[error_el][op].delete('_shards')
|
171
|
-
items[error_el][op]['error'] = error
|
172
|
-
items[error_el][op]['status'] = error_status
|
173
|
-
errors = true
|
174
|
-
else
|
175
|
-
errors = false
|
176
|
-
end
|
177
|
-
@index_cmds = items
|
178
|
-
body = { 'took' => 6, 'errors' => errors, 'items' => items }
|
179
|
-
return body.to_json
|
180
|
-
end
|
181
|
-
|
182
|
-
def stub_opensearch_bad_argument(url="http://localhost:9200/_bulk")
|
183
|
-
error = {
|
184
|
-
"type" => "mapper_parsing_exception",
|
185
|
-
"reason" => "failed to parse [...]",
|
186
|
-
"caused_by" => {
|
187
|
-
"type" => "illegal_argument_exception",
|
188
|
-
"reason" => "Invalid format: \"...\""
|
189
|
-
}
|
190
|
-
}
|
191
|
-
stub_request(:post, url).to_return(lambda { |req| { :status => 200, :body => make_response_body(req, 1, 400, error), :headers => { 'Content-Type' => 'json' } } })
|
192
|
-
end
|
193
|
-
|
194
|
-
def stub_opensearch_bulk_error(url="http://localhost:9200/_bulk")
|
195
|
-
error = {
|
196
|
-
"type" => "some-unrecognized-error",
|
197
|
-
"reason" => "some message printed here ...",
|
198
|
-
}
|
199
|
-
stub_request(:post, url).to_return(lambda { |req| { :status => 200, :body => make_response_body(req, 1, 500, error), :headers => { 'Content-Type' => 'json' } } })
|
200
|
-
end
|
201
|
-
|
202
|
-
def stub_opensearch_bulk_rejected(url="http://localhost:9200/_bulk")
|
203
|
-
error = {
|
204
|
-
"status" => 500,
|
205
|
-
"type" => "rejected_execution_exception",
|
206
|
-
"reason" => "rejected execution of org.opensearch.transport.TransportService$4@1a34d37a on OpenSearchThreadPoolExecutor[bulk, queue capacity = 50, org.opensearch.common.util.concurrent.OpenSearchThreadPoolExecutor@312a2162[Running, pool size = 32, active threads = 32, queued tasks = 50, completed tasks = 327053]]"
|
207
|
-
}
|
208
|
-
stub_request(:post, url).to_return(lambda { |req| { :status => 200, :body => make_response_body(req, 1, 429, error), :headers => { 'Content-Type' => 'json' } } })
|
209
|
-
end
|
210
|
-
|
211
|
-
def stub_opensearch_out_of_memory(url="http://localhost:9200/_bulk")
|
212
|
-
error = {
|
213
|
-
"status" => 500,
|
214
|
-
"type" => "out_of_memory_error",
|
215
|
-
"reason" => "Java heap space"
|
216
|
-
}
|
217
|
-
stub_request(:post, url).to_return(lambda { |req| { :status => 200, :body => make_response_body(req, 1, 500, error), :headers => { 'Content-Type' => 'json' } } })
|
218
|
-
end
|
219
|
-
|
220
|
-
def stub_opensearch_unexpected_response_op(url="http://localhost:9200/_bulk")
|
221
|
-
error = {
|
222
|
-
"category" => "some-other-type",
|
223
|
-
"reason" => "some-other-reason"
|
224
|
-
}
|
225
|
-
stub_request(:post, url).to_return(lambda { |req| bodystr = make_response_body(req, 0, 500, error); body = JSON.parse(bodystr); body['items'][0]['unknown'] = body['items'][0].delete('create'); { :status => 200, :body => body.to_json, :headers => { 'Content-Type' => 'json' } } })
|
226
|
-
end
|
227
|
-
|
228
|
-
def assert_logs_include(logs, msg, exp_matches=1)
|
229
|
-
matches = logs.grep(/#{msg}/)
|
230
|
-
assert_equal(exp_matches, matches.length, "Logs do not contain '#{msg}' '#{logs}'")
|
231
|
-
end
|
232
|
-
|
233
|
-
def assert_logs_include_compare_size(exp_matches=1, operator="<=", logs="", msg="")
|
234
|
-
matches = logs.grep(/#{msg}/)
|
235
|
-
assert_compare(exp_matches, operator, matches.length, "Logs do not contain '#{msg}' '#{logs}'")
|
236
|
-
end
|
237
|
-
|
238
|
-
def alias_endpoint
|
239
|
-
"_aliases"
|
240
|
-
end
|
241
|
-
|
242
|
-
def test_configure
|
243
|
-
config = %{
|
244
|
-
host logs.google.com
|
245
|
-
port 777
|
246
|
-
scheme https
|
247
|
-
path /os/
|
248
|
-
user john
|
249
|
-
password doe
|
250
|
-
}
|
251
|
-
instance = driver(config).instance
|
252
|
-
|
253
|
-
assert_equal 'logs.google.com', instance.host
|
254
|
-
assert_equal 777, instance.port
|
255
|
-
assert_equal :https, instance.scheme
|
256
|
-
assert_equal '/os/', instance.path
|
257
|
-
assert_equal 'john', instance.user
|
258
|
-
assert_equal 'doe', instance.password
|
259
|
-
assert_equal Fluent::Plugin::OpenSearchTLS::DEFAULT_VERSION, instance.ssl_version
|
260
|
-
assert_nil instance.ssl_max_version
|
261
|
-
assert_nil instance.ssl_min_version
|
262
|
-
if Fluent::Plugin::OpenSearchTLS::USE_TLS_MINMAX_VERSION
|
263
|
-
if defined?(OpenSSL::SSL::TLS1_3_VERSION)
|
264
|
-
assert_equal({max_version: OpenSSL::SSL::TLS1_3_VERSION, min_version: OpenSSL::SSL::TLS1_2_VERSION},
|
265
|
-
instance.ssl_version_options)
|
266
|
-
else
|
267
|
-
assert_equal({max_version: nil, min_version: OpenSSL::SSL::TLS1_2_VERSION},
|
268
|
-
instance.ssl_version_options)
|
269
|
-
end
|
270
|
-
else
|
271
|
-
assert_equal({version: Fluent::Plugin::OpensearchTLS::DEFAULT_VERSION},
|
272
|
-
instance.ssl_version_options)
|
273
|
-
end
|
274
|
-
assert_nil instance.client_key
|
275
|
-
assert_nil instance.client_cert
|
276
|
-
assert_nil instance.client_key_pass
|
277
|
-
assert_false instance.with_transporter_log
|
278
|
-
assert_equal "_doc", default_type_name
|
279
|
-
assert_equal :excon, instance.http_backend
|
280
|
-
assert_false instance.prefer_oj_serializer
|
281
|
-
assert_equal ["out_of_memory_error", "rejected_execution_exception"], instance.unrecoverable_error_types
|
282
|
-
assert_true instance.verify_os_version_at_startup
|
283
|
-
assert_equal Fluent::Plugin::OpenSearchOutput::DEFAULT_OPENSEARCH_VERSION, instance.default_opensearch_version
|
284
|
-
assert_false instance.log_os_400_reason
|
285
|
-
assert_equal(-1, Fluent::Plugin::OpenSearchOutput::DEFAULT_TARGET_BULK_BYTES)
|
286
|
-
assert_false instance.compression
|
287
|
-
assert_equal :no_compression, instance.compression_level
|
288
|
-
assert_true instance.http_backend_excon_nonblock
|
289
|
-
|
290
|
-
assert_nil instance.endpoint
|
291
|
-
end
|
292
|
-
|
293
|
-
test 'configure endpoint section' do
|
294
|
-
config = Fluent::Config::Element.new(
|
295
|
-
'ROOT', '', {
|
296
|
-
'@type' => 'opensearch',
|
297
|
-
}, [
|
298
|
-
Fluent::Config::Element.new('endpoint', '', {
|
299
|
-
'url' => "https://search-opensearch.aws.example.com/",
|
300
|
-
'region' => "local",
|
301
|
-
'access_key_id' => 'YOUR_AWESOME_KEY',
|
302
|
-
'secret_access_key' => 'YOUR_AWESOME_SECRET',
|
303
|
-
}, []),
|
304
|
-
Fluent::Config::Element.new('buffer', 'tag', {}, [])
|
305
|
-
|
306
|
-
])
|
307
|
-
instance = driver(config).instance
|
308
|
-
|
309
|
-
assert_equal "https://search-opensearch.aws.example.com", instance.endpoint.url
|
310
|
-
assert_equal "local", instance.endpoint.region
|
311
|
-
assert_equal "YOUR_AWESOME_KEY", instance.endpoint.access_key_id
|
312
|
-
assert_equal "YOUR_AWESOME_SECRET", instance.endpoint.secret_access_key
|
313
|
-
assert_nil instance.endpoint.assume_role_arn
|
314
|
-
assert_nil instance.endpoint.ecs_container_credentials_relative_uri
|
315
|
-
assert_equal "fluentd", instance.endpoint.assume_role_session_name
|
316
|
-
assert_nil instance.endpoint.assume_role_web_identity_token_file
|
317
|
-
assert_nil instance.endpoint.sts_credentials_region
|
318
|
-
assert_equal :es, instance.endpoint.aws_service_name
|
319
|
-
end
|
320
|
-
|
321
|
-
data("OpenSearch Service" => [:es, 'es'],
|
322
|
-
"OpenSearch Serverless" => [:aoss, 'aoss'])
|
323
|
-
test 'configure endpoint section w/ aws_service_name' do |data|
|
324
|
-
expected, conf = data
|
325
|
-
config = Fluent::Config::Element.new(
|
326
|
-
'ROOT', '', {
|
327
|
-
'@type' => 'opensearch',
|
328
|
-
}, [
|
329
|
-
Fluent::Config::Element.new('endpoint', '', {
|
330
|
-
'url' => "https://search-opensearch.aws.example.com/",
|
331
|
-
'region' => "local",
|
332
|
-
'access_key_id' => 'YOUR_AWESOME_KEY',
|
333
|
-
'secret_access_key' => 'YOUR_AWESOME_SECRET',
|
334
|
-
'aws_service_name' => conf,
|
335
|
-
}, []),
|
336
|
-
Fluent::Config::Element.new('buffer', 'tag', {}, [])
|
337
|
-
|
338
|
-
])
|
339
|
-
instance = driver(config).instance
|
340
|
-
|
341
|
-
assert_equal "https://search-opensearch.aws.example.com", instance.endpoint.url
|
342
|
-
assert_equal "local", instance.endpoint.region
|
343
|
-
assert_equal "YOUR_AWESOME_KEY", instance.endpoint.access_key_id
|
344
|
-
assert_equal "YOUR_AWESOME_SECRET", instance.endpoint.secret_access_key
|
345
|
-
assert_nil instance.endpoint.assume_role_arn
|
346
|
-
assert_nil instance.endpoint.ecs_container_credentials_relative_uri
|
347
|
-
assert_equal "fluentd", instance.endpoint.assume_role_session_name
|
348
|
-
assert_nil instance.endpoint.assume_role_web_identity_token_file
|
349
|
-
assert_nil instance.endpoint.sts_credentials_region
|
350
|
-
assert_equal expected, instance.endpoint.aws_service_name
|
351
|
-
end
|
352
|
-
|
353
|
-
test 'configure compression' do
|
354
|
-
config = %{
|
355
|
-
compression_level best_compression
|
356
|
-
}
|
357
|
-
instance = driver(config).instance
|
358
|
-
|
359
|
-
assert_equal true, instance.compression
|
360
|
-
end
|
361
|
-
|
362
|
-
test 'check compression strategy' do
|
363
|
-
config = %{
|
364
|
-
compression_level best_speed
|
365
|
-
}
|
366
|
-
instance = driver(config).instance
|
367
|
-
|
368
|
-
assert_equal Zlib::BEST_SPEED, instance.compression_strategy
|
369
|
-
end
|
370
|
-
|
371
|
-
test 'check content-encoding header with compression' do
|
372
|
-
config = %{
|
373
|
-
compression_level best_compression
|
374
|
-
}
|
375
|
-
instance = driver(config).instance
|
376
|
-
|
377
|
-
assert_equal nil, instance.client.transport.transport.options[:transport_options][:headers]["Content-Encoding"]
|
378
|
-
|
379
|
-
stub_request(:post, "http://localhost:9200/_bulk").
|
380
|
-
to_return(status: 200, body: "", headers: {})
|
381
|
-
stub_opensearch_info
|
382
|
-
driver.run(default_tag: 'test') do
|
383
|
-
driver.feed(sample_record)
|
384
|
-
end
|
385
|
-
compressable = instance.compressable_connection
|
386
|
-
|
387
|
-
assert_equal "gzip", instance.client(nil, compressable).transport.transport.options[:transport_options][:headers]["Content-Encoding"]
|
388
|
-
end
|
389
|
-
|
390
|
-
test 'check compression option is passed to transport' do
|
391
|
-
config = %{
|
392
|
-
compression_level best_compression
|
393
|
-
}
|
394
|
-
instance = driver(config).instance
|
395
|
-
|
396
|
-
assert_equal false, instance.client.transport.transport.options[:compression]
|
397
|
-
|
398
|
-
stub_request(:post, "http://localhost:9200/_bulk").
|
399
|
-
to_return(status: 200, body: "", headers: {})
|
400
|
-
stub_opensearch_info
|
401
|
-
driver.run(default_tag: 'test') do
|
402
|
-
driver.feed(sample_record)
|
403
|
-
end
|
404
|
-
compressable = instance.compressable_connection
|
405
|
-
|
406
|
-
assert_equal true, instance.client(nil, compressable).transport.transport.options[:compression]
|
407
|
-
end
|
408
|
-
|
409
|
-
test 'invalid specification of times of retrying template installation' do
|
410
|
-
config = %{
|
411
|
-
max_retry_putting_template -3
|
412
|
-
}
|
413
|
-
assert_raise(Fluent::ConfigError) {
|
414
|
-
driver(config)
|
415
|
-
}
|
416
|
-
end
|
417
|
-
|
418
|
-
test 'invalid specification of times of retrying get es version' do
|
419
|
-
config = %{
|
420
|
-
max_retry_get_os_version -3
|
421
|
-
}
|
422
|
-
assert_raise(Fluent::ConfigError) {
|
423
|
-
driver(config)
|
424
|
-
}
|
425
|
-
end
|
426
|
-
|
427
|
-
sub_test_case 'Check client.info response' do
|
428
|
-
def create_driver(conf='', os_version=1, client_version="\"1.20\"")
|
429
|
-
# For request stub to detect compatibility.
|
430
|
-
@client_version ||= client_version
|
431
|
-
@default_opensearch_version ||= os_version
|
432
|
-
Fluent::Plugin::OpenSearchOutput.module_eval(<<-CODE)
|
433
|
-
def detect_os_major_version
|
434
|
-
@_os_info ||= client.info
|
435
|
-
begin
|
436
|
-
unless version = @_os_info.dig("version", "number")
|
437
|
-
version = @default_opensearch_version
|
438
|
-
end
|
439
|
-
rescue NoMethodError => e
|
440
|
-
log.warn "#{@_os_info} can not dig version information. Assuming OpenSearch #{@default_opensearch_version}", error: e
|
441
|
-
version = @default_opensearch_version
|
442
|
-
end
|
443
|
-
version.to_i
|
444
|
-
end
|
445
|
-
CODE
|
446
|
-
|
447
|
-
Fluent::Plugin::OpenSearchOutput.module_eval(<<-CODE)
|
448
|
-
def client_library_version
|
449
|
-
#{@client_version}
|
450
|
-
end
|
451
|
-
CODE
|
452
|
-
@driver ||= Fluent::Test::Driver::Output.new(Fluent::Plugin::OpenSearchOutput) {
|
453
|
-
# v0.12's test driver assume format definition. This simulates ObjectBufferedOutput format
|
454
|
-
if !defined?(Fluent::Plugin::Output)
|
455
|
-
def format(tag, time, record)
|
456
|
-
[time, record].to_msgpack
|
457
|
-
end
|
458
|
-
end
|
459
|
-
}.configure(conf)
|
460
|
-
end
|
461
|
-
|
462
|
-
def stub_opensearch_info_bad(url="http://localhost:9200/", version="6.4.2")
|
463
|
-
body ="{\"version\":{\"number\":\"#{version}\",\"build_flavor\":\"default\"},\"tagline\":\"You Know, for Search\"}"
|
464
|
-
stub_request(:get, url).to_return({:status => 200, :body => body, :headers => { 'Content-Type' => 'text/plain' } })
|
465
|
-
end
|
466
|
-
|
467
|
-
test 'handle invalid client.info' do
|
468
|
-
stub_opensearch_info_bad("https://logs.fluentd.com:24225/es//", "7.7.1")
|
469
|
-
config = %{
|
470
|
-
host logs.fluentd.com
|
471
|
-
port 24225
|
472
|
-
scheme https
|
473
|
-
path /es/
|
474
|
-
user john
|
475
|
-
password doe
|
476
|
-
default_elasticsearch_version 7
|
477
|
-
scheme https
|
478
|
-
@log_level info
|
479
|
-
}
|
480
|
-
assert_raise(NoMethodError) do
|
481
|
-
_d = create_driver(config, 1, "\"1.2.2\"")
|
482
|
-
end
|
483
|
-
end
|
484
|
-
end
|
485
|
-
|
486
|
-
sub_test_case 'Check TLS handshake stuck warning log' do
|
487
|
-
test 'warning TLS log' do
|
488
|
-
config = %{
|
489
|
-
scheme https
|
490
|
-
http_backend_excon_nonblock false
|
491
|
-
ssl_version TLSv1_2
|
492
|
-
@log_level info
|
493
|
-
}
|
494
|
-
driver(config)
|
495
|
-
logs = driver.logs
|
496
|
-
assert_logs_include(logs, /TLS handshake will be stucked with block connection.\n Consider to set `http_backend_excon_nonblock` as true\n/)
|
497
|
-
end
|
498
|
-
end
|
499
|
-
|
500
|
-
test 'Detected insecure security' do
|
501
|
-
config = %{
|
502
|
-
ssl_version TLSv1_1
|
503
|
-
@log_level warn
|
504
|
-
scheme https
|
505
|
-
}
|
506
|
-
driver(config, 6)
|
507
|
-
logs = driver.logs
|
508
|
-
assert_logs_include(logs, /Detected OpenSearch 1.x or above and enabled insecure security/, 1)
|
509
|
-
end
|
510
|
-
|
511
|
-
test 'Detected Elasticsearch 7 and secure security' do
|
512
|
-
config = %{
|
513
|
-
ssl_version TLSv1_2
|
514
|
-
@log_level warn
|
515
|
-
scheme https
|
516
|
-
}
|
517
|
-
driver(config, 7)
|
518
|
-
logs = driver.logs
|
519
|
-
assert_logs_include(logs, /Detected ES 6.x or above and enabled insecure security/, 0)
|
520
|
-
end
|
521
|
-
|
522
|
-
test 'Pass OpenSearch and client library are same' do
|
523
|
-
config = %{
|
524
|
-
@log_level warn
|
525
|
-
validate_client_version true
|
526
|
-
}
|
527
|
-
assert_nothing_raised do
|
528
|
-
driver(config, 1, "\"1.2.2\"")
|
529
|
-
end
|
530
|
-
end
|
531
|
-
|
532
|
-
test 'Detected Elasticsearch and client library mismatch' do
|
533
|
-
config = %{
|
534
|
-
@log_level warn
|
535
|
-
validate_client_version true
|
536
|
-
}
|
537
|
-
assert_raise_message(/Detected OpenSearch 1 but you use OpenSearch client 2.0/) do
|
538
|
-
driver(config, 1, "\"2.0.0\"")
|
539
|
-
end
|
540
|
-
end
|
541
|
-
|
542
|
-
sub_test_case "placeholder substitution needed?" do
|
543
|
-
data("host placeholder" => ["host", "host-${tag}.google.com"],
|
544
|
-
"index_name_placeholder" => ["index_name", "logstash-${tag}"],
|
545
|
-
"template_name_placeholder" => ["template_name", "logstash-${tag}"],
|
546
|
-
"customize_template" => ["customize_template", '{"<<TAG>>":"${tag}"}'],
|
547
|
-
"logstash_prefix_placeholder" => ["logstash_prefix", "fluentd-${tag}"],
|
548
|
-
"application_name_placeholder" => ["application_name", "fluentd-${tag}"],
|
549
|
-
)
|
550
|
-
test 'tag placeholder' do |data|
|
551
|
-
param, value = data
|
552
|
-
config = Fluent::Config::Element.new(
|
553
|
-
'ROOT', '', {
|
554
|
-
'@type' => 'opensearch',
|
555
|
-
param => value
|
556
|
-
}, [
|
557
|
-
Fluent::Config::Element.new('buffer', 'tag', {}, [])
|
558
|
-
])
|
559
|
-
driver(config)
|
560
|
-
|
561
|
-
assert_true driver.instance.placeholder_substitution_needed_for_template?
|
562
|
-
end
|
563
|
-
|
564
|
-
|
565
|
-
data("host placeholder" => ["host", "host-%Y%m%d.google.com"],
|
566
|
-
"index_name_placeholder" => ["index_name", "logstash-%Y%m%d"],
|
567
|
-
"template_name_placeholder" => ["template_name", "logstash-%Y%m%d"],
|
568
|
-
"customize_template" => ["customize_template", '{"<<TAG>>":"fluentd-%Y%m%d"}'],
|
569
|
-
"logstash_prefix_placeholder" => ["logstash_prefix", "fluentd-%Y%m%d"],
|
570
|
-
"application_name_placeholder" => ["application_name", "fluentd-%Y%m%d"],
|
571
|
-
)
|
572
|
-
test 'time placeholder' do |data|
|
573
|
-
param, value = data
|
574
|
-
config = Fluent::Config::Element.new(
|
575
|
-
'ROOT', '', {
|
576
|
-
'@type' => 'opensearch',
|
577
|
-
param => value
|
578
|
-
}, [
|
579
|
-
Fluent::Config::Element.new('buffer', 'time', {
|
580
|
-
'timekey' => '1d'
|
581
|
-
}, [])
|
582
|
-
])
|
583
|
-
driver(config)
|
584
|
-
|
585
|
-
assert_true driver.instance.placeholder_substitution_needed_for_template?
|
586
|
-
end
|
587
|
-
|
588
|
-
data("host placeholder" => ["host", "host-${mykey}.google.com"],
|
589
|
-
"index_name_placeholder" => ["index_name", "logstash-${mykey}"],
|
590
|
-
"template_name_placeholder" => ["template_name", "logstash-${mykey}"],
|
591
|
-
"customize_template" => ["customize_template", '{"<<TAG>>":"${mykey}"}'],
|
592
|
-
"logstash_prefix_placeholder" => ["logstash_prefix", "fluentd-${mykey}"],
|
593
|
-
"logstash_dateformat_placeholder" => ["logstash_dateformat", "${mykey}"],
|
594
|
-
"application_name_placeholder" => ["application_name", "fluentd-${mykey}"],
|
595
|
-
)
|
596
|
-
test 'custom placeholder' do |data|
|
597
|
-
param, value = data
|
598
|
-
config = Fluent::Config::Element.new(
|
599
|
-
'ROOT', '', {
|
600
|
-
'@type' => 'elasticsearch',
|
601
|
-
param => value
|
602
|
-
}, [
|
603
|
-
Fluent::Config::Element.new('buffer', 'mykey', {
|
604
|
-
'chunk_keys' => 'mykey',
|
605
|
-
'timekey' => '1d',
|
606
|
-
}, [])
|
607
|
-
])
|
608
|
-
driver(config)
|
609
|
-
|
610
|
-
assert_true driver.instance.placeholder_substitution_needed_for_template?
|
611
|
-
end
|
612
|
-
|
613
|
-
data("host placeholder" => ["host", "host-${tag}.google.com"],
|
614
|
-
"index_name_placeholder" => ["index_name", "logstash-${es_index}-%Y%m%d"],
|
615
|
-
"template_name_placeholder" => ["template_name", "logstash-${tag}-%Y%m%d"],
|
616
|
-
"customize_template" => ["customize_template", '{"<<TAG>>":"${os_index}"}'],
|
617
|
-
"logstash_prefix_placeholder" => ["logstash_prefix", "fluentd-${os_index}-%Y%m%d"],
|
618
|
-
"logstash_dateformat_placeholder" => ["logstash_dateformat", "${os_index}"],
|
619
|
-
"application_name_placeholder" => ["application_name", "fluentd-${tag}-${os_index}-%Y%m%d"],
|
620
|
-
)
|
621
|
-
test 'mixed placeholder' do |data|
|
622
|
-
param, value = data
|
623
|
-
config = Fluent::Config::Element.new(
|
624
|
-
'ROOT', '', {
|
625
|
-
'@type' => 'opensearch',
|
626
|
-
param => value
|
627
|
-
}, [
|
628
|
-
Fluent::Config::Element.new('buffer', 'tag,time,os_index', {
|
629
|
-
'chunk_keys' => 'os_index',
|
630
|
-
'timekey' => '1d',
|
631
|
-
}, [])
|
632
|
-
])
|
633
|
-
driver(config)
|
634
|
-
|
635
|
-
assert_true driver.instance.placeholder_substitution_needed_for_template?
|
636
|
-
end
|
637
|
-
end
|
638
|
-
|
639
|
-
sub_test_case 'chunk_keys requirement' do
|
640
|
-
test 'tag in chunk_keys' do
|
641
|
-
assert_nothing_raised do
|
642
|
-
driver(Fluent::Config::Element.new(
|
643
|
-
'ROOT', '', {
|
644
|
-
'@type' => 'opensearch',
|
645
|
-
'host' => 'log.google.com',
|
646
|
-
'port' => 777,
|
647
|
-
'scheme' => 'https',
|
648
|
-
'path' => '/os/',
|
649
|
-
'user' => 'john',
|
650
|
-
'password' => 'doe',
|
651
|
-
}, [
|
652
|
-
Fluent::Config::Element.new('buffer', 'tag', {
|
653
|
-
'chunk_keys' => 'tag'
|
654
|
-
}, [])
|
655
|
-
]
|
656
|
-
))
|
657
|
-
end
|
658
|
-
end
|
659
|
-
|
660
|
-
test '_index in chunk_keys' do
|
661
|
-
assert_nothing_raised do
|
662
|
-
driver(Fluent::Config::Element.new(
|
663
|
-
'ROOT', '', {
|
664
|
-
'@type' => 'opensearch',
|
665
|
-
'host' => 'log.google.com',
|
666
|
-
'port' => 777,
|
667
|
-
'scheme' => 'https',
|
668
|
-
'path' => '/os/',
|
669
|
-
'user' => 'john',
|
670
|
-
'password' => 'doe',
|
671
|
-
}, [
|
672
|
-
Fluent::Config::Element.new('buffer', '_index', {
|
673
|
-
'chunk_keys' => '_index'
|
674
|
-
}, [])
|
675
|
-
]
|
676
|
-
))
|
677
|
-
end
|
678
|
-
end
|
679
|
-
|
680
|
-
test 'lack of tag and _index in chunk_keys' do
|
681
|
-
assert_raise_message(/'tag' or '_index' in chunk_keys is required./) do
|
682
|
-
driver(Fluent::Config::Element.new(
|
683
|
-
'ROOT', '', {
|
684
|
-
'@type' => 'opensearch',
|
685
|
-
'host' => 'log.google.com',
|
686
|
-
'port' => 777,
|
687
|
-
'scheme' => 'https',
|
688
|
-
'path' => '/os/',
|
689
|
-
'user' => 'john',
|
690
|
-
'password' => 'doe',
|
691
|
-
}, [
|
692
|
-
Fluent::Config::Element.new('buffer', 'mykey', {
|
693
|
-
'chunk_keys' => 'mykey'
|
694
|
-
}, [])
|
695
|
-
]
|
696
|
-
))
|
697
|
-
end
|
698
|
-
end
|
699
|
-
end
|
700
|
-
|
701
|
-
test 'Detected exclusive features which are host placeholder, template installation, and verify OpenSearch version at startup' do
|
702
|
-
cwd = File.dirname(__FILE__)
|
703
|
-
template_file = File.join(cwd, 'test_template.json')
|
704
|
-
|
705
|
-
assert_raise_message(/host placeholder, template installation, and verify OpenSearch version at startup are exclusive feature at same time./) do
|
706
|
-
config = %{
|
707
|
-
host logs-${tag}.google.com
|
708
|
-
port 777
|
709
|
-
scheme https
|
710
|
-
path /os/
|
711
|
-
user john
|
712
|
-
password doe
|
713
|
-
template_name logstash
|
714
|
-
template_file #{template_file}
|
715
|
-
verify_os_version_at_startup true
|
716
|
-
default_opensearch_version 1
|
717
|
-
}
|
718
|
-
driver(config)
|
719
|
-
end
|
720
|
-
end
|
721
|
-
|
722
|
-
class GetOpenSearchVersionTest < self
|
723
|
-
def create_driver(conf='', client_version="\"1.0\"")
|
724
|
-
# For request stub to detect compatibility.
|
725
|
-
@client_version ||= client_version
|
726
|
-
# Ensure original implementation existence.
|
727
|
-
Fluent::Plugin::OpenSearchOutput.module_eval(<<-CODE)
|
728
|
-
def detect_os_major_version
|
729
|
-
@_os_info ||= client.info
|
730
|
-
unless version = @_os_info.dig("version", "number")
|
731
|
-
version = @default_opensearch_version
|
732
|
-
end
|
733
|
-
version.to_i
|
734
|
-
end
|
735
|
-
CODE
|
736
|
-
Fluent::Plugin::OpenSearchOutput.module_eval(<<-CODE)
|
737
|
-
def client_library_version
|
738
|
-
#{@client_version}
|
739
|
-
end
|
740
|
-
CODE
|
741
|
-
Fluent::Test::Driver::Output.new(Fluent::Plugin::OpenSearchOutput).configure(conf)
|
742
|
-
end
|
743
|
-
|
744
|
-
def test_retry_get_os_version
|
745
|
-
config = %{
|
746
|
-
host logs.google.com
|
747
|
-
port 778
|
748
|
-
scheme https
|
749
|
-
path /os/
|
750
|
-
user john
|
751
|
-
password doe
|
752
|
-
verify_os_version_at_startup true
|
753
|
-
max_retry_get_os_version 3
|
754
|
-
}
|
755
|
-
|
756
|
-
connection_resets = 0
|
757
|
-
stub_request(:get, "https://logs.google.com:778/os//").
|
758
|
-
with(basic_auth: ['john', 'doe']) do |req|
|
759
|
-
connection_resets += 1
|
760
|
-
raise Faraday::ConnectionFailed, "Test message"
|
761
|
-
end
|
762
|
-
|
763
|
-
assert_raise(Fluent::Plugin::OpenSearchError::RetryableOperationExhaustedFailure) do
|
764
|
-
create_driver(config)
|
765
|
-
end
|
766
|
-
|
767
|
-
assert_equal(4, connection_resets)
|
768
|
-
end
|
769
|
-
end
|
770
|
-
|
771
|
-
class GetOpenSearchVersionWithFallbackTest < self
|
772
|
-
def create_driver(conf='', client_version="\"1.2\"")
|
773
|
-
# For request stub to detect compatibility.
|
774
|
-
@client_version ||= client_version
|
775
|
-
# Ensure original implementation existence.
|
776
|
-
Fluent::Plugin::OpenSearchOutput.module_eval(<<-CODE)
|
777
|
-
def detect_os_major_version
|
778
|
-
@_os_info ||= client.info
|
779
|
-
unless version = @_os_info.dig("version", "number")
|
780
|
-
version = @default_opensearch_version
|
781
|
-
end
|
782
|
-
version.to_i
|
783
|
-
end
|
784
|
-
CODE
|
785
|
-
Fluent::Plugin::OpenSearchOutput.module_eval(<<-CODE)
|
786
|
-
def client_library_version
|
787
|
-
#{@client_version}
|
788
|
-
end
|
789
|
-
CODE
|
790
|
-
Fluent::Test::Driver::Output.new(Fluent::Plugin::OpenSearchOutput).configure(conf)
|
791
|
-
end
|
792
|
-
|
793
|
-
data("OpenSearch 1" => ["1.2", 1])
|
794
|
-
def test_retry_get_os_version_without_fail_on_detecting_os_version_retry_exceeded(data)
|
795
|
-
client_version, os_major_version = data
|
796
|
-
config = %{
|
797
|
-
host logs.google.com
|
798
|
-
port 778
|
799
|
-
scheme https
|
800
|
-
path /os/
|
801
|
-
user john
|
802
|
-
password doe
|
803
|
-
verify_os_version_at_startup true
|
804
|
-
max_retry_get_os_version 2
|
805
|
-
fail_on_detecting_os_version_retry_exceed false
|
806
|
-
default_opensearch_version #{os_major_version}
|
807
|
-
@log_level info
|
808
|
-
}
|
809
|
-
|
810
|
-
connection_resets = 0
|
811
|
-
stub_request(:get, "https://logs.google.com:778/os//").
|
812
|
-
with(basic_auth: ['john', 'doe']) do |req|
|
813
|
-
connection_resets += 1
|
814
|
-
raise Faraday::ConnectionFailed, "Test message"
|
815
|
-
end
|
816
|
-
|
817
|
-
d = create_driver(config, client_version)
|
818
|
-
|
819
|
-
assert_equal os_major_version, d.instance.default_opensearch_version
|
820
|
-
assert_equal 3, connection_resets
|
821
|
-
assert_equal os_major_version, d.instance.instance_variable_get(:@last_seen_major_version)
|
822
|
-
end
|
823
|
-
end
|
824
|
-
|
825
|
-
data("legacy_template" => [true, "_template"],
|
826
|
-
"new_template" => [false, "_index_template"])
|
827
|
-
def test_template_already_present(data)
|
828
|
-
use_legacy_template_flag, endpoint = data
|
829
|
-
config = %{
|
830
|
-
host logs.google.com
|
831
|
-
port 777
|
832
|
-
scheme https
|
833
|
-
path /os/
|
834
|
-
user john
|
835
|
-
password doe
|
836
|
-
template_name logstash
|
837
|
-
template_file /abc123
|
838
|
-
use_legacy_template #{use_legacy_template_flag}
|
839
|
-
}
|
840
|
-
|
841
|
-
# connection start
|
842
|
-
stub_request(:head, "https://logs.google.com:777/os//").
|
843
|
-
with(basic_auth: ['john', 'doe']).
|
844
|
-
to_return(:status => 200, :body => "", :headers => {})
|
845
|
-
# check if template exists
|
846
|
-
stub_request(:get, "https://logs.google.com:777/os//#{endpoint}/logstash").
|
847
|
-
with(basic_auth: ['john', 'doe']).
|
848
|
-
to_return(:status => 200, :body => "", :headers => {})
|
849
|
-
stub_opensearch_info("https://logs.google.com:777/os//")
|
850
|
-
|
851
|
-
driver(config)
|
852
|
-
|
853
|
-
assert_not_requested(:put, "https://logs.google.com:777/os//#{endpoint}/logstash")
|
854
|
-
end
|
855
|
-
|
856
|
-
data("legacy_template" => [true, "_template"],
|
857
|
-
"new_template" => [false, "_index_template"])
|
858
|
-
def test_template_create(data)
|
859
|
-
use_legacy_template_flag, endpoint = data
|
860
|
-
cwd = File.dirname(__FILE__)
|
861
|
-
template_file = if use_legacy_template_flag
|
862
|
-
File.join(cwd, 'test_template.json')
|
863
|
-
else
|
864
|
-
File.join(cwd, 'test_index_template.json')
|
865
|
-
end
|
866
|
-
|
867
|
-
config = %{
|
868
|
-
host logs.google.com
|
869
|
-
port 777
|
870
|
-
scheme https
|
871
|
-
path /os/
|
872
|
-
user john
|
873
|
-
password doe
|
874
|
-
template_name logstash
|
875
|
-
template_file #{template_file}
|
876
|
-
use_legacy_template #{use_legacy_template_flag}
|
877
|
-
}
|
878
|
-
|
879
|
-
# connection start
|
880
|
-
stub_request(:head, "https://logs.google.com:777/os//").
|
881
|
-
with(basic_auth: ['john', 'doe']).
|
882
|
-
to_return(:status => 200, :body => "", :headers => {})
|
883
|
-
# check if template exists
|
884
|
-
stub_request(:get, "https://logs.google.com:777/os//#{endpoint}/logstash").
|
885
|
-
with(basic_auth: ['john', 'doe']).
|
886
|
-
to_return(:status => 404, :body => "", :headers => {})
|
887
|
-
# creation
|
888
|
-
stub_request(:put, "https://logs.google.com:777/os//#{endpoint}/logstash").
|
889
|
-
with(basic_auth: ['john', 'doe']).
|
890
|
-
to_return(:status => 200, :body => "", :headers => {})
|
891
|
-
stub_opensearch_info("https://logs.google.com:777/os//")
|
892
|
-
|
893
|
-
driver(config)
|
894
|
-
|
895
|
-
assert_requested(:put, "https://logs.google.com:777/os//#{endpoint}/logstash", times: 1)
|
896
|
-
end
|
897
|
-
|
898
|
-
data("legacy_template" => [true, "_template"],
|
899
|
-
"new_template" => [false, "_index_template"])
|
900
|
-
def test_custom_template_create(data)
|
901
|
-
use_legacy_template_flag, endpoint = data
|
902
|
-
cwd = File.dirname(__FILE__)
|
903
|
-
template_file = if use_legacy_template_flag
|
904
|
-
File.join(cwd, 'test_alias_template.json')
|
905
|
-
else
|
906
|
-
File.join(cwd, 'test_index_alias_template.json')
|
907
|
-
end
|
908
|
-
|
909
|
-
config = %{
|
910
|
-
host logs.google.com
|
911
|
-
port 777
|
912
|
-
scheme https
|
913
|
-
path /os/
|
914
|
-
user john
|
915
|
-
password doe
|
916
|
-
template_name myapp_alias_template
|
917
|
-
template_file #{template_file}
|
918
|
-
customize_template {"--appid--": "myapp-logs","--index_prefix--":"mylogs"}
|
919
|
-
use_legacy_template #{use_legacy_template_flag}
|
920
|
-
}
|
921
|
-
|
922
|
-
# connection start
|
923
|
-
stub_request(:head, "https://logs.google.com:777/os//").
|
924
|
-
with(basic_auth: ['john', 'doe']).
|
925
|
-
to_return(:status => 200, :body => "", :headers => {})
|
926
|
-
# check if template exists
|
927
|
-
stub_request(:get, "https://logs.google.com:777/os//#{endpoint}/myapp_alias_template").
|
928
|
-
with(basic_auth: ['john', 'doe']).
|
929
|
-
to_return(:status => 404, :body => "", :headers => {})
|
930
|
-
# creation
|
931
|
-
stub_request(:put, "https://logs.google.com:777/os//#{endpoint}/myapp_alias_template").
|
932
|
-
with(basic_auth: ['john', 'doe']).
|
933
|
-
to_return(:status => 200, :body => "", :headers => {})
|
934
|
-
stub_opensearch_info("https://logs.google.com:777/os//")
|
935
|
-
|
936
|
-
driver(config)
|
937
|
-
|
938
|
-
assert_requested(:put, "https://logs.google.com:777/os//#{endpoint}/myapp_alias_template", times: 1)
|
939
|
-
end
|
940
|
-
|
941
|
-
data("legacy_template" => [true, "_template"],
|
942
|
-
"new_template" => [false, "_index_template"])
|
943
|
-
def test_custom_template_create_with_customize_template_related_placeholders(data)
|
944
|
-
use_legacy_template_flag, endpoint = data
|
945
|
-
cwd = File.dirname(__FILE__)
|
946
|
-
template_file = if use_legacy_template_flag
|
947
|
-
File.join(cwd, 'test_alias_template.json')
|
948
|
-
else
|
949
|
-
File.join(cwd, 'test_index_alias_template.json')
|
950
|
-
end
|
951
|
-
|
952
|
-
config = %{
|
953
|
-
host logs.google.com
|
954
|
-
port 777
|
955
|
-
scheme https
|
956
|
-
path /os/
|
957
|
-
user john
|
958
|
-
password doe
|
959
|
-
template_name myapp_alias_template-${tag}
|
960
|
-
template_file #{template_file}
|
961
|
-
customize_template {"--appid--": "${tag}-logs","--index_prefix--":"${tag}"}
|
962
|
-
use_legacy_template #{use_legacy_template_flag}
|
963
|
-
}
|
964
|
-
|
965
|
-
# connection start
|
966
|
-
stub_request(:head, "https://logs.google.com:777/os//").
|
967
|
-
with(basic_auth: ['john', 'doe']).
|
968
|
-
to_return(:status => 200, :body => "", :headers => {})
|
969
|
-
# check if template exists
|
970
|
-
stub_request(:get, "https://logs.google.com:777/os//#{endpoint}/myapp_alias_template-test.template").
|
971
|
-
with(basic_auth: ['john', 'doe']).
|
972
|
-
to_return(:status => 404, :body => "", :headers => {})
|
973
|
-
# creation
|
974
|
-
stub_request(:put, "https://logs.google.com:777/os//#{endpoint}/myapp_alias_template-test.template").
|
975
|
-
with(basic_auth: ['john', 'doe']).
|
976
|
-
to_return(:status => 200, :body => "", :headers => {})
|
977
|
-
|
978
|
-
stub_request(:put, "https://logs.google.com:777/os//%3Cfluentd-test-default-000001%3E").
|
979
|
-
to_return(status: 200, body: "", headers: {})
|
980
|
-
|
981
|
-
driver(config)
|
982
|
-
|
983
|
-
stub_opensearch("https://logs.google.com:777/os//_bulk")
|
984
|
-
stub_opensearch_info("https://logs.google.com:777/os//")
|
985
|
-
driver.run(default_tag: 'test.template') do
|
986
|
-
driver.feed(sample_record)
|
987
|
-
end
|
988
|
-
|
989
|
-
assert_requested(:put, "https://logs.google.com:777/os//#{endpoint}/myapp_alias_template-test.template", times: 1)
|
990
|
-
end
|
991
|
-
|
992
|
-
data("legacy_template" => [true, "_template"],
|
993
|
-
"new_template" => [false, "_index_template"])
|
994
|
-
def test_custom_template_installation_for_host_placeholder(data)
|
995
|
-
use_legacy_template_flag, endpoint = data
|
996
|
-
cwd = File.dirname(__FILE__)
|
997
|
-
template_file = if use_legacy_template_flag
|
998
|
-
File.join(cwd, 'test_template.json')
|
999
|
-
else
|
1000
|
-
File.join(cwd, 'test_index_template.json')
|
1001
|
-
end
|
1002
|
-
|
1003
|
-
config = %{
|
1004
|
-
host logs-${tag}.google.com
|
1005
|
-
port 777
|
1006
|
-
scheme https
|
1007
|
-
path /os/
|
1008
|
-
user john
|
1009
|
-
password doe
|
1010
|
-
template_name logstash
|
1011
|
-
template_file #{template_file}
|
1012
|
-
verify_os_version_at_startup false
|
1013
|
-
default_elasticsearch_version 6
|
1014
|
-
customize_template {"--appid--": "myapp-logs","--index_prefix--":"mylogs"}
|
1015
|
-
use_legacy_template #{use_legacy_template_flag}
|
1016
|
-
}
|
1017
|
-
|
1018
|
-
# connection start
|
1019
|
-
stub_request(:head, "https://logs-test.google.com:777/os//").
|
1020
|
-
with(basic_auth: ['john', 'doe']).
|
1021
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1022
|
-
# check if template exists
|
1023
|
-
stub_request(:get, "https://logs-test.google.com:777/os//#{endpoint}/logstash").
|
1024
|
-
with(basic_auth: ['john', 'doe']).
|
1025
|
-
to_return(:status => 404, :body => "", :headers => {})
|
1026
|
-
stub_request(:put, "https://logs-test.google.com:777/os//#{endpoint}/logstash").
|
1027
|
-
with(basic_auth: ['john', 'doe']).
|
1028
|
-
to_return(status: 200, body: "", headers: {})
|
1029
|
-
|
1030
|
-
driver(config)
|
1031
|
-
|
1032
|
-
stub_opensearch("https://logs-test.google.com:777/os//_bulk")
|
1033
|
-
stub_opensearch_info("https://logs-test.google.com:777/os//")
|
1034
|
-
driver.run(default_tag: 'test') do
|
1035
|
-
driver.feed(sample_record)
|
1036
|
-
end
|
1037
|
-
end
|
1038
|
-
|
1039
|
-
data("legacy_template" => [true, "_template"],
|
1040
|
-
"new_template" => [false, "_index_template"])
|
1041
|
-
def test_template_overwrite(data)
|
1042
|
-
use_legacy_template_flag, endpoint = data
|
1043
|
-
cwd = File.dirname(__FILE__)
|
1044
|
-
template_file = if use_legacy_template_flag
|
1045
|
-
File.join(cwd, 'test_template.json')
|
1046
|
-
else
|
1047
|
-
File.join(cwd, 'test_index_template.json')
|
1048
|
-
end
|
1049
|
-
|
1050
|
-
config = %{
|
1051
|
-
host logs.google.com
|
1052
|
-
port 777
|
1053
|
-
scheme https
|
1054
|
-
path /os/
|
1055
|
-
user john
|
1056
|
-
password doe
|
1057
|
-
template_name logstash
|
1058
|
-
template_file #{template_file}
|
1059
|
-
template_overwrite true
|
1060
|
-
use_legacy_template #{use_legacy_template_flag}
|
1061
|
-
}
|
1062
|
-
|
1063
|
-
# connection start
|
1064
|
-
stub_request(:head, "https://logs.google.com:777/os//").
|
1065
|
-
with(basic_auth: ['john', 'doe']).
|
1066
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1067
|
-
# check if template exists
|
1068
|
-
stub_request(:get, "https://logs.google.com:777/os//#{endpoint}/logstash").
|
1069
|
-
with(basic_auth: ['john', 'doe']).
|
1070
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1071
|
-
# creation
|
1072
|
-
stub_request(:put, "https://logs.google.com:777/os//#{endpoint}/logstash").
|
1073
|
-
with(basic_auth: ['john', 'doe']).
|
1074
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1075
|
-
stub_opensearch_info("https://logs.google.com:777/os//")
|
1076
|
-
|
1077
|
-
driver(config)
|
1078
|
-
|
1079
|
-
assert_requested(:put, "https://logs.google.com:777/os//#{endpoint}/logstash", times: 1)
|
1080
|
-
end
|
1081
|
-
|
1082
|
-
data("legacy_template" => [true, "_template"],
|
1083
|
-
"new_template" => [false, "_index_template"])
|
1084
|
-
def test_custom_template_overwrite(data)
|
1085
|
-
use_legacy_template_flag, endpoint = data
|
1086
|
-
cwd = File.dirname(__FILE__)
|
1087
|
-
template_file = if use_legacy_template_flag
|
1088
|
-
File.join(cwd, 'test_template.json')
|
1089
|
-
else
|
1090
|
-
File.join(cwd, 'test_index_template.json')
|
1091
|
-
end
|
1092
|
-
|
1093
|
-
config = %{
|
1094
|
-
host logs.google.com
|
1095
|
-
port 777
|
1096
|
-
scheme https
|
1097
|
-
path /os/
|
1098
|
-
user john
|
1099
|
-
password doe
|
1100
|
-
template_name myapp_alias_template
|
1101
|
-
template_file #{template_file}
|
1102
|
-
template_overwrite true
|
1103
|
-
customize_template {"--appid--": "myapp-logs","--index_prefix--":"mylogs"}
|
1104
|
-
use_legacy_template #{use_legacy_template_flag}
|
1105
|
-
}
|
1106
|
-
|
1107
|
-
# connection start
|
1108
|
-
stub_request(:head, "https://logs.google.com:777/os//").
|
1109
|
-
with(basic_auth: ['john', 'doe']).
|
1110
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1111
|
-
# check if template exists
|
1112
|
-
stub_request(:get, "https://logs.google.com:777/os//#{endpoint}/myapp_alias_template").
|
1113
|
-
with(basic_auth: ['john', 'doe']).
|
1114
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1115
|
-
# creation
|
1116
|
-
stub_request(:put, "https://logs.google.com:777/os//#{endpoint}/myapp_alias_template").
|
1117
|
-
with(basic_auth: ['john', 'doe']).
|
1118
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1119
|
-
stub_opensearch_info("https://logs.google.com:777/os//")
|
1120
|
-
|
1121
|
-
driver(config)
|
1122
|
-
|
1123
|
-
assert_requested(:put, "https://logs.google.com:777/os//#{endpoint}/myapp_alias_template", times: 1)
|
1124
|
-
end
|
1125
|
-
|
1126
|
-
def test_template_create_invalid_filename
|
1127
|
-
config = %{
|
1128
|
-
host logs.google.com
|
1129
|
-
port 777
|
1130
|
-
scheme https
|
1131
|
-
path /os/
|
1132
|
-
user john
|
1133
|
-
password doe
|
1134
|
-
template_name logstash
|
1135
|
-
template_file /abc123
|
1136
|
-
}
|
1137
|
-
|
1138
|
-
# connection start
|
1139
|
-
stub_request(:head, "https://logs.google.com:777/os//").
|
1140
|
-
with(basic_auth: ['john', 'doe']).
|
1141
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1142
|
-
# check if template exists
|
1143
|
-
stub_request(:get, "https://logs.google.com:777/os//_template/logstash").
|
1144
|
-
with(basic_auth: ['john', 'doe']).
|
1145
|
-
to_return(:status => 404, :body => "", :headers => {})
|
1146
|
-
stub_opensearch_info("https://logs.google.com:777/os//")
|
1147
|
-
|
1148
|
-
assert_raise(RuntimeError) {
|
1149
|
-
driver(config)
|
1150
|
-
}
|
1151
|
-
end
|
1152
|
-
|
1153
|
-
data("legacy_template" => [true, "_template"],
|
1154
|
-
"new_template" => [false, "_index_template"])
|
1155
|
-
def test_template_create_for_host_placeholder(data)
|
1156
|
-
use_legacy_template_flag, endpoint = data
|
1157
|
-
cwd = File.dirname(__FILE__)
|
1158
|
-
template_file = if use_legacy_template_flag
|
1159
|
-
File.join(cwd, 'test_template.json')
|
1160
|
-
else
|
1161
|
-
File.join(cwd, 'test_index_template.json')
|
1162
|
-
end
|
1163
|
-
|
1164
|
-
config = %{
|
1165
|
-
host logs-${tag}.google.com
|
1166
|
-
port 777
|
1167
|
-
scheme https
|
1168
|
-
path /os/
|
1169
|
-
user john
|
1170
|
-
password doe
|
1171
|
-
template_name logstash
|
1172
|
-
template_file #{template_file}
|
1173
|
-
verify_os_version_at_startup false
|
1174
|
-
default_elasticsearch_version 6
|
1175
|
-
use_legacy_template #{use_legacy_template_flag}
|
1176
|
-
}
|
1177
|
-
|
1178
|
-
# connection start
|
1179
|
-
stub_request(:head, "https://logs-test.google.com:777/os//").
|
1180
|
-
with(basic_auth: ['john', 'doe']).
|
1181
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1182
|
-
# check if template exists
|
1183
|
-
stub_request(:get, "https://logs-test.google.com:777/os//#{endpoint}/logstash").
|
1184
|
-
with(basic_auth: ['john', 'doe']).
|
1185
|
-
to_return(:status => 404, :body => "", :headers => {})
|
1186
|
-
stub_request(:put, "https://logs-test.google.com:777/os//#{endpoint}/logstash").
|
1187
|
-
with(basic_auth: ['john', 'doe']).
|
1188
|
-
to_return(status: 200, body: "", headers: {})
|
1189
|
-
stub_request(:post, "https://logs-test.google.com:777/os//_bulk").
|
1190
|
-
with(basic_auth: ['john', 'doe']).
|
1191
|
-
to_return(status: 200, body: "", headers: {})
|
1192
|
-
|
1193
|
-
driver(config)
|
1194
|
-
|
1195
|
-
stub_opensearch("https://logs-test.google.com:777/os//_bulk")
|
1196
|
-
stub_opensearch_info("https://logs-test.google.com:777/os//")
|
1197
|
-
driver.run(default_tag: 'test') do
|
1198
|
-
driver.feed(sample_record)
|
1199
|
-
end
|
1200
|
-
end
|
1201
|
-
|
1202
|
-
data("legacy_template" => [true, "_template"],
|
1203
|
-
"new_template" => [false, "_index_template"])
|
1204
|
-
def test_template_retry_install_fails(data)
|
1205
|
-
use_legacy_template_flag, endpoint = data
|
1206
|
-
cwd = File.dirname(__FILE__)
|
1207
|
-
template_file = if use_legacy_template_flag
|
1208
|
-
File.join(cwd, 'test_template.json')
|
1209
|
-
else
|
1210
|
-
File.join(cwd, 'test_index_template.json')
|
1211
|
-
end
|
1212
|
-
|
1213
|
-
config = %{
|
1214
|
-
host logs.google.com
|
1215
|
-
port 778
|
1216
|
-
scheme https
|
1217
|
-
path /os/
|
1218
|
-
user john
|
1219
|
-
password doe
|
1220
|
-
template_name logstash
|
1221
|
-
template_file #{template_file}
|
1222
|
-
max_retry_putting_template 3
|
1223
|
-
use_legacy_template #{use_legacy_template_flag}
|
1224
|
-
}
|
1225
|
-
|
1226
|
-
connection_resets = 0
|
1227
|
-
# check if template exists
|
1228
|
-
stub_request(:get, "https://logs.google.com:778/os//#{endpoint}/logstash")
|
1229
|
-
.with(basic_auth: ['john', 'doe']) do |req|
|
1230
|
-
connection_resets += 1
|
1231
|
-
raise Faraday::ConnectionFailed, "Test message"
|
1232
|
-
end
|
1233
|
-
stub_opensearch_info("https://logs.google.com:778/os//")
|
1234
|
-
|
1235
|
-
assert_raise(Fluent::Plugin::OpenSearchError::RetryableOperationExhaustedFailure) do
|
1236
|
-
driver(config)
|
1237
|
-
end
|
1238
|
-
|
1239
|
-
assert_equal(4, connection_resets)
|
1240
|
-
end
|
1241
|
-
|
1242
|
-
transport_errors_handled_separately = [OpenSearch::Transport::Transport::Errors::NotFound]
|
1243
|
-
transport_errors = OpenSearch::Transport::Transport::Errors.constants.map { |err| [err, OpenSearch::Transport::Transport::Errors.const_get(err)] }
|
1244
|
-
transport_errors_hash = Hash[transport_errors.select { |err| !transport_errors_handled_separately.include?(err[1]) } ]
|
1245
|
-
|
1246
|
-
data(transport_errors_hash)
|
1247
|
-
def test_template_retry_transport_errors(error)
|
1248
|
-
endpoint, use_legacy_template_flag = ["_index_template".freeze, false]
|
1249
|
-
cwd = File.dirname(__FILE__)
|
1250
|
-
template_file = File.join(cwd, 'test_index_template.json')
|
1251
|
-
|
1252
|
-
config = %{
|
1253
|
-
host logs.google.com
|
1254
|
-
port 778
|
1255
|
-
scheme https
|
1256
|
-
path /os/
|
1257
|
-
user john
|
1258
|
-
password doe
|
1259
|
-
template_name logstash
|
1260
|
-
template_file #{template_file}
|
1261
|
-
max_retry_putting_template 0
|
1262
|
-
use_legacy_template #{use_legacy_template_flag}
|
1263
|
-
}
|
1264
|
-
|
1265
|
-
retries = 0
|
1266
|
-
stub_request(:get, "https://logs.google.com:778/os//#{endpoint}/logstash")
|
1267
|
-
.with(basic_auth: ['john', 'doe']) do |req|
|
1268
|
-
retries += 1
|
1269
|
-
raise error
|
1270
|
-
end
|
1271
|
-
stub_opensearch_info("https://logs.google.com:778/os//")
|
1272
|
-
|
1273
|
-
assert_raise(Fluent::Plugin::OpenSearchError::RetryableOperationExhaustedFailure) do
|
1274
|
-
driver(config)
|
1275
|
-
end
|
1276
|
-
|
1277
|
-
assert_equal(1, retries)
|
1278
|
-
end
|
1279
|
-
|
1280
|
-
data("legacy_template" => [true, "_template"],
|
1281
|
-
"new_template" => [false, "_index_template"])
|
1282
|
-
def test_template_retry_install_does_not_fail(data)
|
1283
|
-
use_legacy_template_flag, endpoint = data
|
1284
|
-
cwd = File.dirname(__FILE__)
|
1285
|
-
template_file = if use_legacy_template_flag
|
1286
|
-
File.join(cwd, 'test_template.json')
|
1287
|
-
else
|
1288
|
-
File.join(cwd, 'test_index_template.json')
|
1289
|
-
end
|
1290
|
-
|
1291
|
-
config = %{
|
1292
|
-
host logs.google.com
|
1293
|
-
port 778
|
1294
|
-
scheme https
|
1295
|
-
path /os/
|
1296
|
-
user john
|
1297
|
-
password doe
|
1298
|
-
template_name logstash
|
1299
|
-
template_file #{template_file}
|
1300
|
-
max_retry_putting_template 3
|
1301
|
-
fail_on_putting_template_retry_exceed false
|
1302
|
-
use_legacy_template #{use_legacy_template_flag}
|
1303
|
-
}
|
1304
|
-
|
1305
|
-
connection_resets = 0
|
1306
|
-
# check if template exists
|
1307
|
-
stub_request(:get, "https://logs.google.com:778/os//#{endpoint}/logstash")
|
1308
|
-
.with(basic_auth: ['john', 'doe']) do |req|
|
1309
|
-
connection_resets += 1
|
1310
|
-
raise Faraday::ConnectionFailed, "Test message"
|
1311
|
-
end
|
1312
|
-
stub_opensearch_info("https://logs.google.com:778/os//")
|
1313
|
-
|
1314
|
-
driver(config)
|
1315
|
-
|
1316
|
-
assert_equal(4, connection_resets)
|
1317
|
-
end
|
1318
|
-
|
1319
|
-
data("legacy_template" => [true, "_template"],
|
1320
|
-
"new_template" => [false, "_index_template"])
|
1321
|
-
def test_templates_create(data)
|
1322
|
-
use_legacy_template_flag, endpoint = data
|
1323
|
-
cwd = File.dirname(__FILE__)
|
1324
|
-
template_file = if use_legacy_template_flag
|
1325
|
-
File.join(cwd, 'test_template.json')
|
1326
|
-
else
|
1327
|
-
File.join(cwd, 'test_index_template.json')
|
1328
|
-
end
|
1329
|
-
|
1330
|
-
config = %{
|
1331
|
-
host logs.google.com
|
1332
|
-
port 777
|
1333
|
-
scheme https
|
1334
|
-
path /os/
|
1335
|
-
user john
|
1336
|
-
password doe
|
1337
|
-
templates {"logstash1":"#{template_file}", "logstash2":"#{template_file}","logstash3":"#{template_file}" }
|
1338
|
-
use_legacy_template #{use_legacy_template_flag}
|
1339
|
-
}
|
1340
|
-
|
1341
|
-
stub_request(:head, "https://logs.google.com:777/os//").
|
1342
|
-
with(basic_auth: ['john', 'doe']).
|
1343
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1344
|
-
# check if template exists
|
1345
|
-
stub_request(:get, "https://logs.google.com:777/os//#{endpoint}/logstash1").
|
1346
|
-
with(basic_auth: ['john', 'doe']).
|
1347
|
-
to_return(:status => 404, :body => "", :headers => {})
|
1348
|
-
stub_request(:get, "https://logs.google.com:777/os//#{endpoint}/logstash2").
|
1349
|
-
with(basic_auth: ['john', 'doe']).
|
1350
|
-
to_return(:status => 404, :body => "", :headers => {})
|
1351
|
-
|
1352
|
-
stub_request(:get, "https://logs.google.com:777/os//#{endpoint}/logstash3").
|
1353
|
-
with(basic_auth: ['john', 'doe']).
|
1354
|
-
to_return(:status => 200, :body => "", :headers => {}) #exists
|
1355
|
-
|
1356
|
-
stub_request(:put, "https://logs.google.com:777/os//#{endpoint}/logstash1").
|
1357
|
-
with(basic_auth: ['john', 'doe']).
|
1358
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1359
|
-
stub_request(:put, "https://logs.google.com:777/os//#{endpoint}/logstash2").
|
1360
|
-
with(basic_auth: ['john', 'doe']).
|
1361
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1362
|
-
stub_request(:put, "https://logs.google.com:777/os//#{endpoint}/logstash3").
|
1363
|
-
with(basic_auth: ['john', 'doe']).
|
1364
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1365
|
-
stub_opensearch_info("https://logs.google.com:777/os//")
|
1366
|
-
|
1367
|
-
driver(config)
|
1368
|
-
|
1369
|
-
assert_requested( :put, "https://logs.google.com:777/os//#{endpoint}/logstash1", times: 1)
|
1370
|
-
assert_requested( :put, "https://logs.google.com:777/os//#{endpoint}/logstash2", times: 1)
|
1371
|
-
assert_not_requested(:put, "https://logs.google.com:777/os//#{endpoint}/logstash3") #exists
|
1372
|
-
end
|
1373
|
-
|
1374
|
-
data("legacy_template" => [true, "_template"],
|
1375
|
-
"new_template" => [false, "_index_template"])
|
1376
|
-
def test_templates_overwrite(data)
|
1377
|
-
use_legacy_template_flag, endpoint = data
|
1378
|
-
cwd = File.dirname(__FILE__)
|
1379
|
-
template_file = if use_legacy_template_flag
|
1380
|
-
File.join(cwd, 'test_template.json')
|
1381
|
-
else
|
1382
|
-
File.join(cwd, 'test_index_template.json')
|
1383
|
-
end
|
1384
|
-
|
1385
|
-
config = %{
|
1386
|
-
host logs.google.com
|
1387
|
-
port 777
|
1388
|
-
scheme https
|
1389
|
-
path /os/
|
1390
|
-
user john
|
1391
|
-
password doe
|
1392
|
-
templates {"logstash1":"#{template_file}", "logstash2":"#{template_file}","logstash3":"#{template_file}" }
|
1393
|
-
template_overwrite true
|
1394
|
-
use_legacy_template #{use_legacy_template_flag}
|
1395
|
-
}
|
1396
|
-
|
1397
|
-
stub_request(:head, "https://logs.google.com:777/os//").
|
1398
|
-
with(basic_auth: ['john', 'doe']).
|
1399
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1400
|
-
# check if template exists
|
1401
|
-
stub_request(:get, "https://logs.google.com:777/os//#{endpoint}/logstash1").
|
1402
|
-
with(basic_auth: ['john', 'doe']).
|
1403
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1404
|
-
stub_request(:get, "https://logs.google.com:777/os//#{endpoint}/logstash2").
|
1405
|
-
with(basic_auth: ['john', 'doe']).
|
1406
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1407
|
-
stub_request(:get, "https://logs.google.com:777/os//#{endpoint}/logstash3").
|
1408
|
-
with(basic_auth: ['john', 'doe']).
|
1409
|
-
to_return(:status => 200, :body => "", :headers => {}) #exists
|
1410
|
-
|
1411
|
-
stub_request(:put, "https://logs.google.com:777/os//#{endpoint}/logstash1").
|
1412
|
-
with(basic_auth: ['john', 'doe']).
|
1413
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1414
|
-
stub_request(:put, "https://logs.google.com:777/os//#{endpoint}/logstash2").
|
1415
|
-
with(basic_auth: ['john', 'doe']).
|
1416
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1417
|
-
stub_request(:put, "https://logs.google.com:777/os//#{endpoint}/logstash3").
|
1418
|
-
with(basic_auth: ['john', 'doe']).
|
1419
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1420
|
-
stub_opensearch_info("https://logs.google.com:777/os//")
|
1421
|
-
|
1422
|
-
driver(config)
|
1423
|
-
|
1424
|
-
assert_requested(:put, "https://logs.google.com:777/os//#{endpoint}/logstash1", times: 1)
|
1425
|
-
assert_requested(:put, "https://logs.google.com:777/os//#{endpoint}/logstash2", times: 1)
|
1426
|
-
assert_requested(:put, "https://logs.google.com:777/os//#{endpoint}/logstash3", times: 1)
|
1427
|
-
end
|
1428
|
-
|
1429
|
-
data("legacy_template" => [true, "_template"],
|
1430
|
-
"new_template" => [false, "_index_template"])
|
1431
|
-
def test_templates_are_also_used(data)
|
1432
|
-
use_legacy_template_flag, endpoint = data
|
1433
|
-
cwd = File.dirname(__FILE__)
|
1434
|
-
template_file = if use_legacy_template_flag
|
1435
|
-
File.join(cwd, 'test_template.json')
|
1436
|
-
else
|
1437
|
-
File.join(cwd, 'test_index_template.json')
|
1438
|
-
end
|
1439
|
-
|
1440
|
-
config = %{
|
1441
|
-
host logs.google.com
|
1442
|
-
port 777
|
1443
|
-
scheme https
|
1444
|
-
path /os/
|
1445
|
-
user john
|
1446
|
-
password doe
|
1447
|
-
template_name logstash
|
1448
|
-
template_file #{template_file}
|
1449
|
-
templates {"logstash1":"#{template_file}", "logstash2":"#{template_file}" }
|
1450
|
-
use_legacy_template #{use_legacy_template_flag}
|
1451
|
-
}
|
1452
|
-
# connection start
|
1453
|
-
stub_request(:head, "https://logs.google.com:777/os//").
|
1454
|
-
with(basic_auth: ['john', 'doe']).
|
1455
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1456
|
-
# check if template exists
|
1457
|
-
stub_request(:get, "https://logs.google.com:777/os//#{endpoint}/logstash").
|
1458
|
-
with(basic_auth: ['john', 'doe']).
|
1459
|
-
to_return(:status => 404, :body => "", :headers => {})
|
1460
|
-
stub_request(:get, "https://logs.google.com:777/os//#{endpoint}/logstash1").
|
1461
|
-
with(basic_auth: ['john', 'doe']).
|
1462
|
-
to_return(:status => 404, :body => "", :headers => {})
|
1463
|
-
stub_request(:get, "https://logs.google.com:777/os//#{endpoint}/logstash2").
|
1464
|
-
with(basic_auth: ['john', 'doe']).
|
1465
|
-
to_return(:status => 404, :body => "", :headers => {})
|
1466
|
-
#creation
|
1467
|
-
stub_request(:put, "https://logs.google.com:777/os//#{endpoint}/logstash").
|
1468
|
-
with(basic_auth: ['john', 'doe']).
|
1469
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1470
|
-
stub_request(:put, "https://logs.google.com:777/os//#{endpoint}/logstash1").
|
1471
|
-
with(basic_auth: ['john', 'doe']).
|
1472
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1473
|
-
stub_request(:put, "https://logs.google.com:777/os//#{endpoint}/logstash2").
|
1474
|
-
with(basic_auth: ['john', 'doe']).
|
1475
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1476
|
-
stub_opensearch_info("https://logs.google.com:777/os//")
|
1477
|
-
|
1478
|
-
driver(config)
|
1479
|
-
|
1480
|
-
assert_requested(:put, "https://logs.google.com:777/os//#{endpoint}/logstash", times: 1)
|
1481
|
-
|
1482
|
-
assert_requested(:put, "https://logs.google.com:777/os//#{endpoint}/logstash1")
|
1483
|
-
assert_requested(:put, "https://logs.google.com:777/os//#{endpoint}/logstash2")
|
1484
|
-
end
|
1485
|
-
|
1486
|
-
data("legacy_template" => [true, "_template"],
|
1487
|
-
"new_template" => [false, "_index_template"])
|
1488
|
-
def test_templates_can_be_partially_created_if_error_occurs(data)
|
1489
|
-
use_legacy_template_flag, endpoint = data
|
1490
|
-
cwd = File.dirname(__FILE__)
|
1491
|
-
template_file = if use_legacy_template_flag
|
1492
|
-
File.join(cwd, 'test_template.json')
|
1493
|
-
else
|
1494
|
-
File.join(cwd, 'test_index_template.json')
|
1495
|
-
end
|
1496
|
-
|
1497
|
-
config = %{
|
1498
|
-
host logs.google.com
|
1499
|
-
port 777
|
1500
|
-
scheme https
|
1501
|
-
path /os/
|
1502
|
-
user john
|
1503
|
-
password doe
|
1504
|
-
templates {"logstash1":"#{template_file}", "logstash2":"/abc" }
|
1505
|
-
use_legacy_template #{use_legacy_template_flag}
|
1506
|
-
}
|
1507
|
-
stub_request(:head, "https://logs.google.com:777/os//").
|
1508
|
-
with(basic_auth: ['john', 'doe']).
|
1509
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1510
|
-
# check if template exists
|
1511
|
-
stub_request(:get, "https://logs.google.com:777/os//#{endpoint}/logstash1").
|
1512
|
-
with(basic_auth: ['john', 'doe']).
|
1513
|
-
to_return(:status => 404, :body => "", :headers => {})
|
1514
|
-
stub_request(:get, "https://logs.google.com:777/os//#{endpoint}/logstash2").
|
1515
|
-
with(basic_auth: ['john', 'doe']).
|
1516
|
-
to_return(:status => 404, :body => "", :headers => {})
|
1517
|
-
|
1518
|
-
stub_request(:put, "https://logs.google.com:777/os//#{endpoint}/logstash1").
|
1519
|
-
with(basic_auth: ['john', 'doe']).
|
1520
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1521
|
-
stub_request(:put, "https://logs.google.com:777/os//#{endpoint}/logstash2").
|
1522
|
-
with(basic_auth: ['john', 'doe']).
|
1523
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1524
|
-
stub_opensearch_info("https://logs.google.com:777/os//")
|
1525
|
-
|
1526
|
-
assert_raise(RuntimeError) {
|
1527
|
-
driver(config)
|
1528
|
-
}
|
1529
|
-
|
1530
|
-
assert_requested(:put, "https://logs.google.com:777/os//#{endpoint}/logstash1", times: 1)
|
1531
|
-
assert_not_requested(:put, "https://logs.google.com:777/os//#{endpoint}/logstash2")
|
1532
|
-
end
|
1533
|
-
|
1534
|
-
def test_legacy_hosts_list
|
1535
|
-
config = %{
|
1536
|
-
hosts host1:50,host2:100,host3
|
1537
|
-
scheme https
|
1538
|
-
path /os/
|
1539
|
-
port 123
|
1540
|
-
}
|
1541
|
-
stub_opensearch_info("https://host1:50")
|
1542
|
-
stub_opensearch_info("https://host2:100")
|
1543
|
-
stub_opensearch_info("https://host3:123")
|
1544
|
-
instance = driver(config).instance
|
1545
|
-
|
1546
|
-
assert_equal 3, instance.get_connection_options[:hosts].length
|
1547
|
-
host1, host2, host3 = instance.get_connection_options[:hosts]
|
1548
|
-
|
1549
|
-
assert_equal 'host1', host1[:host]
|
1550
|
-
assert_equal 50, host1[:port]
|
1551
|
-
assert_equal 'https', host1[:scheme]
|
1552
|
-
assert_equal '/os/', host2[:path]
|
1553
|
-
assert_equal 'host3', host3[:host]
|
1554
|
-
assert_equal 123, host3[:port]
|
1555
|
-
assert_equal 'https', host3[:scheme]
|
1556
|
-
assert_equal '/os/', host3[:path]
|
1557
|
-
end
|
1558
|
-
|
1559
|
-
def test_hosts_list
|
1560
|
-
config = %{
|
1561
|
-
hosts https://john:password@host1:443/elastic/,http://host2
|
1562
|
-
path /default_path
|
1563
|
-
user default_user
|
1564
|
-
password default_password
|
1565
|
-
}
|
1566
|
-
stub_opensearch_info("https://john:password@host1:443/elastic/")
|
1567
|
-
stub_opensearch_info("http://host2")
|
1568
|
-
instance = driver(config).instance
|
1569
|
-
|
1570
|
-
assert_equal 2, instance.get_connection_options[:hosts].length
|
1571
|
-
host1, host2 = instance.get_connection_options[:hosts]
|
1572
|
-
|
1573
|
-
assert_equal 'host1', host1[:host]
|
1574
|
-
assert_equal 443, host1[:port]
|
1575
|
-
assert_equal 'https', host1[:scheme]
|
1576
|
-
assert_equal 'john', host1[:user]
|
1577
|
-
assert_equal 'password', host1[:password]
|
1578
|
-
assert_equal '/elastic/', host1[:path]
|
1579
|
-
|
1580
|
-
assert_equal 'host2', host2[:host]
|
1581
|
-
assert_equal 'http', host2[:scheme]
|
1582
|
-
assert_equal 'default_user', host2[:user]
|
1583
|
-
assert_equal 'default_password', host2[:password]
|
1584
|
-
assert_equal '/default_path', host2[:path]
|
1585
|
-
end
|
1586
|
-
|
1587
|
-
def test_hosts_list_with_escape_placeholders
|
1588
|
-
config = %{
|
1589
|
-
hosts https://%{j+hn}:%{passw@rd}@host1:443/elastic/,http://host2
|
1590
|
-
path /default_path
|
1591
|
-
user default_user
|
1592
|
-
password default_password
|
1593
|
-
}
|
1594
|
-
stub_opensearch_info("https://j%2Bhn:passw%40rd@host1:443/elastic/")
|
1595
|
-
stub_opensearch_info("http://host2")
|
1596
|
-
|
1597
|
-
instance = driver(config).instance
|
1598
|
-
|
1599
|
-
assert_equal 2, instance.get_connection_options[:hosts].length
|
1600
|
-
host1, host2 = instance.get_connection_options[:hosts]
|
1601
|
-
|
1602
|
-
assert_equal 'host1', host1[:host]
|
1603
|
-
assert_equal 443, host1[:port]
|
1604
|
-
assert_equal 'https', host1[:scheme]
|
1605
|
-
assert_equal 'j%2Bhn', host1[:user]
|
1606
|
-
assert_equal 'passw%40rd', host1[:password]
|
1607
|
-
assert_equal '/elastic/', host1[:path]
|
1608
|
-
|
1609
|
-
assert_equal 'host2', host2[:host]
|
1610
|
-
assert_equal 'http', host2[:scheme]
|
1611
|
-
assert_equal 'default_user', host2[:user]
|
1612
|
-
assert_equal 'default_password', host2[:password]
|
1613
|
-
assert_equal '/default_path', host2[:path]
|
1614
|
-
end
|
1615
|
-
|
1616
|
-
class IPv6AdressStringHostsTest < self
|
1617
|
-
def test_legacy_hosts_list
|
1618
|
-
config = %{
|
1619
|
-
hosts "[2404:7a80:d440:3000:192a:a292:bd7f:ca19]:50,host2:100,host3"
|
1620
|
-
scheme https
|
1621
|
-
path /os/
|
1622
|
-
port 123
|
1623
|
-
}
|
1624
|
-
instance = driver(config).instance
|
1625
|
-
|
1626
|
-
assert_raise(URI::InvalidURIError) do
|
1627
|
-
instance.get_connection_options[:hosts].length
|
1628
|
-
end
|
1629
|
-
end
|
1630
|
-
|
1631
|
-
def test_hosts_list
|
1632
|
-
config = %{
|
1633
|
-
hosts https://john:password@[2404:7a80:d440:3000:192a:a292:bd7f:ca19]:443/opensearch/,http://host2
|
1634
|
-
path /default_path
|
1635
|
-
user default_user
|
1636
|
-
password default_password
|
1637
|
-
}
|
1638
|
-
instance = driver(config).instance
|
1639
|
-
|
1640
|
-
assert_equal 2, instance.get_connection_options[:hosts].length
|
1641
|
-
host1, host2 = instance.get_connection_options[:hosts]
|
1642
|
-
|
1643
|
-
assert_equal '[2404:7a80:d440:3000:192a:a292:bd7f:ca19]', host1[:host]
|
1644
|
-
assert_equal 443, host1[:port]
|
1645
|
-
assert_equal 'https', host1[:scheme]
|
1646
|
-
assert_equal 'john', host1[:user]
|
1647
|
-
assert_equal 'password', host1[:password]
|
1648
|
-
assert_equal '/opensearch/', host1[:path]
|
1649
|
-
|
1650
|
-
assert_equal 'host2', host2[:host]
|
1651
|
-
assert_equal 'http', host2[:scheme]
|
1652
|
-
assert_equal 'default_user', host2[:user]
|
1653
|
-
assert_equal 'default_password', host2[:password]
|
1654
|
-
assert_equal '/default_path', host2[:path]
|
1655
|
-
end
|
1656
|
-
|
1657
|
-
def test_hosts_list_with_escape_placeholders
|
1658
|
-
config = %{
|
1659
|
-
hosts https://%{j+hn}:%{passw@rd}@[2404:7a80:d440:3000:192a:a292:bd7f:ca19]:443/opensearch/,http://host2
|
1660
|
-
path /default_path
|
1661
|
-
user default_user
|
1662
|
-
password default_password
|
1663
|
-
}
|
1664
|
-
instance = driver(config).instance
|
1665
|
-
|
1666
|
-
assert_equal 2, instance.get_connection_options[:hosts].length
|
1667
|
-
host1, host2 = instance.get_connection_options[:hosts]
|
1668
|
-
|
1669
|
-
assert_equal '[2404:7a80:d440:3000:192a:a292:bd7f:ca19]', host1[:host]
|
1670
|
-
assert_equal 443, host1[:port]
|
1671
|
-
assert_equal 'https', host1[:scheme]
|
1672
|
-
assert_equal 'j%2Bhn', host1[:user]
|
1673
|
-
assert_equal 'passw%40rd', host1[:password]
|
1674
|
-
assert_equal '/opensearch/', host1[:path]
|
1675
|
-
|
1676
|
-
assert_equal 'host2', host2[:host]
|
1677
|
-
assert_equal 'http', host2[:scheme]
|
1678
|
-
assert_equal 'default_user', host2[:user]
|
1679
|
-
assert_equal 'default_password', host2[:password]
|
1680
|
-
assert_equal '/default_path', host2[:path]
|
1681
|
-
end
|
1682
|
-
end
|
1683
|
-
|
1684
|
-
def test_single_host_params_and_defaults
|
1685
|
-
config = %{
|
1686
|
-
host logs.google.com
|
1687
|
-
user john
|
1688
|
-
password doe
|
1689
|
-
}
|
1690
|
-
instance = driver(config).instance
|
1691
|
-
|
1692
|
-
assert_equal 1, instance.get_connection_options[:hosts].length
|
1693
|
-
host1 = instance.get_connection_options[:hosts][0]
|
1694
|
-
|
1695
|
-
assert_equal 'logs.google.com', host1[:host]
|
1696
|
-
assert_equal 9200, host1[:port]
|
1697
|
-
assert_equal 'http', host1[:scheme]
|
1698
|
-
assert_equal 'john', host1[:user]
|
1699
|
-
assert_equal 'doe', host1[:password]
|
1700
|
-
assert_equal nil, host1[:path]
|
1701
|
-
end
|
1702
|
-
|
1703
|
-
def test_single_host_params_and_defaults_with_escape_placeholders
|
1704
|
-
config = %{
|
1705
|
-
host logs.google.com
|
1706
|
-
user %{j+hn}
|
1707
|
-
password %{d@e}
|
1708
|
-
}
|
1709
|
-
instance = driver(config).instance
|
1710
|
-
|
1711
|
-
assert_equal 1, instance.get_connection_options[:hosts].length
|
1712
|
-
host1 = instance.get_connection_options[:hosts][0]
|
1713
|
-
|
1714
|
-
assert_equal 'logs.google.com', host1[:host]
|
1715
|
-
assert_equal 9200, host1[:port]
|
1716
|
-
assert_equal 'http', host1[:scheme]
|
1717
|
-
assert_equal 'j%2Bhn', host1[:user]
|
1718
|
-
assert_equal 'd%40e', host1[:password]
|
1719
|
-
assert_equal nil, host1[:path]
|
1720
|
-
end
|
1721
|
-
|
1722
|
-
def test_host_and_port_are_ignored_if_specify_hosts
|
1723
|
-
config = %{
|
1724
|
-
host logs.google.com
|
1725
|
-
port 9200
|
1726
|
-
hosts host1:50,host2:100
|
1727
|
-
}
|
1728
|
-
instance = driver(config).instance
|
1729
|
-
|
1730
|
-
params = instance.get_connection_options[:hosts]
|
1731
|
-
hosts = params.map { |p| p[:host] }
|
1732
|
-
ports = params.map { |p| p[:port] }
|
1733
|
-
assert(hosts.none? { |h| h == 'logs.google.com' })
|
1734
|
-
assert(ports.none? { |p| p == 9200 })
|
1735
|
-
end
|
1736
|
-
|
1737
|
-
class IPv6AdressStringHostTest < self
|
1738
|
-
def test_single_host_params_and_defaults
|
1739
|
-
config = %{
|
1740
|
-
host 2404:7a80:d440:3000:192a:a292:bd7f:ca19
|
1741
|
-
user john
|
1742
|
-
password doe
|
1743
|
-
}
|
1744
|
-
instance = driver(config).instance
|
1745
|
-
|
1746
|
-
assert_equal 1, instance.get_connection_options[:hosts].length
|
1747
|
-
host1 = instance.get_connection_options[:hosts][0]
|
1748
|
-
|
1749
|
-
assert_equal '[2404:7a80:d440:3000:192a:a292:bd7f:ca19]', host1[:host]
|
1750
|
-
assert_equal 9200, host1[:port]
|
1751
|
-
assert_equal 'http', host1[:scheme]
|
1752
|
-
assert_equal 'john', host1[:user]
|
1753
|
-
assert_equal 'doe', host1[:password]
|
1754
|
-
assert_equal nil, host1[:path]
|
1755
|
-
end
|
1756
|
-
|
1757
|
-
def test_single_host_params_and_defaults_with_escape_placeholders
|
1758
|
-
config = %{
|
1759
|
-
host 2404:7a80:d440:3000:192a:a292:bd7f:ca19
|
1760
|
-
user %{j+hn}
|
1761
|
-
password %{d@e}
|
1762
|
-
}
|
1763
|
-
instance = driver(config).instance
|
1764
|
-
|
1765
|
-
assert_equal 1, instance.get_connection_options[:hosts].length
|
1766
|
-
host1 = instance.get_connection_options[:hosts][0]
|
1767
|
-
|
1768
|
-
assert_equal '[2404:7a80:d440:3000:192a:a292:bd7f:ca19]', host1[:host]
|
1769
|
-
assert_equal 9200, host1[:port]
|
1770
|
-
assert_equal 'http', host1[:scheme]
|
1771
|
-
assert_equal 'j%2Bhn', host1[:user]
|
1772
|
-
assert_equal 'd%40e', host1[:password]
|
1773
|
-
assert_equal nil, host1[:path]
|
1774
|
-
end
|
1775
|
-
end
|
1776
|
-
|
1777
|
-
def test_password_is_required_if_specify_user
|
1778
|
-
config = %{
|
1779
|
-
user john
|
1780
|
-
}
|
1781
|
-
|
1782
|
-
assert_raise(Fluent::ConfigError) do
|
1783
|
-
driver(config)
|
1784
|
-
end
|
1785
|
-
end
|
1786
|
-
|
1787
|
-
def test_content_type_header
|
1788
|
-
stub_request(:head, "http://localhost:9200/").
|
1789
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1790
|
-
elastic_request = stub_request(:post, "http://localhost:9200/_bulk").
|
1791
|
-
with(headers: { "Content-Type" => "application/x-ndjson" })
|
1792
|
-
stub_opensearch_info
|
1793
|
-
driver.run(default_tag: 'test') do
|
1794
|
-
driver.feed(sample_record)
|
1795
|
-
end
|
1796
|
-
assert_requested(elastic_request)
|
1797
|
-
end
|
1798
|
-
|
1799
|
-
def test_custom_headers
|
1800
|
-
stub_request(:head, "http://localhost:9200/").
|
1801
|
-
to_return(:status => 200, :body => "", :headers => {})
|
1802
|
-
elastic_request = stub_request(:post, "http://localhost:9200/_bulk").
|
1803
|
-
with(headers: {'custom' => 'header1','and_others' => 'header2' })
|
1804
|
-
stub_opensearch_info
|
1805
|
-
driver.configure(%[custom_headers {"custom":"header1", "and_others":"header2"}])
|
1806
|
-
driver.run(default_tag: 'test') do
|
1807
|
-
driver.feed(sample_record)
|
1808
|
-
end
|
1809
|
-
assert_requested(elastic_request)
|
1810
|
-
end
|
1811
|
-
|
1812
|
-
def test_write_message_with_bad_chunk
|
1813
|
-
driver.configure("target_index_key bad_value\n@log_level debug\n")
|
1814
|
-
stub_opensearch
|
1815
|
-
stub_opensearch_info
|
1816
|
-
driver.run(default_tag: 'test') do
|
1817
|
-
driver.feed({'bad_value'=>"\255"})
|
1818
|
-
end
|
1819
|
-
error_log = driver.error_events.map {|e| e.last.message }
|
1820
|
-
|
1821
|
-
assert_logs_include(error_log, /(input string invalid)|(invalid byte sequence in UTF-8)/)
|
1822
|
-
end
|
1823
|
-
|
1824
|
-
data('OpenSearch 1' => [1, 'fluentd'],
|
1825
|
-
)
|
1826
|
-
def test_writes_to_default_index(data)
|
1827
|
-
version, index_name = data
|
1828
|
-
stub_opensearch
|
1829
|
-
stub_opensearch_info
|
1830
|
-
driver("", version)
|
1831
|
-
driver.run(default_tag: 'test') do
|
1832
|
-
driver.feed(sample_record)
|
1833
|
-
end
|
1834
|
-
assert_equal(index_name, index_cmds.first['index']['_index'])
|
1835
|
-
end
|
1836
|
-
|
1837
|
-
# gzip compress data
|
1838
|
-
def gzip(string, strategy)
|
1839
|
-
wio = StringIO.new("w")
|
1840
|
-
w_gz = Zlib::GzipWriter.new(wio, strategy = strategy)
|
1841
|
-
w_gz.write(string)
|
1842
|
-
w_gz.close
|
1843
|
-
wio.string
|
1844
|
-
end
|
1845
|
-
|
1846
|
-
|
1847
|
-
def test_writes_to_default_index_with_compression
|
1848
|
-
config = %[
|
1849
|
-
compression_level default_compression
|
1850
|
-
]
|
1851
|
-
|
1852
|
-
bodystr = %({
|
1853
|
-
"took" : 500,
|
1854
|
-
"errors" : false,
|
1855
|
-
"items" : [
|
1856
|
-
{
|
1857
|
-
"create": {
|
1858
|
-
"_index" : "fluentd",
|
1859
|
-
"_type" : "fluentd"
|
1860
|
-
}
|
1861
|
-
}
|
1862
|
-
]
|
1863
|
-
})
|
1864
|
-
|
1865
|
-
compressed_body = gzip(bodystr, Zlib::DEFAULT_COMPRESSION)
|
1866
|
-
|
1867
|
-
elastic_request = stub_request(:post, "http://localhost:9200/_bulk").
|
1868
|
-
to_return(:status => 200, :headers => {'Content-Type' => 'Application/json'}, :body => compressed_body)
|
1869
|
-
stub_opensearch_info("http://localhost:9200/")
|
1870
|
-
|
1871
|
-
driver(config)
|
1872
|
-
driver.run(default_tag: 'test') do
|
1873
|
-
driver.feed(sample_record)
|
1874
|
-
end
|
1875
|
-
|
1876
|
-
assert_requested(elastic_request)
|
1877
|
-
end
|
1878
|
-
|
1879
|
-
data('OpenSearch 1' => [1, Fluent::Plugin::OpenSearchOutput::DEFAULT_TYPE_NAME],
|
1880
|
-
)
|
1881
|
-
def test_writes_to_default_type(data)
|
1882
|
-
version, index_type = data
|
1883
|
-
stub_opensearch
|
1884
|
-
stub_opensearch_info
|
1885
|
-
driver("", version)
|
1886
|
-
driver.run(default_tag: 'test') do
|
1887
|
-
driver.feed(sample_record)
|
1888
|
-
end
|
1889
|
-
assert_equal(index_type, index_cmds.first['index']['_type'])
|
1890
|
-
end
|
1891
|
-
|
1892
|
-
def test_writes_to_speficied_index
|
1893
|
-
driver.configure("index_name myindex\n")
|
1894
|
-
stub_opensearch
|
1895
|
-
stub_opensearch_info
|
1896
|
-
driver.run(default_tag: 'test') do
|
1897
|
-
driver.feed(sample_record)
|
1898
|
-
end
|
1899
|
-
assert_equal('myindex', index_cmds.first['index']['_index'])
|
1900
|
-
end
|
1901
|
-
|
1902
|
-
def test_writes_with_huge_records
|
1903
|
-
driver.configure(Fluent::Config::Element.new(
|
1904
|
-
'ROOT', '', {
|
1905
|
-
'@type' => 'opensearch',
|
1906
|
-
'bulk_message_request_threshold' => 20 * 1024 * 1024,
|
1907
|
-
}, [
|
1908
|
-
Fluent::Config::Element.new('buffer', 'tag', {
|
1909
|
-
'chunk_keys' => ['tag', 'time'],
|
1910
|
-
'chunk_limit_size' => '64MB',
|
1911
|
-
}, [])
|
1912
|
-
]
|
1913
|
-
))
|
1914
|
-
request = stub_opensearch
|
1915
|
-
stub_opensearch_info
|
1916
|
-
driver.run(default_tag: 'test') do
|
1917
|
-
driver.feed(sample_record('huge_record' => ("a" * 20 * 1024 * 1024)))
|
1918
|
-
driver.feed(sample_record('huge_record' => ("a" * 20 * 1024 * 1024)))
|
1919
|
-
end
|
1920
|
-
assert_requested(request, times: 2)
|
1921
|
-
end
|
1922
|
-
|
1923
|
-
def test_writes_with_record_metadata
|
1924
|
-
chunk_id_key = "metadata_key".freeze
|
1925
|
-
driver.configure(Fluent::Config::Element.new(
|
1926
|
-
'ROOT', '', {
|
1927
|
-
'@type' => 'opensearch',
|
1928
|
-
}, [
|
1929
|
-
Fluent::Config::Element.new('metadata', '', {
|
1930
|
-
'include_chunk_id' => true,
|
1931
|
-
'chunk_id_key' => chunk_id_key,
|
1932
|
-
}, [])
|
1933
|
-
]
|
1934
|
-
))
|
1935
|
-
stub_request(:post, "http://localhost:9200/_bulk").
|
1936
|
-
with(
|
1937
|
-
body: /{"index":{"_index":"fluentd","_type":"_doc"}}\n{"age":26,"request_id":"42","parent_id":"parent","routing_id":"routing","#{chunk_id_key}":".*"}\n/) do |req|
|
1938
|
-
@index_cmds = req.body.split("\n").map {|r| JSON.parse(r) }
|
1939
|
-
end
|
1940
|
-
stub_opensearch_info
|
1941
|
-
driver.run(default_tag: 'test', shutdown: false) do
|
1942
|
-
driver.feed(sample_record)
|
1943
|
-
end
|
1944
|
-
assert_true index_cmds[1].has_key?(chunk_id_key)
|
1945
|
-
first_chunk_id = index_cmds[1].fetch(chunk_id_key)
|
1946
|
-
|
1947
|
-
driver.run(default_tag: 'test') do
|
1948
|
-
driver.feed(sample_record)
|
1949
|
-
end
|
1950
|
-
assert_true index_cmds[1].has_key?(chunk_id_key)
|
1951
|
-
second_chunk_id = index_cmds[1].fetch(chunk_id_key)
|
1952
|
-
assert do
|
1953
|
-
first_chunk_id != second_chunk_id
|
1954
|
-
end
|
1955
|
-
end
|
1956
|
-
|
1957
|
-
def test_writes_with_huge_records_but_uncheck
|
1958
|
-
driver.configure(Fluent::Config::Element.new(
|
1959
|
-
'ROOT', '', {
|
1960
|
-
'@type' => 'opensearch',
|
1961
|
-
'bulk_message_request_threshold' => -1,
|
1962
|
-
}, [
|
1963
|
-
Fluent::Config::Element.new('buffer', 'tag', {
|
1964
|
-
'chunk_keys' => ['tag', 'time'],
|
1965
|
-
'chunk_limit_size' => '64MB',
|
1966
|
-
}, [])
|
1967
|
-
]
|
1968
|
-
))
|
1969
|
-
request = stub_opensearch
|
1970
|
-
stub_opensearch_info
|
1971
|
-
driver.run(default_tag: 'test') do
|
1972
|
-
driver.feed(sample_record('huge_record' => ("a" * 20 * 1024 * 1024)))
|
1973
|
-
driver.feed(sample_record('huge_record' => ("a" * 20 * 1024 * 1024)))
|
1974
|
-
end
|
1975
|
-
assert_false(driver.instance.split_request?({}, nil))
|
1976
|
-
assert_requested(request, times: 1)
|
1977
|
-
end
|
1978
|
-
|
1979
|
-
class IndexNamePlaceholdersTest < self
|
1980
|
-
def test_writes_to_speficied_index_with_tag_placeholder
|
1981
|
-
driver.configure("index_name myindex.${tag}\n")
|
1982
|
-
stub_opensearch
|
1983
|
-
stub_opensearch_info
|
1984
|
-
driver.run(default_tag: 'test') do
|
1985
|
-
driver.feed(sample_record)
|
1986
|
-
end
|
1987
|
-
assert_equal('myindex.test', index_cmds.first['index']['_index'])
|
1988
|
-
end
|
1989
|
-
|
1990
|
-
def test_writes_to_speficied_index_with_time_placeholder
|
1991
|
-
driver.configure(Fluent::Config::Element.new(
|
1992
|
-
'ROOT', '', {
|
1993
|
-
'@type' => 'opensearch',
|
1994
|
-
'index_name' => 'myindex.%Y.%m.%d',
|
1995
|
-
}, [
|
1996
|
-
Fluent::Config::Element.new('buffer', 'tag,time', {
|
1997
|
-
'chunk_keys' => ['tag', 'time'],
|
1998
|
-
'timekey' => 3600,
|
1999
|
-
}, [])
|
2000
|
-
]
|
2001
|
-
))
|
2002
|
-
stub_opensearch
|
2003
|
-
stub_opensearch_info
|
2004
|
-
time = Time.parse Date.today.iso8601
|
2005
|
-
driver.run(default_tag: 'test') do
|
2006
|
-
driver.feed(time.to_i, sample_record)
|
2007
|
-
end
|
2008
|
-
assert_equal("myindex.#{time.utc.strftime("%Y.%m.%d")}", index_cmds.first['index']['_index'])
|
2009
|
-
end
|
2010
|
-
|
2011
|
-
def test_writes_to_speficied_index_with_custom_key_placeholder
|
2012
|
-
driver.configure(Fluent::Config::Element.new(
|
2013
|
-
'ROOT', '', {
|
2014
|
-
'@type' => 'opensearch',
|
2015
|
-
'index_name' => 'myindex.${pipeline_id}',
|
2016
|
-
}, [
|
2017
|
-
Fluent::Config::Element.new('buffer', 'tag,pipeline_id', {}, [])
|
2018
|
-
]
|
2019
|
-
))
|
2020
|
-
time = Time.parse Date.today.iso8601
|
2021
|
-
pipeline_id = "mypipeline"
|
2022
|
-
logstash_index = "myindex.#{pipeline_id}"
|
2023
|
-
stub_opensearch
|
2024
|
-
stub_opensearch_info
|
2025
|
-
driver.run(default_tag: 'test') do
|
2026
|
-
driver.feed(time.to_i, sample_record.merge({"pipeline_id" => pipeline_id}))
|
2027
|
-
end
|
2028
|
-
assert_equal(logstash_index, index_cmds.first['index']['_index'])
|
2029
|
-
end
|
2030
|
-
end
|
2031
|
-
|
2032
|
-
def test_writes_to_speficied_index_uppercase
|
2033
|
-
driver.configure("index_name MyIndex\n")
|
2034
|
-
stub_opensearch
|
2035
|
-
stub_opensearch_info
|
2036
|
-
driver.run(default_tag: 'test') do
|
2037
|
-
driver.feed(sample_record)
|
2038
|
-
end
|
2039
|
-
# Allthough index_name has upper-case characters,
|
2040
|
-
# it should be set as lower-case when sent to elasticsearch.
|
2041
|
-
assert_equal('myindex', index_cmds.first['index']['_index'])
|
2042
|
-
end
|
2043
|
-
|
2044
|
-
def test_writes_to_target_index_key
|
2045
|
-
driver.configure("target_index_key @target_index\n")
|
2046
|
-
stub_opensearch
|
2047
|
-
stub_opensearch_info
|
2048
|
-
record = sample_record.clone
|
2049
|
-
driver.run(default_tag: 'test') do
|
2050
|
-
driver.feed(sample_record.merge('@target_index' => 'local-override'))
|
2051
|
-
end
|
2052
|
-
assert_equal('local-override', index_cmds.first['index']['_index'])
|
2053
|
-
assert_nil(index_cmds[1]['@target_index'])
|
2054
|
-
end
|
2055
|
-
|
2056
|
-
def test_writes_to_target_index_key_logstash
|
2057
|
-
driver.configure("target_index_key @target_index
|
2058
|
-
logstash_format true")
|
2059
|
-
time = Time.parse Date.today.iso8601
|
2060
|
-
stub_opensearch
|
2061
|
-
stub_opensearch_info
|
2062
|
-
driver.run(default_tag: 'test') do
|
2063
|
-
driver.feed(time.to_i, sample_record.merge('@target_index' => 'local-override'))
|
2064
|
-
end
|
2065
|
-
assert_equal('local-override', index_cmds.first['index']['_index'])
|
2066
|
-
end
|
2067
|
-
|
2068
|
-
def test_writes_to_target_index_key_logstash_uppercase
|
2069
|
-
driver.configure("target_index_key @target_index
|
2070
|
-
logstash_format true")
|
2071
|
-
time = Time.parse Date.today.iso8601
|
2072
|
-
stub_opensearch
|
2073
|
-
stub_opensearch_info
|
2074
|
-
driver.run(default_tag: 'test') do
|
2075
|
-
driver.feed(time.to_i, sample_record.merge('@target_index' => 'LOCAL-OVERRIDE'))
|
2076
|
-
end
|
2077
|
-
# Allthough @target_index has upper-case characters,
|
2078
|
-
# it should be set as lower-case when sent to elasticsearch.
|
2079
|
-
assert_equal('local-override', index_cmds.first['index']['_index'])
|
2080
|
-
end
|
2081
|
-
|
2082
|
-
def test_writes_to_default_index_with_pipeline
|
2083
|
-
pipeline = "fluentd"
|
2084
|
-
driver.configure("pipeline #{pipeline}")
|
2085
|
-
stub_opensearch
|
2086
|
-
stub_opensearch_info
|
2087
|
-
driver.run(default_tag: 'test') do
|
2088
|
-
driver.feed(sample_record)
|
2089
|
-
end
|
2090
|
-
assert_equal(pipeline, index_cmds.first['index']['pipeline'])
|
2091
|
-
end
|
2092
|
-
|
2093
|
-
def stub_opensearch_affinity_target_index_search_with_body(url="http://localhost:9200/logstash-*/_search", ids, return_body_str)
|
2094
|
-
# Note: ids used in query is unique list of ids
|
2095
|
-
stub_request(:post, url)
|
2096
|
-
.with(
|
2097
|
-
body: "{\"query\":{\"ids\":{\"values\":#{ids.uniq.to_json}}},\"_source\":false,\"sort\":[{\"_index\":{\"order\":\"desc\"}}]}",
|
2098
|
-
)
|
2099
|
-
.to_return(lambda do |req|
|
2100
|
-
{ :status => 200,
|
2101
|
-
:headers => { 'Content-Type' => 'json' },
|
2102
|
-
:body => return_body_str
|
2103
|
-
}
|
2104
|
-
end)
|
2105
|
-
end
|
2106
|
-
|
2107
|
-
def stub_opensearch_affinity_target_index_search(url="http://localhost:9200/logstash-*/_search", ids, indices)
|
2108
|
-
# Example ids and indices arrays.
|
2109
|
-
# [ "3408a2c8eecd4fbfb82e45012b54fa82", "2816fc6ef4524b3f8f7e869002005433"]
|
2110
|
-
# [ "logstash-2021.04.28", "logstash-2021.04.29"]
|
2111
|
-
body = %({
|
2112
|
-
"took" : 31,
|
2113
|
-
"timed_out" : false,
|
2114
|
-
"_shards" : {
|
2115
|
-
"total" : 52,
|
2116
|
-
"successful" : 52,
|
2117
|
-
"skipped" : 48,
|
2118
|
-
"failed" : 0
|
2119
|
-
},
|
2120
|
-
"hits" : {
|
2121
|
-
"total" : {
|
2122
|
-
"value" : 356,
|
2123
|
-
"relation" : "eq"
|
2124
|
-
},
|
2125
|
-
"max_score" : null,
|
2126
|
-
"hits" : [
|
2127
|
-
{
|
2128
|
-
"_index" : "#{indices[0]}",
|
2129
|
-
"_type" : "_doc",
|
2130
|
-
"_id" : "#{ids[0]}",
|
2131
|
-
"_score" : null,
|
2132
|
-
"sort" : [
|
2133
|
-
"#{indices[0]}"
|
2134
|
-
]
|
2135
|
-
},
|
2136
|
-
{
|
2137
|
-
"_index" : "#{indices[1]}",
|
2138
|
-
"_type" : "_doc",
|
2139
|
-
"_id" : "#{ids[1]}",
|
2140
|
-
"_score" : null,
|
2141
|
-
"sort" : [
|
2142
|
-
"#{indices[1]}"
|
2143
|
-
]
|
2144
|
-
}
|
2145
|
-
]
|
2146
|
-
}
|
2147
|
-
})
|
2148
|
-
stub_opensearch_affinity_target_index_search_with_body(ids, body)
|
2149
|
-
end
|
2150
|
-
|
2151
|
-
def stub_opensearch_affinity_target_index_search_return_empty(url="http://localhost:9200/logstash-*/_search", ids)
|
2152
|
-
empty_body = %({
|
2153
|
-
"took" : 5,
|
2154
|
-
"timed_out" : false,
|
2155
|
-
"_shards" : {
|
2156
|
-
"total" : 54,
|
2157
|
-
"successful" : 54,
|
2158
|
-
"skipped" : 53,
|
2159
|
-
"failed" : 0
|
2160
|
-
},
|
2161
|
-
"hits" : {
|
2162
|
-
"total" : {
|
2163
|
-
"value" : 0,
|
2164
|
-
"relation" : "eq"
|
2165
|
-
},
|
2166
|
-
"max_score" : null,
|
2167
|
-
"hits" : [ ]
|
2168
|
-
}
|
2169
|
-
})
|
2170
|
-
stub_opensearch_affinity_target_index_search_with_body(ids, empty_body)
|
2171
|
-
end
|
2172
|
-
|
2173
|
-
def test_writes_to_affinity_target_index
|
2174
|
-
driver.configure("target_index_affinity true
|
2175
|
-
logstash_format true
|
2176
|
-
id_key my_id
|
2177
|
-
write_operation update")
|
2178
|
-
|
2179
|
-
my_id_value = "3408a2c8eecd4fbfb82e45012b54fa82"
|
2180
|
-
ids = [my_id_value]
|
2181
|
-
indices = ["logstash-2021.04.28"]
|
2182
|
-
stub_opensearch
|
2183
|
-
stub_opensearch_info
|
2184
|
-
stub_opensearch_affinity_target_index_search(ids, indices)
|
2185
|
-
driver.run(default_tag: 'test') do
|
2186
|
-
driver.feed(sample_record('my_id' => my_id_value))
|
2187
|
-
end
|
2188
|
-
assert_equal('logstash-2021.04.28', index_cmds.first['update']['_index'])
|
2189
|
-
end
|
2190
|
-
|
2191
|
-
def test_writes_to_affinity_target_index_write_operation_upsert
|
2192
|
-
driver.configure("target_index_affinity true
|
2193
|
-
logstash_format true
|
2194
|
-
id_key my_id
|
2195
|
-
write_operation upsert")
|
2196
|
-
|
2197
|
-
my_id_value = "3408a2c8eecd4fbfb82e45012b54fa82"
|
2198
|
-
ids = [my_id_value]
|
2199
|
-
indices = ["logstash-2021.04.28"]
|
2200
|
-
stub_opensearch
|
2201
|
-
stub_opensearch_info
|
2202
|
-
stub_opensearch_affinity_target_index_search(ids, indices)
|
2203
|
-
driver.run(default_tag: 'test') do
|
2204
|
-
driver.feed(sample_record('my_id' => my_id_value))
|
2205
|
-
end
|
2206
|
-
assert_equal('logstash-2021.04.28', index_cmds.first['update']['_index'])
|
2207
|
-
end
|
2208
|
-
|
2209
|
-
def test_writes_to_affinity_target_index_index_not_exists_yet
|
2210
|
-
driver.configure("target_index_affinity true
|
2211
|
-
logstash_format true
|
2212
|
-
id_key my_id
|
2213
|
-
write_operation update")
|
2214
|
-
|
2215
|
-
my_id_value = "3408a2c8eecd4fbfb82e45012b54fa82"
|
2216
|
-
ids = [my_id_value]
|
2217
|
-
stub_opensearch
|
2218
|
-
stub_opensearch_info
|
2219
|
-
stub_opensearch_affinity_target_index_search_return_empty(ids)
|
2220
|
-
time = Time.parse Date.today.iso8601
|
2221
|
-
driver.run(default_tag: 'test') do
|
2222
|
-
driver.feed(time.to_i, sample_record('my_id' => my_id_value))
|
2223
|
-
end
|
2224
|
-
assert_equal("logstash-#{time.utc.strftime("%Y.%m.%d")}", index_cmds.first['update']['_index'])
|
2225
|
-
end
|
2226
|
-
|
2227
|
-
def test_writes_to_affinity_target_index_multiple_indices
|
2228
|
-
driver.configure("target_index_affinity true
|
2229
|
-
logstash_format true
|
2230
|
-
id_key my_id
|
2231
|
-
write_operation update")
|
2232
|
-
|
2233
|
-
my_id_value = "2816fc6ef4524b3f8f7e869002005433"
|
2234
|
-
my_id_value2 = "3408a2c8eecd4fbfb82e45012b54fa82"
|
2235
|
-
ids = [my_id_value, my_id_value2]
|
2236
|
-
indices = ["logstash-2021.04.29", "logstash-2021.04.28"]
|
2237
|
-
stub_opensearch_info
|
2238
|
-
stub_opensearch_all_requests
|
2239
|
-
stub_opensearch_affinity_target_index_search(ids, indices)
|
2240
|
-
driver.run(default_tag: 'test') do
|
2241
|
-
driver.feed(sample_record('my_id' => my_id_value))
|
2242
|
-
driver.feed(sample_record('my_id' => my_id_value2))
|
2243
|
-
end
|
2244
|
-
assert_equal(2, index_cmds_all_requests.count)
|
2245
|
-
assert_equal('logstash-2021.04.29', index_cmds_all_requests[0].first['update']['_index'])
|
2246
|
-
assert_equal(my_id_value, index_cmds_all_requests[0].first['update']['_id'])
|
2247
|
-
assert_equal('logstash-2021.04.28', index_cmds_all_requests[1].first['update']['_index'])
|
2248
|
-
assert_equal(my_id_value2, index_cmds_all_requests[1].first['update']['_id'])
|
2249
|
-
end
|
2250
|
-
|
2251
|
-
def test_writes_to_affinity_target_index_same_id_dublicated_write_to_oldest_index
|
2252
|
-
driver.configure("target_index_affinity true
|
2253
|
-
logstash_format true
|
2254
|
-
id_key my_id
|
2255
|
-
write_operation update")
|
2256
|
-
|
2257
|
-
my_id_value = "2816fc6ef4524b3f8f7e869002005433"
|
2258
|
-
# It may happen than same id has inserted to two index while data inserted during rollover period
|
2259
|
-
ids = [my_id_value, my_id_value]
|
2260
|
-
# Simulate the used sorting here, as search sorts indices in DESC order to pick only oldest index per single _id
|
2261
|
-
indices = ["logstash-2021.04.29", "logstash-2021.04.28"]
|
2262
|
-
|
2263
|
-
stub_opensearch_info
|
2264
|
-
stub_opensearch_all_requests
|
2265
|
-
stub_opensearch_affinity_target_index_search(ids, indices)
|
2266
|
-
driver.run(default_tag: 'test') do
|
2267
|
-
driver.feed(sample_record('my_id' => my_id_value))
|
2268
|
-
driver.feed(sample_record('my_id' => my_id_value))
|
2269
|
-
end
|
2270
|
-
assert_equal('logstash-2021.04.28', index_cmds.first['update']['_index'])
|
2271
|
-
|
2272
|
-
assert_equal(1, index_cmds_all_requests.count)
|
2273
|
-
assert_equal('logstash-2021.04.28', index_cmds_all_requests[0].first['update']['_index'])
|
2274
|
-
assert_equal(my_id_value, index_cmds_all_requests[0].first['update']['_id'])
|
2275
|
-
end
|
2276
|
-
|
2277
|
-
class PipelinePlaceholdersTest < self
|
2278
|
-
def test_writes_to_default_index_with_pipeline_tag_placeholder
|
2279
|
-
pipeline = "fluentd-${tag}"
|
2280
|
-
driver.configure("pipeline #{pipeline}")
|
2281
|
-
stub_opensearch
|
2282
|
-
stub_opensearch_info
|
2283
|
-
driver.run(default_tag: 'test.builtin.placeholder') do
|
2284
|
-
driver.feed(sample_record)
|
2285
|
-
end
|
2286
|
-
assert_equal("fluentd-test.builtin.placeholder", index_cmds.first['index']['pipeline'])
|
2287
|
-
end
|
2288
|
-
|
2289
|
-
def test_writes_to_default_index_with_pipeline_time_placeholder
|
2290
|
-
driver.configure(Fluent::Config::Element.new(
|
2291
|
-
'ROOT', '', {
|
2292
|
-
'@type' => 'elasticsearch',
|
2293
|
-
'pipeline' => 'fluentd-%Y%m%d',
|
2294
|
-
}, [
|
2295
|
-
Fluent::Config::Element.new('buffer', 'tag,time', {
|
2296
|
-
'chunk_keys' => ['tag', 'time'],
|
2297
|
-
'timekey' => 3600,
|
2298
|
-
}, [])
|
2299
|
-
]
|
2300
|
-
))
|
2301
|
-
time = Time.parse Date.today.iso8601
|
2302
|
-
pipeline = "fluentd-#{time.getutc.strftime("%Y%m%d")}"
|
2303
|
-
stub_opensearch
|
2304
|
-
stub_opensearch_info
|
2305
|
-
driver.run(default_tag: 'test') do
|
2306
|
-
driver.feed(time.to_i, sample_record)
|
2307
|
-
end
|
2308
|
-
assert_equal(pipeline, index_cmds.first['index']['pipeline'])
|
2309
|
-
end
|
2310
|
-
|
2311
|
-
def test_writes_to_default_index_with_pipeline_custom_key_placeholder
|
2312
|
-
driver.configure(Fluent::Config::Element.new(
|
2313
|
-
'ROOT', '', {
|
2314
|
-
'@type' => 'elasticsearch',
|
2315
|
-
'pipeline' => 'fluentd-${pipeline_id}',
|
2316
|
-
}, [
|
2317
|
-
Fluent::Config::Element.new('buffer', 'tag,pipeline_id', {}, [])
|
2318
|
-
]
|
2319
|
-
))
|
2320
|
-
time = Time.parse Date.today.iso8601
|
2321
|
-
pipeline_id = "mypipeline"
|
2322
|
-
logstash_index = "fluentd-#{pipeline_id}"
|
2323
|
-
stub_opensearch
|
2324
|
-
stub_opensearch_info
|
2325
|
-
driver.run(default_tag: 'test') do
|
2326
|
-
driver.feed(time.to_i, sample_record.merge({"pipeline_id" => pipeline_id}))
|
2327
|
-
end
|
2328
|
-
assert_equal(logstash_index, index_cmds.first['index']['pipeline'])
|
2329
|
-
end
|
2330
|
-
end
|
2331
|
-
|
2332
|
-
def test_writes_to_target_index_key_fallack
|
2333
|
-
driver.configure("target_index_key @target_index\n")
|
2334
|
-
stub_opensearch
|
2335
|
-
stub_opensearch_info
|
2336
|
-
driver.run(default_tag: 'test') do
|
2337
|
-
driver.feed(sample_record)
|
2338
|
-
end
|
2339
|
-
assert_equal('fluentd', index_cmds.first['index']['_index'])
|
2340
|
-
end
|
2341
|
-
|
2342
|
-
def test_writes_to_target_index_key_fallack_logstash
|
2343
|
-
driver.configure("target_index_key @target_index\n
|
2344
|
-
logstash_format true")
|
2345
|
-
time = Time.parse Date.today.iso8601
|
2346
|
-
logstash_index = "logstash-#{time.getutc.strftime("%Y.%m.%d")}"
|
2347
|
-
stub_opensearch
|
2348
|
-
stub_opensearch_info
|
2349
|
-
driver.run(default_tag: 'test') do
|
2350
|
-
driver.feed(time.to_i, sample_record)
|
2351
|
-
end
|
2352
|
-
assert_equal(logstash_index, index_cmds.first['index']['_index'])
|
2353
|
-
end
|
2354
|
-
|
2355
|
-
data(
|
2356
|
-
"OpenSearch default" => {"os_version" => 1, "_type" => "_doc", "suppress_type" => false},
|
2357
|
-
"Suppressed type" => {"os_version" => 1, "_type" => nil, "suppress_type" => true},
|
2358
|
-
"OpenSearch 2" => {"os_version" => 2, "_type" => nil, "suppress_type" => true},
|
2359
|
-
)
|
2360
|
-
def test_writes_to_speficied_type(data)
|
2361
|
-
driver('', data["os_version"]).configure("suppress_type_name #{data['suppress_type']}")
|
2362
|
-
stub_opensearch
|
2363
|
-
stub_opensearch_info
|
2364
|
-
driver.run(default_tag: 'test') do
|
2365
|
-
driver.feed(sample_record)
|
2366
|
-
end
|
2367
|
-
if data["suppress_type"] || data["os_version"] >= 2
|
2368
|
-
assert_false(index_cmds.first['index'].has_key?("_type"))
|
2369
|
-
else
|
2370
|
-
assert_true(index_cmds.first['index'].has_key?("_type"))
|
2371
|
-
assert_equal(data['_type'], index_cmds.first['index']['_type'])
|
2372
|
-
end
|
2373
|
-
end
|
2374
|
-
|
2375
|
-
def test_writes_to_speficied_host
|
2376
|
-
driver.configure("host 192.168.33.50\n")
|
2377
|
-
elastic_request = stub_opensearch("http://192.168.33.50:9200/_bulk")
|
2378
|
-
stub_opensearch_info("http://192.168.33.50:9200/")
|
2379
|
-
driver.run(default_tag: 'test') do
|
2380
|
-
driver.feed(sample_record)
|
2381
|
-
end
|
2382
|
-
assert_requested(elastic_request)
|
2383
|
-
end
|
2384
|
-
|
2385
|
-
def test_writes_to_speficied_port
|
2386
|
-
driver.configure("port 9201\n")
|
2387
|
-
elastic_request = stub_opensearch("http://localhost:9201/_bulk")
|
2388
|
-
stub_opensearch_info("http://localhost:9201")
|
2389
|
-
driver.run(default_tag: 'test') do
|
2390
|
-
driver.feed(sample_record)
|
2391
|
-
end
|
2392
|
-
assert_requested(elastic_request)
|
2393
|
-
end
|
2394
|
-
|
2395
|
-
def test_writes_to_multi_hosts
|
2396
|
-
hosts = [['192.168.33.50', 9201], ['192.168.33.51', 9201], ['192.168.33.52', 9201]]
|
2397
|
-
hosts_string = hosts.map {|x| "#{x[0]}:#{x[1]}"}.compact.join(',')
|
2398
|
-
|
2399
|
-
driver.configure("hosts #{hosts_string}")
|
2400
|
-
|
2401
|
-
hosts.each do |host_info|
|
2402
|
-
host, port = host_info
|
2403
|
-
stub_opensearch_with_store_index_command_counts("http://#{host}:#{port}/_bulk")
|
2404
|
-
stub_opensearch_info("http://#{host}:#{port}/")
|
2405
|
-
end
|
2406
|
-
|
2407
|
-
driver.run(default_tag: 'test') do
|
2408
|
-
1000.times do
|
2409
|
-
driver.feed(sample_record.merge('age'=>rand(100)))
|
2410
|
-
end
|
2411
|
-
end
|
2412
|
-
|
2413
|
-
# @note: we cannot make multi chunks with options (flush_interval, buffer_chunk_limit)
|
2414
|
-
# it's Fluentd test driver's constraint
|
2415
|
-
# so @index_command_counts.size is always 1
|
2416
|
-
|
2417
|
-
assert(@index_command_counts.size > 0, "not working with hosts options")
|
2418
|
-
|
2419
|
-
total = 0
|
2420
|
-
@index_command_counts.each do |url, count|
|
2421
|
-
total += count
|
2422
|
-
end
|
2423
|
-
assert_equal(2000, total)
|
2424
|
-
end
|
2425
|
-
|
2426
|
-
def test_nested_record_with_flattening_on
|
2427
|
-
driver.configure("flatten_hashes true
|
2428
|
-
flatten_hashes_separator |")
|
2429
|
-
|
2430
|
-
original_hash = {"foo" => {"bar" => "baz"}, "people" => [
|
2431
|
-
{"age" => "25", "height" => "1ft"},
|
2432
|
-
{"age" => "30", "height" => "2ft"}
|
2433
|
-
]}
|
2434
|
-
|
2435
|
-
expected_output = {"foo|bar"=>"baz", "people" => [
|
2436
|
-
{"age" => "25", "height" => "1ft"},
|
2437
|
-
{"age" => "30", "height" => "2ft"}
|
2438
|
-
]}
|
2439
|
-
|
2440
|
-
stub_opensearch
|
2441
|
-
stub_opensearch_info
|
2442
|
-
driver.run(default_tag: 'test') do
|
2443
|
-
driver.feed(original_hash)
|
2444
|
-
end
|
2445
|
-
assert_equal expected_output, index_cmds[1]
|
2446
|
-
end
|
2447
|
-
|
2448
|
-
def test_nested_record_with_flattening_off
|
2449
|
-
# flattening off by default
|
2450
|
-
|
2451
|
-
original_hash = {"foo" => {"bar" => "baz"}}
|
2452
|
-
expected_output = {"foo" => {"bar" => "baz"}}
|
2453
|
-
|
2454
|
-
stub_opensearch
|
2455
|
-
stub_opensearch_info
|
2456
|
-
driver.run(default_tag: 'test') do
|
2457
|
-
driver.feed(original_hash)
|
2458
|
-
end
|
2459
|
-
assert_equal expected_output, index_cmds[1]
|
2460
|
-
end
|
2461
|
-
|
2462
|
-
def test_makes_bulk_request
|
2463
|
-
stub_opensearch
|
2464
|
-
stub_opensearch_info
|
2465
|
-
driver.run(default_tag: 'test') do
|
2466
|
-
driver.feed(sample_record)
|
2467
|
-
driver.feed(sample_record.merge('age' => 27))
|
2468
|
-
end
|
2469
|
-
assert_equal(4, index_cmds.count)
|
2470
|
-
end
|
2471
|
-
|
2472
|
-
def test_all_re
|
2473
|
-
stub_opensearch
|
2474
|
-
stub_opensearch_info
|
2475
|
-
driver.run(default_tag: 'test') do
|
2476
|
-
driver.feed(sample_record)
|
2477
|
-
driver.feed(sample_record.merge('age' => 27))
|
2478
|
-
end
|
2479
|
-
assert_equal(26, index_cmds[1]['age'])
|
2480
|
-
assert_equal(27, index_cmds[3]['age'])
|
2481
|
-
end
|
2482
|
-
|
2483
|
-
def test_writes_to_logstash_index
|
2484
|
-
driver.configure("logstash_format true\n")
|
2485
|
-
#
|
2486
|
-
# This is 1 second past midnight in BST, so the UTC index should be the day before
|
2487
|
-
dt = DateTime.new(2015, 6, 1, 0, 0, 1, "+01:00")
|
2488
|
-
logstash_index = "logstash-2015.05.31"
|
2489
|
-
stub_opensearch
|
2490
|
-
stub_opensearch_info
|
2491
|
-
driver.run(default_tag: 'test') do
|
2492
|
-
driver.feed(dt.to_time.to_i, sample_record)
|
2493
|
-
end
|
2494
|
-
assert_equal(logstash_index, index_cmds.first['index']['_index'])
|
2495
|
-
end
|
2496
|
-
|
2497
|
-
def test_writes_to_logstash_non_utc_index
|
2498
|
-
driver.configure("logstash_format true
|
2499
|
-
utc_index false")
|
2500
|
-
# When using `utc_index false` the index time will be the local day of
|
2501
|
-
# ingestion time
|
2502
|
-
time = Date.today.to_time
|
2503
|
-
index = "logstash-#{time.strftime("%Y.%m.%d")}"
|
2504
|
-
stub_opensearch
|
2505
|
-
stub_opensearch_info
|
2506
|
-
driver.run(default_tag: 'test') do
|
2507
|
-
driver.feed(time.to_i, sample_record)
|
2508
|
-
end
|
2509
|
-
assert_equal(index, index_cmds.first['index']['_index'])
|
2510
|
-
end
|
2511
|
-
|
2512
|
-
def test_writes_to_logstash_index_with_specified_prefix
|
2513
|
-
driver.configure("logstash_format true
|
2514
|
-
logstash_prefix myprefix")
|
2515
|
-
time = Time.parse Date.today.iso8601
|
2516
|
-
logstash_index = "myprefix-#{time.getutc.strftime("%Y.%m.%d")}"
|
2517
|
-
stub_opensearch
|
2518
|
-
stub_opensearch_info
|
2519
|
-
driver.run(default_tag: 'test') do
|
2520
|
-
driver.feed(time.to_i, sample_record)
|
2521
|
-
end
|
2522
|
-
assert_equal(logstash_index, index_cmds.first['index']['_index'])
|
2523
|
-
end
|
2524
|
-
|
2525
|
-
def test_writes_to_logstash_index_with_specified_prefix_and_separator
|
2526
|
-
separator = '_'
|
2527
|
-
driver.configure("logstash_format true
|
2528
|
-
logstash_prefix_separator #{separator}
|
2529
|
-
logstash_prefix myprefix")
|
2530
|
-
time = Time.parse Date.today.iso8601
|
2531
|
-
logstash_index = "myprefix#{separator}#{time.getutc.strftime("%Y.%m.%d")}"
|
2532
|
-
stub_opensearch
|
2533
|
-
stub_opensearch_info
|
2534
|
-
driver.run(default_tag: 'test') do
|
2535
|
-
driver.feed(time.to_i, sample_record)
|
2536
|
-
end
|
2537
|
-
assert_equal(logstash_index, index_cmds.first['index']['_index'])
|
2538
|
-
end
|
2539
|
-
|
2540
|
-
class LogStashPrefixPlaceholdersTest < self
|
2541
|
-
def test_writes_to_logstash_index_with_specified_prefix_and_tag_placeholder
|
2542
|
-
driver.configure("logstash_format true
|
2543
|
-
logstash_prefix myprefix-${tag}")
|
2544
|
-
time = Time.parse Date.today.iso8601
|
2545
|
-
logstash_index = "myprefix-test-#{time.getutc.strftime("%Y.%m.%d")}"
|
2546
|
-
stub_opensearch
|
2547
|
-
stub_opensearch_info
|
2548
|
-
driver.run(default_tag: 'test') do
|
2549
|
-
driver.feed(time.to_i, sample_record)
|
2550
|
-
end
|
2551
|
-
assert_equal(logstash_index, index_cmds.first['index']['_index'])
|
2552
|
-
end
|
2553
|
-
|
2554
|
-
def test_writes_to_logstash_index_with_specified_prefix_and_time_placeholder
|
2555
|
-
driver.configure(Fluent::Config::Element.new(
|
2556
|
-
'ROOT', '', {
|
2557
|
-
'@type' => 'opensearch',
|
2558
|
-
'logstash_format' => true,
|
2559
|
-
'logstash_prefix' => 'myprefix-%H',
|
2560
|
-
}, [
|
2561
|
-
Fluent::Config::Element.new('buffer', 'tag,time', {
|
2562
|
-
'chunk_keys' => ['tag', 'time'],
|
2563
|
-
'timekey' => 3600,
|
2564
|
-
}, [])
|
2565
|
-
]
|
2566
|
-
))
|
2567
|
-
time = Time.parse Date.today.iso8601
|
2568
|
-
logstash_index = "myprefix-#{time.getutc.strftime("%H")}-#{time.getutc.strftime("%Y.%m.%d")}"
|
2569
|
-
stub_opensearch
|
2570
|
-
stub_opensearch_info
|
2571
|
-
driver.run(default_tag: 'test') do
|
2572
|
-
driver.feed(time.to_i, sample_record)
|
2573
|
-
end
|
2574
|
-
assert_equal(logstash_index, index_cmds.first['index']['_index'])
|
2575
|
-
end
|
2576
|
-
|
2577
|
-
def test_writes_to_logstash_index_with_specified_prefix_and_custom_key_placeholder
|
2578
|
-
driver.configure(Fluent::Config::Element.new(
|
2579
|
-
'ROOT', '', {
|
2580
|
-
'@type' => 'opensearch',
|
2581
|
-
'logstash_format' => true,
|
2582
|
-
'logstash_prefix' => 'myprefix-${pipeline_id}',
|
2583
|
-
}, [
|
2584
|
-
Fluent::Config::Element.new('buffer', 'tag,pipeline_id', {}, [])
|
2585
|
-
]
|
2586
|
-
))
|
2587
|
-
time = Time.parse Date.today.iso8601
|
2588
|
-
pipeline_id = "mypipeline"
|
2589
|
-
logstash_index = "myprefix-#{pipeline_id}-#{time.getutc.strftime("%Y.%m.%d")}"
|
2590
|
-
stub_opensearch
|
2591
|
-
stub_opensearch_info
|
2592
|
-
driver.run(default_tag: 'test') do
|
2593
|
-
driver.feed(time.to_i, sample_record.merge({"pipeline_id" => pipeline_id}))
|
2594
|
-
end
|
2595
|
-
assert_equal(logstash_index, index_cmds.first['index']['_index'])
|
2596
|
-
end
|
2597
|
-
end
|
2598
|
-
|
2599
|
-
class LogStashDateformatPlaceholdersTest < self
|
2600
|
-
def test_writes_to_logstash_index_with_specified_prefix_and_dateformat_placeholder_pattern_1
|
2601
|
-
driver.configure(Fluent::Config::Element.new(
|
2602
|
-
'ROOT', '', {
|
2603
|
-
'@type' => 'opensearch',
|
2604
|
-
'logstash_format' => true,
|
2605
|
-
'logstash_dateformat' => '${indexformat}',
|
2606
|
-
'logstash_prefix' => 'myprefix',
|
2607
|
-
}, [
|
2608
|
-
Fluent::Config::Element.new('buffer', 'tag,time,indexformat', {
|
2609
|
-
'chunk_keys' => ['tag', 'time', 'indexformat'],
|
2610
|
-
'timekey' => 3600,
|
2611
|
-
}, [])
|
2612
|
-
]
|
2613
|
-
))
|
2614
|
-
time = Time.parse Date.today.iso8601
|
2615
|
-
logstash_index = "myprefix-#{time.getutc.strftime("%Y.%m.%d")}"
|
2616
|
-
stub_opensearch
|
2617
|
-
stub_opensearch_info
|
2618
|
-
driver.run(default_tag: 'test') do
|
2619
|
-
driver.feed(time.to_i, sample_record.merge('indexformat' => '%Y.%m.%d'))
|
2620
|
-
end
|
2621
|
-
assert_equal(logstash_index, index_cmds.first['index']['_index'])
|
2622
|
-
end
|
2623
|
-
|
2624
|
-
def test_writes_to_logstash_index_with_specified_prefix_and_dateformat_placeholder_pattern_2
|
2625
|
-
driver.configure(Fluent::Config::Element.new(
|
2626
|
-
'ROOT', '', {
|
2627
|
-
'@type' => 'opensearch',
|
2628
|
-
'logstash_format' => true,
|
2629
|
-
'logstash_dateformat' => '${indexformat}',
|
2630
|
-
'logstash_prefix' => 'myprefix',
|
2631
|
-
}, [
|
2632
|
-
Fluent::Config::Element.new('buffer', 'tag,time,indexformat', {
|
2633
|
-
'chunk_keys' => ['tag', 'time', 'indexformat'],
|
2634
|
-
'timekey' => 3600,
|
2635
|
-
}, [])
|
2636
|
-
]
|
2637
|
-
))
|
2638
|
-
time = Time.parse Date.today.iso8601
|
2639
|
-
logstash_index = "myprefix-#{time.getutc.strftime("%Y.%m")}"
|
2640
|
-
stub_opensearch
|
2641
|
-
stub_opensearch_info
|
2642
|
-
driver.run(default_tag: 'test') do
|
2643
|
-
driver.feed(time.to_i, sample_record.merge('indexformat' => '%Y.%m'))
|
2644
|
-
end
|
2645
|
-
assert_equal(logstash_index, index_cmds.first['index']['_index'])
|
2646
|
-
end
|
2647
|
-
end
|
2648
|
-
|
2649
|
-
class HostnamePlaceholders < self
|
2650
|
-
def test_writes_to_extracted_host
|
2651
|
-
driver.configure("host ${tag}\n")
|
2652
|
-
time = Time.parse Date.today.iso8601
|
2653
|
-
elastic_request = stub_opensearch("http://extracted-host:9200/_bulk")
|
2654
|
-
stub_opensearch_info("http://extracted-host:9200/")
|
2655
|
-
driver.run(default_tag: 'extracted-host') do
|
2656
|
-
driver.feed(time.to_i, sample_record)
|
2657
|
-
end
|
2658
|
-
assert_requested(elastic_request)
|
2659
|
-
end
|
2660
|
-
|
2661
|
-
def test_writes_to_multi_hosts_with_placeholders
|
2662
|
-
hosts = [['${tag}', 9201], ['192.168.33.51', 9201], ['192.168.33.52', 9201]]
|
2663
|
-
hosts_string = hosts.map {|x| "#{x[0]}:#{x[1]}"}.compact.join(',')
|
2664
|
-
|
2665
|
-
driver.configure("hosts #{hosts_string}")
|
2666
|
-
|
2667
|
-
hosts.each do |host_info|
|
2668
|
-
host, port = host_info
|
2669
|
-
host = "extracted-host" if host == '${tag}'
|
2670
|
-
stub_opensearch_with_store_index_command_counts("http://#{host}:#{port}/_bulk")
|
2671
|
-
stub_opensearch_info("http://#{host}:#{port}")
|
2672
|
-
end
|
2673
|
-
|
2674
|
-
driver.run(default_tag: 'extracted-host') do
|
2675
|
-
1000.times do
|
2676
|
-
driver.feed(sample_record.merge('age'=>rand(100)))
|
2677
|
-
end
|
2678
|
-
end
|
2679
|
-
|
2680
|
-
# @note: we cannot make multi chunks with options (flush_interval, buffer_chunk_limit)
|
2681
|
-
# it's Fluentd test driver's constraint
|
2682
|
-
# so @index_command_counts.size is always 1
|
2683
|
-
|
2684
|
-
assert(@index_command_counts.size > 0, "not working with hosts options")
|
2685
|
-
|
2686
|
-
total = 0
|
2687
|
-
@index_command_counts.each do |url, count|
|
2688
|
-
total += count
|
2689
|
-
end
|
2690
|
-
assert_equal(2000, total)
|
2691
|
-
end
|
2692
|
-
|
2693
|
-
def test_writes_to_extracted_host_with_time_placeholder
|
2694
|
-
driver.configure(Fluent::Config::Element.new(
|
2695
|
-
'ROOT', '', {
|
2696
|
-
'@type' => 'elasticsearch',
|
2697
|
-
'host' => 'host-%Y%m%d',
|
2698
|
-
}, [
|
2699
|
-
Fluent::Config::Element.new('buffer', 'tag,time', {
|
2700
|
-
'chunk_keys' => ['tag', 'time'],
|
2701
|
-
'timekey' => 3600,
|
2702
|
-
}, [])
|
2703
|
-
]
|
2704
|
-
))
|
2705
|
-
stub_opensearch
|
2706
|
-
stub_opensearch_info
|
2707
|
-
time = Time.parse Date.today.iso8601
|
2708
|
-
elastic_request = stub_opensearch("http://host-#{time.utc.strftime('%Y%m%d')}:9200/_bulk")
|
2709
|
-
stub_opensearch_info("http://host-#{time.utc.strftime('%Y%m%d')}:9200/")
|
2710
|
-
driver.run(default_tag: 'test') do
|
2711
|
-
driver.feed(time.to_i, sample_record)
|
2712
|
-
end
|
2713
|
-
assert_requested(elastic_request)
|
2714
|
-
end
|
2715
|
-
|
2716
|
-
def test_writes_to_extracted_host_with_custom_key_placeholder
|
2717
|
-
driver.configure(Fluent::Config::Element.new(
|
2718
|
-
'ROOT', '', {
|
2719
|
-
'@type' => 'opensearch',
|
2720
|
-
'host' => 'myhost-${pipeline_id}',
|
2721
|
-
}, [
|
2722
|
-
Fluent::Config::Element.new('buffer', 'tag,pipeline_id', {}, [])
|
2723
|
-
]
|
2724
|
-
))
|
2725
|
-
time = Time.parse Date.today.iso8601
|
2726
|
-
first_pipeline_id = "1"
|
2727
|
-
second_pipeline_id = "2"
|
2728
|
-
first_request = stub_opensearch("http://myhost-1:9200/_bulk")
|
2729
|
-
second_request = stub_opensearch("http://myhost-2:9200/_bulk")
|
2730
|
-
stub_opensearch_info("http://myhost-1:9200/")
|
2731
|
-
stub_opensearch_info("http://myhost-2:9200/")
|
2732
|
-
driver.run(default_tag: 'test') do
|
2733
|
-
driver.feed(time.to_i, sample_record.merge({"pipeline_id" => first_pipeline_id}))
|
2734
|
-
driver.feed(time.to_i, sample_record.merge({"pipeline_id" => second_pipeline_id}))
|
2735
|
-
end
|
2736
|
-
assert_requested(first_request)
|
2737
|
-
assert_requested(second_request)
|
2738
|
-
end
|
2739
|
-
|
2740
|
-
def test_writes_to_extracted_host_with_placeholder_replaced_in_exception_message
|
2741
|
-
driver.configure(Fluent::Config::Element.new(
|
2742
|
-
'ROOT', '', {
|
2743
|
-
'@type' => 'opensearch',
|
2744
|
-
'host' => 'myhost-${pipeline_id}',
|
2745
|
-
}, [
|
2746
|
-
Fluent::Config::Element.new('buffer', 'tag,pipeline_id', {}, [])
|
2747
|
-
]
|
2748
|
-
))
|
2749
|
-
time = Time.parse Date.today.iso8601
|
2750
|
-
pipeline_id = "1"
|
2751
|
-
request = stub_opensearch_unavailable("http://myhost-1:9200/_bulk")
|
2752
|
-
stub_opensearch_info("http://myhost-1:9200/")
|
2753
|
-
exception = assert_raise(Fluent::Plugin::OpenSearchOutput::RecoverableRequestFailure) {
|
2754
|
-
driver.run(default_tag: 'test') do
|
2755
|
-
driver.feed(time.to_i, sample_record.merge({"pipeline_id" => pipeline_id}))
|
2756
|
-
end
|
2757
|
-
}
|
2758
|
-
assert_equal("could not push logs to OpenSearch cluster ({:host=>\"myhost-1\", :port=>9200, :scheme=>\"http\"}): [503] ", exception.message)
|
2759
|
-
end
|
2760
|
-
end
|
2761
|
-
|
2762
|
-
def test_writes_to_logstash_index_with_specified_prefix_uppercase
|
2763
|
-
driver.configure("logstash_format true
|
2764
|
-
logstash_prefix MyPrefix")
|
2765
|
-
time = Time.parse Date.today.iso8601
|
2766
|
-
logstash_index = "myprefix-#{time.getutc.strftime("%Y.%m.%d")}"
|
2767
|
-
stub_opensearch
|
2768
|
-
stub_opensearch_info
|
2769
|
-
driver.run(default_tag: 'test') do
|
2770
|
-
driver.feed(time.to_i, sample_record)
|
2771
|
-
end
|
2772
|
-
# Allthough logstash_prefix has upper-case characters,
|
2773
|
-
# it should be set as lower-case when sent to elasticsearch.
|
2774
|
-
assert_equal(logstash_index, index_cmds.first['index']['_index'])
|
2775
|
-
end
|
2776
|
-
|
2777
|
-
def test_writes_to_logstash_index_with_specified_dateformat
|
2778
|
-
driver.configure("logstash_format true
|
2779
|
-
logstash_dateformat %Y.%m")
|
2780
|
-
time = Time.parse Date.today.iso8601
|
2781
|
-
logstash_index = "logstash-#{time.getutc.strftime("%Y.%m")}"
|
2782
|
-
stub_opensearch
|
2783
|
-
stub_opensearch_info
|
2784
|
-
driver.run(default_tag: 'test') do
|
2785
|
-
driver.feed(time.to_i, sample_record)
|
2786
|
-
end
|
2787
|
-
assert_equal(logstash_index, index_cmds.first['index']['_index'])
|
2788
|
-
end
|
2789
|
-
|
2790
|
-
def test_writes_to_logstash_index_with_specified_prefix_and_dateformat
|
2791
|
-
driver.configure("logstash_format true
|
2792
|
-
logstash_prefix myprefix
|
2793
|
-
logstash_dateformat %Y.%m")
|
2794
|
-
time = Time.parse Date.today.iso8601
|
2795
|
-
logstash_index = "myprefix-#{time.getutc.strftime("%Y.%m")}"
|
2796
|
-
stub_opensearch
|
2797
|
-
stub_opensearch_info
|
2798
|
-
driver.run(default_tag: 'test') do
|
2799
|
-
driver.feed(time.to_i, sample_record)
|
2800
|
-
end
|
2801
|
-
assert_equal(logstash_index, index_cmds.first['index']['_index'])
|
2802
|
-
end
|
2803
|
-
|
2804
|
-
def test_error_if_tag_not_in_chunk_keys
|
2805
|
-
assert_raise(Fluent::ConfigError) {
|
2806
|
-
config = %{
|
2807
|
-
<buffer foo>
|
2808
|
-
</buffer>
|
2809
|
-
}
|
2810
|
-
driver.configure(config)
|
2811
|
-
}
|
2812
|
-
end
|
2813
|
-
|
2814
|
-
def test_can_use_custom_chunk_along_with_tag
|
2815
|
-
config = %{
|
2816
|
-
<buffer tag, foo>
|
2817
|
-
</buffer>
|
2818
|
-
}
|
2819
|
-
driver.configure(config)
|
2820
|
-
end
|
2821
|
-
|
2822
|
-
def test_doesnt_add_logstash_timestamp_by_default
|
2823
|
-
stub_opensearch
|
2824
|
-
stub_opensearch_info
|
2825
|
-
driver.run(default_tag: 'test') do
|
2826
|
-
driver.feed(sample_record)
|
2827
|
-
end
|
2828
|
-
assert_nil(index_cmds[1]['@timestamp'])
|
2829
|
-
end
|
2830
|
-
|
2831
|
-
def test_adds_timestamp_when_logstash
|
2832
|
-
driver.configure("logstash_format true\n")
|
2833
|
-
stub_opensearch
|
2834
|
-
stub_opensearch_info
|
2835
|
-
ts = DateTime.now
|
2836
|
-
time = Fluent::EventTime.from_time(ts.to_time)
|
2837
|
-
driver.run(default_tag: 'test') do
|
2838
|
-
driver.feed(time, sample_record)
|
2839
|
-
end
|
2840
|
-
assert(index_cmds[1].has_key? '@timestamp')
|
2841
|
-
assert_equal(ts.iso8601(9), index_cmds[1]['@timestamp'])
|
2842
|
-
end
|
2843
|
-
|
2844
|
-
def test_adds_timestamp_when_include_timestamp
|
2845
|
-
driver.configure("include_timestamp true\n")
|
2846
|
-
stub_opensearch
|
2847
|
-
stub_opensearch_info
|
2848
|
-
ts = DateTime.now
|
2849
|
-
time = Fluent::EventTime.from_time(ts.to_time)
|
2850
|
-
driver.run(default_tag: 'test') do
|
2851
|
-
driver.feed(time, sample_record)
|
2852
|
-
end
|
2853
|
-
assert(index_cmds[1].has_key? '@timestamp')
|
2854
|
-
assert_equal(ts.iso8601(9), index_cmds[1]['@timestamp'])
|
2855
|
-
end
|
2856
|
-
|
2857
|
-
def test_uses_custom_timestamp_when_included_in_record
|
2858
|
-
driver.configure("logstash_format true\n")
|
2859
|
-
stub_opensearch
|
2860
|
-
stub_opensearch_info
|
2861
|
-
ts = DateTime.new(2001,2,3).iso8601
|
2862
|
-
driver.run(default_tag: 'test') do
|
2863
|
-
driver.feed(sample_record.merge!('@timestamp' => ts))
|
2864
|
-
end
|
2865
|
-
assert(index_cmds[1].has_key? '@timestamp')
|
2866
|
-
assert_equal(ts, index_cmds[1]['@timestamp'])
|
2867
|
-
end
|
2868
|
-
|
2869
|
-
def test_uses_custom_timestamp_when_included_in_record_without_logstash
|
2870
|
-
driver.configure("include_timestamp true\n")
|
2871
|
-
stub_opensearch
|
2872
|
-
stub_opensearch_info
|
2873
|
-
ts = DateTime.new(2001,2,3).iso8601
|
2874
|
-
driver.run(default_tag: 'test') do
|
2875
|
-
driver.feed(sample_record.merge!('@timestamp' => ts))
|
2876
|
-
end
|
2877
|
-
assert(index_cmds[1].has_key? '@timestamp')
|
2878
|
-
assert_equal(ts, index_cmds[1]['@timestamp'])
|
2879
|
-
end
|
2880
|
-
|
2881
|
-
def test_uses_custom_time_key
|
2882
|
-
driver.configure("logstash_format true
|
2883
|
-
time_key vtm\n")
|
2884
|
-
stub_opensearch
|
2885
|
-
stub_opensearch_info
|
2886
|
-
ts = DateTime.new(2001,2,3).iso8601(9)
|
2887
|
-
driver.run(default_tag: 'test') do
|
2888
|
-
driver.feed(sample_record.merge!('vtm' => ts))
|
2889
|
-
end
|
2890
|
-
assert(index_cmds[1].has_key? '@timestamp')
|
2891
|
-
assert_equal(ts, index_cmds[1]['@timestamp'])
|
2892
|
-
end
|
2893
|
-
|
2894
|
-
def test_uses_custom_time_key_with_float_record
|
2895
|
-
driver.configure("logstash_format true
|
2896
|
-
time_precision 3
|
2897
|
-
time_key vtm\n")
|
2898
|
-
stub_opensearch
|
2899
|
-
stub_opensearch_info
|
2900
|
-
time = Time.now
|
2901
|
-
float_time = time.to_f
|
2902
|
-
driver.run(default_tag: 'test') do
|
2903
|
-
driver.feed(sample_record.merge!('vtm' => float_time))
|
2904
|
-
end
|
2905
|
-
assert(index_cmds[1].has_key? '@timestamp')
|
2906
|
-
assert_equal(time.to_datetime.iso8601(3), index_cmds[1]['@timestamp'])
|
2907
|
-
end
|
2908
|
-
|
2909
|
-
def test_uses_custom_time_key_with_format
|
2910
|
-
driver.configure("logstash_format true
|
2911
|
-
time_key_format %Y-%m-%d %H:%M:%S.%N%z
|
2912
|
-
time_key vtm\n")
|
2913
|
-
stub_opensearch
|
2914
|
-
stub_opensearch_info
|
2915
|
-
ts = "2001-02-03 13:14:01.673+02:00"
|
2916
|
-
driver.run(default_tag: 'test') do
|
2917
|
-
driver.feed(sample_record.merge!('vtm' => ts))
|
2918
|
-
end
|
2919
|
-
assert(index_cmds[1].has_key? '@timestamp')
|
2920
|
-
assert_equal(DateTime.parse(ts).iso8601(9), index_cmds[1]['@timestamp'])
|
2921
|
-
assert_equal("logstash-2001.02.03", index_cmds[0]['index']['_index'])
|
2922
|
-
end
|
2923
|
-
|
2924
|
-
def test_uses_custom_time_key_with_float_record_and_format
|
2925
|
-
driver.configure("logstash_format true
|
2926
|
-
time_key_format %Y-%m-%d %H:%M:%S.%N%z
|
2927
|
-
time_key vtm\n")
|
2928
|
-
stub_opensearch
|
2929
|
-
stub_opensearch_info
|
2930
|
-
ts = "2001-02-03 13:14:01.673+02:00"
|
2931
|
-
time = Time.parse(ts)
|
2932
|
-
current_zone_offset = Time.new(2001, 02, 03).to_datetime.offset
|
2933
|
-
float_time = time.to_f
|
2934
|
-
driver.run(default_tag: 'test') do
|
2935
|
-
driver.feed(sample_record.merge!('vtm' => float_time))
|
2936
|
-
end
|
2937
|
-
assert(index_cmds[1].has_key? '@timestamp')
|
2938
|
-
assert_equal(DateTime.parse(ts).new_offset(current_zone_offset).iso8601(9), index_cmds[1]['@timestamp'])
|
2939
|
-
end
|
2940
|
-
|
2941
|
-
def test_uses_custom_time_key_with_format_without_logstash
|
2942
|
-
driver.configure("include_timestamp true
|
2943
|
-
index_name test
|
2944
|
-
time_key_format %Y-%m-%d %H:%M:%S.%N%z
|
2945
|
-
time_key vtm\n")
|
2946
|
-
stub_opensearch
|
2947
|
-
stub_opensearch_info
|
2948
|
-
ts = "2001-02-03 13:14:01.673+02:00"
|
2949
|
-
driver.run(default_tag: 'test') do
|
2950
|
-
driver.feed(sample_record.merge!('vtm' => ts))
|
2951
|
-
end
|
2952
|
-
assert(index_cmds[1].has_key? '@timestamp')
|
2953
|
-
assert_equal(DateTime.parse(ts).iso8601(9), index_cmds[1]['@timestamp'])
|
2954
|
-
assert_equal("test", index_cmds[0]['index']['_index'])
|
2955
|
-
end
|
2956
|
-
|
2957
|
-
def test_uses_custom_time_key_exclude_timekey
|
2958
|
-
driver.configure("logstash_format true
|
2959
|
-
time_key vtm
|
2960
|
-
time_key_exclude_timestamp true\n")
|
2961
|
-
stub_opensearch
|
2962
|
-
stub_opensearch_info
|
2963
|
-
ts = DateTime.new(2001,2,3).iso8601
|
2964
|
-
driver.run(default_tag: 'test') do
|
2965
|
-
driver.feed(sample_record.merge!('vtm' => ts))
|
2966
|
-
end
|
2967
|
-
assert(!index_cmds[1].key?('@timestamp'), '@timestamp should be messing')
|
2968
|
-
end
|
2969
|
-
|
2970
|
-
def test_uses_custom_time_key_format
|
2971
|
-
driver.configure("logstash_format true
|
2972
|
-
time_key_format %Y-%m-%dT%H:%M:%S.%N%z\n")
|
2973
|
-
stub_opensearch
|
2974
|
-
stub_opensearch_info
|
2975
|
-
ts = "2001-02-03T13:14:01.673+02:00"
|
2976
|
-
driver.run(default_tag: 'test') do
|
2977
|
-
driver.feed(sample_record.merge!('@timestamp' => ts))
|
2978
|
-
end
|
2979
|
-
assert_equal("logstash-2001.02.03", index_cmds[0]['index']['_index'])
|
2980
|
-
assert(index_cmds[1].has_key? '@timestamp')
|
2981
|
-
assert_equal(ts, index_cmds[1]['@timestamp'])
|
2982
|
-
end
|
2983
|
-
|
2984
|
-
def test_uses_custom_time_key_format_without_logstash
|
2985
|
-
driver.configure("include_timestamp true
|
2986
|
-
index_name test
|
2987
|
-
time_key_format %Y-%m-%dT%H:%M:%S.%N%z\n")
|
2988
|
-
stub_opensearch
|
2989
|
-
stub_opensearch_info
|
2990
|
-
ts = "2001-02-03T13:14:01.673+02:00"
|
2991
|
-
driver.run(default_tag: 'test') do
|
2992
|
-
driver.feed(sample_record.merge!('@timestamp' => ts))
|
2993
|
-
end
|
2994
|
-
assert_equal("test", index_cmds[0]['index']['_index'])
|
2995
|
-
assert(index_cmds[1].has_key? '@timestamp')
|
2996
|
-
assert_equal(ts, index_cmds[1]['@timestamp'])
|
2997
|
-
end
|
2998
|
-
|
2999
|
-
data(:default => nil,
|
3000
|
-
:custom_tag => 'es_plugin.output.time.error')
|
3001
|
-
def test_uses_custom_time_key_format_logs_an_error(tag_for_error)
|
3002
|
-
tag_config = tag_for_error ? "time_parse_error_tag #{tag_for_error}" : ''
|
3003
|
-
tag_for_error = 'opensearch_plugin.output.time.error' if tag_for_error.nil?
|
3004
|
-
driver.configure("logstash_format true
|
3005
|
-
time_key_format %Y-%m-%dT%H:%M:%S.%N%z\n#{tag_config}\n")
|
3006
|
-
stub_opensearch
|
3007
|
-
stub_opensearch_info
|
3008
|
-
|
3009
|
-
ts = "2001/02/03 13:14:01,673+02:00"
|
3010
|
-
index = "logstash-#{Time.now.getutc.strftime("%Y.%m.%d")}"
|
3011
|
-
|
3012
|
-
flexmock(driver.instance.router).should_receive(:emit_error_event)
|
3013
|
-
.with(tag_for_error, Fluent::EventTime, Hash, ArgumentError).once
|
3014
|
-
driver.run(default_tag: 'test') do
|
3015
|
-
driver.feed(sample_record.merge!('@timestamp' => ts))
|
3016
|
-
end
|
3017
|
-
|
3018
|
-
assert_equal(index, index_cmds[0]['index']['_index'])
|
3019
|
-
assert(index_cmds[1].has_key? '@timestamp')
|
3020
|
-
assert_equal(ts, index_cmds[1]['@timestamp'])
|
3021
|
-
end
|
3022
|
-
|
3023
|
-
|
3024
|
-
def test_uses_custom_time_key_format_obscure_format
|
3025
|
-
driver.configure("logstash_format true
|
3026
|
-
time_key_format %a %b %d %H:%M:%S %Z %Y\n")
|
3027
|
-
stub_opensearch
|
3028
|
-
stub_opensearch_info
|
3029
|
-
ts = "Thu Nov 29 14:33:20 GMT 2001"
|
3030
|
-
driver.run(default_tag: 'test') do
|
3031
|
-
driver.feed(sample_record.merge!('@timestamp' => ts))
|
3032
|
-
end
|
3033
|
-
assert_equal("logstash-2001.11.29", index_cmds[0]['index']['_index'])
|
3034
|
-
assert(index_cmds[1].has_key? '@timestamp')
|
3035
|
-
assert_equal(ts, index_cmds[1]['@timestamp'])
|
3036
|
-
end
|
3037
|
-
|
3038
|
-
def test_uses_nanosecond_precision_by_default
|
3039
|
-
driver.configure("logstash_format true\n")
|
3040
|
-
stub_opensearch
|
3041
|
-
stub_opensearch_info
|
3042
|
-
time = Fluent::EventTime.new(Time.now.to_i, 123456789)
|
3043
|
-
driver.run(default_tag: 'test') do
|
3044
|
-
driver.feed(time, sample_record)
|
3045
|
-
end
|
3046
|
-
assert(index_cmds[1].has_key? '@timestamp')
|
3047
|
-
assert_equal(Time.at(time).iso8601(9), index_cmds[1]['@timestamp'])
|
3048
|
-
end
|
3049
|
-
|
3050
|
-
def test_uses_subsecond_precision_when_configured
|
3051
|
-
driver.configure("logstash_format true
|
3052
|
-
time_precision 3\n")
|
3053
|
-
stub_opensearch
|
3054
|
-
stub_opensearch_info
|
3055
|
-
time = Fluent::EventTime.new(Time.now.to_i, 123456789)
|
3056
|
-
driver.run(default_tag: 'test') do
|
3057
|
-
driver.feed(time, sample_record)
|
3058
|
-
end
|
3059
|
-
assert(index_cmds[1].has_key? '@timestamp')
|
3060
|
-
assert_equal(Time.at(time).iso8601(3), index_cmds[1]['@timestamp'])
|
3061
|
-
end
|
3062
|
-
|
3063
|
-
def test_doesnt_add_tag_key_by_default
|
3064
|
-
stub_opensearch
|
3065
|
-
stub_opensearch_info
|
3066
|
-
driver.run(default_tag: 'test') do
|
3067
|
-
driver.feed(sample_record)
|
3068
|
-
end
|
3069
|
-
assert_nil(index_cmds[1]['tag'])
|
3070
|
-
end
|
3071
|
-
|
3072
|
-
def test_adds_tag_key_when_configured
|
3073
|
-
driver.configure("include_tag_key true\n")
|
3074
|
-
stub_opensearch
|
3075
|
-
stub_opensearch_info
|
3076
|
-
driver.run(default_tag: 'mytag') do
|
3077
|
-
driver.feed(sample_record)
|
3078
|
-
end
|
3079
|
-
assert(index_cmds[1].has_key?('tag'))
|
3080
|
-
assert_equal('mytag', index_cmds[1]['tag'])
|
3081
|
-
end
|
3082
|
-
|
3083
|
-
def test_adds_id_key_when_configured
|
3084
|
-
driver.configure("id_key request_id\n")
|
3085
|
-
stub_opensearch
|
3086
|
-
stub_opensearch_info
|
3087
|
-
driver.run(default_tag: 'test') do
|
3088
|
-
driver.feed(sample_record)
|
3089
|
-
end
|
3090
|
-
assert_equal('42', index_cmds[0]['index']['_id'])
|
3091
|
-
end
|
3092
|
-
|
3093
|
-
class NestedIdKeyTest < self
|
3094
|
-
def test_adds_nested_id_key_with_dot
|
3095
|
-
driver.configure("id_key nested.request_id\n")
|
3096
|
-
stub_opensearch
|
3097
|
-
stub_opensearch_info
|
3098
|
-
driver.run(default_tag: 'test') do
|
3099
|
-
driver.feed(nested_sample_record)
|
3100
|
-
end
|
3101
|
-
assert_equal('42', index_cmds[0]['index']['_id'])
|
3102
|
-
end
|
3103
|
-
|
3104
|
-
def test_adds_nested_id_key_with_dollar_dot
|
3105
|
-
driver.configure("id_key $.nested.request_id\n")
|
3106
|
-
stub_opensearch
|
3107
|
-
stub_opensearch_info
|
3108
|
-
driver.run(default_tag: 'test') do
|
3109
|
-
driver.feed(nested_sample_record)
|
3110
|
-
end
|
3111
|
-
assert_equal('42', index_cmds[0]['index']['_id'])
|
3112
|
-
end
|
3113
|
-
|
3114
|
-
def test_adds_nested_id_key_with_bracket
|
3115
|
-
driver.configure("id_key $['nested']['request_id']\n")
|
3116
|
-
stub_opensearch
|
3117
|
-
stub_opensearch_info
|
3118
|
-
driver.run(default_tag: 'test') do
|
3119
|
-
driver.feed(nested_sample_record)
|
3120
|
-
end
|
3121
|
-
assert_equal('42', index_cmds[0]['index']['_id'])
|
3122
|
-
end
|
3123
|
-
end
|
3124
|
-
|
3125
|
-
def test_doesnt_add_id_key_if_missing_when_configured
|
3126
|
-
driver.configure("id_key another_request_id\n")
|
3127
|
-
stub_opensearch
|
3128
|
-
stub_opensearch_info
|
3129
|
-
driver.run(default_tag: 'test') do
|
3130
|
-
driver.feed(sample_record)
|
3131
|
-
end
|
3132
|
-
assert(!index_cmds[0]['index'].has_key?('_id'))
|
3133
|
-
end
|
3134
|
-
|
3135
|
-
def test_adds_id_key_when_not_configured
|
3136
|
-
stub_opensearch
|
3137
|
-
stub_opensearch_info
|
3138
|
-
driver.run(default_tag: 'test') do
|
3139
|
-
driver.feed(sample_record)
|
3140
|
-
end
|
3141
|
-
assert(!index_cmds[0]['index'].has_key?('_id'))
|
3142
|
-
end
|
3143
|
-
|
3144
|
-
def test_adds_parent_key_when_configured
|
3145
|
-
driver.configure("parent_key parent_id\n")
|
3146
|
-
stub_opensearch
|
3147
|
-
stub_opensearch_info
|
3148
|
-
driver.run(default_tag: 'test') do
|
3149
|
-
driver.feed(sample_record)
|
3150
|
-
end
|
3151
|
-
assert_equal('parent', index_cmds[0]['index']['_parent'])
|
3152
|
-
end
|
3153
|
-
|
3154
|
-
class NestedParentKeyTest < self
|
3155
|
-
def test_adds_nested_parent_key_with_dot
|
3156
|
-
driver.configure("parent_key nested.parent_id\n")
|
3157
|
-
stub_opensearch
|
3158
|
-
stub_opensearch_info
|
3159
|
-
driver.run(default_tag: 'test') do
|
3160
|
-
driver.feed(nested_sample_record)
|
3161
|
-
end
|
3162
|
-
assert_equal('parent', index_cmds[0]['index']['_parent'])
|
3163
|
-
end
|
3164
|
-
|
3165
|
-
def test_adds_nested_parent_key_with_dollar_dot
|
3166
|
-
driver.configure("parent_key $.nested.parent_id\n")
|
3167
|
-
stub_opensearch
|
3168
|
-
stub_opensearch_info
|
3169
|
-
driver.run(default_tag: 'test') do
|
3170
|
-
driver.feed(nested_sample_record)
|
3171
|
-
end
|
3172
|
-
assert_equal('parent', index_cmds[0]['index']['_parent'])
|
3173
|
-
end
|
3174
|
-
|
3175
|
-
def test_adds_nested_parent_key_with_bracket
|
3176
|
-
driver.configure("parent_key $['nested']['parent_id']\n")
|
3177
|
-
stub_opensearch
|
3178
|
-
stub_opensearch_info
|
3179
|
-
driver.run(default_tag: 'test') do
|
3180
|
-
driver.feed(nested_sample_record)
|
3181
|
-
end
|
3182
|
-
assert_equal('parent', index_cmds[0]['index']['_parent'])
|
3183
|
-
end
|
3184
|
-
end
|
3185
|
-
|
3186
|
-
def test_doesnt_add_parent_key_if_missing_when_configured
|
3187
|
-
driver.configure("parent_key another_parent_id\n")
|
3188
|
-
stub_opensearch
|
3189
|
-
stub_opensearch_info
|
3190
|
-
driver.run(default_tag: 'test') do
|
3191
|
-
driver.feed(sample_record)
|
3192
|
-
end
|
3193
|
-
assert(!index_cmds[0]['index'].has_key?('_parent'))
|
3194
|
-
end
|
3195
|
-
|
3196
|
-
def test_adds_parent_key_when_not_configured
|
3197
|
-
stub_opensearch
|
3198
|
-
stub_opensearch_info
|
3199
|
-
driver.run(default_tag: 'test') do
|
3200
|
-
driver.feed(sample_record)
|
3201
|
-
end
|
3202
|
-
assert(!index_cmds[0]['index'].has_key?('_parent'))
|
3203
|
-
end
|
3204
|
-
|
3205
|
-
class AddsRoutingKeyWhenConfiguredTest < self
|
3206
|
-
def test_os1
|
3207
|
-
driver("routing_key routing_id\n", 1)
|
3208
|
-
stub_opensearch
|
3209
|
-
stub_opensearch_info
|
3210
|
-
driver.run(default_tag: 'test') do
|
3211
|
-
driver.feed(sample_record)
|
3212
|
-
end
|
3213
|
-
assert_equal('routing', index_cmds[0]['index']['routing'])
|
3214
|
-
end
|
3215
|
-
end
|
3216
|
-
|
3217
|
-
class NestedRoutingKeyTest < self
|
3218
|
-
def test_adds_nested_routing_key_with_dot
|
3219
|
-
driver.configure("routing_key nested.routing_id\n")
|
3220
|
-
stub_opensearch
|
3221
|
-
stub_opensearch_info
|
3222
|
-
driver.run(default_tag: 'test') do
|
3223
|
-
driver.feed(nested_sample_record)
|
3224
|
-
end
|
3225
|
-
assert_equal('routing', index_cmds[0]['index']['routing'])
|
3226
|
-
end
|
3227
|
-
|
3228
|
-
def test_adds_nested_routing_key_with_dollar_dot
|
3229
|
-
driver.configure("routing_key $.nested.routing_id\n")
|
3230
|
-
stub_opensearch
|
3231
|
-
stub_opensearch_info
|
3232
|
-
driver.run(default_tag: 'test') do
|
3233
|
-
driver.feed(nested_sample_record)
|
3234
|
-
end
|
3235
|
-
assert_equal('routing', index_cmds[0]['index']['routing'])
|
3236
|
-
end
|
3237
|
-
|
3238
|
-
def test_adds_nested_routing_key_with_bracket
|
3239
|
-
driver.configure("routing_key $['nested']['routing_id']\n")
|
3240
|
-
stub_opensearch
|
3241
|
-
stub_opensearch_info
|
3242
|
-
driver.run(default_tag: 'test') do
|
3243
|
-
driver.feed(nested_sample_record)
|
3244
|
-
end
|
3245
|
-
assert_equal('routing', index_cmds[0]['index']['routing'])
|
3246
|
-
end
|
3247
|
-
end
|
3248
|
-
|
3249
|
-
def test_doesnt_add_routing_key_if_missing_when_configured
|
3250
|
-
driver.configure("routing_key another_routing_id\n")
|
3251
|
-
stub_opensearch
|
3252
|
-
stub_opensearch_info
|
3253
|
-
driver.run(default_tag: 'test') do
|
3254
|
-
driver.feed(sample_record)
|
3255
|
-
end
|
3256
|
-
assert(!index_cmds[0]['index'].has_key?('_routing'))
|
3257
|
-
end
|
3258
|
-
|
3259
|
-
def test_adds_routing_key_when_not_configured
|
3260
|
-
stub_opensearch
|
3261
|
-
stub_opensearch_info
|
3262
|
-
driver.run(default_tag: 'test') do
|
3263
|
-
driver.feed(sample_record)
|
3264
|
-
end
|
3265
|
-
assert(!index_cmds[0]['index'].has_key?('_routing'))
|
3266
|
-
end
|
3267
|
-
|
3268
|
-
def test_remove_one_key
|
3269
|
-
driver.configure("remove_keys key1\n")
|
3270
|
-
stub_opensearch
|
3271
|
-
stub_opensearch_info
|
3272
|
-
driver.run(default_tag: 'test') do
|
3273
|
-
driver.feed(sample_record.merge('key1' => 'v1', 'key2' => 'v2'))
|
3274
|
-
end
|
3275
|
-
assert(!index_cmds[1].has_key?('key1'))
|
3276
|
-
assert(index_cmds[1].has_key?('key2'))
|
3277
|
-
end
|
3278
|
-
|
3279
|
-
def test_remove_multi_keys
|
3280
|
-
driver.configure("remove_keys key1, key2\n")
|
3281
|
-
stub_opensearch
|
3282
|
-
stub_opensearch_info
|
3283
|
-
driver.run(default_tag: 'test') do
|
3284
|
-
driver.feed(sample_record.merge('key1' => 'v1', 'key2' => 'v2'))
|
3285
|
-
end
|
3286
|
-
assert(!index_cmds[1].has_key?('key1'))
|
3287
|
-
assert(!index_cmds[1].has_key?('key2'))
|
3288
|
-
end
|
3289
|
-
|
3290
|
-
def test_request_error
|
3291
|
-
stub_opensearch_info
|
3292
|
-
stub_opensearch_unavailable
|
3293
|
-
assert_raise(Fluent::Plugin::OpenSearchOutput::RecoverableRequestFailure) {
|
3294
|
-
driver.run(default_tag: 'test', shutdown: false) do
|
3295
|
-
driver.feed(sample_record)
|
3296
|
-
end
|
3297
|
-
}
|
3298
|
-
end
|
3299
|
-
|
3300
|
-
def test_request_forever
|
3301
|
-
omit("retry_forever test is unstable.") if ENV["CI"]
|
3302
|
-
stub_opensearch
|
3303
|
-
stub_opensearch_info
|
3304
|
-
driver.configure(Fluent::Config::Element.new(
|
3305
|
-
'ROOT', '', {
|
3306
|
-
'@type' => 'opensearch',
|
3307
|
-
}, [
|
3308
|
-
Fluent::Config::Element.new('buffer', '', {
|
3309
|
-
'retry_forever' => true
|
3310
|
-
}, [])
|
3311
|
-
]
|
3312
|
-
))
|
3313
|
-
stub_opensearch_timeout
|
3314
|
-
assert_raise(Timeout::Error) {
|
3315
|
-
driver.run(default_tag: 'test', timeout: 10, force_flush_retry: true) do
|
3316
|
-
driver.feed(sample_record)
|
3317
|
-
end
|
3318
|
-
}
|
3319
|
-
end
|
3320
|
-
|
3321
|
-
def test_connection_failed
|
3322
|
-
connection_resets = 0
|
3323
|
-
|
3324
|
-
stub_request(:post, "http://localhost:9200/_bulk").with do |req|
|
3325
|
-
connection_resets += 1
|
3326
|
-
raise Faraday::ConnectionFailed, "Test message"
|
3327
|
-
end
|
3328
|
-
stub_opensearch_info
|
3329
|
-
|
3330
|
-
assert_raise(Fluent::Plugin::OpenSearchOutput::RecoverableRequestFailure) {
|
3331
|
-
driver.run(default_tag: 'test', shutdown: false) do
|
3332
|
-
driver.feed(sample_record)
|
3333
|
-
end
|
3334
|
-
}
|
3335
|
-
assert_equal(1, connection_resets)
|
3336
|
-
end
|
3337
|
-
|
3338
|
-
def test_reconnect_on_error_enabled
|
3339
|
-
connection_resets = 0
|
3340
|
-
|
3341
|
-
stub_request(:post, "http://localhost:9200/_bulk").with do |req|
|
3342
|
-
connection_resets += 1
|
3343
|
-
raise ZeroDivisionError, "any not host_unreachable_exceptions exception"
|
3344
|
-
end
|
3345
|
-
stub_opensearch_info
|
3346
|
-
|
3347
|
-
driver.configure("reconnect_on_error true\n")
|
3348
|
-
|
3349
|
-
assert_raise(Fluent::Plugin::OpenSearchOutput::RecoverableRequestFailure) {
|
3350
|
-
driver.run(default_tag: 'test', shutdown: false) do
|
3351
|
-
driver.feed(sample_record)
|
3352
|
-
end
|
3353
|
-
}
|
3354
|
-
|
3355
|
-
assert_raise(Timeout::Error) {
|
3356
|
-
driver.run(default_tag: 'test', shutdown: false) do
|
3357
|
-
driver.feed(sample_record)
|
3358
|
-
end
|
3359
|
-
}
|
3360
|
-
# FIXME: Consider keywords arguments in #run and how to test this later.
|
3361
|
-
# Because v0.14 test driver does not have 1 to 1 correspondence between #run and #flush in tests.
|
3362
|
-
assert_equal(1, connection_resets)
|
3363
|
-
end
|
3364
|
-
|
3365
|
-
def test_reconnect_on_error_disabled
|
3366
|
-
connection_resets = 0
|
3367
|
-
|
3368
|
-
stub_request(:post, "http://localhost:9200/_bulk").with do |req|
|
3369
|
-
connection_resets += 1
|
3370
|
-
raise ZeroDivisionError, "any not host_unreachable_exceptions exception"
|
3371
|
-
end
|
3372
|
-
stub_opensearch_info
|
3373
|
-
|
3374
|
-
driver.configure("reconnect_on_error false\n")
|
3375
|
-
|
3376
|
-
assert_raise(Fluent::Plugin::OpenSearchOutput::RecoverableRequestFailure) {
|
3377
|
-
driver.run(default_tag: 'test', shutdown: false) do
|
3378
|
-
driver.feed(sample_record)
|
3379
|
-
end
|
3380
|
-
}
|
3381
|
-
|
3382
|
-
assert_raise(Timeout::Error) {
|
3383
|
-
driver.run(default_tag: 'test', shutdown: false) do
|
3384
|
-
driver.feed(sample_record)
|
3385
|
-
end
|
3386
|
-
}
|
3387
|
-
assert_equal(1, connection_resets)
|
3388
|
-
end
|
3389
|
-
|
3390
|
-
def test_bulk_error_retags_when_configured
|
3391
|
-
driver.configure("retry_tag retry\n")
|
3392
|
-
stub_request(:post, 'http://localhost:9200/_bulk')
|
3393
|
-
.to_return(lambda do |req|
|
3394
|
-
{ :status => 200,
|
3395
|
-
:headers => { 'Content-Type' => 'json' },
|
3396
|
-
:body => %({
|
3397
|
-
"took" : 1,
|
3398
|
-
"errors" : true,
|
3399
|
-
"items" : [
|
3400
|
-
{
|
3401
|
-
"create" : {
|
3402
|
-
"_index" : "foo",
|
3403
|
-
"_type" : "bar",
|
3404
|
-
"_id" : "abc",
|
3405
|
-
"status" : 500,
|
3406
|
-
"error" : {
|
3407
|
-
"type" : "some unrecognized type",
|
3408
|
-
"reason":"some error to cause version mismatch"
|
3409
|
-
}
|
3410
|
-
}
|
3411
|
-
}
|
3412
|
-
]
|
3413
|
-
})
|
3414
|
-
}
|
3415
|
-
end)
|
3416
|
-
stub_opensearch_info
|
3417
|
-
|
3418
|
-
driver.run(default_tag: 'test') do
|
3419
|
-
driver.feed(1, sample_record)
|
3420
|
-
end
|
3421
|
-
|
3422
|
-
assert_equal [['retry', 1, sample_record]], driver.events
|
3423
|
-
end
|
3424
|
-
|
3425
|
-
class FulfilledBufferRetryStreamTest < self
|
3426
|
-
def test_bulk_error_retags_with_error_when_configured_and_fullfilled_buffer
|
3427
|
-
def create_driver(conf='', os_version=1, client_version="\"1.0\"")
|
3428
|
-
@client_version ||= client_version
|
3429
|
-
Fluent::Plugin::OpenSearchOutput.module_eval(<<-CODE)
|
3430
|
-
def retry_stream_retryable?
|
3431
|
-
false
|
3432
|
-
end
|
3433
|
-
CODE
|
3434
|
-
# For request stub to detect compatibility.
|
3435
|
-
@os_version ||= os_version
|
3436
|
-
@client_version ||= client_version
|
3437
|
-
if @os_version
|
3438
|
-
Fluent::Plugin::OpenSearchOutput.module_eval(<<-CODE)
|
3439
|
-
def detect_os_major_version
|
3440
|
-
#{@os_version}
|
3441
|
-
end
|
3442
|
-
CODE
|
3443
|
-
end
|
3444
|
-
Fluent::Plugin::OpenSearchOutput.module_eval(<<-CODE)
|
3445
|
-
def client_library_version
|
3446
|
-
#{@client_version}
|
3447
|
-
end
|
3448
|
-
CODE
|
3449
|
-
Fluent::Test::Driver::Output.new(Fluent::Plugin::OpenSearchOutput).configure(conf)
|
3450
|
-
end
|
3451
|
-
driver = create_driver("retry_tag retry\n")
|
3452
|
-
stub_request(:post, 'http://localhost:9200/_bulk')
|
3453
|
-
.to_return(lambda do |req|
|
3454
|
-
{ :status => 200,
|
3455
|
-
:headers => { 'Content-Type' => 'json' },
|
3456
|
-
:body => %({
|
3457
|
-
"took" : 1,
|
3458
|
-
"errors" : true,
|
3459
|
-
"items" : [
|
3460
|
-
{
|
3461
|
-
"create" : {
|
3462
|
-
"_index" : "foo",
|
3463
|
-
"_type" : "bar",
|
3464
|
-
"_id" : "abc1",
|
3465
|
-
"status" : 403,
|
3466
|
-
"error" : {
|
3467
|
-
"type" : "cluster_block_exception",
|
3468
|
-
"reason":"index [foo] blocked by: [FORBIDDEN/8/index write (api)]"
|
3469
|
-
}
|
3470
|
-
}
|
3471
|
-
},
|
3472
|
-
{
|
3473
|
-
"create" : {
|
3474
|
-
"_index" : "foo",
|
3475
|
-
"_type" : "bar",
|
3476
|
-
"_id" : "abc2",
|
3477
|
-
"status" : 403,
|
3478
|
-
"error" : {
|
3479
|
-
"type" : "cluster_block_exception",
|
3480
|
-
"reason":"index [foo] blocked by: [FORBIDDEN/8/index write (api)]"
|
3481
|
-
}
|
3482
|
-
}
|
3483
|
-
}
|
3484
|
-
]
|
3485
|
-
})
|
3486
|
-
}
|
3487
|
-
end)
|
3488
|
-
stub_opensearch_info
|
3489
|
-
|
3490
|
-
# Check buffer fulfillment condition
|
3491
|
-
assert_raise(Fluent::Plugin::OpenSearchOutput::RetryStreamEmitFailure) do
|
3492
|
-
driver.run(default_tag: 'test') do
|
3493
|
-
driver.feed(1, sample_record)
|
3494
|
-
driver.feed(1, sample_record)
|
3495
|
-
end
|
3496
|
-
end
|
3497
|
-
|
3498
|
-
assert_equal [], driver.events
|
3499
|
-
end
|
3500
|
-
end
|
3501
|
-
|
3502
|
-
def test_create_should_write_records_with_ids_and_skip_those_without
|
3503
|
-
driver.configure("write_operation create\nid_key my_id\n@log_level debug")
|
3504
|
-
stub_request(:post, 'http://localhost:9200/_bulk')
|
3505
|
-
.to_return(lambda do |req|
|
3506
|
-
{ :status => 200,
|
3507
|
-
:headers => { 'Content-Type' => 'json' },
|
3508
|
-
:body => %({
|
3509
|
-
"took" : 1,
|
3510
|
-
"errors" : true,
|
3511
|
-
"items" : [
|
3512
|
-
{
|
3513
|
-
"create" : {
|
3514
|
-
"_index" : "foo",
|
3515
|
-
"_type" : "bar",
|
3516
|
-
"_id" : "abc"
|
3517
|
-
}
|
3518
|
-
},
|
3519
|
-
{
|
3520
|
-
"create" : {
|
3521
|
-
"_index" : "foo",
|
3522
|
-
"_type" : "bar",
|
3523
|
-
"_id" : "xyz",
|
3524
|
-
"status" : 500,
|
3525
|
-
"error" : {
|
3526
|
-
"type" : "some unrecognized type",
|
3527
|
-
"reason":"some error to cause version mismatch"
|
3528
|
-
}
|
3529
|
-
}
|
3530
|
-
}
|
3531
|
-
]
|
3532
|
-
})
|
3533
|
-
}
|
3534
|
-
end)
|
3535
|
-
stub_opensearch_info
|
3536
|
-
|
3537
|
-
sample_record1 = sample_record('my_id' => 'abc')
|
3538
|
-
sample_record4 = sample_record('my_id' => 'xyz')
|
3539
|
-
|
3540
|
-
driver.run(default_tag: 'test') do
|
3541
|
-
driver.feed(1, sample_record1)
|
3542
|
-
driver.feed(2, sample_record)
|
3543
|
-
driver.feed(3, sample_record)
|
3544
|
-
driver.feed(4, sample_record4)
|
3545
|
-
end
|
3546
|
-
|
3547
|
-
logs = driver.logs
|
3548
|
-
# one record succeeded while the other should be 'retried'
|
3549
|
-
assert_equal [['test', 4, sample_record4]], driver.events
|
3550
|
-
assert_logs_include(logs, /(Dropping record)/, 2)
|
3551
|
-
end
|
3552
|
-
|
3553
|
-
def test_create_should_write_records_with_ids_and_emit_those_without
|
3554
|
-
driver.configure("write_operation create\nid_key my_id\nemit_error_for_missing_id true\n@log_level debug")
|
3555
|
-
stub_request(:post, 'http://localhost:9200/_bulk')
|
3556
|
-
.to_return(lambda do |req|
|
3557
|
-
{ :status => 200,
|
3558
|
-
:headers => { 'Content-Type' => 'json' },
|
3559
|
-
:body => %({
|
3560
|
-
"took" : 1,
|
3561
|
-
"errors" : true,
|
3562
|
-
"items" : [
|
3563
|
-
{
|
3564
|
-
"create" : {
|
3565
|
-
"_index" : "foo",
|
3566
|
-
"_type" : "bar",
|
3567
|
-
"_id" : "abc"
|
3568
|
-
}
|
3569
|
-
},
|
3570
|
-
{
|
3571
|
-
"create" : {
|
3572
|
-
"_index" : "foo",
|
3573
|
-
"_type" : "bar",
|
3574
|
-
"_id" : "xyz",
|
3575
|
-
"status" : 500,
|
3576
|
-
"error" : {
|
3577
|
-
"type" : "some unrecognized type",
|
3578
|
-
"reason":"some error to cause version mismatch"
|
3579
|
-
}
|
3580
|
-
}
|
3581
|
-
}
|
3582
|
-
]
|
3583
|
-
})
|
3584
|
-
}
|
3585
|
-
end)
|
3586
|
-
stub_opensearch_info
|
3587
|
-
|
3588
|
-
sample_record1 = sample_record('my_id' => 'abc')
|
3589
|
-
sample_record4 = sample_record('my_id' => 'xyz')
|
3590
|
-
|
3591
|
-
driver.run(default_tag: 'test') do
|
3592
|
-
driver.feed(1, sample_record1)
|
3593
|
-
driver.feed(2, sample_record)
|
3594
|
-
driver.feed(3, sample_record)
|
3595
|
-
driver.feed(4, sample_record4)
|
3596
|
-
end
|
3597
|
-
|
3598
|
-
error_log = driver.error_events.map {|e| e.last.message }
|
3599
|
-
# one record succeeded while the other should be 'retried'
|
3600
|
-
assert_equal [['test', 4, sample_record4]], driver.events
|
3601
|
-
assert_logs_include(error_log, /(Missing '_id' field)/, 2)
|
3602
|
-
end
|
3603
|
-
|
3604
|
-
def test_bulk_error
|
3605
|
-
stub_request(:post, 'http://localhost:9200/_bulk')
|
3606
|
-
.to_return(lambda do |req|
|
3607
|
-
{ :status => 200,
|
3608
|
-
:headers => { 'Content-Type' => 'json' },
|
3609
|
-
:body => %({
|
3610
|
-
"took" : 1,
|
3611
|
-
"errors" : true,
|
3612
|
-
"items" : [
|
3613
|
-
{
|
3614
|
-
"create" : {
|
3615
|
-
"_index" : "foo",
|
3616
|
-
"_type" : "bar",
|
3617
|
-
"_id" : "abc",
|
3618
|
-
"status" : 500,
|
3619
|
-
"error" : {
|
3620
|
-
"type" : "some unrecognized type",
|
3621
|
-
"reason":"some error to cause version mismatch"
|
3622
|
-
}
|
3623
|
-
}
|
3624
|
-
},
|
3625
|
-
{
|
3626
|
-
"create" : {
|
3627
|
-
"_index" : "foo",
|
3628
|
-
"_type" : "bar",
|
3629
|
-
"_id" : "abc",
|
3630
|
-
"status" : 201
|
3631
|
-
}
|
3632
|
-
},
|
3633
|
-
{
|
3634
|
-
"create" : {
|
3635
|
-
"_index" : "foo",
|
3636
|
-
"_type" : "bar",
|
3637
|
-
"_id" : "abc",
|
3638
|
-
"status" : 500,
|
3639
|
-
"error" : {
|
3640
|
-
"type" : "some unrecognized type",
|
3641
|
-
"reason":"some error to cause version mismatch"
|
3642
|
-
}
|
3643
|
-
}
|
3644
|
-
},
|
3645
|
-
{
|
3646
|
-
"create" : {
|
3647
|
-
"_index" : "foo",
|
3648
|
-
"_type" : "bar",
|
3649
|
-
"_id" : "abc",
|
3650
|
-
"_id" : "abc",
|
3651
|
-
"status" : 409
|
3652
|
-
}
|
3653
|
-
}
|
3654
|
-
]
|
3655
|
-
})
|
3656
|
-
}
|
3657
|
-
end)
|
3658
|
-
stub_opensearch_info
|
3659
|
-
|
3660
|
-
driver.run(default_tag: 'test') do
|
3661
|
-
driver.feed(1, sample_record)
|
3662
|
-
driver.feed(2, sample_record)
|
3663
|
-
driver.feed(3, sample_record)
|
3664
|
-
driver.feed(4, sample_record)
|
3665
|
-
end
|
3666
|
-
|
3667
|
-
expect = [['test', 1, sample_record],
|
3668
|
-
['test', 3, sample_record]]
|
3669
|
-
assert_equal expect, driver.events
|
3670
|
-
end
|
3671
|
-
|
3672
|
-
def test_update_should_not_write_if_theres_no_id
|
3673
|
-
driver.configure("write_operation update\n")
|
3674
|
-
stub_opensearch
|
3675
|
-
stub_opensearch_info
|
3676
|
-
driver.run(default_tag: 'test') do
|
3677
|
-
driver.feed(sample_record)
|
3678
|
-
end
|
3679
|
-
assert_nil(index_cmds)
|
3680
|
-
end
|
3681
|
-
|
3682
|
-
def test_upsert_should_not_write_if_theres_no_id
|
3683
|
-
driver.configure("write_operation upsert\n")
|
3684
|
-
stub_opensearch
|
3685
|
-
stub_opensearch_info
|
3686
|
-
driver.run(default_tag: 'test') do
|
3687
|
-
driver.feed(sample_record)
|
3688
|
-
end
|
3689
|
-
assert_nil(index_cmds)
|
3690
|
-
end
|
3691
|
-
|
3692
|
-
def test_create_should_not_write_if_theres_no_id
|
3693
|
-
driver.configure("write_operation create\n")
|
3694
|
-
stub_opensearch
|
3695
|
-
stub_opensearch_info
|
3696
|
-
driver.run(default_tag: 'test') do
|
3697
|
-
driver.feed(sample_record)
|
3698
|
-
end
|
3699
|
-
assert_nil(index_cmds)
|
3700
|
-
end
|
3701
|
-
|
3702
|
-
def test_update_should_write_update_op_and_doc_as_upsert_is_false
|
3703
|
-
driver.configure("write_operation update
|
3704
|
-
id_key request_id")
|
3705
|
-
stub_opensearch
|
3706
|
-
stub_opensearch_info
|
3707
|
-
driver.run(default_tag: 'test') do
|
3708
|
-
driver.feed(sample_record)
|
3709
|
-
end
|
3710
|
-
assert(index_cmds[0].has_key?("update"))
|
3711
|
-
assert(!index_cmds[1]["doc_as_upsert"])
|
3712
|
-
assert(!index_cmds[1]["upsert"])
|
3713
|
-
end
|
3714
|
-
|
3715
|
-
def test_update_should_remove_keys_from_doc_when_keys_are_skipped
|
3716
|
-
driver.configure("write_operation update
|
3717
|
-
id_key request_id
|
3718
|
-
remove_keys_on_update parent_id")
|
3719
|
-
stub_opensearch
|
3720
|
-
stub_opensearch_info
|
3721
|
-
driver.run(default_tag: 'test') do
|
3722
|
-
driver.feed(sample_record)
|
3723
|
-
end
|
3724
|
-
assert(index_cmds[1]["doc"])
|
3725
|
-
assert(!index_cmds[1]["doc"]["parent_id"])
|
3726
|
-
end
|
3727
|
-
|
3728
|
-
def test_upsert_should_write_update_op_and_doc_as_upsert_is_true
|
3729
|
-
driver.configure("write_operation upsert
|
3730
|
-
id_key request_id")
|
3731
|
-
stub_opensearch
|
3732
|
-
stub_opensearch_info
|
3733
|
-
driver.run(default_tag: 'test') do
|
3734
|
-
driver.feed(sample_record)
|
3735
|
-
end
|
3736
|
-
assert(index_cmds[0].has_key?("update"))
|
3737
|
-
assert(index_cmds[1]["doc_as_upsert"])
|
3738
|
-
assert(!index_cmds[1]["upsert"])
|
3739
|
-
end
|
3740
|
-
|
3741
|
-
def test_upsert_should_write_update_op_upsert_and_doc_when_keys_are_skipped
|
3742
|
-
driver.configure("write_operation upsert
|
3743
|
-
id_key request_id
|
3744
|
-
remove_keys_on_update parent_id")
|
3745
|
-
stub_opensearch
|
3746
|
-
stub_opensearch_info
|
3747
|
-
driver.run(default_tag: 'test') do
|
3748
|
-
driver.feed(sample_record)
|
3749
|
-
end
|
3750
|
-
assert(index_cmds[0].has_key?("update"))
|
3751
|
-
assert(!index_cmds[1]["doc_as_upsert"])
|
3752
|
-
assert(index_cmds[1]["upsert"])
|
3753
|
-
assert(index_cmds[1]["doc"])
|
3754
|
-
end
|
3755
|
-
|
3756
|
-
def test_upsert_should_remove_keys_from_doc_when_keys_are_skipped
|
3757
|
-
driver.configure("write_operation upsert
|
3758
|
-
id_key request_id
|
3759
|
-
remove_keys_on_update parent_id")
|
3760
|
-
stub_opensearch
|
3761
|
-
stub_opensearch_info
|
3762
|
-
driver.run(default_tag: 'test') do
|
3763
|
-
driver.feed(sample_record)
|
3764
|
-
end
|
3765
|
-
assert(index_cmds[1]["upsert"] != index_cmds[1]["doc"])
|
3766
|
-
assert(!index_cmds[1]["doc"]["parent_id"])
|
3767
|
-
assert(index_cmds[1]["upsert"]["parent_id"])
|
3768
|
-
end
|
3769
|
-
|
3770
|
-
def test_upsert_should_remove_multiple_keys_when_keys_are_skipped
|
3771
|
-
driver.configure("write_operation upsert
|
3772
|
-
id_key id
|
3773
|
-
remove_keys_on_update foo,baz")
|
3774
|
-
stub_opensearch
|
3775
|
-
stub_opensearch_info
|
3776
|
-
driver.run(default_tag: 'test') do
|
3777
|
-
driver.feed("id" => 1, "foo" => "bar", "baz" => "quix", "zip" => "zam")
|
3778
|
-
end
|
3779
|
-
assert(
|
3780
|
-
index_cmds[1]["doc"] == {
|
3781
|
-
"id" => 1,
|
3782
|
-
"zip" => "zam",
|
3783
|
-
}
|
3784
|
-
)
|
3785
|
-
assert(
|
3786
|
-
index_cmds[1]["upsert"] == {
|
3787
|
-
"id" => 1,
|
3788
|
-
"foo" => "bar",
|
3789
|
-
"baz" => "quix",
|
3790
|
-
"zip" => "zam",
|
3791
|
-
}
|
3792
|
-
)
|
3793
|
-
end
|
3794
|
-
|
3795
|
-
def test_upsert_should_remove_keys_from_when_the_keys_are_in_the_record
|
3796
|
-
driver.configure("write_operation upsert
|
3797
|
-
id_key id
|
3798
|
-
remove_keys_on_update_key keys_to_skip")
|
3799
|
-
stub_opensearch
|
3800
|
-
stub_opensearch_info
|
3801
|
-
driver.run(default_tag: 'test') do
|
3802
|
-
driver.feed("id" => 1, "foo" => "bar", "baz" => "quix", "keys_to_skip" => ["baz"])
|
3803
|
-
end
|
3804
|
-
assert(
|
3805
|
-
index_cmds[1]["doc"] == {
|
3806
|
-
"id" => 1,
|
3807
|
-
"foo" => "bar",
|
3808
|
-
}
|
3809
|
-
)
|
3810
|
-
assert(
|
3811
|
-
index_cmds[1]["upsert"] == {
|
3812
|
-
"id" => 1,
|
3813
|
-
"foo" => "bar",
|
3814
|
-
"baz" => "quix",
|
3815
|
-
}
|
3816
|
-
)
|
3817
|
-
end
|
3818
|
-
|
3819
|
-
def test_upsert_should_remove_keys_from_key_on_record_has_higher_presedence_than_config
|
3820
|
-
driver.configure("write_operation upsert
|
3821
|
-
id_key id
|
3822
|
-
remove_keys_on_update foo,bar
|
3823
|
-
remove_keys_on_update_key keys_to_skip")
|
3824
|
-
stub_opensearch
|
3825
|
-
stub_opensearch_info
|
3826
|
-
driver.run(default_tag: 'test') do
|
3827
|
-
driver.feed("id" => 1, "foo" => "bar", "baz" => "quix", "keys_to_skip" => ["baz"])
|
3828
|
-
end
|
3829
|
-
assert(
|
3830
|
-
index_cmds[1]["doc"] == {
|
3831
|
-
"id" => 1,
|
3832
|
-
# we only expect baz to be stripped here, if the config was more important
|
3833
|
-
# foo would be stripped too.
|
3834
|
-
"foo" => "bar",
|
3835
|
-
}
|
3836
|
-
)
|
3837
|
-
assert(
|
3838
|
-
index_cmds[1]["upsert"] == {
|
3839
|
-
"id" => 1,
|
3840
|
-
"foo" => "bar",
|
3841
|
-
"baz" => "quix",
|
3842
|
-
}
|
3843
|
-
)
|
3844
|
-
end
|
3845
|
-
|
3846
|
-
def test_create_should_write_create_op
|
3847
|
-
driver.configure("write_operation create
|
3848
|
-
id_key request_id")
|
3849
|
-
stub_opensearch
|
3850
|
-
stub_opensearch_info
|
3851
|
-
driver.run(default_tag: 'test') do
|
3852
|
-
driver.feed(sample_record)
|
3853
|
-
end
|
3854
|
-
assert(index_cmds[0].has_key?("create"))
|
3855
|
-
end
|
3856
|
-
|
3857
|
-
def test_include_index_in_url
|
3858
|
-
stub_opensearch('http://localhost:9200/logstash-2018.01.01/_bulk')
|
3859
|
-
stub_opensearch_info('http://localhost:9200/')
|
3860
|
-
|
3861
|
-
driver.configure("index_name logstash-2018.01.01
|
3862
|
-
include_index_in_url true")
|
3863
|
-
driver.run(default_tag: 'test') do
|
3864
|
-
driver.feed(sample_record)
|
3865
|
-
end
|
3866
|
-
|
3867
|
-
assert_equal(2, index_cmds.length)
|
3868
|
-
assert_equal(nil, index_cmds.first['index']['_index'])
|
3869
|
-
end
|
3870
|
-
|
3871
|
-
def test_use_simple_sniffer
|
3872
|
-
require 'fluent/plugin/opensearch_simple_sniffer'
|
3873
|
-
stub_opensearch
|
3874
|
-
stub_opensearch_info
|
3875
|
-
config = %[
|
3876
|
-
sniffer_class_name Fluent::Plugin::OpenSearchSimpleSniffer
|
3877
|
-
log_level debug
|
3878
|
-
with_transporter_log true
|
3879
|
-
reload_connections true
|
3880
|
-
reload_after 1
|
3881
|
-
]
|
3882
|
-
driver(config, nil)
|
3883
|
-
driver.run(default_tag: 'test') do
|
3884
|
-
driver.feed(sample_record)
|
3885
|
-
end
|
3886
|
-
log = driver.logs
|
3887
|
-
# 2 or 3 - one for the ping, one for the _bulk, (and client.info)
|
3888
|
-
assert_logs_include_compare_size(3, ">", log, /In Fluent::Plugin::OpenSearchSimpleSniffer hosts/)
|
3889
|
-
assert_logs_include_compare_size(1, "<=", log, /In Fluent::Plugin::OpenSearchSimpleSniffer hosts/)
|
3890
|
-
end
|
3891
|
-
|
3892
|
-
def test_suppress_doc_wrap
|
3893
|
-
driver.configure('write_operation update
|
3894
|
-
id_key id
|
3895
|
-
remove_keys id
|
3896
|
-
suppress_doc_wrap true')
|
3897
|
-
stub_opensearch
|
3898
|
-
stub_opensearch_info
|
3899
|
-
doc_body = {'field' => 'value'}
|
3900
|
-
script_body = {'source' => 'ctx._source.counter += params.param1',
|
3901
|
-
'lang' => 'painless',
|
3902
|
-
'params' => {'param1' => 1}}
|
3903
|
-
upsert_body = {'counter' => 1}
|
3904
|
-
driver.run(default_tag: 'test') do
|
3905
|
-
driver.feed('id' => 1, 'doc' => doc_body)
|
3906
|
-
driver.feed('id' => 2, 'script' => script_body, 'upsert' => upsert_body)
|
3907
|
-
end
|
3908
|
-
assert(
|
3909
|
-
index_cmds[1] == {'doc' => doc_body}
|
3910
|
-
)
|
3911
|
-
assert(
|
3912
|
-
index_cmds[3] == {
|
3913
|
-
'script' => script_body,
|
3914
|
-
'upsert' => upsert_body
|
3915
|
-
}
|
3916
|
-
)
|
3917
|
-
end
|
3918
|
-
|
3919
|
-
def test_suppress_doc_wrap_should_handle_record_as_is_at_upsert
|
3920
|
-
driver.configure('write_operation upsert
|
3921
|
-
id_key id
|
3922
|
-
remove_keys id
|
3923
|
-
suppress_doc_wrap true')
|
3924
|
-
stub_opensearch
|
3925
|
-
stub_opensearch_info
|
3926
|
-
doc_body = {'field' => 'value'}
|
3927
|
-
script_body = {'source' => 'ctx._source.counter += params.param1',
|
3928
|
-
'lang' => 'painless',
|
3929
|
-
'params' => {'param1' => 1}}
|
3930
|
-
upsert_body = {'counter' => 1}
|
3931
|
-
driver.run(default_tag: 'test') do
|
3932
|
-
driver.feed('id' => 1, 'doc' => doc_body, 'doc_as_upsert' => true)
|
3933
|
-
driver.feed('id' => 2, 'script' => script_body, 'upsert' => upsert_body)
|
3934
|
-
end
|
3935
|
-
assert(
|
3936
|
-
index_cmds[1] == {
|
3937
|
-
'doc' => doc_body,
|
3938
|
-
'doc_as_upsert' => true
|
3939
|
-
}
|
3940
|
-
)
|
3941
|
-
assert(
|
3942
|
-
index_cmds[3] == {
|
3943
|
-
'script' => script_body,
|
3944
|
-
'upsert' => upsert_body
|
3945
|
-
}
|
3946
|
-
)
|
3947
|
-
end
|
3948
|
-
|
3949
|
-
def test_ignore_exception
|
3950
|
-
driver.configure('ignore_exceptions ["OpenSearch::Transport::Transport::Errors::ServiceUnavailable"]')
|
3951
|
-
stub_opensearch_unavailable
|
3952
|
-
stub_opensearch_info
|
3953
|
-
|
3954
|
-
driver.run(default_tag: 'test') do
|
3955
|
-
driver.feed(sample_record)
|
3956
|
-
end
|
3957
|
-
end
|
3958
|
-
|
3959
|
-
def test_ignore_exception_with_superclass
|
3960
|
-
driver.configure('ignore_exceptions ["OpenSearch::Transport::Transport::ServerError"]')
|
3961
|
-
stub_opensearch_unavailable
|
3962
|
-
stub_opensearch_info
|
3963
|
-
|
3964
|
-
driver.run(default_tag: 'test') do
|
3965
|
-
driver.feed(sample_record)
|
3966
|
-
end
|
3967
|
-
end
|
3968
|
-
|
3969
|
-
def test_ignore_excetion_handles_appropriate_ones
|
3970
|
-
driver.configure('ignore_exceptions ["Faraday::ConnectionFailed"]')
|
3971
|
-
stub_opensearch_unavailable
|
3972
|
-
stub_opensearch_info
|
3973
|
-
|
3974
|
-
assert_raise(Fluent::Plugin::OpenSearchOutput::RecoverableRequestFailure) {
|
3975
|
-
driver.run(default_tag: 'test', shutdown: false) do
|
3976
|
-
driver.feed(sample_record)
|
3977
|
-
end
|
3978
|
-
}
|
3979
|
-
end
|
3980
|
-
end
|