From fb65fd8723ae3a443010ecc804809ece2b73d3bd Mon Sep 17 00:00:00 2001 From: Gordon Brown Date: Tue, 8 Dec 2020 13:21:00 -0700 Subject: [PATCH] [7.10] Correctly determine defaults of settings which depend on other settings (#65989) This commit adjusts the behavior when calculating the diff between two `AbstractScopedSettings` objects, so that the default values of settings whose default values depend on the values of other settings are correctly calculated. Previously, when calculating the diff, the default value of a depended setting would be calculated based on the default value of the setting(s) it depends on, rather than the current value of those settings. --- .../common/settings/Setting.java | 9 +++++++- .../common/settings/ScopedSettingsTests.java | 22 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/org/elasticsearch/common/settings/Setting.java b/server/src/main/java/org/elasticsearch/common/settings/Setting.java index 408f70e0f279c..64be5e4648d37 100644 --- a/server/src/main/java/org/elasticsearch/common/settings/Setting.java +++ b/server/src/main/java/org/elasticsearch/common/settings/Setting.java @@ -487,7 +487,14 @@ private T get(Settings settings, boolean validate) { */ public void diff(Settings.Builder builder, Settings source, Settings defaultSettings) { if (exists(source) == false) { - builder.put(getKey(), getRaw(defaultSettings)); + if (exists(defaultSettings)) { + // If the setting is only in the defaults, use the value from the defaults + builder.put(getKey(), getRaw(defaultSettings)); + } else { + // If the setting is in neither `source` nor `default`, get the value + // from `source` as it may depend on the value of other settings + builder.put(getKey(), getRaw(source)); + } } } diff --git a/server/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java b/server/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java index c4b4b80488b3b..9fa2ecde9b281 100644 --- a/server/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java +++ b/server/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java @@ -737,6 +737,28 @@ public void testDiff() throws IOException { assertThat(diff.getAsInt("foo.bar", null), equalTo(1)); } + public void testDiffWithDependentSettings() { + final String dependedSettingName = "this.setting.is.depended.on"; + Setting dependedSetting = Setting.intSetting(dependedSettingName, 1, Property.Dynamic, Property.NodeScope); + + final String dependentSettingName = "this.setting.depends.on.another"; + Setting dependentSetting = new Setting<>(dependentSettingName, + (s) -> Integer.toString(dependedSetting.get(s) + 10), + (s) -> Setting.parseInt(s, 1, dependentSettingName), + Property.Dynamic, Property.NodeScope); + + ClusterSettings settings = new ClusterSettings(Settings.EMPTY, new HashSet<>(Arrays.asList(dependedSetting, dependentSetting))); + + // Ensure that the value of the dependent setting is correctly calculated based on the "source" settings + Settings diff = settings.diff(Settings.builder().put(dependedSettingName, 2).build(), Settings.EMPTY); + assertThat(diff.getAsInt(dependentSettingName, null), equalTo(12)); + + // Ensure that the value is correctly calculated if neither is set + diff = settings.diff(Settings.EMPTY, Settings.EMPTY); + assertThat(diff.getAsInt(dependedSettingName, null), equalTo(1)); + assertThat(diff.getAsInt(dependentSettingName, null), equalTo(11)); + } + public void testDiffWithAffixAndComplexMatcher() { Setting fooBarBaz = Setting.intSetting("foo.bar.baz", 1, Property.NodeScope); Setting fooBar = Setting.intSetting("foo.bar", 1, Property.Dynamic, Property.NodeScope);