Validate tribe node settings on startup

This commit is contained in:
Simon Willnauer 2016-01-26 16:19:13 +01:00
parent 4e5316591a
commit 429b372edb
2 changed files with 108 additions and 10 deletions

View File

@ -24,6 +24,7 @@ import org.elasticsearch.common.inject.AbstractModule;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.function.Predicate;
/**
* A module that binds the provided settings to the {@link Settings} interface.
@ -54,18 +55,13 @@ public class SettingsModule extends AbstractModule {
final ClusterSettings clusterSettings = new ClusterSettings(settings, new HashSet<>(this.clusterSettings.values()));
// by now we are fully configured, lets check node level settings for unregistered index settings
indexScopedSettings.validate(settings.filter(IndexScopedSettings.INDEX_SETTINGS_KEY_PREDICATE));
// we can't call this method yet since we have not all node level settings registered.
// yet we can validate the ones we have registered to not have invalid values. this is better than nothing
// and progress over perfection and we fail as soon as possible.
// clusterSettings.validate(settings.filter(IndexScopedSettings.INDEX_SETTINGS_KEY_PREDICATE.negate()));
for (Map.Entry<String, String> entry : settings.filter(IndexScopedSettings.INDEX_SETTINGS_KEY_PREDICATE.negate()).getAsMap().entrySet()) {
if (clusterSettings.get(entry.getKey()) != null) {
clusterSettings.validate(entry.getKey(), settings);
} else if (AbstractScopedSettings.isValidKey(entry.getKey()) == false) {
throw new IllegalArgumentException("illegal settings key: [" + entry.getKey() + "]");
}
Predicate<String> noIndexSettingPredicate = IndexScopedSettings.INDEX_SETTINGS_KEY_PREDICATE.negate();
Predicate<String> noTribePredicate = (s) -> s.startsWith("tribe.") == false;
for (Map.Entry<String, String> entry : settings.filter(noTribePredicate.and(noIndexSettingPredicate)).getAsMap().entrySet()) {
validateClusterSetting(clusterSettings, entry.getKey(), settings);
}
validateTribeSettings(settings, clusterSettings);
bind(Settings.class).toInstance(settings);
bind(SettingsFilter.class).toInstance(settingsFilter);
@ -90,4 +86,25 @@ public class SettingsModule extends AbstractModule {
}
}
public void validateTribeSettings(Settings settings, ClusterSettings clusterSettings) {
Map<String, Settings> groups = settings.getGroups("tribe.");
for (Map.Entry<String, Settings> tribeSettings : groups.entrySet()) {
for (Map.Entry<String, String> entry : tribeSettings.getValue().getAsMap().entrySet()) {
validateClusterSetting(clusterSettings, entry.getKey(), tribeSettings.getValue());
}
}
}
private final void validateClusterSetting(ClusterSettings clusterSettings, String key, Settings settings) {
// we can't call this method yet since we have not all node level settings registered.
// yet we can validate the ones we have registered to not have invalid values. this is better than nothing
// and progress over perfection and we fail as soon as possible.
// clusterSettings.validate(settings.filter(IndexScopedSettings.INDEX_SETTINGS_KEY_PREDICATE.negate()));
if (clusterSettings.get(key) != null) {
clusterSettings.validate(key, settings);
} else if (AbstractScopedSettings.isValidKey(key) == false) {
throw new IllegalArgumentException("illegal settings key: [" + key + "]");
}
}
}

View File

@ -0,0 +1,81 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.common.settings;
import org.elasticsearch.common.inject.ModuleTestCase;
public class SettingsModuleTests extends ModuleTestCase {
public void testValidate() {
{
Settings settings = Settings.builder().put("cluster.routing.allocation.balance.shard", "2.0").build();
SettingsModule module = new SettingsModule(settings, new SettingsFilter(Settings.EMPTY));
assertInstanceBinding(module, Settings.class, (s) -> s == settings);
}
{
Settings settings = Settings.builder().put("cluster.routing.allocation.balance.shard", "[2.0]").build();
SettingsModule module = new SettingsModule(settings, new SettingsFilter(Settings.EMPTY));
try {
assertInstanceBinding(module, Settings.class, (s) -> s == settings);
fail();
} catch (IllegalArgumentException ex) {
assertEquals("Failed to parse value [[2.0]] for setting [cluster.routing.allocation.balance.shard]", ex.getMessage());
}
}
}
public void testRegisterSettings() {
{
Settings settings = Settings.builder().put("some.custom.setting", "2.0").build();
SettingsModule module = new SettingsModule(settings, new SettingsFilter(Settings.EMPTY));
module.registerSetting(Setting.floatSetting("some.custom.setting", 1.0f, false, Setting.Scope.CLUSTER));
assertInstanceBinding(module, Settings.class, (s) -> s == settings);
}
{
Settings settings = Settings.builder().put("some.custom.setting", "false").build();
SettingsModule module = new SettingsModule(settings, new SettingsFilter(Settings.EMPTY));
module.registerSetting(Setting.floatSetting("some.custom.setting", 1.0f, false, Setting.Scope.CLUSTER));
try {
assertInstanceBinding(module, Settings.class, (s) -> s == settings);
fail();
} catch (IllegalArgumentException ex) {
assertEquals("Failed to parse value [false] for setting [some.custom.setting]", ex.getMessage());
}
}
}
public void testTribeSetting() {
{
Settings settings = Settings.builder().put("tribe.t1.cluster.routing.allocation.balance.shard", "2.0").build();
SettingsModule module = new SettingsModule(settings, new SettingsFilter(Settings.EMPTY));
assertInstanceBinding(module, Settings.class, (s) -> s == settings);
}
{
Settings settings = Settings.builder().put("tribe.t1.cluster.routing.allocation.balance.shard", "[2.0]").build();
SettingsModule module = new SettingsModule(settings, new SettingsFilter(Settings.EMPTY));
try {
assertInstanceBinding(module, Settings.class, (s) -> s == settings);
fail();
} catch (IllegalArgumentException ex) {
assertEquals("Failed to parse value [[2.0]] for setting [cluster.routing.allocation.balance.shard]", ex.getMessage());
}
}
}
}