Automatically add "index." prefix to the settings are changed on restore if the prefix is missing

Closes #10133
This commit is contained in:
Igor Motov 2015-03-25 18:24:47 -04:00
parent b00b2b9baa
commit 96f4c06f46
10 changed files with 69 additions and 35 deletions

View File

@ -154,7 +154,7 @@ public class IndexMetaData {
throw new ElasticsearchIllegalStateException("No state match for [" + state + "]");
}
}
public static final String INDEX_SETTING_PREFIX = "index.";
public static final String SETTING_NUMBER_OF_SHARDS = "index.number_of_shards";
public static final String SETTING_NUMBER_OF_REPLICAS = "index.number_of_replicas";
public static final String SETTING_SHADOW_REPLICAS = "index.shadow_replicas";

View File

@ -329,13 +329,7 @@ public class IndexTemplateMetaData {
} else if (token == XContentParser.Token.START_OBJECT) {
if ("settings".equals(currentFieldName)) {
ImmutableSettings.Builder templateSettingsBuilder = ImmutableSettings.settingsBuilder();
for (Map.Entry<String, String> entry : SettingsLoader.Helper.loadNestedFromMap(parser.mapOrdered()).entrySet()) {
if (!entry.getKey().startsWith("index.")) {
templateSettingsBuilder.put("index." + entry.getKey(), entry.getValue());
} else {
templateSettingsBuilder.put(entry.getKey(), entry.getValue());
}
}
templateSettingsBuilder.put(SettingsLoader.Helper.loadNestedFromMap(parser.mapOrdered())).normalizePrefix(IndexMetaData.INDEX_SETTING_PREFIX);
builder.settings(templateSettingsBuilder.build());
} else if ("mappings".equals(currentFieldName)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {

View File

@ -195,13 +195,7 @@ public class MetaDataCreateIndexService extends AbstractComponent {
private void createIndex(final CreateIndexClusterStateUpdateRequest request, final ActionListener<ClusterStateUpdateResponse> listener, final Semaphore mdLock) {
ImmutableSettings.Builder updatedSettingsBuilder = ImmutableSettings.settingsBuilder();
for (Map.Entry<String, String> entry : request.settings().getAsMap().entrySet()) {
if (!entry.getKey().startsWith("index.")) {
updatedSettingsBuilder.put("index." + entry.getKey(), entry.getValue());
} else {
updatedSettingsBuilder.put(entry.getKey(), entry.getValue());
}
}
updatedSettingsBuilder.put(request.settings()).normalizePrefix(IndexMetaData.INDEX_SETTING_PREFIX);
request.settings(updatedSettingsBuilder.build());
clusterService.submitStateUpdateTask("create-index [" + request.index() + "], cause [" + request.cause() + "]", Priority.URGENT, new AckedClusterStateUpdateTask<ClusterStateUpdateResponse>(request, listener) {

View File

@ -107,13 +107,7 @@ public class MetaDataIndexTemplateService extends AbstractComponent {
public void putTemplate(final PutRequest request, final PutListener listener) {
ImmutableSettings.Builder updatedSettingsBuilder = ImmutableSettings.settingsBuilder();
for (Map.Entry<String, String> entry : request.settings.getAsMap().entrySet()) {
if (!entry.getKey().startsWith("index.")) {
updatedSettingsBuilder.put("index." + entry.getKey(), entry.getValue());
} else {
updatedSettingsBuilder.put(entry.getKey(), entry.getValue());
}
}
updatedSettingsBuilder.put(request.settings).normalizePrefix(IndexMetaData.INDEX_SETTING_PREFIX);
request.settings(updatedSettingsBuilder.build());
if (request.name == null) {

View File

@ -168,16 +168,7 @@ public class MetaDataUpdateSettingsService extends AbstractComponent implements
public void updateSettings(final UpdateSettingsClusterStateUpdateRequest request, final ActionListener<ClusterStateUpdateResponse> listener) {
ImmutableSettings.Builder updatedSettingsBuilder = ImmutableSettings.settingsBuilder();
for (Map.Entry<String, String> entry : request.settings().getAsMap().entrySet()) {
if (entry.getKey().equals("index")) {
continue;
}
if (!entry.getKey().startsWith("index.")) {
updatedSettingsBuilder.put("index." + entry.getKey(), entry.getValue());
} else {
updatedSettingsBuilder.put(entry.getKey(), entry.getValue());
}
}
updatedSettingsBuilder.put(request.settings()).normalizePrefix(IndexMetaData.INDEX_SETTING_PREFIX);
// never allow to change the number of shards
for (String key : updatedSettingsBuilder.internalMap().keySet()) {
if (key.equals(IndexMetaData.SETTING_NUMBER_OF_SHARDS)) {

View File

@ -1100,6 +1100,25 @@ public class ImmutableSettings implements Settings {
return this;
}
/**
* Checks that all settings in the builder start with the specified prefix.
*
* If a setting doesn't start with the prefix, the builder appends the prefix to such setting.
*/
public Builder normalizePrefix(String prefix) {
Map<String, String> replacements = Maps.newHashMap();
Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
while(iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
if (entry.getKey().startsWith(prefix) == false) {
replacements.put(prefix + entry.getKey(), entry.getValue());
iterator.remove();
}
}
map.putAll(replacements);
return this;
}
/**
* Builds a {@link Settings} (underlying uses {@link ImmutableSettings}) based on everything
* set on this builder.

View File

@ -19,6 +19,7 @@
package org.elasticsearch.index.settings;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
@ -44,7 +45,7 @@ public class IndexSettingsService extends AbstractIndexComponent {
public synchronized void refreshSettings(Settings settings) {
// this.settings include also the node settings
if (this.settings.getByPrefix("index.").getAsMap().equals(settings.getByPrefix("index.").getAsMap())) {
if (this.settings.getByPrefix(IndexMetaData.INDEX_SETTING_PREFIX).getAsMap().equals(settings.getByPrefix(IndexMetaData.INDEX_SETTING_PREFIX).getAsMap())) {
// nothing to update, same settings
return;
}

View File

@ -314,6 +314,7 @@ public class RestoreService extends AbstractComponent implements ClusterStateLis
if (changeSettings.names().isEmpty() && ignoreSettings.length == 0) {
return indexMetaData;
}
Settings normalizedChangeSettings = ImmutableSettings.settingsBuilder().put(changeSettings).normalizePrefix(IndexMetaData.INDEX_SETTING_PREFIX).build();
IndexMetaData.Builder builder = IndexMetaData.builder(indexMetaData);
Map<String, String> settingsMap = newHashMap(indexMetaData.settings().getAsMap());
List<String> simpleMatchPatterns = newArrayList();
@ -340,7 +341,7 @@ public class RestoreService extends AbstractComponent implements ClusterStateLis
}
}
}
for(Map.Entry<String, String> entry : changeSettings.getAsMap().entrySet()) {
for(Map.Entry<String, String> entry : normalizedChangeSettings.getAsMap().entrySet()) {
if (UNMODIFIABLE_SETTINGS.contains(entry.getKey())) {
throw new SnapshotRestoreException(snapshotId, "cannot modify setting [" + entry.getKey() + "] on restore");
} else {

View File

@ -324,4 +324,44 @@ public class ImmutableSettingsTests extends ElasticsearchTestCase {
assertThat(settings.get("value.data"), is("1"));
assertThat(settings.get("value"), is(nullValue()));
}
@Test
public void testPrefixNormalization() {
Settings settings = settingsBuilder().normalizePrefix("foo.").build();
assertThat(settings.names().size(), equalTo(0));
settings = settingsBuilder()
.put("bar", "baz")
.normalizePrefix("foo.")
.build();
assertThat(settings.getAsMap().size(), equalTo(1));
assertThat(settings.get("bar"), nullValue());
assertThat(settings.get("foo.bar"), equalTo("baz"));
settings = settingsBuilder()
.put("bar", "baz")
.put("foo.test", "test")
.normalizePrefix("foo.")
.build();
assertThat(settings.getAsMap().size(), equalTo(2));
assertThat(settings.get("bar"), nullValue());
assertThat(settings.get("foo.bar"), equalTo("baz"));
assertThat(settings.get("foo.test"), equalTo("test"));
settings = settingsBuilder()
.put("foo.test", "test")
.normalizePrefix("foo.")
.build();
assertThat(settings.getAsMap().size(), equalTo(1));
assertThat(settings.get("foo.test"), equalTo("test"));
}
}

View File

@ -1557,7 +1557,7 @@ public class SharedClusterSnapshotRestoreTests extends AbstractSnapshotTests {
cluster().wipeIndices("test-idx");
Settings newIndexSettings = ImmutableSettings.builder()
.put(INDEX_REFRESH_INTERVAL, "5s")
.put("refresh_interval", "5s")
.put("index.analysis.analyzer.my_analyzer.type", "standard")
.build();