Make sure to accept empty unnested mappings in create index requests. (#37089)
This commit is contained in:
parent
e613bcae43
commit
54f53d2a51
|
@ -172,12 +172,29 @@ public class DocumentMapperParser {
|
|||
return extractMapping(type, root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an optional type name and mapping definition, returns the type and a normalized form of the mappings.
|
||||
*
|
||||
* The provided mapping definition may or may not contain the type name as the root key in the map. This method
|
||||
* attempts to unwrap the mappings, so that they no longer contain a type name at the root. If no type name can
|
||||
* be found, through either the 'type' parameter or by examining the provided mappings, then an exception will be
|
||||
* thrown.
|
||||
*
|
||||
* @param type An optional type name.
|
||||
* @param root The mapping definition.
|
||||
*
|
||||
* @return A tuple of the form (type, normalized mappings).
|
||||
*/
|
||||
@SuppressWarnings({"unchecked"})
|
||||
private Tuple<String, Map<String, Object>> extractMapping(String type, Map<String, Object> root) throws MapperParsingException {
|
||||
if (root.size() == 0) {
|
||||
// if we don't have any keys throw an exception
|
||||
throw new MapperParsingException("malformed mapping no root object found");
|
||||
if (type != null) {
|
||||
return new Tuple<>(type, root);
|
||||
} else {
|
||||
throw new MapperParsingException("malformed mapping, no type name found");
|
||||
}
|
||||
}
|
||||
|
||||
String rootName = root.keySet().iterator().next();
|
||||
Tuple<String, Map<String, Object>> mapping;
|
||||
if (type == null || type.equals(rootName)) {
|
||||
|
|
|
@ -24,17 +24,20 @@ import org.elasticsearch.ElasticsearchException;
|
|||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.UnavailableShardsException;
|
||||
import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.action.support.ActiveShardCount;
|
||||
import org.elasticsearch.action.support.IndicesOptions;
|
||||
import org.elasticsearch.action.support.master.AcknowledgedResponse;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.metadata.MappingMetaData;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.gateway.MetaStateService;
|
||||
import org.elasticsearch.index.IndexNotFoundException;
|
||||
import org.elasticsearch.index.query.RangeQueryBuilder;
|
||||
|
@ -120,6 +123,56 @@ public class CreateIndexIT extends ESIntegTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void testNonNestedMappings() throws Exception {
|
||||
assertAcked(prepareCreate("test")
|
||||
.addMapping("_doc", XContentFactory.jsonBuilder().startObject()
|
||||
.startObject("properties")
|
||||
.startObject("date")
|
||||
.field("type", "date")
|
||||
.endObject()
|
||||
.endObject()
|
||||
.endObject()));
|
||||
|
||||
GetMappingsResponse response = client().admin().indices().prepareGetMappings("test").get();
|
||||
|
||||
ImmutableOpenMap<String, MappingMetaData> mappings = response.mappings().get("test");
|
||||
assertNotNull(mappings);
|
||||
|
||||
MappingMetaData metadata = mappings.get("_doc");
|
||||
assertNotNull(metadata);
|
||||
assertFalse(metadata.sourceAsMap().isEmpty());
|
||||
}
|
||||
|
||||
public void testEmptyNestedMappings() throws Exception {
|
||||
assertAcked(prepareCreate("test")
|
||||
.addMapping("_doc", XContentFactory.jsonBuilder().startObject().endObject()));
|
||||
|
||||
GetMappingsResponse response = client().admin().indices().prepareGetMappings("test").get();
|
||||
|
||||
ImmutableOpenMap<String, MappingMetaData> mappings = response.mappings().get("test");
|
||||
assertNotNull(mappings);
|
||||
|
||||
MappingMetaData metadata = mappings.get("_doc");
|
||||
assertNotNull(metadata);
|
||||
assertTrue(metadata.sourceAsMap().isEmpty());
|
||||
}
|
||||
|
||||
public void testEmptyMappings() throws Exception {
|
||||
assertAcked(prepareCreate("test")
|
||||
.addMapping("_doc", XContentFactory.jsonBuilder().startObject()
|
||||
.startObject("_doc").endObject()
|
||||
.endObject()));
|
||||
|
||||
GetMappingsResponse response = client().admin().indices().prepareGetMappings("test").get();
|
||||
|
||||
ImmutableOpenMap<String, MappingMetaData> mappings = response.mappings().get("test");
|
||||
assertNotNull(mappings);
|
||||
|
||||
MappingMetaData metadata = mappings.get("_doc");
|
||||
assertNotNull(metadata);
|
||||
assertTrue(metadata.sourceAsMap().isEmpty());
|
||||
}
|
||||
|
||||
public void testInvalidShardCountSettings() throws Exception {
|
||||
int value = randomIntBetween(-10, 0);
|
||||
try {
|
||||
|
|
|
@ -97,17 +97,6 @@ public class MetaDataIndexTemplateServiceTests extends ESSingleNodeTestCase {
|
|||
assertThat(errors.get(0).getMessage(), equalTo("Alias [foobar] cannot be the same as any pattern in [foo, foobar]"));
|
||||
}
|
||||
|
||||
public void testIndexTemplateWithValidateEmptyMapping() throws Exception {
|
||||
PutRequest request = new PutRequest("api", "validate_template");
|
||||
request.patterns(Collections.singletonList("validate_template"));
|
||||
request.putMapping("type1", "{}");
|
||||
|
||||
List<Throwable> errors = putTemplateDetail(request);
|
||||
assertThat(errors.size(), equalTo(1));
|
||||
assertThat(errors.get(0), instanceOf(MapperParsingException.class));
|
||||
assertThat(errors.get(0).getMessage(), containsString("malformed mapping no root object found"));
|
||||
}
|
||||
|
||||
public void testIndexTemplateWithValidateMapping() throws Exception {
|
||||
PutRequest request = new PutRequest("api", "validate_template");
|
||||
request.patterns(Collections.singletonList("te*"));
|
||||
|
@ -132,17 +121,6 @@ public class MetaDataIndexTemplateServiceTests extends ESSingleNodeTestCase {
|
|||
assertThat(errors.get(0).getMessage(), containsString("Failed to parse mapping "));
|
||||
}
|
||||
|
||||
public void testBlankMapping() throws Exception {
|
||||
PutRequest request = new PutRequest("api", "blank_mapping");
|
||||
request.patterns(Collections.singletonList("te*"));
|
||||
request.putMapping("type1", "{}");
|
||||
|
||||
List<Throwable> errors = putTemplateDetail(request);
|
||||
assertThat(errors.size(), equalTo(1));
|
||||
assertThat(errors.get(0), instanceOf(MapperParsingException.class));
|
||||
assertThat(errors.get(0).getMessage(), containsString("malformed mapping no root object found"));
|
||||
}
|
||||
|
||||
public void testAliasInvalidFilterInvalidJson() throws Exception {
|
||||
//invalid json: put index template fails
|
||||
PutRequest request = new PutRequest("api", "blank_mapping");
|
||||
|
|
|
@ -39,8 +39,6 @@ import org.elasticsearch.test.InternalSettingsPlugin;
|
|||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
|
@ -179,25 +177,7 @@ public class MapperServiceTests extends ESSingleNodeTestCase {
|
|||
assertWarnings("[unmapped_type:string] should be replaced with [unmapped_type:keyword]");
|
||||
}
|
||||
|
||||
public void testMergeWithMap() throws Throwable {
|
||||
IndexService indexService1 = createIndex("index1");
|
||||
MapperService mapperService = indexService1.mapperService();
|
||||
Map<String, Map<String, Object>> mappings = new HashMap<>();
|
||||
|
||||
mappings.put(MapperService.DEFAULT_MAPPING, MapperService.parseMapping(xContentRegistry(), "{}"));
|
||||
MapperException e = expectThrows(MapperParsingException.class,
|
||||
() -> mapperService.merge(mappings, MergeReason.MAPPING_UPDATE));
|
||||
assertThat(e.getMessage(), startsWith("Failed to parse mapping [" + MapperService.DEFAULT_MAPPING + "]: "));
|
||||
|
||||
mappings.clear();
|
||||
mappings.put("type1", MapperService.parseMapping(xContentRegistry(), "{}"));
|
||||
|
||||
e = expectThrows( MapperParsingException.class,
|
||||
() -> mapperService.merge(mappings, MergeReason.MAPPING_UPDATE));
|
||||
assertThat(e.getMessage(), startsWith("Failed to parse mapping [type1]: "));
|
||||
}
|
||||
|
||||
public void testPartitionedConstraints() {
|
||||
public void testPartitionedConstraints() {
|
||||
// partitioned index must have routing
|
||||
IllegalArgumentException noRoutingException = expectThrows(IllegalArgumentException.class, () -> {
|
||||
client().admin().indices().prepareCreate("test-index")
|
||||
|
|
Loading…
Reference in New Issue