Skip to content

Commit e43a9bf

Browse files
committed
Fix upgrading of list settings (#33589)
Upgrading list settings is broken because of the conversion that we do to strings, and then when we try to put back the upgraded value we do not know that it is a representation of a list. This commit addresses this by adding special handling for list settings.
1 parent fe4c886 commit e43a9bf

File tree

3 files changed

+65
-11
lines changed

3 files changed

+65
-11
lines changed

server/src/main/java/org/elasticsearch/common/settings/AbstractScopedSettings.java

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import org.elasticsearch.common.component.AbstractComponent;
2828
import org.elasticsearch.common.regex.Regex;
2929

30-
import java.util.AbstractMap;
3130
import java.util.ArrayList;
3231
import java.util.Collections;
3332
import java.util.HashMap;
@@ -54,7 +53,7 @@ public abstract class AbstractScopedSettings extends AbstractComponent {
5453
private final List<SettingUpdater<?>> settingUpdaters = new CopyOnWriteArrayList<>();
5554
private final Map<String, Setting<?>> complexMatchers;
5655
private final Map<String, Setting<?>> keySettings;
57-
private final Map<Setting<?>, Function<Map.Entry<String, String>, Map.Entry<String, String>>> settingUpgraders;
56+
private final Map<Setting<?>, SettingUpgrader<?>> settingUpgraders;
5857
private final Setting.Property scope;
5958
private static final Pattern KEY_PATTERN = Pattern.compile("^(?:[-\\w]+[.])*[-\\w]+$");
6059
private static final Pattern GROUP_KEY_PATTERN = Pattern.compile("^(?:[-\\w]+[.])+$");
@@ -70,12 +69,8 @@ protected AbstractScopedSettings(
7069

7170
this.settingUpgraders =
7271
Collections.unmodifiableMap(
73-
settingUpgraders
74-
.stream()
75-
.collect(
76-
Collectors.toMap(
77-
SettingUpgrader::getSetting,
78-
u -> e -> new AbstractMap.SimpleEntry<>(u.getKey(e.getKey()), u.getValue(e.getValue())))));
72+
settingUpgraders.stream().collect(Collectors.toMap(SettingUpgrader::getSetting, Function.identity())));
73+
7974

8075
this.scope = scope;
8176
Map<String, Setting<?>> complexMatchers = new HashMap<>();
@@ -786,15 +781,24 @@ public Settings upgradeSettings(final Settings settings) {
786781
boolean changed = false; // track if any settings were upgraded
787782
for (final String key : settings.keySet()) {
788783
final Setting<?> setting = getRaw(key);
789-
final Function<Map.Entry<String, String>, Map.Entry<String, String>> upgrader = settingUpgraders.get(setting);
784+
final SettingUpgrader<?> upgrader = settingUpgraders.get(setting);
790785
if (upgrader == null) {
791786
// the setting does not have an upgrader, copy the setting
792787
builder.copy(key, settings);
793788
} else {
794789
// the setting has an upgrader, so mark that we have changed a setting and apply the upgrade logic
795790
changed = true;
796-
final Map.Entry<String, String> upgrade = upgrader.apply(new Entry(key, settings));
797-
builder.put(upgrade.getKey(), upgrade.getValue());
791+
if (setting.isListSetting()) {
792+
final List<String> value = settings.getAsList(key);
793+
final String upgradedKey = upgrader.getKey(key);
794+
final List<String> upgradedValue = upgrader.getListValue(value);
795+
builder.putList(upgradedKey, upgradedValue);
796+
} else {
797+
final String value = settings.get(key);
798+
final String upgradedKey = upgrader.getKey(key);
799+
final String upgradedValue = upgrader.getValue(value);
800+
builder.put(upgradedKey, upgradedValue);
801+
}
798802
}
799803
}
800804
// we only return a new instance if there was an upgrade

server/src/main/java/org/elasticsearch/common/settings/SettingUpgrader.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
package org.elasticsearch.common.settings;
2121

22+
import java.util.List;
23+
2224
/**
2325
* Represents the logic to upgrade a setting.
2426
*
@@ -51,4 +53,8 @@ default String getValue(final String value) {
5153
return value;
5254
}
5355

56+
default List<String> getListValue(final List<String> value) {
57+
return value;
58+
}
59+
5460
}

server/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import java.util.function.BiConsumer;
4848
import java.util.function.Consumer;
4949
import java.util.function.Function;
50+
import java.util.stream.Collectors;
5051

5152
import static org.hamcrest.CoreMatchers.containsString;
5253
import static org.hamcrest.CoreMatchers.equalTo;
@@ -1171,4 +1172,47 @@ public String getValue(final String value) {
11711172
}
11721173
}
11731174

1175+
public void testUpgradeListSetting() {
1176+
final Setting<List<String>> oldSetting =
1177+
Setting.listSetting("foo.old", Collections.emptyList(), Function.identity(), Property.NodeScope);
1178+
final Setting<List<String>> newSetting =
1179+
Setting.listSetting("foo.new", Collections.emptyList(), Function.identity(), Property.NodeScope);
1180+
1181+
final AbstractScopedSettings service =
1182+
new ClusterSettings(
1183+
Settings.EMPTY,
1184+
new HashSet<>(Arrays.asList(oldSetting, newSetting)),
1185+
Collections.singleton(new SettingUpgrader<List<String>>() {
1186+
1187+
@Override
1188+
public Setting<List<String>> getSetting() {
1189+
return oldSetting;
1190+
}
1191+
1192+
@Override
1193+
public String getKey(final String key) {
1194+
return "foo.new";
1195+
}
1196+
1197+
@Override
1198+
public List<String> getListValue(final List<String> value) {
1199+
return value.stream().map(s -> "new." + s).collect(Collectors.toList());
1200+
}
1201+
}));
1202+
1203+
final int length = randomIntBetween(0, 16);
1204+
final List<String> values = length == 0 ? Collections.emptyList() : new ArrayList<>(length);
1205+
for (int i = 0; i < length; i++) {
1206+
values.add(randomAlphaOfLength(8));
1207+
}
1208+
1209+
final Settings settings = Settings.builder().putList("foo.old", values).build();
1210+
final Settings upgradedSettings = service.upgradeSettings(settings);
1211+
assertFalse(oldSetting.exists(upgradedSettings));
1212+
assertTrue(newSetting.exists(upgradedSettings));
1213+
assertThat(
1214+
newSetting.get(upgradedSettings),
1215+
equalTo(oldSetting.get(settings).stream().map(s -> "new." + s).collect(Collectors.toList())));
1216+
}
1217+
11741218
}

0 commit comments

Comments
 (0)