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,141 @@
|
|
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_helper'
|
11
|
+
|
12
|
+
require 'elasticsearch'
|
13
|
+
|
14
|
+
require 'json'
|
15
|
+
require 'cabin'
|
16
|
+
|
17
|
+
module OpenSearchHelper
|
18
|
+
def get_host_port
|
19
|
+
if ENV["INTEGRATION"] == "true"
|
20
|
+
"integration:9200"
|
21
|
+
else
|
22
|
+
"localhost:9200"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_client
|
27
|
+
Elasticsearch::Client.new(:hosts => [get_host_port])
|
28
|
+
end
|
29
|
+
|
30
|
+
def doc_type
|
31
|
+
"_doc"
|
32
|
+
end
|
33
|
+
|
34
|
+
def todays_date
|
35
|
+
Time.now.strftime("%Y.%m.%d")
|
36
|
+
end
|
37
|
+
|
38
|
+
def field_properties_from_template(template_name, field)
|
39
|
+
template = get_template(@client, template_name)
|
40
|
+
mappings = get_template_mappings(template)
|
41
|
+
mappings["properties"][field]["properties"]
|
42
|
+
end
|
43
|
+
|
44
|
+
def routing_field_name
|
45
|
+
:routing
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.version
|
49
|
+
RSpec.configuration.filter[:version]
|
50
|
+
end
|
51
|
+
|
52
|
+
RSpec::Matchers.define :have_hits do |expected|
|
53
|
+
match do |actual|
|
54
|
+
expected == actual['hits']['total']['value']
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
RSpec::Matchers.define :have_index_pattern do |expected|
|
59
|
+
match do |actual|
|
60
|
+
test_against = Array(actual['index_patterns'].nil? ? actual['template'] : actual['index_patterns'])
|
61
|
+
test_against.include?(expected)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def clean(client)
|
66
|
+
client.indices.delete_template(:name => "*")
|
67
|
+
client.indices.delete_index_template(:name => "logstash*") rescue nil
|
68
|
+
# This can fail if there are no indexes, ignore failure.
|
69
|
+
client.indices.delete(:index => "*") rescue nil
|
70
|
+
end
|
71
|
+
|
72
|
+
def set_cluster_settings(client, cluster_settings)
|
73
|
+
client.cluster.put_settings(body: cluster_settings)
|
74
|
+
get_cluster_settings(client)
|
75
|
+
end
|
76
|
+
|
77
|
+
def get_cluster_settings(client)
|
78
|
+
client.cluster.get_settings
|
79
|
+
end
|
80
|
+
|
81
|
+
def put_alias(client, the_alias, index)
|
82
|
+
body = {
|
83
|
+
"aliases" => {
|
84
|
+
index => {
|
85
|
+
"is_write_index"=> true
|
86
|
+
}
|
87
|
+
}
|
88
|
+
}
|
89
|
+
client.put_alias({name: the_alias, body: body})
|
90
|
+
end
|
91
|
+
|
92
|
+
def max_docs_policy(max_docs)
|
93
|
+
{
|
94
|
+
"policy" => {
|
95
|
+
"phases"=> {
|
96
|
+
"hot" => {
|
97
|
+
"actions" => {
|
98
|
+
"rollover" => {
|
99
|
+
"max_docs" => max_docs
|
100
|
+
}
|
101
|
+
}
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}
|
105
|
+
}
|
106
|
+
end
|
107
|
+
|
108
|
+
def max_age_policy(max_age)
|
109
|
+
{
|
110
|
+
"policy" => {
|
111
|
+
"phases"=> {
|
112
|
+
"hot" => {
|
113
|
+
"actions" => {
|
114
|
+
"rollover" => {
|
115
|
+
"max_age" => max_age
|
116
|
+
}
|
117
|
+
}
|
118
|
+
}
|
119
|
+
}
|
120
|
+
}
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
def get_template(client, name)
|
125
|
+
t = client.indices.get_template(name: name)
|
126
|
+
# TODO: use index template if version >= 7.8 & OpenSearch
|
127
|
+
t[name]
|
128
|
+
end
|
129
|
+
|
130
|
+
def get_template_settings(template)
|
131
|
+
template['template']
|
132
|
+
end
|
133
|
+
|
134
|
+
def get_template_mappings(template)
|
135
|
+
template['mappings']
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
RSpec.configure do |config|
|
140
|
+
config.include OpenSearchHelper
|
141
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,19 @@
|
|
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 "logstash/devutils/rspec/spec_helper"
|
11
|
+
|
12
|
+
require "logstash/outputs/opensearch"
|
13
|
+
|
14
|
+
module LogStash::Outputs::OpenSearch::SpecHelper
|
15
|
+
end
|
16
|
+
|
17
|
+
RSpec.configure do |config|
|
18
|
+
config.include LogStash::Outputs::OpenSearch::SpecHelper
|
19
|
+
end
|
@@ -0,0 +1,194 @@
|
|
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 "logstash/devutils/rspec/spec_helper"
|
11
|
+
require "logstash/outputs/opensearch"
|
12
|
+
require "logstash/outputs/opensearch/http_client"
|
13
|
+
require "logstash/outputs/opensearch/http_client_builder"
|
14
|
+
|
15
|
+
describe LogStash::Outputs::OpenSearch::HttpClientBuilder do
|
16
|
+
describe "auth setup with url encodable passwords" do
|
17
|
+
let(:klass) { LogStash::Outputs::OpenSearch::HttpClientBuilder }
|
18
|
+
let(:user) { "foo@bar"}
|
19
|
+
let(:password) {"baz@blah" }
|
20
|
+
let(:password_secured) do
|
21
|
+
secured = double("password")
|
22
|
+
allow(secured).to receive(:value).and_return(password)
|
23
|
+
secured
|
24
|
+
end
|
25
|
+
let(:options) { {"user" => user, "password" => password} }
|
26
|
+
let(:logger) { mock("logger") }
|
27
|
+
let(:auth_setup) { klass.setup_basic_auth(double("logger"), {"user" => user, "password" => password_secured}) }
|
28
|
+
|
29
|
+
it "should return the user escaped" do
|
30
|
+
expect(auth_setup[:user]).to eql(CGI.escape(user))
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should return the password escaped" do
|
34
|
+
expect(auth_setup[:password]).to eql(CGI.escape(password))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "customizing action paths" do
|
39
|
+
let(:hosts) { [ ::LogStash::Util::SafeURI.new("http://localhost:9200") ] }
|
40
|
+
let(:options) { {"hosts" => hosts } }
|
41
|
+
let(:logger) { double("logger") }
|
42
|
+
before :each do
|
43
|
+
[:debug, :debug?, :info?, :info, :warn].each do |level|
|
44
|
+
allow(logger).to receive(level)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "healthcheck_path" do
|
49
|
+
|
50
|
+
context "when setting bulk_path" do
|
51
|
+
let(:bulk_path) { "/meh" }
|
52
|
+
let(:options) { super().merge("bulk_path" => bulk_path) }
|
53
|
+
|
54
|
+
context "when using path" do
|
55
|
+
let(:options) { super().merge("path" => "/path") }
|
56
|
+
it "ignores the path setting" do
|
57
|
+
expect(described_class).to receive(:create_http_client) do |options|
|
58
|
+
expect(options[:bulk_path]).to eq(bulk_path)
|
59
|
+
end
|
60
|
+
described_class.build(logger, hosts, options)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
context "when not using path" do
|
64
|
+
|
65
|
+
it "uses the bulk_path setting" do
|
66
|
+
expect(described_class).to receive(:create_http_client) do |options|
|
67
|
+
expect(options[:bulk_path]).to eq(bulk_path)
|
68
|
+
end
|
69
|
+
described_class.build(logger, hosts, options)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "when not setting bulk_path" do
|
75
|
+
|
76
|
+
context "when using path" do
|
77
|
+
let(:path) { "/meh" }
|
78
|
+
let(:options) { super().merge("path" => path) }
|
79
|
+
it "sets bulk_path to path+_bulk" do
|
80
|
+
expect(described_class).to receive(:create_http_client) do |options|
|
81
|
+
expect(options[:bulk_path]).to eq("#{path}/_bulk")
|
82
|
+
end
|
83
|
+
described_class.build(logger, hosts, options)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "when not using path" do
|
88
|
+
it "sets the bulk_path to _bulk" do
|
89
|
+
expect(described_class).to receive(:create_http_client) do |options|
|
90
|
+
expect(options[:bulk_path]).to eq("/_bulk")
|
91
|
+
end
|
92
|
+
described_class.build(logger, hosts, options)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
describe "healthcheck_path" do
|
98
|
+
context "when setting healthcheck_path" do
|
99
|
+
let(:healthcheck_path) { "/meh" }
|
100
|
+
let(:options) { super().merge("healthcheck_path" => healthcheck_path) }
|
101
|
+
|
102
|
+
context "when using path" do
|
103
|
+
let(:options) { super().merge("path" => "/path") }
|
104
|
+
it "ignores the path setting" do
|
105
|
+
expect(described_class).to receive(:create_http_client) do |options|
|
106
|
+
expect(options[:healthcheck_path]).to eq(healthcheck_path)
|
107
|
+
end
|
108
|
+
described_class.build(logger, hosts, options)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
context "when not using path" do
|
112
|
+
|
113
|
+
it "uses the healthcheck_path setting" do
|
114
|
+
expect(described_class).to receive(:create_http_client) do |options|
|
115
|
+
expect(options[:healthcheck_path]).to eq(healthcheck_path)
|
116
|
+
end
|
117
|
+
described_class.build(logger, hosts, options)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context "when not setting healthcheck_path" do
|
123
|
+
|
124
|
+
context "when using path" do
|
125
|
+
let(:path) { "/meh" }
|
126
|
+
let(:options) { super().merge("path" => path) }
|
127
|
+
it "sets healthcheck_path to path" do
|
128
|
+
expect(described_class).to receive(:create_http_client) do |options|
|
129
|
+
expect(options[:healthcheck_path]).to eq(path)
|
130
|
+
end
|
131
|
+
described_class.build(logger, hosts, options)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context "when not using path" do
|
136
|
+
it "sets the healthcheck_path to root" do
|
137
|
+
expect(described_class).to receive(:create_http_client) do |options|
|
138
|
+
expect(options[:healthcheck_path]).to eq("/")
|
139
|
+
end
|
140
|
+
described_class.build(logger, hosts, options)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
describe "sniffing_path" do
|
146
|
+
context "when setting sniffing_path" do
|
147
|
+
let(:sniffing_path) { "/meh" }
|
148
|
+
let(:options) { super().merge("sniffing_path" => sniffing_path) }
|
149
|
+
|
150
|
+
context "when using path" do
|
151
|
+
let(:options) { super().merge("path" => "/path") }
|
152
|
+
it "ignores the path setting" do
|
153
|
+
expect(described_class).to receive(:create_http_client) do |options|
|
154
|
+
expect(options[:sniffing_path]).to eq(sniffing_path)
|
155
|
+
end
|
156
|
+
described_class.build(logger, hosts, options)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
context "when not using path" do
|
160
|
+
|
161
|
+
it "uses the sniffing_path setting" do
|
162
|
+
expect(described_class).to receive(:create_http_client) do |options|
|
163
|
+
expect(options[:sniffing_path]).to eq(sniffing_path)
|
164
|
+
end
|
165
|
+
described_class.build(logger, hosts, options)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
context "when not setting sniffing_path" do
|
171
|
+
|
172
|
+
context "when using path" do
|
173
|
+
let(:path) { "/meh" }
|
174
|
+
let(:options) { super().merge("path" => path) }
|
175
|
+
it "sets sniffing_path to path+_nodes/http" do
|
176
|
+
expect(described_class).to receive(:create_http_client) do |options|
|
177
|
+
expect(options[:sniffing_path]).to eq("#{path}/_nodes/http")
|
178
|
+
end
|
179
|
+
described_class.build(logger, hosts, options)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
context "when not using path" do
|
184
|
+
it "sets the sniffing_path to _nodes/http" do
|
185
|
+
expect(described_class).to receive(:create_http_client) do |options|
|
186
|
+
expect(options[:sniffing_path]).to eq("/_nodes/http")
|
187
|
+
end
|
188
|
+
described_class.build(logger, hosts, options)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
@@ -0,0 +1,62 @@
|
|
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 "logstash/outputs/opensearch"
|
11
|
+
require_relative "../../../spec/opensearch_spec_helper"
|
12
|
+
|
13
|
+
describe "whitelisting error types in expected behavior" do
|
14
|
+
let(:template) { '{"template" : "not important, will be updated by :index"}' }
|
15
|
+
let(:event1) { LogStash::Event.new("somevalue" => 100, "@timestamp" => "2014-11-17T20:37:17.223Z") }
|
16
|
+
let(:action1) { ["index", {:_id=>1, :routing=>nil, :_index=>"logstash-2014.11.17", :_type=> doc_type }, event1] }
|
17
|
+
let(:settings) { {"manage_template" => true, "index" => "logstash-2014.11.17", "template_overwrite" => true, "hosts" => get_host_port() } }
|
18
|
+
|
19
|
+
subject { LogStash::Outputs::OpenSearch.new(settings) }
|
20
|
+
|
21
|
+
before :each do
|
22
|
+
allow(subject.logger).to receive(:warn)
|
23
|
+
allow(subject).to receive(:maximum_seen_major_version).and_return(0)
|
24
|
+
allow(subject).to receive(:finish_register)
|
25
|
+
|
26
|
+
subject.register
|
27
|
+
allow(subject.client).to receive(:bulk).and_return(
|
28
|
+
{
|
29
|
+
"errors" => true,
|
30
|
+
"items" => [{
|
31
|
+
"create" => {
|
32
|
+
"status" => 409,
|
33
|
+
"error" => {
|
34
|
+
"type" => "document_already_exists_exception",
|
35
|
+
"reason" => "[shard] document already exists"
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}]
|
39
|
+
})
|
40
|
+
|
41
|
+
subject.multi_receive([event1])
|
42
|
+
end
|
43
|
+
|
44
|
+
after :each do
|
45
|
+
subject.close
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "when failure logging is enabled for everything" do
|
49
|
+
it "should log a failure on the action" do
|
50
|
+
expect(subject.logger).to have_received(:warn).with("Failed action", anything)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "when failure logging is disabled for docuemnt exists error" do
|
55
|
+
let(:settings) { super().merge("failure_type_logging_whitelist" => ["document_already_exists_exception"]) }
|
56
|
+
|
57
|
+
it "should log a failure on the action" do
|
58
|
+
expect(subject.logger).not_to have_received(:warn).with("Failed action", anything)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,159 @@
|
|
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 "logstash/devutils/rspec/spec_helper"
|
11
|
+
require "logstash/outputs/opensearch/http_client"
|
12
|
+
require 'cabin'
|
13
|
+
|
14
|
+
describe LogStash::Outputs::OpenSearch::HttpClient::ManticoreAdapter do
|
15
|
+
let(:logger) { Cabin::Channel.get }
|
16
|
+
let(:options) { {} }
|
17
|
+
|
18
|
+
subject { described_class.new(logger, options) }
|
19
|
+
|
20
|
+
it "should raise an exception if requests are issued after close" do
|
21
|
+
subject.close
|
22
|
+
expect { subject.perform_request(::LogStash::Util::SafeURI.new("http://localhost:9200"), :get, '/') }.to raise_error(::Manticore::ClientStoppedException)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should implement host unreachable exceptions" do
|
26
|
+
expect(subject.host_unreachable_exceptions).to be_a(Array)
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "auth" do
|
30
|
+
let(:user) { "myuser" }
|
31
|
+
let(:password) { "mypassword" }
|
32
|
+
let(:noauth_uri) { clone = uri.clone; clone.user=nil; clone.password=nil; clone }
|
33
|
+
let(:uri) { ::LogStash::Util::SafeURI.new("http://#{user}:#{password}@localhost:9200") }
|
34
|
+
|
35
|
+
it "should convert the auth to params" do
|
36
|
+
resp = double("response")
|
37
|
+
allow(resp).to receive(:call)
|
38
|
+
allow(resp).to receive(:code).and_return(200)
|
39
|
+
|
40
|
+
expected_uri = noauth_uri.clone
|
41
|
+
expected_uri.path = "/"
|
42
|
+
|
43
|
+
expect(subject.manticore).to receive(:get).
|
44
|
+
with(expected_uri.to_s, {
|
45
|
+
:headers => {"Content-Type" => "application/json"},
|
46
|
+
:auth => {
|
47
|
+
:user => user,
|
48
|
+
:password => password,
|
49
|
+
:eager => true
|
50
|
+
}
|
51
|
+
}).and_return resp
|
52
|
+
|
53
|
+
subject.perform_request(uri, :get, "/")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "bad response codes" do
|
58
|
+
let(:uri) { ::LogStash::Util::SafeURI.new("http://localhost:9200") }
|
59
|
+
|
60
|
+
it "should raise a bad response code error" do
|
61
|
+
resp = double("response")
|
62
|
+
allow(resp).to receive(:call)
|
63
|
+
allow(resp).to receive(:code).and_return(500)
|
64
|
+
allow(resp).to receive(:body).and_return("a body")
|
65
|
+
|
66
|
+
expect(subject.manticore).to receive(:get).
|
67
|
+
with(uri.to_s + "/", anything).
|
68
|
+
and_return(resp)
|
69
|
+
|
70
|
+
uri_with_path = uri.clone
|
71
|
+
uri_with_path.path = "/"
|
72
|
+
|
73
|
+
expect(::LogStash::Outputs::OpenSearch::HttpClient::Pool::BadResponseCodeError).to receive(:new).
|
74
|
+
with(resp.code, uri_with_path, nil, resp.body).and_call_original
|
75
|
+
|
76
|
+
expect do
|
77
|
+
subject.perform_request(uri, :get, "/")
|
78
|
+
end.to raise_error(::LogStash::Outputs::OpenSearch::HttpClient::Pool::BadResponseCodeError)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "format_url" do
|
83
|
+
let(:url) { ::LogStash::Util::SafeURI.new("http://localhost:9200/path/") }
|
84
|
+
let(:path) { "_bulk" }
|
85
|
+
subject { described_class.new(double("logger"), {}) }
|
86
|
+
|
87
|
+
it "should add the path argument to the uri's path" do
|
88
|
+
expect(subject.format_url(url, path).path).to eq("/path/_bulk")
|
89
|
+
end
|
90
|
+
|
91
|
+
context "when uri contains query parameters" do
|
92
|
+
let(:query_params) { "query=value&key=value2" }
|
93
|
+
let(:url) { ::LogStash::Util::SafeURI.new("http://localhost:9200/path/?#{query_params}") }
|
94
|
+
let(:formatted) { subject.format_url(url, path)}
|
95
|
+
|
96
|
+
it "should retain query_params after format" do
|
97
|
+
expect(formatted.query).to eq(query_params)
|
98
|
+
end
|
99
|
+
|
100
|
+
context "and the path contains query parameters" do
|
101
|
+
let(:path) { "/special_path?specialParam=123" }
|
102
|
+
|
103
|
+
it "should join the query correctly" do
|
104
|
+
expect(formatted.query).to eq(query_params + "&specialParam=123")
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context "when the path contains query parameters" do
|
110
|
+
let(:path) { "/special_bulk?pathParam=1"}
|
111
|
+
let(:formatted) { subject.format_url(url, path) }
|
112
|
+
|
113
|
+
it "should add the path correctly" do
|
114
|
+
expect(formatted.path).to eq("#{url.path}special_bulk")
|
115
|
+
expect(subject.remove_double_escaping(formatted.path)).to eq("#{url.path}special_bulk")
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should add the query parameters correctly" do
|
119
|
+
expect(formatted.query).to eq("pathParam=1")
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "when uri contains credentials" do
|
124
|
+
let(:url) { ::LogStash::Util::SafeURI.new("http://myuser:mypass@localhost:9200") }
|
125
|
+
let(:formatted) { subject.format_url(url, path) }
|
126
|
+
|
127
|
+
it "should remove credentials after format" do
|
128
|
+
expect(formatted.userinfo).to be_nil
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context 'when uri contains date math' do
|
133
|
+
let(:url) { ::LogStash::Util::SafeURI.new("http://localhost:9200") }
|
134
|
+
let(:path) { CGI.escape("<logstash-{now/d}-0001>") }
|
135
|
+
let(:formatted) { subject.format_url(url, path) }
|
136
|
+
|
137
|
+
it 'should escape the uri correctly' do
|
138
|
+
expect(subject.remove_double_escaping(formatted.path)).to eq("/%3Clogstash-%7Bnow%2Fd%7D-0001%3E")
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'when uri does not contain date math' do
|
143
|
+
let(:url) { ::LogStash::Util::SafeURI.new("http://localhost:9200") }
|
144
|
+
let(:path) { CGI.escape("logstash-0001") }
|
145
|
+
let(:formatted) { subject.format_url(url, path) }
|
146
|
+
|
147
|
+
it 'should escape the uri correctly' do
|
148
|
+
expect(subject.remove_double_escaping(formatted.path)).to eq("/logstash-0001")
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe "integration specs", :integration => true do
|
154
|
+
it "should perform correct tests without error" do
|
155
|
+
resp = subject.perform_request(::LogStash::Util::SafeURI.new("http://localhost:9200"), :get, "/")
|
156
|
+
expect(resp.code).to eql(200)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|