diff options
Diffstat (limited to 'core/src/main/java/org/elasticsearch/common/settings')
6 files changed, 85 insertions, 33 deletions
diff --git a/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java b/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java index 14e7958661..5f587cc270 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java +++ b/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java @@ -344,9 +344,8 @@ public final class ClusterSettings extends AbstractScopedSettings { ZenDiscovery.JOIN_RETRY_DELAY_SETTING, ZenDiscovery.MAX_PINGS_FROM_ANOTHER_MASTER_SETTING, ZenDiscovery.SEND_LEAVE_REQUEST_SETTING, - ZenDiscovery.MASTER_ELECTION_FILTER_CLIENT_SETTING, ZenDiscovery.MASTER_ELECTION_WAIT_FOR_JOINS_TIMEOUT_SETTING, - ZenDiscovery.MASTER_ELECTION_FILTER_DATA_SETTING, + ZenDiscovery.MASTER_ELECTION_IGNORE_NON_MASTER_PINGS_SETTING, UnicastZenPing.DISCOVERY_ZEN_PING_UNICAST_HOSTS_SETTING, UnicastZenPing.DISCOVERY_ZEN_PING_UNICAST_CONCURRENT_CONNECTS_SETTING, SearchService.DEFAULT_KEEPALIVE_SETTING, diff --git a/core/src/main/java/org/elasticsearch/common/settings/loader/JsonSettingsLoader.java b/core/src/main/java/org/elasticsearch/common/settings/loader/JsonSettingsLoader.java index f6f77192c7..02f7a5c37a 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/loader/JsonSettingsLoader.java +++ b/core/src/main/java/org/elasticsearch/common/settings/loader/JsonSettingsLoader.java @@ -27,6 +27,10 @@ import org.elasticsearch.common.xcontent.XContentType; */ public class JsonSettingsLoader extends XContentSettingsLoader { + public JsonSettingsLoader(boolean allowNullValues) { + super(allowNullValues); + } + @Override public XContentType contentType() { return XContentType.JSON; diff --git a/core/src/main/java/org/elasticsearch/common/settings/loader/PropertiesSettingsLoader.java b/core/src/main/java/org/elasticsearch/common/settings/loader/PropertiesSettingsLoader.java index 57c9419f5b..6ee1f58cf4 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/loader/PropertiesSettingsLoader.java +++ b/core/src/main/java/org/elasticsearch/common/settings/loader/PropertiesSettingsLoader.java @@ -24,10 +24,12 @@ import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.io.FastStringReader; import org.elasticsearch.common.io.stream.StreamInput; +import java.io.Closeable; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Properties; +import java.util.function.Supplier; /** * Settings loader that loads (parses) the settings in a properties format. @@ -36,42 +38,49 @@ public class PropertiesSettingsLoader implements SettingsLoader { @Override public Map<String, String> load(String source) throws IOException { - Properties props = new NoDuplicatesProperties(); - FastStringReader reader = new FastStringReader(source); - try { - props.load(reader); - Map<String, String> result = new HashMap<>(); - for (Map.Entry entry : props.entrySet()) { - result.put((String) entry.getKey(), (String) entry.getValue()); - } - return result; - } finally { - IOUtils.closeWhileHandlingException(reader); - } + return load(() -> new FastStringReader(source), (reader, props) -> props.load(reader)); } @Override public Map<String, String> load(byte[] source) throws IOException { - Properties props = new NoDuplicatesProperties(); - StreamInput stream = StreamInput.wrap(source); + return load(() -> StreamInput.wrap(source), (inStream, props) -> props.load(inStream)); + } + + private final <T extends Closeable> Map<String, String> load( + Supplier<T> supplier, + IOExceptionThrowingBiConsumer<T, Properties> properties + ) throws IOException { + T t = null; try { - props.load(stream); - Map<String, String> result = new HashMap<>(); + t = supplier.get(); + final Properties props = new NoDuplicatesProperties(); + properties.accept(t, props); + final Map<String, String> result = new HashMap<>(); for (Map.Entry entry : props.entrySet()) { result.put((String) entry.getKey(), (String) entry.getValue()); } return result; } finally { - IOUtils.closeWhileHandlingException(stream); + IOUtils.closeWhileHandlingException(t); } } + @FunctionalInterface + private interface IOExceptionThrowingBiConsumer<T, U> { + void accept(T t, U u) throws IOException; + } + class NoDuplicatesProperties extends Properties { @Override public synchronized Object put(Object key, Object value) { - Object previousValue = super.put(key, value); + final Object previousValue = super.put(key, value); if (previousValue != null) { - throw new ElasticsearchParseException("duplicate settings key [{}] found, previous value [{}], current value [{}]", key, previousValue, value); + throw new ElasticsearchParseException( + "duplicate settings key [{}] found, previous value [{}], current value [{}]", + key, + previousValue, + value + ); } return previousValue; } diff --git a/core/src/main/java/org/elasticsearch/common/settings/loader/SettingsLoaderFactory.java b/core/src/main/java/org/elasticsearch/common/settings/loader/SettingsLoaderFactory.java index e55cb1092f..5bf9916ee0 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/loader/SettingsLoaderFactory.java +++ b/core/src/main/java/org/elasticsearch/common/settings/loader/SettingsLoaderFactory.java @@ -20,43 +20,63 @@ package org.elasticsearch.common.settings.loader; /** - * A settings loader factory automatically trying to identify what type of - * {@link SettingsLoader} to use. - * - * + * A class holding factory methods for settings loaders that attempts + * to infer the type of the underlying settings content. */ public final class SettingsLoaderFactory { private SettingsLoaderFactory() { - } /** - * Returns a {@link SettingsLoader} based on the resource name. + * Returns a {@link SettingsLoader} based on the source resource + * name. This factory method assumes that if the resource name ends + * with ".json" then the content should be parsed as JSON, else if + * the resource name ends with ".yml" or ".yaml" then the content + * should be parsed as YAML, else if the resource name ends with + * ".properties" then the content should be parsed as properties, + * otherwise default to attempting to parse as JSON. Note that the + * parsers returned by this method will not accept null-valued + * keys. + * + * @param resourceName The resource name containing the settings + * content. + * @return A settings loader. */ public static SettingsLoader loaderFromResource(String resourceName) { if (resourceName.endsWith(".json")) { - return new JsonSettingsLoader(); + return new JsonSettingsLoader(false); } else if (resourceName.endsWith(".yml") || resourceName.endsWith(".yaml")) { - return new YamlSettingsLoader(); + return new YamlSettingsLoader(false); } else if (resourceName.endsWith(".properties")) { return new PropertiesSettingsLoader(); } else { // lets default to the json one - return new JsonSettingsLoader(); + return new JsonSettingsLoader(false); } } /** - * Returns a {@link SettingsLoader} based on the actual settings source. + * Returns a {@link SettingsLoader} based on the source content. + * This factory method assumes that if the underlying content + * contains an opening and closing brace ('{' and '}') then the + * content should be parsed as JSON, else if the underlying content + * fails this condition but contains a ':' then the content should + * be parsed as YAML, and otherwise should be parsed as properties. + * Note that the JSON and YAML parsers returned by this method will + * accept null-valued keys. + * + * @param source The underlying settings content. + * @return A settings loader. */ public static SettingsLoader loaderFromSource(String source) { if (source.indexOf('{') != -1 && source.indexOf('}') != -1) { - return new JsonSettingsLoader(); + return new JsonSettingsLoader(true); } if (source.indexOf(':') != -1) { - return new YamlSettingsLoader(); + return new YamlSettingsLoader(true); } return new PropertiesSettingsLoader(); } + } diff --git a/core/src/main/java/org/elasticsearch/common/settings/loader/XContentSettingsLoader.java b/core/src/main/java/org/elasticsearch/common/settings/loader/XContentSettingsLoader.java index 9c2f973b96..3875c1ef85 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/loader/XContentSettingsLoader.java +++ b/core/src/main/java/org/elasticsearch/common/settings/loader/XContentSettingsLoader.java @@ -38,6 +38,12 @@ public abstract class XContentSettingsLoader implements SettingsLoader { public abstract XContentType contentType(); + private final boolean allowNullValues; + + XContentSettingsLoader(boolean allowNullValues) { + this.allowNullValues = allowNullValues; + } + @Override public Map<String, String> load(String source) throws IOException { try (XContentParser parser = XContentFactory.xContent(contentType()).createParser(source)) { @@ -153,6 +159,16 @@ public abstract class XContentSettingsLoader implements SettingsLoader { currentValue ); } + + if (currentValue == null && !allowNullValues) { + throw new ElasticsearchParseException( + "null-valued setting found for key [{}] found at line number [{}], column number [{}]", + key, + parser.getTokenLocation().lineNumber, + parser.getTokenLocation().columnNumber + ); + } + settings.put(key, currentValue); } } diff --git a/core/src/main/java/org/elasticsearch/common/settings/loader/YamlSettingsLoader.java b/core/src/main/java/org/elasticsearch/common/settings/loader/YamlSettingsLoader.java index 248fe090b5..12cde97669 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/loader/YamlSettingsLoader.java +++ b/core/src/main/java/org/elasticsearch/common/settings/loader/YamlSettingsLoader.java @@ -30,6 +30,10 @@ import java.util.Map; */ public class YamlSettingsLoader extends XContentSettingsLoader { + public YamlSettingsLoader(boolean allowNullValues) { + super(allowNullValues); + } + @Override public XContentType contentType() { return XContentType.YAML; |