logstash-output-opensearch 1.0.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/ADMINS.md +29 -0
- data/CODE_OF_CONDUCT.md +25 -0
- data/CONTRIBUTING.md +99 -0
- data/DEVELOPER_GUIDE.md +208 -0
- data/Gemfile +20 -0
- data/LICENSE +202 -0
- data/MAINTAINERS.md +71 -0
- data/NOTICE +2 -0
- data/README.md +37 -0
- data/RELEASING.md +36 -0
- data/SECURITY.md +3 -0
- data/lib/logstash/outputs/opensearch.rb +449 -0
- data/lib/logstash/outputs/opensearch/distribution_checker.rb +44 -0
- data/lib/logstash/outputs/opensearch/http_client.rb +465 -0
- data/lib/logstash/outputs/opensearch/http_client/manticore_adapter.rb +140 -0
- data/lib/logstash/outputs/opensearch/http_client/pool.rb +467 -0
- data/lib/logstash/outputs/opensearch/http_client_builder.rb +182 -0
- data/lib/logstash/outputs/opensearch/template_manager.rb +60 -0
- data/lib/logstash/outputs/opensearch/templates/ecs-disabled/1x.json +44 -0
- data/lib/logstash/outputs/opensearch/templates/ecs-disabled/7x.json +44 -0
- data/lib/logstash/plugin_mixins/opensearch/api_configs.rb +168 -0
- data/lib/logstash/plugin_mixins/opensearch/common.rb +294 -0
- data/lib/logstash/plugin_mixins/opensearch/noop_distribution_checker.rb +18 -0
- data/logstash-output-opensearch.gemspec +40 -0
- data/spec/fixtures/_nodes/nodes.json +74 -0
- data/spec/fixtures/htpasswd +2 -0
- data/spec/fixtures/nginx_reverse_proxy.conf +22 -0
- data/spec/fixtures/scripts/painless/scripted_update.painless +2 -0
- data/spec/fixtures/scripts/painless/scripted_update_nested.painless +1 -0
- data/spec/fixtures/scripts/painless/scripted_upsert.painless +1 -0
- data/spec/integration/outputs/compressed_indexing_spec.rb +76 -0
- data/spec/integration/outputs/create_spec.rb +76 -0
- data/spec/integration/outputs/delete_spec.rb +72 -0
- data/spec/integration/outputs/index_spec.rb +164 -0
- data/spec/integration/outputs/index_version_spec.rb +110 -0
- data/spec/integration/outputs/ingest_pipeline_spec.rb +82 -0
- data/spec/integration/outputs/metrics_spec.rb +75 -0
- data/spec/integration/outputs/no_opensearch_on_startup_spec.rb +67 -0
- data/spec/integration/outputs/painless_update_spec.rb +147 -0
- data/spec/integration/outputs/parent_spec.rb +103 -0
- data/spec/integration/outputs/retry_spec.rb +182 -0
- data/spec/integration/outputs/routing_spec.rb +70 -0
- data/spec/integration/outputs/sniffer_spec.rb +70 -0
- data/spec/integration/outputs/templates_spec.rb +105 -0
- data/spec/integration/outputs/update_spec.rb +123 -0
- data/spec/opensearch_spec_helper.rb +141 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/unit/http_client_builder_spec.rb +194 -0
- data/spec/unit/outputs/error_whitelist_spec.rb +62 -0
- data/spec/unit/outputs/opensearch/http_client/manticore_adapter_spec.rb +159 -0
- data/spec/unit/outputs/opensearch/http_client/pool_spec.rb +306 -0
- data/spec/unit/outputs/opensearch/http_client_spec.rb +292 -0
- data/spec/unit/outputs/opensearch/template_manager_spec.rb +36 -0
- data/spec/unit/outputs/opensearch_proxy_spec.rb +112 -0
- data/spec/unit/outputs/opensearch_spec.rb +800 -0
- data/spec/unit/outputs/opensearch_ssl_spec.rb +179 -0
- metadata +289 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1 @@
|
|
1
|
+
ctx._source.counter += params.event.data.count
|
@@ -0,0 +1 @@
|
|
1
|
+
ctx._source.counter = params.event.counter
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
2
|
+
#
|
3
|
+
# The 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 OpenSearch Contributors. See
|
8
|
+
# GitHub history for details.
|
9
|
+
|
10
|
+
require_relative "../../../spec/opensearch_spec_helper"
|
11
|
+
require "logstash/outputs/opensearch"
|
12
|
+
require "stringio"
|
13
|
+
|
14
|
+
RSpec::Matchers.define :a_valid_gzip_encoded_string do
|
15
|
+
match { |data|
|
16
|
+
expect { Zlib::GzipReader.new(StringIO.new(data)).read }.not_to raise_error
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
describe "indexing with http_compression turned on", :integration => true do
|
22
|
+
let(:event) { LogStash::Event.new("message" => "Hello World!", "type" => type) }
|
23
|
+
let(:index) { 10.times.collect { rand(10).to_s }.join("") }
|
24
|
+
let(:type) { "_doc" }
|
25
|
+
let(:event_count) { 10000 + rand(500) }
|
26
|
+
let(:events) { event_count.times.map { event }.to_a }
|
27
|
+
let(:config) {
|
28
|
+
{
|
29
|
+
"hosts" => get_host_port,
|
30
|
+
"index" => index,
|
31
|
+
"http_compression" => true
|
32
|
+
}
|
33
|
+
}
|
34
|
+
subject { LogStash::Outputs::OpenSearch.new(config) }
|
35
|
+
|
36
|
+
let(:es_url) { "http://#{get_host_port}" }
|
37
|
+
let(:index_url) {"#{es_url}/#{index}"}
|
38
|
+
let(:http_client_options) { {} }
|
39
|
+
let(:http_client) do
|
40
|
+
Manticore::Client.new(http_client_options)
|
41
|
+
end
|
42
|
+
|
43
|
+
before do
|
44
|
+
subject.register
|
45
|
+
subject.multi_receive([])
|
46
|
+
end
|
47
|
+
|
48
|
+
shared_examples "an indexer" do
|
49
|
+
it "ships events" do
|
50
|
+
subject.multi_receive(events)
|
51
|
+
|
52
|
+
http_client.post("#{es_url}/_refresh").call
|
53
|
+
|
54
|
+
response = http_client.get("#{index_url}/_count?q=*")
|
55
|
+
result = LogStash::Json.load(response.body)
|
56
|
+
cur_count = result["count"]
|
57
|
+
expect(cur_count).to eq(event_count)
|
58
|
+
|
59
|
+
response = http_client.get("#{index_url}/_search?q=*&size=1000")
|
60
|
+
result = LogStash::Json.load(response.body)
|
61
|
+
result["hits"]["hits"].each do |doc|
|
62
|
+
expect(doc["_type"]).to eq(type)
|
63
|
+
expect(doc["_index"]).to eq(index)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "sets the correct content-encoding header and body is compressed" do
|
69
|
+
expect(subject.client.pool.adapter.client).to receive(:send).
|
70
|
+
with(anything, anything, {:headers=>{"Content-Encoding"=>"gzip", "Content-Type"=>"application/json"}, :body => a_valid_gzip_encoded_string}).
|
71
|
+
and_call_original
|
72
|
+
subject.multi_receive(events)
|
73
|
+
end
|
74
|
+
|
75
|
+
it_behaves_like("an indexer")
|
76
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
2
|
+
#
|
3
|
+
# The 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 OpenSearch Contributors. See
|
8
|
+
# GitHub history for details.
|
9
|
+
|
10
|
+
require_relative "../../../spec/opensearch_spec_helper"
|
11
|
+
|
12
|
+
describe "client create actions", :integration => true do
|
13
|
+
require "logstash/outputs/opensearch"
|
14
|
+
|
15
|
+
def get_es_output(action, id, version=nil, version_type=nil)
|
16
|
+
settings = {
|
17
|
+
"manage_template" => true,
|
18
|
+
"index" => "logstash-create",
|
19
|
+
"template_overwrite" => true,
|
20
|
+
"hosts" => get_host_port(),
|
21
|
+
"action" => action
|
22
|
+
}
|
23
|
+
settings['document_id'] = id
|
24
|
+
settings['version'] = version if version
|
25
|
+
settings['version_type'] = version_type if version_type
|
26
|
+
LogStash::Outputs::OpenSearch.new(settings)
|
27
|
+
end
|
28
|
+
|
29
|
+
before :each do
|
30
|
+
@client = get_client
|
31
|
+
# Delete all templates first.
|
32
|
+
# Clean OpenSearch of data before we start.
|
33
|
+
@client.indices.delete_template(:name => "*")
|
34
|
+
# This can fail if there are no indexes, ignore failure.
|
35
|
+
@client.indices.delete(:index => "*") rescue nil
|
36
|
+
end
|
37
|
+
|
38
|
+
context "when action => create" do
|
39
|
+
it "should create new documents with or without id" do
|
40
|
+
subject = get_es_output("create", "id123")
|
41
|
+
subject.register
|
42
|
+
subject.multi_receive([LogStash::Event.new("message" => "sample message here")])
|
43
|
+
@client.indices.refresh
|
44
|
+
# Wait or fail until everything's indexed.
|
45
|
+
Stud::try(3.times) do
|
46
|
+
r = @client.search(index: 'logstash-*')
|
47
|
+
expect(r).to have_hits(1)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should allow default (internal) version" do
|
52
|
+
subject = get_es_output("create", "id123", 43)
|
53
|
+
subject.register
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should allow internal version" do
|
57
|
+
subject = get_es_output("create", "id123", 43, "internal")
|
58
|
+
subject.register
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should not allow external version" do
|
62
|
+
subject = get_es_output("create", "id123", 43, "external")
|
63
|
+
expect { subject.register }.to raise_error(LogStash::ConfigurationError)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should not allow external_gt version" do
|
67
|
+
subject = get_es_output("create", "id123", 43, "external_gt")
|
68
|
+
expect { subject.register }.to raise_error(LogStash::ConfigurationError)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should not allow external_gte version" do
|
72
|
+
subject = get_es_output("create", "id123", 43, "external_gte")
|
73
|
+
expect { subject.register }.to raise_error(LogStash::ConfigurationError)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
2
|
+
#
|
3
|
+
# The 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 OpenSearch Contributors. See
|
8
|
+
# GitHub history for details.
|
9
|
+
|
10
|
+
require_relative "../../../spec/opensearch_spec_helper"
|
11
|
+
require "logstash/outputs/opensearch"
|
12
|
+
|
13
|
+
|
14
|
+
describe "Versioned delete", :integration => true do
|
15
|
+
require "logstash/outputs/opensearch"
|
16
|
+
|
17
|
+
let(:es) { get_client }
|
18
|
+
|
19
|
+
before :each do
|
20
|
+
# Delete all templates first.
|
21
|
+
# Clean ES of data before we start.
|
22
|
+
es.indices.delete_template(:name => "*")
|
23
|
+
# This can fail if there are no indexes, ignore failure.
|
24
|
+
es.indices.delete(:index => "*") rescue nil
|
25
|
+
es.indices.refresh
|
26
|
+
end
|
27
|
+
|
28
|
+
context "when delete only" do
|
29
|
+
subject { LogStash::Outputs::OpenSearch.new(settings) }
|
30
|
+
|
31
|
+
before do
|
32
|
+
subject.register
|
33
|
+
end
|
34
|
+
|
35
|
+
let(:settings) do
|
36
|
+
{
|
37
|
+
"manage_template" => true,
|
38
|
+
"index" => "logstash-delete",
|
39
|
+
"template_overwrite" => true,
|
40
|
+
"hosts" => get_host_port(),
|
41
|
+
"document_id" => "%{my_id}",
|
42
|
+
"version" => "%{my_version}",
|
43
|
+
"version_type" => "external",
|
44
|
+
"action" => "%{my_action}"
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should ignore non-monotonic external version updates" do
|
49
|
+
id = "ev2"
|
50
|
+
subject.multi_receive([LogStash::Event.new("my_id" => id, "my_action" => "index", "message" => "foo", "my_version" => 99)])
|
51
|
+
r = es.get(:index => 'logstash-delete', :type => doc_type, :id => id, :refresh => true)
|
52
|
+
expect(r['_version']).to eq(99)
|
53
|
+
expect(r['_source']['message']).to eq('foo')
|
54
|
+
|
55
|
+
subject.multi_receive([LogStash::Event.new("my_id" => id, "my_action" => "delete", "message" => "foo", "my_version" => 98)])
|
56
|
+
r2 = es.get(:index => 'logstash-delete', :type => doc_type, :id => id, :refresh => true)
|
57
|
+
expect(r2['_version']).to eq(99)
|
58
|
+
expect(r2['_source']['message']).to eq('foo')
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should commit monotonic external version updates" do
|
62
|
+
id = "ev3"
|
63
|
+
subject.multi_receive([LogStash::Event.new("my_id" => id, "my_action" => "index", "message" => "foo", "my_version" => 99)])
|
64
|
+
r = es.get(:index => 'logstash-delete', :type => doc_type, :id => id, :refresh => true)
|
65
|
+
expect(r['_version']).to eq(99)
|
66
|
+
expect(r['_source']['message']).to eq('foo')
|
67
|
+
|
68
|
+
subject.multi_receive([LogStash::Event.new("my_id" => id, "my_action" => "delete", "message" => "foo", "my_version" => 100)])
|
69
|
+
expect { es.get(:index => 'logstash-delete', :type => doc_type, :id => id, :refresh => true) }.to raise_error(Elasticsearch::Transport::Transport::Errors::NotFound)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
2
|
+
#
|
3
|
+
# The 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 OpenSearch Contributors. See
|
8
|
+
# GitHub history for details.
|
9
|
+
|
10
|
+
require_relative "../../../spec/opensearch_spec_helper"
|
11
|
+
require "logstash/outputs/opensearch"
|
12
|
+
|
13
|
+
describe "TARGET_BULK_BYTES", :integration => true do
|
14
|
+
let(:target_bulk_bytes) { LogStash::Outputs::OpenSearch::TARGET_BULK_BYTES }
|
15
|
+
let(:event_count) { 1000 }
|
16
|
+
let(:events) { event_count.times.map { event }.to_a }
|
17
|
+
let(:config) {
|
18
|
+
{
|
19
|
+
"hosts" => get_host_port,
|
20
|
+
"index" => index
|
21
|
+
}
|
22
|
+
}
|
23
|
+
let(:index) { 10.times.collect { rand(10).to_s }.join("") }
|
24
|
+
let(:type) { "_doc" }
|
25
|
+
|
26
|
+
subject { LogStash::Outputs::OpenSearch.new(config) }
|
27
|
+
|
28
|
+
before do
|
29
|
+
subject.register
|
30
|
+
allow(subject.client).to receive(:bulk_send).with(any_args).and_call_original
|
31
|
+
subject.multi_receive(events)
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "batches that are too large for one" do
|
35
|
+
let(:event) { LogStash::Event.new("message" => "a " * (((target_bulk_bytes/2) / event_count)+1)) }
|
36
|
+
|
37
|
+
it "should send in two batches" do
|
38
|
+
expect(subject.client).to have_received(:bulk_send).twice do |payload|
|
39
|
+
expect(payload.size).to be <= target_bulk_bytes
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "batches that fit in one" do
|
44
|
+
# Normally you'd want to generate a request that's just 1 byte below the limit, but it's
|
45
|
+
# impossible to know how many bytes an event will serialize as with bulk proto overhead
|
46
|
+
let(:event) { LogStash::Event.new("message" => "a") }
|
47
|
+
|
48
|
+
it "should send in one batch" do
|
49
|
+
expect(subject.client).to have_received(:bulk_send).once do |payload|
|
50
|
+
expect(payload.size).to be <= target_bulk_bytes
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "indexing" do
|
58
|
+
let(:event) { LogStash::Event.new("message" => "Hello World!", "type" => type) }
|
59
|
+
let(:index) { 10.times.collect { rand(10).to_s }.join("") }
|
60
|
+
let(:type) { "_doc" }
|
61
|
+
let(:event_count) { 1 + rand(2) }
|
62
|
+
let(:config) { "not implemented" }
|
63
|
+
let(:events) { event_count.times.map { event }.to_a }
|
64
|
+
subject { LogStash::Outputs::OpenSearch.new(config) }
|
65
|
+
|
66
|
+
let(:es_url) { "http://#{get_host_port}" }
|
67
|
+
let(:index_url) {"#{es_url}/#{index}"}
|
68
|
+
let(:http_client_options) { {} }
|
69
|
+
let(:http_client) do
|
70
|
+
Manticore::Client.new(http_client_options)
|
71
|
+
end
|
72
|
+
|
73
|
+
before do
|
74
|
+
subject.register
|
75
|
+
subject.multi_receive([])
|
76
|
+
end
|
77
|
+
|
78
|
+
shared_examples "an indexer" do |secure|
|
79
|
+
it "ships events" do
|
80
|
+
subject.multi_receive(events)
|
81
|
+
|
82
|
+
http_client.post("#{es_url}/_refresh").call
|
83
|
+
|
84
|
+
response = http_client.get("#{index_url}/_count?q=*")
|
85
|
+
result = LogStash::Json.load(response.body)
|
86
|
+
cur_count = result["count"]
|
87
|
+
expect(cur_count).to eq(event_count)
|
88
|
+
|
89
|
+
response = http_client.get("#{index_url}/_search?q=*&size=1000")
|
90
|
+
result = LogStash::Json.load(response.body)
|
91
|
+
result["hits"]["hits"].each do |doc|
|
92
|
+
expect(doc["_type"]).to eq(type)
|
93
|
+
expect(doc["_index"]).to eq(index)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
it "sets the correct content-type header" do
|
98
|
+
expected_manticore_opts = {:headers => {"Content-Type" => "application/json"}, :body => anything}
|
99
|
+
if secure
|
100
|
+
expected_manticore_opts = {
|
101
|
+
:headers => {"Content-Type" => "application/json"},
|
102
|
+
:body => anything,
|
103
|
+
:auth => {
|
104
|
+
:user => user,
|
105
|
+
:password => password,
|
106
|
+
:eager => true
|
107
|
+
}}
|
108
|
+
end
|
109
|
+
expect(subject.client.pool.adapter.client).to receive(:send).
|
110
|
+
with(anything, anything, expected_manticore_opts).at_least(:once).
|
111
|
+
and_call_original
|
112
|
+
subject.multi_receive(events)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "an indexer with custom index_type", :integration => true do
|
117
|
+
let(:config) {
|
118
|
+
{
|
119
|
+
"hosts" => get_host_port,
|
120
|
+
"index" => index
|
121
|
+
}
|
122
|
+
}
|
123
|
+
it_behaves_like("an indexer")
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "an indexer with no type value set (default to doc)", :integration => true do
|
127
|
+
let(:type) { "_doc" }
|
128
|
+
let(:config) {
|
129
|
+
{
|
130
|
+
"hosts" => get_host_port,
|
131
|
+
"index" => index
|
132
|
+
}
|
133
|
+
}
|
134
|
+
it_behaves_like("an indexer")
|
135
|
+
end
|
136
|
+
describe "a secured indexer", :secure_integration => true do
|
137
|
+
let(:user) { "admin" }
|
138
|
+
let(:password) { "admin" }
|
139
|
+
let(:es_url) {"https://integration:9200"}
|
140
|
+
let(:config) do
|
141
|
+
{
|
142
|
+
"hosts" => ["integration:9200"],
|
143
|
+
"user" => user,
|
144
|
+
"password" => password,
|
145
|
+
"ssl" => true,
|
146
|
+
"ssl_certificate_verification" => false,
|
147
|
+
"index" => index
|
148
|
+
}
|
149
|
+
end
|
150
|
+
let(:http_client_options) do
|
151
|
+
{
|
152
|
+
:auth => {
|
153
|
+
:user => user,
|
154
|
+
:password => password
|
155
|
+
},
|
156
|
+
:ssl => {
|
157
|
+
:enabled => true,
|
158
|
+
:verify => false
|
159
|
+
}
|
160
|
+
}
|
161
|
+
end
|
162
|
+
it_behaves_like("an indexer", true)
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
2
|
+
#
|
3
|
+
# The 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 OpenSearch Contributors. See
|
8
|
+
# GitHub history for details.
|
9
|
+
|
10
|
+
require_relative "../../../spec/opensearch_spec_helper"
|
11
|
+
require "logstash/outputs/opensearch"
|
12
|
+
|
13
|
+
describe "Versioned indexing", :integration => true do
|
14
|
+
require "logstash/outputs/opensearch"
|
15
|
+
|
16
|
+
let(:es) { get_client }
|
17
|
+
|
18
|
+
before :each do
|
19
|
+
# Delete all templates first.
|
20
|
+
# Clean OpenSearch of data before we start.
|
21
|
+
es.indices.delete_template(:name => "*")
|
22
|
+
# This can fail if there are no indexes, ignore failure.
|
23
|
+
es.indices.delete(:index => "*") rescue nil
|
24
|
+
es.indices.refresh
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when index only" do
|
28
|
+
subject { LogStash::Outputs::OpenSearch.new(settings) }
|
29
|
+
|
30
|
+
before do
|
31
|
+
subject.register
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "unversioned output" do
|
35
|
+
let(:settings) do
|
36
|
+
{
|
37
|
+
"manage_template" => true,
|
38
|
+
"index" => "logstash-index",
|
39
|
+
"template_overwrite" => true,
|
40
|
+
"hosts" => get_host_port(),
|
41
|
+
"action" => "index",
|
42
|
+
"script_lang" => "groovy",
|
43
|
+
"document_id" => "%{my_id}"
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should default to OpenSearch version" do
|
48
|
+
subject.multi_receive([LogStash::Event.new("my_id" => "123", "message" => "foo")])
|
49
|
+
r = es.get(:index => 'logstash-index', :type => doc_type, :id => "123", :refresh => true)
|
50
|
+
expect(r["_version"]).to eq(1)
|
51
|
+
expect(r["_source"]["message"]).to eq('foo')
|
52
|
+
subject.multi_receive([LogStash::Event.new("my_id" => "123", "message" => "foobar")])
|
53
|
+
r2 = es.get(:index => 'logstash-index', :type => doc_type, :id => "123", :refresh => true)
|
54
|
+
expect(r2["_version"]).to eq(2)
|
55
|
+
expect(r2["_source"]["message"]).to eq('foobar')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "versioned output" do
|
60
|
+
let(:settings) do
|
61
|
+
{
|
62
|
+
"manage_template" => true,
|
63
|
+
"index" => "logstash-index",
|
64
|
+
"template_overwrite" => true,
|
65
|
+
"hosts" => get_host_port(),
|
66
|
+
"action" => "index",
|
67
|
+
"script_lang" => "groovy",
|
68
|
+
"document_id" => "%{my_id}",
|
69
|
+
"version" => "%{my_version}",
|
70
|
+
"version_type" => "external",
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should respect the external version" do
|
75
|
+
id = "ev1"
|
76
|
+
subject.multi_receive([LogStash::Event.new("my_id" => id, "my_version" => "99", "message" => "foo")])
|
77
|
+
r = es.get(:index => 'logstash-index', :type => doc_type, :id => id, :refresh => true)
|
78
|
+
expect(r["_version"]).to eq(99)
|
79
|
+
expect(r["_source"]["message"]).to eq('foo')
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should ignore non-monotonic external version updates" do
|
83
|
+
id = "ev2"
|
84
|
+
subject.multi_receive([LogStash::Event.new("my_id" => id, "my_version" => "99", "message" => "foo")])
|
85
|
+
r = es.get(:index => 'logstash-index', :type => doc_type, :id => id, :refresh => true)
|
86
|
+
expect(r["_version"]).to eq(99)
|
87
|
+
expect(r["_source"]["message"]).to eq('foo')
|
88
|
+
|
89
|
+
subject.multi_receive([LogStash::Event.new("my_id" => id, "my_version" => "98", "message" => "foo")])
|
90
|
+
r2 = es.get(:index => 'logstash-index', :type => doc_type, :id => id, :refresh => true)
|
91
|
+
expect(r2["_version"]).to eq(99)
|
92
|
+
expect(r2["_source"]["message"]).to eq('foo')
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should commit monotonic external version updates" do
|
96
|
+
id = "ev3"
|
97
|
+
subject.multi_receive([LogStash::Event.new("my_id" => id, "my_version" => "99", "message" => "foo")])
|
98
|
+
r = es.get(:index => 'logstash-index', :type => doc_type, :id => id, :refresh => true)
|
99
|
+
expect(r["_version"]).to eq(99)
|
100
|
+
expect(r["_source"]["message"]).to eq('foo')
|
101
|
+
|
102
|
+
subject.multi_receive([LogStash::Event.new("my_id" => id, "my_version" => "100", "message" => "foo")])
|
103
|
+
r2 = es.get(:index => 'logstash-index', :type => doc_type, :id => id, :refresh => true)
|
104
|
+
expect(r2["_version"]).to eq(100)
|
105
|
+
expect(r2["_source"]["message"]).to eq('foo')
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|