浏览代码

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
Mayya Sharipova 7 年之前
父节点
当前提交
caa63ada6b

+ 14 - 3
core/src/main/java/org/elasticsearch/common/settings/Settings.java

@@ -64,6 +64,7 @@ import java.util.Map;
 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;
@@ -414,7 +415,7 @@ public final class Settings implements ToXContentFragment {
         final Object valueFromPrefix = settings.get(key);
         if (valueFromPrefix != null) {
             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) {
                 String[] strings = Strings.splitStringByCommaToArray(get(key));
                 if (strings.length > 0) {
@@ -1042,7 +1043,7 @@ public final class Settings implements ToXContentFragment {
          */
         public Builder putList(String setting, List<String> values) {
             remove(setting);
-            map.put(setting, Collections.unmodifiableList(new ArrayList<>(values)));
+            map.put(setting, new ArrayList<>(values));
             return this;
         }
 
@@ -1210,10 +1211,20 @@ public final class Settings implements ToXContentFragment {
             Iterator<Map.Entry<String, Object>> entryItr = map.entrySet().iterator();
             while (entryItr.hasNext()) {
                 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
                     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);
                 // if the values exists and has length, we should maintain it  in the map
                 // otherwise, the replace process resolved into removing it

+ 10 - 0
core/src/test/java/org/elasticsearch/common/settings/SettingsTests.java

@@ -68,6 +68,16 @@ public class SettingsTests extends ESTestCase {
         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);