Reimplement LogStash::String setting in Java (#16576)

Reimplements `LogStash::Setting::String` Ruby setting class into the `org.logstash.settings.SettingString` and exposes it through `java_import` as `LogStash::Setting::SettingString`.
Updates the rspec tests in two ways:
- logging mock is now converted to real Log4J appender that spy log line that are later verified
- verifies `java.lang.IllegalArgumentException` instead of `ArgumentError` is thrown because the kind of exception thrown by Java code, during verification.
This commit is contained in:
Andrea Selva 2025-01-24 16:56:53 +01:00 committed by GitHub
parent dc740b46ca
commit 03b11e9827
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 326 additions and 117 deletions

View file

@ -34,17 +34,17 @@ module LogStash
[
Setting::Boolean.new("allow_superuser", false),
Setting::String.new("node.name", Socket.gethostname),
Setting::NullableString.new("path.config", nil, false),
Setting::SettingString.new("node.name", Socket.gethostname),
Setting::SettingNullableString.new("path.config", nil, false),
Setting::WritableDirectory.new("path.data", ::File.join(LogStash::Environment::LOGSTASH_HOME, "data")),
Setting::NullableString.new("config.string", nil, false),
Setting::SettingNullableString.new("config.string", nil, false),
Setting::Boolean.new("config.test_and_exit", false),
Setting::Boolean.new("config.reload.automatic", false),
Setting::TimeValue.new("config.reload.interval", "3s"), # in seconds
Setting::Boolean.new("config.support_escapes", false),
Setting::String.new("config.field_reference.escape_style", "none", true, %w(none percent ampersand)),
Setting::SettingString.new("config.field_reference.escape_style", "none", true, %w(none percent ampersand)),
Setting::Boolean.new("metric.collect", true),
Setting::String.new("pipeline.id", "main"),
Setting::SettingString.new("pipeline.id", "main"),
Setting::Boolean.new("pipeline.system", false),
Setting::PositiveInteger.new("pipeline.workers", LogStash::Config::CpuCoreStrategy.maximum),
Setting::PositiveInteger.new("pipeline.batch.size", 125),
@ -56,32 +56,32 @@ module LogStash
Setting::CoercibleString.new("pipeline.ordered", "auto", true, ["auto", "true", "false"]),
Setting::CoercibleString.new("pipeline.ecs_compatibility", "v8", true, %w(disabled v1 v8)),
Setting.new("path.plugins", Array, []),
Setting::NullableString.new("interactive", nil, false),
Setting::SettingNullableString.new("interactive", nil, false),
Setting::Boolean.new("config.debug", false),
Setting::String.new("log.level", "info", true, ["fatal", "error", "warn", "debug", "info", "trace"]),
Setting::SettingString.new("log.level", "info", true, ["fatal", "error", "warn", "debug", "info", "trace"]),
Setting::Boolean.new("version", false),
Setting::Boolean.new("help", false),
Setting::Boolean.new("enable-local-plugin-development", false),
Setting::String.new("log.format", "plain", true, ["json", "plain"]),
Setting::SettingString.new("log.format", "plain", true, ["json", "plain"]),
Setting::Boolean.new("log.format.json.fix_duplicate_message_fields", true),
Setting::Boolean.new("api.enabled", true),
Setting::String.new("api.http.host", "127.0.0.1"),
Setting::SettingString.new("api.http.host", "127.0.0.1"),
Setting::PortRange.new("api.http.port", 9600..9700),
Setting::String.new("api.environment", "production"),
Setting::String.new("api.auth.type", "none", true, %w(none basic)),
Setting::String.new("api.auth.basic.username", nil, false).nullable,
Setting::SettingString.new("api.environment", "production"),
Setting::SettingString.new("api.auth.type", "none", true, %w(none basic)),
Setting::SettingString.new("api.auth.basic.username", nil, false).nullable,
Setting::Password.new("api.auth.basic.password", nil, false).nullable,
Setting::String.new("api.auth.basic.password_policy.mode", "WARN", true, %w[WARN ERROR]),
Setting::SettingString.new("api.auth.basic.password_policy.mode", "WARN", true, %w[WARN ERROR]),
Setting::Numeric.new("api.auth.basic.password_policy.length.minimum", 8),
Setting::String.new("api.auth.basic.password_policy.include.upper", "REQUIRED", true, %w[REQUIRED OPTIONAL]),
Setting::String.new("api.auth.basic.password_policy.include.lower", "REQUIRED", true, %w[REQUIRED OPTIONAL]),
Setting::String.new("api.auth.basic.password_policy.include.digit", "REQUIRED", true, %w[REQUIRED OPTIONAL]),
Setting::String.new("api.auth.basic.password_policy.include.symbol", "OPTIONAL", true, %w[REQUIRED OPTIONAL]),
Setting::SettingString.new("api.auth.basic.password_policy.include.upper", "REQUIRED", true, %w[REQUIRED OPTIONAL]),
Setting::SettingString.new("api.auth.basic.password_policy.include.lower", "REQUIRED", true, %w[REQUIRED OPTIONAL]),
Setting::SettingString.new("api.auth.basic.password_policy.include.digit", "REQUIRED", true, %w[REQUIRED OPTIONAL]),
Setting::SettingString.new("api.auth.basic.password_policy.include.symbol", "OPTIONAL", true, %w[REQUIRED OPTIONAL]),
Setting::Boolean.new("api.ssl.enabled", false),
Setting::ExistingFilePath.new("api.ssl.keystore.path", nil, false).nullable,
Setting::Password.new("api.ssl.keystore.password", nil, false).nullable,
Setting::StringArray.new("api.ssl.supported_protocols", nil, true, %w[TLSv1 TLSv1.1 TLSv1.2 TLSv1.3]),
Setting::String.new("queue.type", "memory", true, ["persisted", "memory"]),
Setting::SettingString.new("queue.type", "memory", true, ["persisted", "memory"]),
Setting::Boolean.new("queue.drain", false),
Setting::Bytes.new("queue.page_capacity", "64mb"),
Setting::Bytes.new("queue.max_bytes", "1024mb"),
@ -93,16 +93,16 @@ module LogStash
Setting::Boolean.new("dead_letter_queue.enable", false),
Setting::Bytes.new("dead_letter_queue.max_bytes", "1024mb"),
Setting::Numeric.new("dead_letter_queue.flush_interval", 5000),
Setting::String.new("dead_letter_queue.storage_policy", "drop_newer", true, ["drop_newer", "drop_older"]),
Setting::NullableString.new("dead_letter_queue.retain.age"), # example 5d
Setting::SettingString.new("dead_letter_queue.storage_policy", "drop_newer", true, ["drop_newer", "drop_older"]),
Setting::SettingNullableString.new("dead_letter_queue.retain.age"), # example 5d
Setting::TimeValue.new("slowlog.threshold.warn", "-1"),
Setting::TimeValue.new("slowlog.threshold.info", "-1"),
Setting::TimeValue.new("slowlog.threshold.debug", "-1"),
Setting::TimeValue.new("slowlog.threshold.trace", "-1"),
Setting::String.new("keystore.classname", "org.logstash.secret.store.backend.JavaKeyStore"),
Setting::String.new("keystore.file", ::File.join(::File.join(LogStash::Environment::LOGSTASH_HOME, "config"), "logstash.keystore"), false), # will be populated on
Setting::NullableString.new("monitoring.cluster_uuid"),
Setting::String.new("pipeline.buffer.type", "heap", true, ["direct", "heap"])
Setting::SettingString.new("keystore.classname", "org.logstash.secret.store.backend.JavaKeyStore"),
Setting::SettingString.new("keystore.file", ::File.join(::File.join(LogStash::Environment::LOGSTASH_HOME, "config"), "logstash.keystore"), false), # will be populated on
Setting::SettingNullableString.new("monitoring.cluster_uuid"),
Setting::SettingString.new("pipeline.buffer.type", "heap", true, ["direct", "heap"])
# post_process
].each {|setting| SETTINGS.register(setting) }

View file

@ -523,27 +523,10 @@ module LogStash
@validator_class.validate(value)
end
end
java_import org.logstash.settings.SettingString
class String < Setting
def initialize(name, default = nil, strict = true, possible_strings = [])
@possible_strings = possible_strings
super(name, ::String, default, strict)
end
def validate(value)
super(value)
unless @possible_strings.empty? || @possible_strings.include?(value)
raise ArgumentError.new("Invalid value \"#{name}: #{value}\". Options are: #{@possible_strings.inspect}")
end
end
end
class NullableString < String
def validate(value)
return if value.nil?
super(value)
end
end
java_import org.logstash.settings.SettingNullableString
class Password < Coercible
def initialize(name, default = nil, strict = true)
@ -800,6 +783,8 @@ module LogStash
end
end
java_import org.logstash.settings.NullableSetting
# @see Setting#nullable
# @api internal
class Nullable < SimpleDelegator

View file

@ -33,8 +33,8 @@ module LogStash::Util::SettingsHelper
# The `path.settings` and `path.logs` can not be defined in "logstash/environment" since the `Environment::LOGSTASH_HOME` doesn't
# exist unless launched via "bootstrap/environment"
def self.pre_process
LogStash::SETTINGS.register(LogStash::Setting::String.new("path.settings", ::File.join(LogStash::Environment::LOGSTASH_HOME, "config")))
LogStash::SETTINGS.register(LogStash::Setting::String.new("path.logs", ::File.join(LogStash::Environment::LOGSTASH_HOME, "logs")))
LogStash::SETTINGS.register(LogStash::Setting::SettingString.new("path.settings", ::File.join(LogStash::Environment::LOGSTASH_HOME, "config")))
LogStash::SETTINGS.register(LogStash::Setting::SettingString.new("path.logs", ::File.join(LogStash::Environment::LOGSTASH_HOME, "logs")))
end
# Ensure that any settings are re-calculated after loading yaml

View file

@ -35,8 +35,8 @@ describe LogStash::Api::Commands::DefaultMetadata do
before :all do
registerIfNot(LogStash::Setting::Boolean.new("xpack.monitoring.enabled", false))
registerIfNot(LogStash::Setting::ArrayCoercible.new("xpack.monitoring.elasticsearch.hosts", String, ["http://localhost:9200"]))
registerIfNot(LogStash::Setting::NullableString.new("xpack.monitoring.elasticsearch.username", "logstash_TEST system"))
registerIfNot(LogStash::Setting::NullableString.new("xpack.monitoring.elasticsearch.username", "logstash_TEST system"))
registerIfNot(LogStash::Setting::SettingNullableString.new("xpack.monitoring.elasticsearch.username", "logstash_TEST system"))
registerIfNot(LogStash::Setting::SettingNullableString.new("xpack.monitoring.elasticsearch.username", "logstash_TEST system"))
end
after :each do

View file

@ -23,7 +23,7 @@ describe LogStash::QueueFactory do
let(:settings_array) do
[
LogStash::Setting::WritableDirectory.new("path.queue", Stud::Temporary.pathname),
LogStash::Setting::String.new("queue.type", "memory", true, ["persisted", "memory"]),
LogStash::Setting::SettingString.new("queue.type", "memory", true, ["persisted", "memory"]),
LogStash::Setting::Bytes.new("queue.page_capacity", "8mb"),
LogStash::Setting::Bytes.new("queue.max_bytes", "64mb"),
LogStash::Setting::Numeric.new("queue.max_events", 0),
@ -31,7 +31,7 @@ describe LogStash::QueueFactory do
LogStash::Setting::Numeric.new("queue.checkpoint.writes", 1024),
LogStash::Setting::Numeric.new("queue.checkpoint.interval", 1000),
LogStash::Setting::Boolean.new("queue.checkpoint.retry", false),
LogStash::Setting::String.new("pipeline.id", pipeline_id),
LogStash::Setting::SettingString.new("pipeline.id", pipeline_id),
LogStash::Setting::PositiveInteger.new("pipeline.batch.size", 125),
LogStash::Setting::PositiveInteger.new("pipeline.workers", LogStash::Config::CpuCoreStrategy.maximum)
]

View file

@ -20,13 +20,13 @@ require "logstash/settings"
describe LogStash::Setting::Nullable do
let(:setting_name) { "this.that" }
let(:normal_setting) { LogStash::Setting::String.new(setting_name, nil, false, possible_strings) }
let(:normal_setting) { LogStash::Setting::SettingString.new(setting_name, nil, false, possible_strings) }
let(:possible_strings) { [] } # empty means any string passes
subject(:nullable_setting) { normal_setting.nullable }
it 'is a kind of Nullable' do
expect(nullable_setting).to be_a_kind_of(described_class)
expect(nullable_setting).to be_a_kind_of(LogStash::Setting::NullableSetting)
end
it "retains the wrapped setting's name" do
@ -56,14 +56,14 @@ describe LogStash::Setting::Nullable do
context 'to an invalid wrong-type value' do
let(:candidate_value) { 127 } # wrong type, expects String
it 'is an invalid setting' do
expect { nullable_setting.validate_value }.to raise_error(ArgumentError, a_string_including("Setting \"#{setting_name}\" must be a "))
expect { nullable_setting.validate_value }.to raise_error(java.lang.ClassCastException, a_string_including("class java.lang.Long cannot be cast to class java.lang.String"))
end
end
context 'to an invalid value not in the allow-list' do
let(:possible_strings) { %w(this that)}
let(:candidate_value) { "another" } # wrong type, expects String
it 'is an invalid setting' do
expect { nullable_setting.validate_value }.to raise_error(ArgumentError, a_string_including("Invalid value"))
expect { nullable_setting.validate_value }.to raise_error(java.lang.IllegalArgumentException, a_string_including("Invalid value"))
end
end
context 'to a valid value' do

View file

@ -25,15 +25,44 @@ describe LogStash::Setting::SettingWithDeprecatedAlias do
let(:default_value) { "DeFaUlT" }
let(:settings) { LogStash::Settings.new }
let(:canonical_setting) { LogStash::Setting::String.new(canonical_setting_name, default_value, true) }
let(:canonical_setting) { LogStash::Setting::SettingString.new(canonical_setting_name, default_value, true) }
let(:events) { [] }
before(:each) do
java_import org.apache.logging.log4j.LogManager
logger = LogManager.getLogger("org.logstash.settings.DeprecatedAlias")
deprecated_logger = LogManager.getLogger("org.logstash.deprecation.settings.DeprecatedAlias")
@custom_appender = CustomAppender.new(events).tap {|appender| appender.start }
java_import org.apache.logging.log4j.Level
logger.addAppender(@custom_appender)
deprecated_logger.addAppender(@custom_appender)
# had to set level after appending as it was "error" for some reason
logger.setLevel(Level::INFO)
deprecated_logger.setLevel(Level::INFO)
expect(@custom_appender.started?).to be_truthy
allow(LogStash::Settings).to receive(:logger).and_return(double("SettingsLogger").as_null_object)
allow(LogStash::Settings).to receive(:deprecation_logger).and_return(double("SettingsDeprecationLogger").as_null_object)
settings.register(canonical_setting.with_deprecated_alias(deprecated_setting_name))
end
after(:each) do
events.clear
java_import org.apache.logging.log4j.LogManager
logger = LogManager.getLogger("org.logstash.settings.DeprecatedAlias")
deprecated_logger = LogManager.getLogger("org.logstash.deprecation.settings.DeprecatedAlias")
# The Logger's AbstractConfiguration contains a cache of Appender, by class name. The cache is updated
# iff is absent, so to make subsequent add_appender effective we have cleanup on teardown, else the new
# appender instance is simply not used by the logger
logger.remove_appender(@custom_appender)
deprecated_logger.remove_appender(@custom_appender)
end
shared_examples '#validate_value success' do
context '#validate_value' do
it "returns without raising" do
@ -57,6 +86,7 @@ describe LogStash::Setting::SettingWithDeprecatedAlias do
it 'does not emit a deprecation warning' do
expect(LogStash::Settings.deprecation_logger).to_not receive(:deprecated).with(a_string_including(deprecated_setting_name))
settings.get_setting(deprecated_setting_name).observe_post_process
expect(events).to be_empty
end
end
end
@ -66,6 +96,7 @@ describe LogStash::Setting::SettingWithDeprecatedAlias do
before(:each) do
settings.set(deprecated_setting_name, value)
settings.get_setting(deprecated_setting_name).observe_post_process
end
it 'resolves to the value provided for the deprecated alias' do
@ -73,15 +104,15 @@ describe LogStash::Setting::SettingWithDeprecatedAlias do
end
it 'logs a deprecation warning' do
expect(LogStash::Settings.deprecation_logger).to have_received(:deprecated).with(a_string_including(deprecated_setting_name))
expect(events[0]).to include(deprecated_setting_name)
end
include_examples '#validate_value success'
context "#observe_post_process" do
it 're-emits the deprecation warning' do
expect(LogStash::Settings.deprecation_logger).to receive(:deprecated).with(a_string_including(deprecated_setting_name))
settings.get_setting(deprecated_setting_name).observe_post_process
expect(events[0]).to include(deprecated_setting_name)
end
end
@ -116,13 +147,14 @@ describe LogStash::Setting::SettingWithDeprecatedAlias do
let(:old_value) { "iron man" }
let(:canonical_name) { "iron.setting" }
let(:deprecated_name) { "iron.oxide.setting" }
subject { LogStash::Setting::String.new(canonical_name, old_value, true) }
subject { LogStash::Setting::SettingString.new(canonical_name, old_value, true) }
it 'logs a deprecation warning with target remove version' do
settings.set(deprecated_name, new_value)
expect(LogStash::Settings.deprecation_logger).to have_received(:deprecated)
.with(a_string_including(deprecated_name))
.with(a_string_including("version 9"))
settings.get_setting(deprecated_name).observe_post_process
expect(events.length).to be 2
expect(events[1]).to include(deprecated_name)
expect(events[1]).to include("version 9")
end
end
describe "java boolean setting" do
@ -149,15 +181,16 @@ describe LogStash::Setting::SettingWithDeprecatedAlias do
end
it 'does not produce a relevant deprecation warning' do
expect(LogStash::Settings.deprecation_logger).to_not have_received(:deprecated).with(a_string_including(deprecated_setting_name))
settings.get_setting(deprecated_setting_name).observe_post_process
expect(events).to be_empty
end
include_examples '#validate_value success'
context "#observe_post_process" do
it 'does not emit a deprecation warning' do
expect(LogStash::Settings.deprecation_logger).to_not receive(:deprecated).with(a_string_including(deprecated_setting_name))
settings.get_setting(deprecated_setting_name).observe_post_process
expect(events).to be_empty
end
end
end
@ -171,15 +204,15 @@ describe LogStash::Setting::SettingWithDeprecatedAlias do
context '#validate_value' do
it "raises helpful exception" do
expect { settings.get_setting(canonical_setting_name).validate_value }
.to raise_exception(ArgumentError, a_string_including("Both `#{canonical_setting_name}` and its deprecated alias `#{deprecated_setting_name}` have been set. Please only set `#{canonical_setting_name}`"))
.to raise_exception(java.lang.IllegalStateException, a_string_including("Both `#{canonical_setting_name}` and its deprecated alias `#{deprecated_setting_name}` have been set. Please only set `#{canonical_setting_name}`"))
end
end
end
context 'Settings#get on deprecated alias' do
it 'produces a WARN-level message to the logger' do
expect(LogStash::Settings.logger).to receive(:warn).with(a_string_including "setting `#{canonical_setting_name}` has been queried by its deprecated alias `#{deprecated_setting_name}`")
settings.get(deprecated_setting_name)
expect(events[0]).to include("setting `#{canonical_setting_name}` has been queried by its deprecated alias `#{deprecated_setting_name}`")
end
end
end

View file

@ -18,13 +18,14 @@
require "spec_helper"
require "logstash/settings"
describe LogStash::Setting::String do
# Mirrored in java class org.logstash.settings.SettingStringTest
describe LogStash::Setting::SettingString do
let(:possible_values) { ["a", "b", "c"] }
subject { described_class.new("mytext", possible_values.first, true, possible_values) }
describe "#set" do
context "when a value is given outside of possible_values" do
it "should raise an ArgumentError" do
expect { subject.set("d") }.to raise_error(ArgumentError)
expect { subject.set("d") }.to raise_error(java.lang.IllegalArgumentException)
end
end
context "when a value is given within possible_values" do

View file

@ -154,8 +154,8 @@ describe LogStash::Settings do
settings.on_post_process do
settings.set("baz", "bot")
end
settings.register(LogStash::Setting::String.new("foo", "bar"))
settings.register(LogStash::Setting::String.new("baz", "somedefault"))
settings.register(LogStash::Setting::SettingString.new("foo", "bar"))
settings.register(LogStash::Setting::SettingString.new("baz", "somedefault"))
settings.post_process
end
@ -183,7 +183,7 @@ describe LogStash::Settings do
context "transient settings" do
subject do
settings = described_class.new
settings.register(LogStash::Setting::String.new("exist", "bonsoir"))
settings.register(LogStash::Setting::SettingString.new("exist", "bonsoir"))
settings
end
@ -237,9 +237,9 @@ describe LogStash::Settings do
subject do
settings = described_class.new
settings.register(LogStash::Setting::String.new("interpolated_env", "missing"))
settings.register(LogStash::Setting::String.new("with_dot_env", "missing"))
settings.register(LogStash::Setting::String.new("interpolated_store", "missing"))
settings.register(LogStash::Setting::SettingString.new("interpolated_env", "missing"))
settings.register(LogStash::Setting::SettingString.new("with_dot_env", "missing"))
settings.register(LogStash::Setting::SettingString.new("interpolated_store", "missing"))
settings
end

View file

@ -166,7 +166,7 @@ public class BaseSetting<T> implements Setting<T> {
}
public void validateValue() {
validate(this.value);
validate(this.value());
}
public T getDefault() {

View file

@ -0,0 +1,48 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.logstash.settings;
import java.util.List;
public class SettingNullableString extends SettingString {
public SettingNullableString(String name, String defaultValue, boolean strict, List<String> possibleStrings) {
super(name, defaultValue, strict, possibleStrings);
}
public SettingNullableString(String name, String defaultValue) {
super(name, defaultValue);
}
public SettingNullableString(String name, String defaultValue, boolean strict) {
super(name, defaultValue, strict);
}
public SettingNullableString(String name) {
super(name, null);
}
@Override
public void validate(String input) throws IllegalArgumentException {
if (input == null) {
return;
}
super.validate(input);
}
}

View file

@ -0,0 +1,56 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.logstash.settings;
import java.util.Collections;
import java.util.List;
public class SettingString extends BaseSetting<String> {
private List<String> possibleStrings = Collections.emptyList();
public SettingString(String name, String defaultValue, boolean strict, List<String> possibleStrings) {
super(name, strict, noValidator()); // this super doesn't call validate either if it's strict
this.possibleStrings = possibleStrings;
this.defaultValue = defaultValue;
if (strict) {
staticValidate(defaultValue, possibleStrings, name);
}
}
public SettingString(String name, String defaultValue) {
this(name, defaultValue, true, Collections.emptyList());
}
public SettingString(String name, String defaultValue, boolean strict) {
this(name, defaultValue, strict, Collections.emptyList());
}
@Override
public void validate(String input) throws IllegalArgumentException {
staticValidate(input, possibleStrings, this.getName());
}
private static void staticValidate(String input, List<String> possibleStrings, String name) {
if (!possibleStrings.isEmpty() && !possibleStrings.contains(input)) {
throw new IllegalArgumentException(String.format("Invalid value \"%s: %s\" . Options are: %s", name, input, possibleStrings));
}
}
}

View file

@ -99,7 +99,7 @@ public class SettingWithDeprecatedAlias<T> extends SettingDelegator<T> {
@Override
public void validateValue() {
if (deprecatedAlias.isSet() && getCanonicalSetting().isSet()) {
throw new IllegalStateException(String.format("Both `%s` and its deprecated alias `%s` have been set.\n" +
throw new IllegalStateException(String.format("Both `%s` and its deprecated alias `%s` have been set. " +
"Please only set `%s`", getCanonicalSetting().getName(), deprecatedAlias.getName(), getCanonicalSetting().getName()));
}
super.validateValue();

View file

@ -1,3 +1,22 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.logstash.settings;
import org.junit.Assert;

View file

@ -0,0 +1,50 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.logstash.settings;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
import static org.junit.Assert.assertEquals;
// Mirrored from logstash-core/spec/logstash/settings/string_spec.rb
public class SettingStringTest {
private static final List<String> POSSIBLE_VALUES = List.of("a", "b", "c");
private SettingString sut;
@Before
public void setUp() throws Exception {
sut = new SettingString("mytext", POSSIBLE_VALUES.iterator().next(), true, POSSIBLE_VALUES);
}
@Test(expected = IllegalArgumentException.class)
public void whenSetValueNotPresentInPossibleValuesThenThrowAnError() {
sut.set("d");
}
@Test
public void whenSetValuePresentInPossibleValuesThenSetValue() {
sut.set("a");
assertEquals("a", sut.value());
}
}

View file

@ -90,3 +90,20 @@ end
def installed_plugins
Gem::Specification.find_all.select { |spec| spec.metadata["logstash_plugin"] }.map { |plugin| plugin.name }
end
java_import org.apache.logging.log4j.core.appender.AbstractAppender
class CustomAppender < AbstractAppender
attr_reader :events_collector
def initialize(events)
super("CustomCaptorAppender", nil, nil, true, org.apache.logging.log4j.core.config.Property::EMPTY_ARRAY)
@events_collector = events
end
# override the append to catch all the calls and collect the events
def append(log_event)
@events_collector << log_event.message.formatted_message
end
end

View file

@ -24,23 +24,23 @@ module LogStash
settings.register(LogStash::Setting::Boolean.new("xpack.management.enabled", false))
settings.register(LogStash::Setting::TimeValue.new("xpack.management.logstash.poll_interval", "5s"))
settings.register(LogStash::Setting::ArrayCoercible.new("xpack.management.pipeline.id", String, ["main"]))
settings.register(LogStash::Setting::NullableString.new("xpack.management.elasticsearch.username", "logstash_system"))
settings.register(LogStash::Setting::NullableString.new("xpack.management.elasticsearch.password"))
settings.register(LogStash::Setting::SettingNullableString.new("xpack.management.elasticsearch.username", "logstash_system"))
settings.register(LogStash::Setting::SettingNullableString.new("xpack.management.elasticsearch.password"))
settings.register(LogStash::Setting::ArrayCoercible.new("xpack.management.elasticsearch.hosts", String, ["https://localhost:9200"]))
settings.register(LogStash::Setting::NullableString.new("xpack.management.elasticsearch.cloud_id"))
settings.register(LogStash::Setting::NullableString.new("xpack.management.elasticsearch.cloud_auth"))
settings.register(LogStash::Setting::NullableString.new("xpack.management.elasticsearch.api_key"))
settings.register(LogStash::Setting::NullableString.new("xpack.management.elasticsearch.proxy"))
settings.register(LogStash::Setting::NullableString.new("xpack.management.elasticsearch.ssl.certificate_authority"))
settings.register(LogStash::Setting::NullableString.new("xpack.management.elasticsearch.ssl.ca_trusted_fingerprint"))
settings.register(LogStash::Setting::NullableString.new("xpack.management.elasticsearch.ssl.truststore.path"))
settings.register(LogStash::Setting::NullableString.new("xpack.management.elasticsearch.ssl.truststore.password"))
settings.register(LogStash::Setting::NullableString.new("xpack.management.elasticsearch.ssl.keystore.path"))
settings.register(LogStash::Setting::NullableString.new("xpack.management.elasticsearch.ssl.keystore.password"))
settings.register(LogStash::Setting::NullableString.new("xpack.management.elasticsearch.ssl.certificate"))
settings.register(LogStash::Setting::NullableString.new("xpack.management.elasticsearch.ssl.key"))
settings.register(LogStash::Setting::SettingNullableString.new("xpack.management.elasticsearch.cloud_id"))
settings.register(LogStash::Setting::SettingNullableString.new("xpack.management.elasticsearch.cloud_auth"))
settings.register(LogStash::Setting::SettingNullableString.new("xpack.management.elasticsearch.api_key"))
settings.register(LogStash::Setting::SettingNullableString.new("xpack.management.elasticsearch.proxy"))
settings.register(LogStash::Setting::SettingNullableString.new("xpack.management.elasticsearch.ssl.certificate_authority"))
settings.register(LogStash::Setting::SettingNullableString.new("xpack.management.elasticsearch.ssl.ca_trusted_fingerprint"))
settings.register(LogStash::Setting::SettingNullableString.new("xpack.management.elasticsearch.ssl.truststore.path"))
settings.register(LogStash::Setting::SettingNullableString.new("xpack.management.elasticsearch.ssl.truststore.password"))
settings.register(LogStash::Setting::SettingNullableString.new("xpack.management.elasticsearch.ssl.keystore.path"))
settings.register(LogStash::Setting::SettingNullableString.new("xpack.management.elasticsearch.ssl.keystore.password"))
settings.register(LogStash::Setting::SettingNullableString.new("xpack.management.elasticsearch.ssl.certificate"))
settings.register(LogStash::Setting::SettingNullableString.new("xpack.management.elasticsearch.ssl.key"))
settings.register(LogStash::Setting::ArrayCoercible.new("xpack.management.elasticsearch.ssl.cipher_suites", String, []))
settings.register(LogStash::Setting::String.new("xpack.management.elasticsearch.ssl.verification_mode", "full", true, %w[none certificate full]))
settings.register(LogStash::Setting::SettingString.new("xpack.management.elasticsearch.ssl.verification_mode", "full", true, %w[none certificate full]))
settings.register(LogStash::Setting::Boolean.new("xpack.management.elasticsearch.sniffing", false))
rescue => e
logger.error("Cannot register new settings", :message => e.message, :backtrace => e.backtrace)

View file

@ -11,7 +11,7 @@ module LogStash module GeoipDatabaseManagement
def additionals_settings(settings)
require "logstash/runner"
logger.trace("Registering additional geoip settings")
settings.register(LogStash::Setting::String.new("xpack.geoip.downloader.endpoint", "https://geoip.elastic.co/v1/database")
settings.register(LogStash::Setting::SettingString.new("xpack.geoip.downloader.endpoint", "https://geoip.elastic.co/v1/database")
.with_deprecated_alias("xpack.geoip.download.endpoint"))
settings.register(LogStash::Setting::TimeValue.new("xpack.geoip.downloader.poll.interval", "24h"))
settings.register(LogStash::Setting::Boolean.new("xpack.geoip.downloader.enabled", true))

View file

@ -262,7 +262,7 @@ module LogStash
# (Experimental) Direct shipping settings
register_monitoring_settings(settings)
settings.register(LogStash::Setting::String.new("node.uuid", ""))
settings.register(LogStash::Setting::SettingString.new("node.uuid", ""))
rescue => e
logger.error e.message
logger.error e.backtrace.to_s
@ -278,21 +278,21 @@ module LogStash
settings.register(LogStash::Setting::ArrayCoercible.new("#{prefix}monitoring.elasticsearch.hosts", String, ["http://localhost:9200"]))
settings.register(LogStash::Setting::TimeValue.new("#{prefix}monitoring.collection.interval", "10s"))
settings.register(LogStash::Setting::TimeValue.new("#{prefix}monitoring.collection.timeout_interval", "10m"))
settings.register(LogStash::Setting::NullableString.new("#{prefix}monitoring.elasticsearch.username", "logstash_system"))
settings.register(LogStash::Setting::NullableString.new("#{prefix}monitoring.elasticsearch.password"))
settings.register(LogStash::Setting::NullableString.new("#{prefix}monitoring.elasticsearch.proxy"))
settings.register(LogStash::Setting::NullableString.new("#{prefix}monitoring.elasticsearch.cloud_id"))
settings.register(LogStash::Setting::NullableString.new("#{prefix}monitoring.elasticsearch.cloud_auth"))
settings.register(LogStash::Setting::NullableString.new("#{prefix}monitoring.elasticsearch.api_key"))
settings.register(LogStash::Setting::NullableString.new("#{prefix}monitoring.elasticsearch.ssl.certificate_authority"))
settings.register(LogStash::Setting::NullableString.new("#{prefix}monitoring.elasticsearch.ssl.ca_trusted_fingerprint"))
settings.register(LogStash::Setting::NullableString.new("#{prefix}monitoring.elasticsearch.ssl.truststore.path"))
settings.register(LogStash::Setting::NullableString.new("#{prefix}monitoring.elasticsearch.ssl.truststore.password"))
settings.register(LogStash::Setting::NullableString.new("#{prefix}monitoring.elasticsearch.ssl.keystore.path"))
settings.register(LogStash::Setting::NullableString.new("#{prefix}monitoring.elasticsearch.ssl.keystore.password"))
settings.register(LogStash::Setting::String.new("#{prefix}monitoring.elasticsearch.ssl.verification_mode", "full", true, ["none", "certificate", "full"]))
settings.register(LogStash::Setting::NullableString.new("#{prefix}monitoring.elasticsearch.ssl.certificate"))
settings.register(LogStash::Setting::NullableString.new("#{prefix}monitoring.elasticsearch.ssl.key"))
settings.register(LogStash::Setting::SettingNullableString.new("#{prefix}monitoring.elasticsearch.username", "logstash_system"))
settings.register(LogStash::Setting::SettingNullableString.new("#{prefix}monitoring.elasticsearch.password"))
settings.register(LogStash::Setting::SettingNullableString.new("#{prefix}monitoring.elasticsearch.proxy"))
settings.register(LogStash::Setting::SettingNullableString.new("#{prefix}monitoring.elasticsearch.cloud_id"))
settings.register(LogStash::Setting::SettingNullableString.new("#{prefix}monitoring.elasticsearch.cloud_auth"))
settings.register(LogStash::Setting::SettingNullableString.new("#{prefix}monitoring.elasticsearch.api_key"))
settings.register(LogStash::Setting::SettingNullableString.new("#{prefix}monitoring.elasticsearch.ssl.certificate_authority"))
settings.register(LogStash::Setting::SettingNullableString.new("#{prefix}monitoring.elasticsearch.ssl.ca_trusted_fingerprint"))
settings.register(LogStash::Setting::SettingNullableString.new("#{prefix}monitoring.elasticsearch.ssl.truststore.path"))
settings.register(LogStash::Setting::SettingNullableString.new("#{prefix}monitoring.elasticsearch.ssl.truststore.password"))
settings.register(LogStash::Setting::SettingNullableString.new("#{prefix}monitoring.elasticsearch.ssl.keystore.path"))
settings.register(LogStash::Setting::SettingNullableString.new("#{prefix}monitoring.elasticsearch.ssl.keystore.password"))
settings.register(LogStash::Setting::SettingString.new("#{prefix}monitoring.elasticsearch.ssl.verification_mode", "full", true, ["none", "certificate", "full"]))
settings.register(LogStash::Setting::SettingNullableString.new("#{prefix}monitoring.elasticsearch.ssl.certificate"))
settings.register(LogStash::Setting::SettingNullableString.new("#{prefix}monitoring.elasticsearch.ssl.key"))
settings.register(LogStash::Setting::ArrayCoercible.new("#{prefix}monitoring.elasticsearch.ssl.cipher_suites", String, []))
settings.register(LogStash::Setting::Boolean.new("#{prefix}monitoring.elasticsearch.sniffing", false))
settings.register(LogStash::Setting::Boolean.new("#{prefix}monitoring.collection.pipeline.details.enabled", true))

View file

@ -32,16 +32,16 @@ describe LogStash::ConfigManagement::Extension do
"xpack.management.logstash.poll_interval" => [LogStash::Setting::TimeValue, LogStash::Util::TimeValue.from_value("5s")],
"xpack.management.pipeline.id" => [LogStash::Setting::ArrayCoercible, ["main"]],
"xpack.management.elasticsearch.hosts" => [LogStash::Setting::ArrayCoercible, ["https://localhost:9200"]],
"xpack.management.elasticsearch.username" => [LogStash::Setting::String, "logstash_system"],
"xpack.management.elasticsearch.password" => [LogStash::Setting::String, nil],
"xpack.management.elasticsearch.ssl.certificate_authority" => [LogStash::Setting::NullableString, nil],
"xpack.management.elasticsearch.ssl.ca_trusted_fingerprint" => [LogStash::Setting::NullableString, nil],
"xpack.management.elasticsearch.ssl.truststore.path" => [LogStash::Setting::NullableString, nil],
"xpack.management.elasticsearch.ssl.truststore.password" => [LogStash::Setting::NullableString, nil],
"xpack.management.elasticsearch.ssl.keystore.path" => [LogStash::Setting::NullableString, nil],
"xpack.management.elasticsearch.ssl.keystore.password" => [LogStash::Setting::NullableString, nil],
"xpack.management.elasticsearch.ssl.certificate" => [LogStash::Setting::NullableString, nil],
"xpack.management.elasticsearch.ssl.key" => [LogStash::Setting::NullableString, nil],
"xpack.management.elasticsearch.username" => [LogStash::Setting::SettingString, "logstash_system"],
"xpack.management.elasticsearch.password" => [LogStash::Setting::SettingString, nil],
"xpack.management.elasticsearch.ssl.certificate_authority" => [LogStash::Setting::SettingNullableString, nil],
"xpack.management.elasticsearch.ssl.ca_trusted_fingerprint" => [LogStash::Setting::SettingNullableString, nil],
"xpack.management.elasticsearch.ssl.truststore.path" => [LogStash::Setting::SettingNullableString, nil],
"xpack.management.elasticsearch.ssl.truststore.password" => [LogStash::Setting::SettingNullableString, nil],
"xpack.management.elasticsearch.ssl.keystore.path" => [LogStash::Setting::SettingNullableString, nil],
"xpack.management.elasticsearch.ssl.keystore.password" => [LogStash::Setting::SettingNullableString, nil],
"xpack.management.elasticsearch.ssl.certificate" => [LogStash::Setting::SettingNullableString, nil],
"xpack.management.elasticsearch.ssl.key" => [LogStash::Setting::SettingNullableString, nil],
"xpack.management.elasticsearch.ssl.cipher_suites" => [LogStash::Setting::ArrayCoercible, []],
)