Add dynamic settings validation

Fixes #2749
This commit is contained in:
Igor Motov 2013-03-12 14:41:00 -04:00
parent c008c59927
commit 3a534c64e5
7 changed files with 263 additions and 80 deletions

View File

@ -95,8 +95,13 @@ public class TransportClusterUpdateSettingsAction extends TransportMasterNodeOpe
transientSettings.put(currentState.metaData().transientSettings()); transientSettings.put(currentState.metaData().transientSettings());
for (Map.Entry<String, String> entry : request.transientSettings().getAsMap().entrySet()) { for (Map.Entry<String, String> entry : request.transientSettings().getAsMap().entrySet()) {
if (dynamicSettings.hasDynamicSetting(entry.getKey()) || entry.getKey().startsWith("logger.")) { if (dynamicSettings.hasDynamicSetting(entry.getKey()) || entry.getKey().startsWith("logger.")) {
String error = dynamicSettings.validateDynamicSetting(entry.getKey(), entry.getValue());
if (error == null) {
transientSettings.put(entry.getKey(), entry.getValue()); transientSettings.put(entry.getKey(), entry.getValue());
changed = true; changed = true;
} else {
logger.warn("ignoring transient setting [{}], [{}]", entry.getKey(), error);
}
} else { } else {
logger.warn("ignoring transient setting [{}], not dynamically updateable", entry.getKey()); logger.warn("ignoring transient setting [{}], not dynamically updateable", entry.getKey());
} }
@ -106,8 +111,13 @@ public class TransportClusterUpdateSettingsAction extends TransportMasterNodeOpe
persistentSettings.put(currentState.metaData().persistentSettings()); persistentSettings.put(currentState.metaData().persistentSettings());
for (Map.Entry<String, String> entry : request.persistentSettings().getAsMap().entrySet()) { for (Map.Entry<String, String> entry : request.persistentSettings().getAsMap().entrySet()) {
if (dynamicSettings.hasDynamicSetting(entry.getKey()) || entry.getKey().startsWith("logger.")) { if (dynamicSettings.hasDynamicSetting(entry.getKey()) || entry.getKey().startsWith("logger.")) {
changed = true; String error = dynamicSettings.validateDynamicSetting(entry.getKey(), entry.getValue());
if (error == null) {
persistentSettings.put(entry.getKey(), entry.getValue()); persistentSettings.put(entry.getKey(), entry.getValue());
changed = true;
} else {
logger.warn("ignoring persistent setting [{}], [{}]", entry.getKey(), error);
}
} else { } else {
logger.warn("ignoring persistent setting [{}], not dynamically updateable", entry.getKey()); logger.warn("ignoring persistent setting [{}], not dynamically updateable", entry.getKey());
} }

View File

@ -143,11 +143,23 @@ public class MetaDataUpdateSettingsService extends AbstractComponent implements
final Settings closeSettings = updatedSettingsBuilder.build(); final Settings closeSettings = updatedSettingsBuilder.build();
final Set<String> removedSettings = Sets.newHashSet(); final Set<String> removedSettings = Sets.newHashSet();
for (String key : updatedSettingsBuilder.internalMap().keySet()) { final Set<String> errors = Sets.newHashSet();
if (!dynamicSettings.hasDynamicSetting(key)) { for (Map.Entry<String, String> setting : updatedSettingsBuilder.internalMap().entrySet()) {
removedSettings.add(key); if (!dynamicSettings.hasDynamicSetting(setting.getKey())) {
removedSettings.add(setting.getKey());
} else {
String error = dynamicSettings.validateDynamicSetting(setting.getKey(), setting.getValue());
if (error != null) {
errors.add("[" + setting.getKey() + "] - " + error);
} }
} }
}
if (!errors.isEmpty()) {
listener.onFailure(new ElasticSearchIllegalArgumentException("can't process the settings: " + errors.toString()));
return;
}
if (!removedSettings.isEmpty()) { if (!removedSettings.isEmpty()) {
for (String removedSetting : removedSettings) { for (String removedSetting : removedSettings) {
updatedSettingsBuilder.remove(removedSetting); updatedSettingsBuilder.remove(removedSetting);

View File

@ -71,10 +71,15 @@ public class ClusterDynamicSettingsModule extends AbstractModule {
); );
} }
public void addDynamicSetting(String... settings) { public void addDynamicSettings(String... settings) {
clusterDynamicSettings.addDynamicSettings(settings); clusterDynamicSettings.addDynamicSettings(settings);
} }
public void addDynamicSetting(String setting, Validator validator) {
clusterDynamicSettings.addDynamicSetting(setting, validator);
}
@Override @Override
protected void configure() { protected void configure() {
bind(DynamicSettings.class).annotatedWith(ClusterDynamicSettings.class).toInstance(clusterDynamicSettings); bind(DynamicSettings.class).annotatedWith(ClusterDynamicSettings.class).toInstance(clusterDynamicSettings);

View File

@ -19,20 +19,20 @@
package org.elasticsearch.cluster.settings; package org.elasticsearch.cluster.settings;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableMap;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.regex.Regex;
import java.util.Arrays; import java.util.Map;
import java.util.HashSet;
/** /**
*/ */
public class DynamicSettings { public class DynamicSettings {
private ImmutableSet<String> dynamicSettings = ImmutableSet.of(); private ImmutableMap<String, Validator> dynamicSettings = ImmutableMap.of();
public boolean hasDynamicSetting(String key) { public boolean hasDynamicSetting(String key) {
for (String dynamicSetting : dynamicSettings) { for (String dynamicSetting : dynamicSettings.keySet()) {
if (Regex.simpleMatch(dynamicSetting, key)) { if (Regex.simpleMatch(dynamicSetting, key)) {
return true; return true;
} }
@ -40,10 +40,32 @@ public class DynamicSettings {
return false; return false;
} }
public String validateDynamicSetting(String dynamicSetting, String value) {
for (Map.Entry<String, Validator> setting : dynamicSettings.entrySet()) {
if (Regex.simpleMatch(dynamicSetting, setting.getKey())) {
return setting.getValue().validate(dynamicSetting, value);
}
}
return null;
}
public synchronized void addDynamicSetting(String setting, Validator validator) {
MapBuilder<String, Validator> updatedSettings = MapBuilder.newMapBuilder(dynamicSettings);
updatedSettings.put(setting, validator);
dynamicSettings = updatedSettings.immutableMap();
}
public synchronized void addDynamicSetting(String setting) {
addDynamicSetting(setting, Validator.EmptyValidator.INSTANCE);
}
public synchronized void addDynamicSettings(String... settings) { public synchronized void addDynamicSettings(String... settings) {
HashSet<String> updatedSettings = new HashSet<String>(dynamicSettings); MapBuilder<String, Validator> updatedSettings = MapBuilder.newMapBuilder(dynamicSettings);
updatedSettings.addAll(Arrays.asList(settings)); for (String setting : settings) {
dynamicSettings = ImmutableSet.copyOf(updatedSettings); updatedSettings.put(setting, Validator.EmptyValidator.INSTANCE);
}
dynamicSettings = updatedSettings.immutableMap();
} }
} }

View File

@ -0,0 +1,64 @@
/*
* Licensed to ElasticSearch and Shay Banon 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.cluster.settings;
import org.elasticsearch.ElasticSearchParseException;
import org.elasticsearch.common.unit.TimeValue;
/**
*/
public interface Validator {
String validate(String setting, String value);
public static class EmptyValidator implements Validator {
public static final EmptyValidator INSTANCE = new EmptyValidator();
private EmptyValidator() {
}
@Override
public String validate(String setting, String value) {
return null;
}
}
public static class TimeValueValidator implements Validator {
public static final TimeValueValidator INSTANCE = new TimeValueValidator();
private TimeValueValidator() {
}
@Override
public String validate(String setting, String value) {
try {
if (TimeValue.parseTimeValue(value, null) == null) {
return "cannot parse value [" + value + "] as time";
}
} catch (ElasticSearchParseException ex) {
return "cannot parse value [" + value + "] as time";
}
return null;
}
}
}

View File

@ -23,6 +23,7 @@ import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.routing.allocation.decider.FilterAllocationDecider; import org.elasticsearch.cluster.routing.allocation.decider.FilterAllocationDecider;
import org.elasticsearch.cluster.routing.allocation.decider.ShardsLimitAllocationDecider; import org.elasticsearch.cluster.routing.allocation.decider.ShardsLimitAllocationDecider;
import org.elasticsearch.cluster.settings.DynamicSettings; import org.elasticsearch.cluster.settings.DynamicSettings;
import org.elasticsearch.cluster.settings.Validator;
import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.gateway.local.LocalGatewayAllocator; import org.elasticsearch.gateway.local.LocalGatewayAllocator;
import org.elasticsearch.index.engine.robin.RobinEngine; import org.elasticsearch.index.engine.robin.RobinEngine;
@ -46,75 +47,78 @@ public class IndexDynamicSettingsModule extends AbstractModule {
public IndexDynamicSettingsModule() { public IndexDynamicSettingsModule() {
indexDynamicSettings = new DynamicSettings(); indexDynamicSettings = new DynamicSettings();
indexDynamicSettings.addDynamicSettings( indexDynamicSettings.addDynamicSetting(AbstractIndexStore.INDEX_STORE_THROTTLE_MAX_BYTES_PER_SEC);
AbstractIndexStore.INDEX_STORE_THROTTLE_MAX_BYTES_PER_SEC, indexDynamicSettings.addDynamicSetting(AbstractIndexStore.INDEX_STORE_THROTTLE_TYPE);
AbstractIndexStore.INDEX_STORE_THROTTLE_TYPE, indexDynamicSettings.addDynamicSetting(FilterAllocationDecider.INDEX_ROUTING_REQUIRE_GROUP + "*");
FilterAllocationDecider.INDEX_ROUTING_REQUIRE_GROUP + "*", indexDynamicSettings.addDynamicSetting(FilterAllocationDecider.INDEX_ROUTING_INCLUDE_GROUP + "*");
FilterAllocationDecider.INDEX_ROUTING_INCLUDE_GROUP + "*", indexDynamicSettings.addDynamicSetting(FilterAllocationDecider.INDEX_ROUTING_EXCLUDE_GROUP + "*");
FilterAllocationDecider.INDEX_ROUTING_EXCLUDE_GROUP + "*", indexDynamicSettings.addDynamicSetting(FsTranslog.INDEX_TRANSLOG_FS_TYPE);
FsTranslog.INDEX_TRANSLOG_FS_TYPE, indexDynamicSettings.addDynamicSetting(FsTranslog.INDEX_TRANSLOG_FS_BUFFER_SIZE);
FsTranslog.INDEX_TRANSLOG_FS_BUFFER_SIZE, indexDynamicSettings.addDynamicSetting(FsTranslog.INDEX_TRANSLOG_FS_TRANSIENT_BUFFER_SIZE);
FsTranslog.INDEX_TRANSLOG_FS_TRANSIENT_BUFFER_SIZE, indexDynamicSettings.addDynamicSetting(IndexMetaData.SETTING_NUMBER_OF_REPLICAS);
IndexMetaData.SETTING_NUMBER_OF_REPLICAS, indexDynamicSettings.addDynamicSetting(IndexMetaData.SETTING_AUTO_EXPAND_REPLICAS);
IndexMetaData.SETTING_AUTO_EXPAND_REPLICAS, indexDynamicSettings.addDynamicSetting(IndexMetaData.SETTING_READ_ONLY);
IndexMetaData.SETTING_READ_ONLY, indexDynamicSettings.addDynamicSetting(IndexMetaData.SETTING_BLOCKS_READ);
IndexMetaData.SETTING_BLOCKS_READ, indexDynamicSettings.addDynamicSetting(IndexMetaData.SETTING_BLOCKS_WRITE);
IndexMetaData.SETTING_BLOCKS_WRITE, indexDynamicSettings.addDynamicSetting(IndexMetaData.SETTING_BLOCKS_METADATA);
IndexMetaData.SETTING_BLOCKS_METADATA, indexDynamicSettings.addDynamicSetting(IndexShardGatewayService.INDEX_GATEWAY_SNAPSHOT_INTERVAL);
IndexShardGatewayService.INDEX_GATEWAY_SNAPSHOT_INTERVAL, indexDynamicSettings.addDynamicSetting(IndicesTTLService.INDEX_TTL_DISABLE_PURGE);
IndicesTTLService.INDEX_TTL_DISABLE_PURGE, indexDynamicSettings.addDynamicSetting(InternalIndexShard.INDEX_REFRESH_INTERVAL, Validator.TimeValueValidator.INSTANCE);
InternalIndexShard.INDEX_REFRESH_INTERVAL, indexDynamicSettings.addDynamicSetting(LocalGatewayAllocator.INDEX_RECOVERY_INITIAL_SHARDS);
LocalGatewayAllocator.INDEX_RECOVERY_INITIAL_SHARDS, indexDynamicSettings.addDynamicSetting(LogByteSizeMergePolicyProvider.INDEX_MERGE_POLICY_MIN_MERGE_SIZE);
LogByteSizeMergePolicyProvider.INDEX_MERGE_POLICY_MIN_MERGE_SIZE, indexDynamicSettings.addDynamicSetting(LogByteSizeMergePolicyProvider.INDEX_MERGE_POLICY_MAX_MERGE_SIZE);
LogByteSizeMergePolicyProvider.INDEX_MERGE_POLICY_MAX_MERGE_SIZE, indexDynamicSettings.addDynamicSetting(LogByteSizeMergePolicyProvider.INDEX_MERGE_POLICY_MAX_MERGE_DOCS);
LogByteSizeMergePolicyProvider.INDEX_MERGE_POLICY_MAX_MERGE_DOCS, indexDynamicSettings.addDynamicSetting(LogByteSizeMergePolicyProvider.INDEX_MERGE_POLICY_MERGE_FACTOR);
LogByteSizeMergePolicyProvider.INDEX_MERGE_POLICY_MERGE_FACTOR, indexDynamicSettings.addDynamicSetting(LogByteSizeMergePolicyProvider.INDEX_COMPOUND_FORMAT);
LogByteSizeMergePolicyProvider.INDEX_COMPOUND_FORMAT, indexDynamicSettings.addDynamicSetting(LogDocMergePolicyProvider.INDEX_MERGE_POLICY_MIN_MERGE_DOCS);
LogDocMergePolicyProvider.INDEX_MERGE_POLICY_MIN_MERGE_DOCS, indexDynamicSettings.addDynamicSetting(LogDocMergePolicyProvider.INDEX_MERGE_POLICY_MAX_MERGE_DOCS);
LogDocMergePolicyProvider.INDEX_MERGE_POLICY_MAX_MERGE_DOCS, indexDynamicSettings.addDynamicSetting(LogDocMergePolicyProvider.INDEX_MERGE_POLICY_MERGE_FACTOR);
LogDocMergePolicyProvider.INDEX_MERGE_POLICY_MERGE_FACTOR, indexDynamicSettings.addDynamicSetting(LogDocMergePolicyProvider.INDEX_COMPOUND_FORMAT);
LogDocMergePolicyProvider.INDEX_COMPOUND_FORMAT, indexDynamicSettings.addDynamicSetting(RobinEngine.INDEX_TERM_INDEX_INTERVAL);
RobinEngine.INDEX_TERM_INDEX_INTERVAL, indexDynamicSettings.addDynamicSetting(RobinEngine.INDEX_TERM_INDEX_DIVISOR);
RobinEngine.INDEX_TERM_INDEX_DIVISOR, indexDynamicSettings.addDynamicSetting(RobinEngine.INDEX_INDEX_CONCURRENCY);
RobinEngine.INDEX_INDEX_CONCURRENCY, indexDynamicSettings.addDynamicSetting(RobinEngine.INDEX_GC_DELETES);
RobinEngine.INDEX_GC_DELETES, indexDynamicSettings.addDynamicSetting(RobinEngine.INDEX_CODEC);
RobinEngine.INDEX_CODEC, indexDynamicSettings.addDynamicSetting(RobinEngine.INDEX_FAIL_ON_MERGE_FAILURE);
RobinEngine.INDEX_FAIL_ON_MERGE_FAILURE, indexDynamicSettings.addDynamicSetting(ShardSlowLogIndexingService.INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_WARN);
ShardSlowLogIndexingService.INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_WARN, indexDynamicSettings.addDynamicSetting(ShardSlowLogIndexingService.INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_INFO);
ShardSlowLogIndexingService.INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_INFO, indexDynamicSettings.addDynamicSetting(ShardSlowLogIndexingService.INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_DEBUG);
ShardSlowLogIndexingService.INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_DEBUG, indexDynamicSettings.addDynamicSetting(ShardSlowLogIndexingService.INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_TRACE);
ShardSlowLogIndexingService.INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_TRACE, indexDynamicSettings.addDynamicSetting(ShardSlowLogIndexingService.INDEX_INDEXING_SLOWLOG_REFORMAT);
ShardSlowLogIndexingService.INDEX_INDEXING_SLOWLOG_REFORMAT, indexDynamicSettings.addDynamicSetting(ShardSlowLogIndexingService.INDEX_INDEXING_SLOWLOG_LEVEL);
ShardSlowLogIndexingService.INDEX_INDEXING_SLOWLOG_LEVEL, indexDynamicSettings.addDynamicSetting(ShardSlowLogSearchService.INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_WARN);
ShardSlowLogSearchService.INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_WARN, indexDynamicSettings.addDynamicSetting(ShardSlowLogSearchService.INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_INFO);
ShardSlowLogSearchService.INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_INFO, indexDynamicSettings.addDynamicSetting(ShardSlowLogSearchService.INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_DEBUG);
ShardSlowLogSearchService.INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_DEBUG, indexDynamicSettings.addDynamicSetting(ShardSlowLogSearchService.INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_TRACE);
ShardSlowLogSearchService.INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_TRACE, indexDynamicSettings.addDynamicSetting(ShardSlowLogSearchService.INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_WARN);
ShardSlowLogSearchService.INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_WARN, indexDynamicSettings.addDynamicSetting(ShardSlowLogSearchService.INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_INFO);
ShardSlowLogSearchService.INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_INFO, indexDynamicSettings.addDynamicSetting(ShardSlowLogSearchService.INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_DEBUG);
ShardSlowLogSearchService.INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_DEBUG, indexDynamicSettings.addDynamicSetting(ShardSlowLogSearchService.INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_TRACE);
ShardSlowLogSearchService.INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_TRACE, indexDynamicSettings.addDynamicSetting(ShardSlowLogSearchService.INDEX_SEARCH_SLOWLOG_REFORMAT);
ShardSlowLogSearchService.INDEX_SEARCH_SLOWLOG_REFORMAT, indexDynamicSettings.addDynamicSetting(ShardSlowLogSearchService.INDEX_SEARCH_SLOWLOG_LEVEL);
ShardSlowLogSearchService.INDEX_SEARCH_SLOWLOG_LEVEL, indexDynamicSettings.addDynamicSetting(ShardsLimitAllocationDecider.INDEX_TOTAL_SHARDS_PER_NODE);
ShardsLimitAllocationDecider.INDEX_TOTAL_SHARDS_PER_NODE, indexDynamicSettings.addDynamicSetting(TieredMergePolicyProvider.INDEX_MERGE_POLICY_EXPUNGE_DELETES_ALLOWED);
TieredMergePolicyProvider.INDEX_MERGE_POLICY_EXPUNGE_DELETES_ALLOWED, indexDynamicSettings.addDynamicSetting(TieredMergePolicyProvider.INDEX_MERGE_POLICY_FLOOR_SEGMENT);
TieredMergePolicyProvider.INDEX_MERGE_POLICY_FLOOR_SEGMENT, indexDynamicSettings.addDynamicSetting(TieredMergePolicyProvider.INDEX_MERGE_POLICY_MAX_MERGE_AT_ONCE);
TieredMergePolicyProvider.INDEX_MERGE_POLICY_MAX_MERGE_AT_ONCE, indexDynamicSettings.addDynamicSetting(TieredMergePolicyProvider.INDEX_MERGE_POLICY_MAX_MERGE_AT_ONCE_EXPLICIT);
TieredMergePolicyProvider.INDEX_MERGE_POLICY_MAX_MERGE_AT_ONCE_EXPLICIT, indexDynamicSettings.addDynamicSetting(TieredMergePolicyProvider.INDEX_MERGE_POLICY_MAX_MERGED_SEGMENT);
TieredMergePolicyProvider.INDEX_MERGE_POLICY_MAX_MERGED_SEGMENT, indexDynamicSettings.addDynamicSetting(TieredMergePolicyProvider.INDEX_MERGE_POLICY_SEGMENTS_PER_TIER);
TieredMergePolicyProvider.INDEX_MERGE_POLICY_SEGMENTS_PER_TIER, indexDynamicSettings.addDynamicSetting(TieredMergePolicyProvider.INDEX_MERGE_POLICY_RECLAIM_DELETES_WEIGHT);
TieredMergePolicyProvider.INDEX_MERGE_POLICY_RECLAIM_DELETES_WEIGHT, indexDynamicSettings.addDynamicSetting(TieredMergePolicyProvider.INDEX_COMPOUND_FORMAT);
TieredMergePolicyProvider.INDEX_COMPOUND_FORMAT, indexDynamicSettings.addDynamicSetting(TranslogService.INDEX_TRANSLOG_FLUSH_THRESHOLD_OPS);
TranslogService.INDEX_TRANSLOG_FLUSH_THRESHOLD_OPS, indexDynamicSettings.addDynamicSetting(TranslogService.INDEX_TRANSLOG_FLUSH_THRESHOLD_SIZE);
TranslogService.INDEX_TRANSLOG_FLUSH_THRESHOLD_SIZE, indexDynamicSettings.addDynamicSetting(TranslogService.INDEX_TRANSLOG_FLUSH_THRESHOLD_PERIOD);
TranslogService.INDEX_TRANSLOG_FLUSH_THRESHOLD_PERIOD, indexDynamicSettings.addDynamicSetting(TranslogService.INDEX_TRANSLOG_DISABLE_FLUSH);
TranslogService.INDEX_TRANSLOG_DISABLE_FLUSH);
} }
public void addDynamicSetting(String... settings) { public void addDynamicSettings(String... settings) {
indexDynamicSettings.addDynamicSettings(settings); indexDynamicSettings.addDynamicSettings(settings);
} }
public void addDynamicSetting(String setting, Validator validator) {
indexDynamicSettings.addDynamicSetting(setting, validator);
}
@Override @Override
protected void configure() { protected void configure() {
bind(DynamicSettings.class).annotatedWith(IndexDynamicSettings.class).toInstance(indexDynamicSettings); bind(DynamicSettings.class).annotatedWith(IndexDynamicSettings.class).toInstance(indexDynamicSettings);

View File

@ -0,0 +1,66 @@
/*
* Licensed to ElasticSearch and Shay Banon 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.test.integration.cluster;
import org.elasticsearch.ElasticSearchIllegalArgumentException;
import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
import org.elasticsearch.common.Priority;
import org.elasticsearch.test.integration.AbstractNodesTests;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
/**
*/
public class UpdateSettingsValidationTests extends AbstractNodesTests {
@AfterMethod
public void closeNodes() {
closeAllNodes();
}
@Test
public void testUpdateSettingsValidation() throws Exception {
startNode("master", settingsBuilder().put("node.data", false).build());
startNode("node1", settingsBuilder().put("node.master", false).build());
startNode("node2", settingsBuilder().put("node.master", false).build());
client("master").admin().indices().prepareCreate("test")
.setSettings(settingsBuilder().put("index.number_of_shards", 5).put("index.number_of_replicas", 1)).execute().actionGet();
ClusterHealthResponse healthResponse = client("master").admin().cluster().prepareHealth("test").setWaitForEvents(Priority.LANGUID).setWaitForNodes("3").setWaitForGreenStatus().execute().actionGet();
assertThat(healthResponse.isTimedOut(), equalTo(false));
assertThat(healthResponse.getIndices().get("test").getActiveShards(), equalTo(10));
client("master").admin().indices().prepareUpdateSettings("test").setSettings(settingsBuilder().put("index.number_of_replicas", 0)).execute().actionGet();
healthResponse = client("master").admin().cluster().prepareHealth("test").setWaitForEvents(Priority.LANGUID).setWaitForGreenStatus().execute().actionGet();
assertThat(healthResponse.isTimedOut(), equalTo(false));
assertThat(healthResponse.getIndices().get("test").getActiveShards(), equalTo(5));
try {
client("master").admin().indices().prepareUpdateSettings("test").setSettings(settingsBuilder().put("index.refresh_interval", "")).execute().actionGet();
assert false;
} catch (ElasticSearchIllegalArgumentException ex) {
logger.info("Error message: [{}]", ex.getMessage());
}
}
}