diff --git a/core/src/main/java/org/elasticsearch/common/settings/Settings.java b/core/src/main/java/org/elasticsearch/common/settings/Settings.java index 9ff467ae27c45..e5f4430d1d1ed 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/Settings.java +++ b/core/src/main/java/org/elasticsearch/common/settings/Settings.java @@ -64,6 +64,7 @@ import java.util.NoSuchElementException; import java.util.Set; import java.util.TreeMap; +import java.util.ListIterator; import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.function.Predicate; @@ -444,7 +445,7 @@ public List getAsList(String key, List defaultValue, Boolean com final Object valueFromPrefix = settings.get(key); if (valueFromPrefix != null) { if (valueFromPrefix instanceof List) { - return ((List) valueFromPrefix); // it's already unmodifiable since the builder puts it as a such + return Collections.unmodifiableList((List) valueFromPrefix); } else if (commaDelimited) { String[] strings = Strings.splitStringByCommaToArray(get(key)); if (strings.length > 0) { @@ -1072,7 +1073,7 @@ public Builder putList(String setting, String... values) { */ public Builder putList(String setting, List values) { remove(setting); - map.put(setting, Collections.unmodifiableList(new ArrayList<>(values))); + map.put(setting, new ArrayList<>(values)); return this; } @@ -1240,10 +1241,20 @@ public boolean shouldRemoveMissingPlaceholder(String placeholderName) { Iterator> entryItr = map.entrySet().iterator(); while (entryItr.hasNext()) { Map.Entry entry = entryItr.next(); - if (entry.getValue() == null || entry.getValue() instanceof List) { + if (entry.getValue() == null) { // a null value obviously can't be replaced continue; } + if (entry.getValue() instanceof List) { + final ListIterator li = ((List) entry.getValue()).listIterator(); + while (li.hasNext()) { + final String settingValueRaw = li.next(); + final String settingValueResolved = propertyPlaceholder.replacePlaceholders(settingValueRaw, placeholderResolver); + li.set(settingValueResolved); + } + continue; + } + String value = propertyPlaceholder.replacePlaceholders(Settings.toString(entry.getValue()), placeholderResolver); // if the values exists and has length, we should maintain it in the map // otherwise, the replace process resolved into removing it diff --git a/core/src/test/java/org/elasticsearch/common/settings/SettingsTests.java b/core/src/test/java/org/elasticsearch/common/settings/SettingsTests.java index 5a59b205cea5d..f467edfb8d40c 100644 --- a/core/src/test/java/org/elasticsearch/common/settings/SettingsTests.java +++ b/core/src/test/java/org/elasticsearch/common/settings/SettingsTests.java @@ -73,6 +73,16 @@ public void testReplacePropertiesPlaceholderSystemProperty() { assertThat(settings.get("setting1"), equalTo(value)); } + public void testReplacePropertiesPlaceholderSystemPropertyList() { + final String hostname = randomAlphaOfLength(16); + final String hostip = randomAlphaOfLength(16); + final Settings settings = Settings.builder() + .putList("setting1", "${HOSTNAME}", "${HOSTIP}") + .replacePropertyPlaceholders(name -> name.equals("HOSTNAME") ? hostname : name.equals("HOSTIP") ? hostip : null) + .build(); + assertThat(settings.getAsList("setting1"), contains(hostname, hostip)); + } + public void testReplacePropertiesPlaceholderSystemVariablesHaveNoEffect() { final String value = System.getProperty("java.home"); assertNotNull(value);