Fix environment variable substitutions in list setting (#28106)

Since Elasticsearch 6.1.0 environment variable substitutions in lists do not work.
Environment variables in a list setting were not resolved, because settings with a list type were skipped during variables resolution.
This commit fixes by processing list settings as well.

Closes #27926
This commit is contained in:
Mayya Sharipova 2018-01-10 12:08:35 -05:00 committed by GitHub
parent 4182e9e3bb
commit caa63ada6b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 3 deletions

View File

@ -64,6 +64,7 @@ import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Set; import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.ListIterator;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
@ -414,7 +415,7 @@ public final class Settings implements ToXContentFragment {
final Object valueFromPrefix = settings.get(key); final Object valueFromPrefix = settings.get(key);
if (valueFromPrefix != null) { if (valueFromPrefix != null) {
if (valueFromPrefix instanceof List) { if (valueFromPrefix instanceof List) {
return ((List<String>) valueFromPrefix); // it's already unmodifiable since the builder puts it as a such return Collections.unmodifiableList((List<String>) valueFromPrefix);
} else if (commaDelimited) { } else if (commaDelimited) {
String[] strings = Strings.splitStringByCommaToArray(get(key)); String[] strings = Strings.splitStringByCommaToArray(get(key));
if (strings.length > 0) { if (strings.length > 0) {
@ -1042,7 +1043,7 @@ public final class Settings implements ToXContentFragment {
*/ */
public Builder putList(String setting, List<String> values) { public Builder putList(String setting, List<String> values) {
remove(setting); remove(setting);
map.put(setting, Collections.unmodifiableList(new ArrayList<>(values))); map.put(setting, new ArrayList<>(values));
return this; return this;
} }
@ -1210,10 +1211,20 @@ public final class Settings implements ToXContentFragment {
Iterator<Map.Entry<String, Object>> entryItr = map.entrySet().iterator(); Iterator<Map.Entry<String, Object>> entryItr = map.entrySet().iterator();
while (entryItr.hasNext()) { while (entryItr.hasNext()) {
Map.Entry<String, Object> entry = entryItr.next(); Map.Entry<String, Object> entry = entryItr.next();
if (entry.getValue() == null || entry.getValue() instanceof List) { if (entry.getValue() == null) {
// a null value obviously can't be replaced // a null value obviously can't be replaced
continue; continue;
} }
if (entry.getValue() instanceof List) {
final ListIterator<String> li = ((List<String>) 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); String value = propertyPlaceholder.replacePlaceholders(Settings.toString(entry.getValue()), placeholderResolver);
// if the values exists and has length, we should maintain it in the map // if the values exists and has length, we should maintain it in the map
// otherwise, the replace process resolved into removing it // otherwise, the replace process resolved into removing it

View File

@ -68,6 +68,16 @@ public class SettingsTests extends ESTestCase {
assertThat(settings.get("setting1"), equalTo(value)); 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() { public void testReplacePropertiesPlaceholderSystemVariablesHaveNoEffect() {
final String value = System.getProperty("java.home"); final String value = System.getProperty("java.home");
assertNotNull(value); assertNotNull(value);