Merge pull request #17324 from jasontedor/settings-cleanup

Settings loader cleanup
This commit is contained in:
Jason Tedor 2016-03-24 10:44:12 -04:00
commit 4b17a5c73f
5 changed files with 90 additions and 86 deletions

View File

@ -380,7 +380,6 @@
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]settings[/\\]IndexScopedSettings.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]settings[/\\]Setting.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]settings[/\\]Settings.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]settings[/\\]loader[/\\]PropertiesSettingsLoader.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]settings[/\\]loader[/\\]XContentSettingsLoader.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]unit[/\\]ByteSizeValue.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]unit[/\\]TimeValue.java" checks="LineLength" />
@ -1078,8 +1077,6 @@
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]rounding[/\\]TimeZoneRoundingTests.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]settings[/\\]ScopedSettingsTests.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]settings[/\\]SettingTests.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]settings[/\\]loader[/\\]JsonSettingsLoaderTests.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]settings[/\\]loader[/\\]YamlSettingsLoaderTests.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]transport[/\\]BoundTransportAddressTests.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]unit[/\\]DistanceUnitTests.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]unit[/\\]FuzzinessTests.java" checks="LineLength" />

View File

@ -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;
}

View File

@ -28,13 +28,11 @@ import static org.elasticsearch.common.settings.Settings.settingsBuilder;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.Matchers.equalTo;
/**
*
*/
public class JsonSettingsLoaderTests extends ESTestCase {
public void testSimpleJsonSettings() throws Exception {
String json = "/org/elasticsearch/common/settings/loader/test-settings.json";
Settings settings = settingsBuilder()
final String json = "/org/elasticsearch/common/settings/loader/test-settings.json";
final Settings settings = settingsBuilder()
.loadFromStream(json, getClass().getResourceAsStream(json))
.build();
@ -51,21 +49,23 @@ public class JsonSettingsLoaderTests extends ESTestCase {
}
public void testDuplicateKeysThrowsException() {
String json = "{\"foo\":\"bar\",\"foo\":\"baz\"}";
try {
settingsBuilder()
.loadFromSource(json)
.build();
fail("expected exception");
} catch (SettingsException e) {
assertEquals(e.getCause().getClass(), ElasticsearchParseException.class);
assertTrue(e.toString().contains("duplicate settings key [foo] found at line number [1], column number [20], previous value [bar], current value [baz]"));
}
final String json = "{\"foo\":\"bar\",\"foo\":\"baz\"}";
final SettingsException e = expectThrows(SettingsException.class, () -> settingsBuilder().loadFromSource(json).build());
assertEquals(e.getCause().getClass(), ElasticsearchParseException.class);
assertThat(
e.toString(),
containsString("duplicate settings key [foo] " +
"found at line number [1], " +
"column number [20], " +
"previous value [bar], " +
"current value [baz]"));
}
public void testNullValuedSettingThrowsException() {
final String json = "{\"foo\":null}";
final ElasticsearchParseException e = expectThrows(ElasticsearchParseException.class, () -> new JsonSettingsLoader(false).load(json));
final ElasticsearchParseException e =
expectThrows(ElasticsearchParseException.class, () -> new JsonSettingsLoader(false).load(json));
assertThat(e.toString(), containsString("null-valued setting found for key [foo] found at line number [1], column number [8]"));
}
}

View File

@ -21,33 +21,37 @@ package org.elasticsearch.common.settings.loader;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.test.ESTestCase;
import org.junit.Before;
import java.io.IOException;
import java.nio.charset.Charset;
public class PropertiesSettingsLoaderTests extends ESTestCase {
private PropertiesSettingsLoader loader;
@Before
public void setUp() throws Exception {
super.setUp();
loader = new PropertiesSettingsLoader();
}
public void testDuplicateKeyFromStringThrowsException() throws IOException {
PropertiesSettingsLoader loader = new PropertiesSettingsLoader();
try {
loader.load("foo=bar\nfoo=baz");
fail("expected exception");
} catch (ElasticsearchParseException e) {
assertEquals(e.getMessage(), "duplicate settings key [foo] found, previous value [bar], current value [baz]");
}
final ElasticsearchParseException e = expectThrows(ElasticsearchParseException.class, () -> loader.load("foo=bar\nfoo=baz"));
assertEquals(e.getMessage(), "duplicate settings key [foo] found, previous value [bar], current value [baz]");
}
public void testDuplicateKeysFromBytesThrowsException() throws IOException {
PropertiesSettingsLoader loader = new PropertiesSettingsLoader();
try {
loader.load("foo=bar\nfoo=baz".getBytes(Charset.defaultCharset()));
} catch (ElasticsearchParseException e) {
assertEquals(e.getMessage(), "duplicate settings key [foo] found, previous value [bar], current value [baz]");
}
final ElasticsearchParseException e = expectThrows(
ElasticsearchParseException.class,
() -> loader.load("foo=bar\nfoo=baz".getBytes(Charset.defaultCharset()))
);
assertEquals(e.getMessage(), "duplicate settings key [foo] found, previous value [bar], current value [baz]");
}
public void testThatNoDuplicatesPropertiesDoesNotAcceptNullValues() {
final PropertiesSettingsLoader loader = new PropertiesSettingsLoader();
final PropertiesSettingsLoader.NoDuplicatesProperties properties = loader.new NoDuplicatesProperties();
expectThrows(NullPointerException.class, () -> properties.put("key", null));
}
}

View File

@ -28,13 +28,11 @@ import static org.elasticsearch.common.settings.Settings.settingsBuilder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
/**
*
*/
public class YamlSettingsLoaderTests extends ESTestCase {
public void testSimpleYamlSettings() throws Exception {
String yaml = "/org/elasticsearch/common/settings/loader/test-settings.yml";
Settings settings = settingsBuilder()
final String yaml = "/org/elasticsearch/common/settings/loader/test-settings.yml";
final Settings settings = settingsBuilder()
.loadFromStream(yaml, getClass().getResourceAsStream(yaml))
.build();
@ -51,45 +49,41 @@ public class YamlSettingsLoaderTests extends ESTestCase {
}
public void testIndentation() {
String yaml = "/org/elasticsearch/common/settings/loader/indentation-settings.yml";
try {
settingsBuilder()
.loadFromStream(yaml, getClass().getResourceAsStream(yaml))
.build();
fail("Expected SettingsException");
} catch(SettingsException e ) {
assertThat(e.getMessage(), containsString("Failed to load settings"));
}
final String yaml = "/org/elasticsearch/common/settings/loader/indentation-settings.yml";
final SettingsException e =
expectThrows(
SettingsException.class,
() -> settingsBuilder().loadFromStream(yaml, getClass().getResourceAsStream(yaml)).build());
assertThat(e.getMessage(), containsString("Failed to load settings"));
}
public void testIndentationWithExplicitDocumentStart() {
String yaml = "/org/elasticsearch/common/settings/loader/indentation-with-explicit-document-start-settings.yml";
try {
settingsBuilder()
.loadFromStream(yaml, getClass().getResourceAsStream(yaml))
.build();
fail("Expected SettingsException");
} catch (SettingsException e) {
assertThat(e.getMessage(), containsString("Failed to load settings"));
}
final String yaml = "/org/elasticsearch/common/settings/loader/indentation-with-explicit-document-start-settings.yml";
final SettingsException e =
expectThrows(
SettingsException.class,
() -> settingsBuilder().loadFromStream(yaml, getClass().getResourceAsStream(yaml)).build());
assertThat(e.getMessage(), containsString("Failed to load settings"));
}
public void testDuplicateKeysThrowsException() {
String yaml = "foo: bar\nfoo: baz";
try {
settingsBuilder()
.loadFromSource(yaml)
.build();
fail("expected exception");
} catch (SettingsException e) {
assertEquals(e.getCause().getClass(), ElasticsearchParseException.class);
assertTrue(e.toString().contains("duplicate settings key [foo] found at line number [2], column number [6], previous value [bar], current value [baz]"));
}
final String yaml = "foo: bar\nfoo: baz";
final SettingsException e = expectThrows(SettingsException.class, () -> settingsBuilder().loadFromSource(yaml).build());
assertEquals(e.getCause().getClass(), ElasticsearchParseException.class);
assertThat(
e.toString(),
containsString("duplicate settings key [foo] " +
"found at line number [2], " +
"column number [6], " +
"previous value [bar], " +
"current value [baz]"));
}
public void testNullValuedSettingThrowsException() {
final String yaml = "foo:";
final ElasticsearchParseException e = expectThrows(ElasticsearchParseException.class, () -> new YamlSettingsLoader(false).load(yaml));
final ElasticsearchParseException e =
expectThrows(ElasticsearchParseException.class, () -> new YamlSettingsLoader(false).load(yaml));
assertThat(e.toString(), containsString("null-valued setting found for key [foo] found at line number [1], column number [5]"));
}
}