Permalink
Browse files

MapperService: check index.mapper.dynamic during index creation

The MapperService doesn't currently check the
index.mapper.dynamic setting during index creation,
so indices can be created with dynamic mappings even
if this setting is false. Add a check that throws an
exception in this case. Fixes #15381
  • Loading branch information...
Dave authored and jpountz committed Dec 14, 2015
1 parent 4986817 commit 3f9c0fbb58ad2120cbc800d424f4365be287e349
@@ -26,6 +26,7 @@
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.regex.Regex;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.mapper.MapperService;
/**
* Encapsulates the logic of whether a new index should be automatically created when
@@ -35,13 +36,15 @@
private final boolean needToCheck;
private final boolean globallyDisabled;
private final boolean dynamicMappingDisabled;
private final String[] matches;
private final String[] matches2;
private final IndexNameExpressionResolver resolver;
@Inject
public AutoCreateIndex(Settings settings, IndexNameExpressionResolver resolver) {
this.resolver = resolver;
dynamicMappingDisabled = !settings.getAsBoolean(MapperService.INDEX_MAPPER_DYNAMIC_SETTING, MapperService.INDEX_MAPPER_DYNAMIC_DEFAULT);
String value = settings.get("action.auto_create_index");
if (value == null || Booleans.isExplicitTrue(value)) {
needToCheck = true;
@@ -82,7 +85,7 @@ public boolean shouldAutoCreate(String index, ClusterState state) {
if (exists) {
return false;
}
if (globallyDisabled) {
if (globallyDisabled || dynamicMappingDisabled) {
return false;
}
// matches not set, default value of "true"
@@ -78,6 +78,8 @@
public class MapperService extends AbstractIndexComponent implements Closeable {
public static final String DEFAULT_MAPPING = "_default_";
public static final String INDEX_MAPPER_DYNAMIC_SETTING = "index.mapper.dynamic";
public static final boolean INDEX_MAPPER_DYNAMIC_DEFAULT = true;
private static ObjectHashSet<String> META_FIELDS = ObjectHashSet.from(
"_uid", "_id", "_type", "_all", "_parent", "_routing", "_index",
"_size", "_timestamp", "_ttl"
@@ -124,7 +126,7 @@ public MapperService(IndexSettings indexSettings, AnalysisService analysisServic
this.searchQuoteAnalyzer = new MapperAnalyzerWrapper(analysisService.defaultSearchQuoteAnalyzer(), p -> p.searchQuoteAnalyzer());
this.mapperRegistry = mapperRegistry;
this.dynamic = this.indexSettings.getSettings().getAsBoolean("index.mapper.dynamic", true);
this.dynamic = this.indexSettings.getSettings().getAsBoolean(INDEX_MAPPER_DYNAMIC_SETTING, INDEX_MAPPER_DYNAMIC_DEFAULT);
defaultPercolatorMappingSource = "{\n" +
"\"_default_\":{\n" +
"\"properties\" : {\n" +
@@ -0,0 +1,114 @@
/*
* 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.index.mapper;
import org.elasticsearch.Version;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.index.TransportIndexAction;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.AutoCreateIndex;
import org.elasticsearch.cluster.action.shard.ShardStateAction;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.indices.IndicesService;
import org.elasticsearch.test.ESSingleNodeTestCase;
import org.elasticsearch.transport.TransportService;
import org.elasticsearch.transport.local.LocalTransport;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.test.cluster.TestClusterService;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import static org.hamcrest.CoreMatchers.instanceOf;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
public class DynamicMappingDisabledTests extends ESSingleNodeTestCase {
private static ThreadPool THREAD_POOL;
private TestClusterService clusterService;
private LocalTransport transport;
private TransportService transportService;
private IndicesService indicesService;
private ShardStateAction shardStateAction;
private ActionFilters actionFilters;
private IndexNameExpressionResolver indexNameExpressionResolver;
private AutoCreateIndex autoCreateIndex;
private Settings settings;
@BeforeClass
public static void createThreadPool() {
THREAD_POOL = new ThreadPool("DynamicMappingDisabledTests");
}
@Override
public void setUp() throws Exception {
super.setUp();
settings = Settings.builder()
.put(MapperService.INDEX_MAPPER_DYNAMIC_SETTING, false)
.build();
clusterService = new TestClusterService(THREAD_POOL);
transport = new LocalTransport(settings, THREAD_POOL, Version.CURRENT, new NamedWriteableRegistry());
transportService = new TransportService(transport, THREAD_POOL);
indicesService = getInstanceFromNode(IndicesService.class);
shardStateAction = new ShardStateAction(settings, clusterService, transportService, null, null);
actionFilters = new ActionFilters(Collections.emptySet());
indexNameExpressionResolver = new IndexNameExpressionResolver(settings);
autoCreateIndex = new AutoCreateIndex(settings, indexNameExpressionResolver);
}
@AfterClass
public static void destroyThreadPool() {
ThreadPool.terminate(THREAD_POOL, 30, TimeUnit.SECONDS);
// since static must set to null to be eligible for collection
THREAD_POOL = null;
}
public void testDynamicDisabled() {
TransportIndexAction action = new TransportIndexAction(settings, transportService, clusterService,
indicesService, THREAD_POOL, shardStateAction, null, null, actionFilters, indexNameExpressionResolver,
autoCreateIndex);
IndexRequest request = new IndexRequest("index", "type", "1");
request.source("foo", 3);
final AtomicBoolean onFailureCalled = new AtomicBoolean();
action.execute(request, new ActionListener<IndexResponse>() {
@Override
public void onResponse(IndexResponse indexResponse) {
fail("Indexing request should have failed");
}
@Override
public void onFailure(Throwable e) {
onFailureCalled.set(true);
assertThat(e, instanceOf(IndexNotFoundException.class));
assertEquals(e.getMessage(), "no such index");
}
});
assertTrue(onFailureCalled.get());
}
}
@@ -21,6 +21,7 @@
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.test.ESIntegTestCase;
import java.util.Arrays;
@@ -40,7 +41,7 @@ public void testGetSettingsWithBlocks() throws Exception {
.setSettings(Settings.settingsBuilder()
.put("index.refresh_interval", -1)
.put("index.merge.policy.expunge_deletes_allowed", "30")
.put("index.mapper.dynamic", false)));
.put(MapperService.INDEX_MAPPER_DYNAMIC_SETTING, false)));
for (String block : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE, SETTING_READ_ONLY)) {
try {
@@ -49,7 +50,7 @@ public void testGetSettingsWithBlocks() throws Exception {
assertThat(response.getIndexToSettings().size(), greaterThanOrEqualTo(1));
assertThat(response.getSetting("test", "index.refresh_interval"), equalTo("-1"));
assertThat(response.getSetting("test", "index.merge.policy.expunge_deletes_allowed"), equalTo("30"));
assertThat(response.getSetting("test", "index.mapper.dynamic"), equalTo("false"));
assertThat(response.getSetting("test", MapperService.INDEX_MAPPER_DYNAMIC_SETTING), equalTo("false"));
} finally {
disableIndexBlock("test", block);
}

0 comments on commit 3f9c0fb

Please sign in to comment.