mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-25 22:36:20 +00:00
Automatically created indices should honor index.mapper.dynamic
. #19478
Today they don't because the create index request that is implicitly created adds an empty mapping for the type of the document. So to Elasticsearch it looks like this type was explicitly created and `index.mapper.dynamic` is not checked. Closes #17592
This commit is contained in:
parent
3f6c0feee3
commit
37e20c6f34
@ -119,29 +119,21 @@ public class TransportBulkAction extends HandledTransportAction<BulkRequest, Bul
|
|||||||
|
|
||||||
if (needToCheck()) {
|
if (needToCheck()) {
|
||||||
// Keep track of all unique indices and all unique types per index for the create index requests:
|
// Keep track of all unique indices and all unique types per index for the create index requests:
|
||||||
final Map<String, Set<String>> indicesAndTypes = new HashMap<>();
|
final Set<String> autoCreateIndices = new HashSet<>();
|
||||||
for (ActionRequest request : bulkRequest.requests) {
|
for (ActionRequest request : bulkRequest.requests) {
|
||||||
if (request instanceof DocumentRequest) {
|
if (request instanceof DocumentRequest) {
|
||||||
DocumentRequest req = (DocumentRequest) request;
|
DocumentRequest req = (DocumentRequest) request;
|
||||||
Set<String> types = indicesAndTypes.get(req.index());
|
autoCreateIndices.add(req.index());
|
||||||
if (types == null) {
|
|
||||||
indicesAndTypes.put(req.index(), types = new HashSet<>());
|
|
||||||
}
|
|
||||||
types.add(req.type());
|
|
||||||
} else {
|
} else {
|
||||||
throw new ElasticsearchException("Parsed unknown request in bulk actions: " + request.getClass().getSimpleName());
|
throw new ElasticsearchException("Parsed unknown request in bulk actions: " + request.getClass().getSimpleName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final AtomicInteger counter = new AtomicInteger(indicesAndTypes.size());
|
final AtomicInteger counter = new AtomicInteger(autoCreateIndices.size());
|
||||||
ClusterState state = clusterService.state();
|
ClusterState state = clusterService.state();
|
||||||
for (Map.Entry<String, Set<String>> entry : indicesAndTypes.entrySet()) {
|
for (String index : autoCreateIndices) {
|
||||||
final String index = entry.getKey();
|
|
||||||
if (shouldAutoCreate(index, state)) {
|
if (shouldAutoCreate(index, state)) {
|
||||||
CreateIndexRequest createIndexRequest = new CreateIndexRequest();
|
CreateIndexRequest createIndexRequest = new CreateIndexRequest();
|
||||||
createIndexRequest.index(index);
|
createIndexRequest.index(index);
|
||||||
for (String type : entry.getValue()) {
|
|
||||||
createIndexRequest.mapping(type);
|
|
||||||
}
|
|
||||||
createIndexRequest.cause("auto(bulk api)");
|
createIndexRequest.cause("auto(bulk api)");
|
||||||
createIndexRequest.masterNodeTimeout(bulkRequest.timeout());
|
createIndexRequest.masterNodeTimeout(bulkRequest.timeout());
|
||||||
createIndexAction.execute(createIndexRequest, new ActionListener<CreateIndexResponse>() {
|
createIndexAction.execute(createIndexRequest, new ActionListener<CreateIndexResponse>() {
|
||||||
|
@ -91,7 +91,6 @@ public class TransportIndexAction extends TransportWriteAction<IndexRequest, Ind
|
|||||||
if (autoCreateIndex.shouldAutoCreate(request.index(), state)) {
|
if (autoCreateIndex.shouldAutoCreate(request.index(), state)) {
|
||||||
CreateIndexRequest createIndexRequest = new CreateIndexRequest();
|
CreateIndexRequest createIndexRequest = new CreateIndexRequest();
|
||||||
createIndexRequest.index(request.index());
|
createIndexRequest.index(request.index());
|
||||||
createIndexRequest.mapping(request.type());
|
|
||||||
createIndexRequest.cause("auto(index api)");
|
createIndexRequest.cause("auto(index api)");
|
||||||
createIndexRequest.masterNodeTimeout(request.timeout());
|
createIndexRequest.masterNodeTimeout(request.timeout());
|
||||||
createIndexAction.execute(task, createIndexRequest, new ActionListener<CreateIndexResponse>() {
|
createIndexAction.execute(task, createIndexRequest, new ActionListener<CreateIndexResponse>() {
|
||||||
|
@ -538,7 +538,8 @@ public class MapperService extends AbstractIndexComponent {
|
|||||||
return new DocumentMapperForType(mapper, null);
|
return new DocumentMapperForType(mapper, null);
|
||||||
}
|
}
|
||||||
if (!dynamic) {
|
if (!dynamic) {
|
||||||
throw new TypeMissingException(index(), type, "trying to auto create mapping, but dynamic mapping is disabled");
|
throw new TypeMissingException(index(),
|
||||||
|
new IllegalStateException("trying to auto create mapping, but dynamic mapping is disabled"), type);
|
||||||
}
|
}
|
||||||
mapper = parse(type, null, true);
|
mapper = parse(type, null, true);
|
||||||
return new DocumentMapperForType(mapper, mapper.mapping());
|
return new DocumentMapperForType(mapper, mapper.mapping());
|
||||||
|
@ -33,7 +33,12 @@ import java.util.Arrays;
|
|||||||
public class TypeMissingException extends ElasticsearchException {
|
public class TypeMissingException extends ElasticsearchException {
|
||||||
|
|
||||||
public TypeMissingException(Index index, String... types) {
|
public TypeMissingException(Index index, String... types) {
|
||||||
super("type[" + Arrays.toString(types) + "] missing");
|
super("type" + Arrays.toString(types) + " missing");
|
||||||
|
setIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeMissingException(Index index, Throwable cause, String... types) {
|
||||||
|
super("type" + Arrays.toString(types) + " missing", cause);
|
||||||
setIndex(index);
|
setIndex(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,10 +18,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.elasticsearch.index.mapper;
|
package org.elasticsearch.index.mapper;
|
||||||
|
|
||||||
|
import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
|
||||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
|
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
|
||||||
import org.elasticsearch.action.bulk.BulkResponse;
|
import org.elasticsearch.action.bulk.BulkResponse;
|
||||||
import org.elasticsearch.cluster.metadata.MappingMetaData;
|
import org.elasticsearch.cluster.metadata.MappingMetaData;
|
||||||
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.indices.TypeMissingException;
|
||||||
import org.elasticsearch.test.ESIntegTestCase;
|
import org.elasticsearch.test.ESIntegTestCase;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -29,8 +32,9 @@ import java.util.Map;
|
|||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||||
|
|
||||||
public class DynamicMappingIntegrationIT extends ESIntegTestCase {
|
public class DynamicMappingIT extends ESIntegTestCase {
|
||||||
|
|
||||||
public void testConflictingDynamicMappings() {
|
public void testConflictingDynamicMappings() {
|
||||||
// we don't use indexRandom because the order of requests is important here
|
// we don't use indexRandom because the order of requests is important here
|
||||||
@ -120,4 +124,26 @@ public class DynamicMappingIntegrationIT extends ESIntegTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testAutoCreateWithDisabledDynamicMappings() throws Exception {
|
||||||
|
assertAcked(client().admin().indices().preparePutTemplate("my_template")
|
||||||
|
.setCreate(true)
|
||||||
|
.setTemplate("index_*")
|
||||||
|
.addMapping("foo", "field", "type=keyword")
|
||||||
|
.setSettings(Settings.builder().put("index.mapper.dynamic", false).build())
|
||||||
|
.get());
|
||||||
|
|
||||||
|
// succeeds since 'foo' has an explicit mapping in the template
|
||||||
|
indexRandom(true, false, client().prepareIndex("index_1", "foo", "1").setSource("field", "abc"));
|
||||||
|
|
||||||
|
// fails since 'bar' does not have an explicit mapping in the template and dynamic template creation is disabled
|
||||||
|
TypeMissingException e1 = expectThrows(TypeMissingException.class,
|
||||||
|
() -> client().prepareIndex("index_2", "bar", "1").setSource("field", "abc").get());
|
||||||
|
assertEquals("type[bar] missing", e1.getMessage());
|
||||||
|
assertEquals("trying to auto create mapping, but dynamic mapping is disabled", e1.getCause().getMessage());
|
||||||
|
|
||||||
|
// make sure no mappings were created for bar
|
||||||
|
GetIndexResponse getIndexResponse = client().admin().indices().prepareGetIndex().addIndices("index_2").get();
|
||||||
|
assertFalse(getIndexResponse.mappings().containsKey("bar"));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user