From 999c360cb9034c469779adfbc3c6fb5df1a53e98 Mon Sep 17 00:00:00 2001 From: Julie Tibshirani Date: Thu, 20 Dec 2018 17:13:45 -0800 Subject: [PATCH 1/7] Stop automatically wrapping mapping definitions with the type name. Now that we unwrap mappings in DocumentMapperParser#extractMappings, it is not necessary for the mapping definition to always be nested under the type. This leniency around the mapping format was added in 2341825358e740b0bea4c16d164c5acdf12fc6b3. --- .../admin/indices/create/CreateIndexRequest.java | 5 ----- .../index/mapper/DocumentMapperParser.java | 13 +++++++++++++ .../indices/create/CreateIndexRequestTests.java | 16 ++++++++++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java b/server/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java index 1bbce19ee8dec..9e7ab111f1cfd 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java @@ -33,7 +33,6 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesReference; -import org.elasticsearch.common.collect.MapBuilder; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.settings.Settings; @@ -256,10 +255,6 @@ public CreateIndexRequest mapping(String type, Map source) { if (mappings.containsKey(type)) { throw new IllegalStateException("mappings for type \"" + type + "\" were already defined"); } - // wrap it in a type map if its not - if (source.size() != 1 || !source.containsKey(type)) { - source = MapBuilder.newMapBuilder().put(type, source).map(); - } try { XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON); builder.map(source); diff --git a/server/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java b/server/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java index 15faa70456c2a..3a674b876d718 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java @@ -172,6 +172,19 @@ private Tuple> extractMapping(String type, String so 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> extractMapping(String type, Map root) throws MapperParsingException { if (root.size() == 0) { diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequestTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequestTests.java index 1c27934927413..f633463e0a359 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequestTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequestTests.java @@ -22,12 +22,14 @@ import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.action.admin.indices.alias.Alias; import org.elasticsearch.common.Strings; +import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; import org.elasticsearch.common.xcontent.NamedXContentRegistry; +import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.common.xcontent.json.JsonXContent; @@ -109,6 +111,20 @@ public void testToXContent() throws IOException { assertEquals(expectedRequestBody, actualRequestBody); } + public void testMappingsToXContent() { + String source = "{\"properties\":{\"field\":{\"type\":\"keyword\"}}}}"; + Map sourceAsMap = XContentHelper.convertToMap(new BytesArray(source), false, + XContentType.JSON).v2(); + + CreateIndexRequest request = new CreateIndexRequest("index"); + request.mapping("my_type", sourceAsMap); + + String expectedContent = "{\"settings\":{}," + + "\"mappings\":{\"my_type\":{\"properties\":{\"field\":{\"type\":\"keyword\"}}}}," + + "\"aliases\":{}}"; + assertEquals(expectedContent, Strings.toString(request)); + } + public void testToAndFromXContent() throws IOException { final CreateIndexRequest createIndexRequest = RandomCreateIndexGenerator.randomCreateIndexRequest(); From 463520668b0b42534d97eee322b6ff429f281cca Mon Sep 17 00:00:00 2001 From: Julie Tibshirani Date: Fri, 21 Dec 2018 17:44:07 -0800 Subject: [PATCH 2/7] Make CreateIndexRequestTests extend AbstractXContentTestCase for better test coverage. --- .../create/CreateIndexRequestTests.java | 165 +++++++----------- 1 file changed, 65 insertions(+), 100 deletions(-) diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequestTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequestTests.java index f633463e0a359..64b77d0dc349b 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequestTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequestTests.java @@ -22,33 +22,86 @@ import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.action.admin.indices.alias.Alias; import org.elasticsearch.common.Strings; -import org.elasticsearch.common.bytes.BytesArray; -import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; import org.elasticsearch.common.xcontent.NamedXContentRegistry; -import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.index.RandomCreateIndexGenerator; -import org.elasticsearch.test.ESTestCase; -import org.elasticsearch.test.hamcrest.ElasticsearchAssertions; +import org.elasticsearch.test.AbstractXContentTestCase; import java.io.IOException; import java.util.Map; import java.util.Set; -import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_SHARDS; -import static org.elasticsearch.common.xcontent.ToXContent.EMPTY_PARAMS; +public class CreateIndexRequestTests extends AbstractXContentTestCase { -public class CreateIndexRequestTests extends ESTestCase { + @Override + protected CreateIndexRequest createTestInstance() { + try { + return RandomCreateIndexGenerator.randomCreateIndexRequest(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + protected CreateIndexRequest doParseInstance(XContentParser parser) throws IOException { + CreateIndexRequest request = new CreateIndexRequest(); + request.source(parser.map(), LoggingDeprecationHandler.INSTANCE); + return request; + } + + @Override + protected void assertEqualInstances(CreateIndexRequest expectedInstance, CreateIndexRequest newInstance) { + assertEquals(expectedInstance.settings(), newInstance.settings()); + assertAliasesEqual(expectedInstance.aliases(), newInstance.aliases()); + assertMappingsEqual(expectedInstance.mappings(), newInstance.mappings()); + } + + @Override + protected boolean supportsUnknownFields() { + return false; + } + + public static void assertMappingsEqual(Map expected, Map actual) { + assertEquals(expected.keySet(), actual.keySet()); + + for (Map.Entry expectedEntry : expected.entrySet()) { + String expectedValue = expectedEntry.getValue(); + String actualValue = actual.get(expectedEntry.getKey()); + try (XContentParser expectedJson = JsonXContent.jsonXContent.createParser(NamedXContentRegistry.EMPTY, + LoggingDeprecationHandler.INSTANCE, expectedValue); + XContentParser actualJson = JsonXContent.jsonXContent.createParser(NamedXContentRegistry.EMPTY, + LoggingDeprecationHandler.INSTANCE, actualValue)) { + assertEquals(expectedJson.map(), actualJson.map()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + public static void assertAliasesEqual(Set expected, Set actual) { + assertEquals(expected, actual); + + for (Alias expectedAlias : expected) { + for (Alias actualAlias : actual) { + if (expectedAlias.equals(actualAlias)) { + // As Alias#equals only looks at name, we check the equality of the other Alias parameters here. + assertEquals(expectedAlias.filter(), actualAlias.filter()); + assertEquals(expectedAlias.indexRouting(), actualAlias.indexRouting()); + assertEquals(expectedAlias.searchRouting(), actualAlias.searchRouting()); + } + } + } + } public void testSerialization() throws IOException { CreateIndexRequest request = new CreateIndexRequest("foo"); - String mapping = Strings.toString(JsonXContent.contentBuilder().startObject().startObject("type").endObject().endObject()); + String mapping = Strings.toString(JsonXContent.contentBuilder().startObject() + .startObject("type").endObject().endObject()); request.mapping("my_type", mapping, XContentType.JSON); try (BytesStreamOutput output = new BytesStreamOutput()) { @@ -65,7 +118,7 @@ public void testSerialization() throws IOException { public void testTopLevelKeys() { String createIndex = - "{\n" + "{\n" + " \"FOO_SHOULD_BE_ILLEGAL_HERE\": {\n" + " \"BAR_IS_THE_SAME\": 42\n" + " },\n" @@ -82,95 +135,7 @@ public void testTopLevelKeys() { CreateIndexRequest request = new CreateIndexRequest(); ElasticsearchParseException e = expectThrows(ElasticsearchParseException.class, - () -> {request.source(createIndex, XContentType.JSON);}); + () -> {request.source(createIndex, XContentType.JSON);}); assertEquals("unknown key [FOO_SHOULD_BE_ILLEGAL_HERE] for create index", e.getMessage()); } - - public void testToXContent() throws IOException { - CreateIndexRequest request = new CreateIndexRequest("foo"); - - String mapping = Strings.toString(JsonXContent.contentBuilder().startObject().startObject("type").endObject().endObject()); - request.mapping("my_type", mapping, XContentType.JSON); - - Alias alias = new Alias("test_alias"); - alias.routing("1"); - alias.filter("{\"term\":{\"year\":2016}}"); - alias.writeIndex(true); - request.alias(alias); - - Settings.Builder settings = Settings.builder(); - settings.put(SETTING_NUMBER_OF_SHARDS, 10); - request.settings(settings); - - String actualRequestBody = Strings.toString(request); - - String expectedRequestBody = "{\"settings\":{\"index\":{\"number_of_shards\":\"10\"}}," + - "\"mappings\":{\"my_type\":{\"type\":{}}}," + - "\"aliases\":{\"test_alias\":{\"filter\":{\"term\":{\"year\":2016}},\"routing\":\"1\",\"is_write_index\":true}}}"; - - assertEquals(expectedRequestBody, actualRequestBody); - } - - public void testMappingsToXContent() { - String source = "{\"properties\":{\"field\":{\"type\":\"keyword\"}}}}"; - Map sourceAsMap = XContentHelper.convertToMap(new BytesArray(source), false, - XContentType.JSON).v2(); - - CreateIndexRequest request = new CreateIndexRequest("index"); - request.mapping("my_type", sourceAsMap); - - String expectedContent = "{\"settings\":{}," + - "\"mappings\":{\"my_type\":{\"properties\":{\"field\":{\"type\":\"keyword\"}}}}," + - "\"aliases\":{}}"; - assertEquals(expectedContent, Strings.toString(request)); - } - - public void testToAndFromXContent() throws IOException { - - final CreateIndexRequest createIndexRequest = RandomCreateIndexGenerator.randomCreateIndexRequest(); - - boolean humanReadable = randomBoolean(); - final XContentType xContentType = randomFrom(XContentType.values()); - BytesReference originalBytes = toShuffledXContent(createIndexRequest, xContentType, EMPTY_PARAMS, humanReadable); - - CreateIndexRequest parsedCreateIndexRequest = new CreateIndexRequest(); - parsedCreateIndexRequest.source(originalBytes, xContentType); - - assertMappingsEqual(createIndexRequest.mappings(), parsedCreateIndexRequest.mappings()); - assertAliasesEqual(createIndexRequest.aliases(), parsedCreateIndexRequest.aliases()); - assertEquals(createIndexRequest.settings(), parsedCreateIndexRequest.settings()); - - BytesReference finalBytes = toShuffledXContent(parsedCreateIndexRequest, xContentType, EMPTY_PARAMS, humanReadable); - ElasticsearchAssertions.assertToXContentEquivalent(originalBytes, finalBytes, xContentType); - } - - public static void assertMappingsEqual(Map expected, Map actual) throws IOException { - assertEquals(expected.keySet(), actual.keySet()); - - for (Map.Entry expectedEntry : expected.entrySet()) { - String expectedValue = expectedEntry.getValue(); - String actualValue = actual.get(expectedEntry.getKey()); - try (XContentParser expectedJson = JsonXContent.jsonXContent.createParser(NamedXContentRegistry.EMPTY, - LoggingDeprecationHandler.INSTANCE, expectedValue); - XContentParser actualJson = JsonXContent.jsonXContent.createParser(NamedXContentRegistry.EMPTY, - LoggingDeprecationHandler.INSTANCE, actualValue)){ - assertEquals(expectedJson.map(), actualJson.map()); - } - } - } - - public static void assertAliasesEqual(Set expected, Set actual) throws IOException { - assertEquals(expected, actual); - - for (Alias expectedAlias : expected) { - for (Alias actualAlias : actual) { - if (expectedAlias.equals(actualAlias)) { - // As Alias#equals only looks at name, we check the equality of the other Alias parameters here. - assertEquals(expectedAlias.filter(), actualAlias.filter()); - assertEquals(expectedAlias.indexRouting(), actualAlias.indexRouting()); - assertEquals(expectedAlias.searchRouting(), actualAlias.searchRouting()); - } - } - } - } } From b374d245d6469c71bc0580fc50fbf4e3746ed6d5 Mon Sep 17 00:00:00 2001 From: Julie Tibshirani Date: Fri, 21 Dec 2018 17:50:18 -0800 Subject: [PATCH 3/7] Add tests for mapping definitions that are not nested under the type name. --- .../admin/indices/create/CreateIndexIT.java | 19 ++++++++++++++++++ .../index/RandomCreateIndexGenerator.java | 20 +++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexIT.java b/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexIT.java index 3253eb1dc1c88..e4ce89fbbb0a0 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexIT.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexIT.java @@ -24,17 +24,20 @@ 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,22 @@ public void testDoubleAddMapping() throws Exception { } } + 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> mappings = response.mappings(); + assertTrue(mappings.containsKey("test")); + assertTrue(mappings.get("test").containsKey("_doc")); + } + public void testInvalidShardCountSettings() throws Exception { int value = randomIntBetween(-10, 0); try { diff --git a/test/framework/src/main/java/org/elasticsearch/index/RandomCreateIndexGenerator.java b/test/framework/src/main/java/org/elasticsearch/index/RandomCreateIndexGenerator.java index e88a9f0a38d2c..27b7db3d36a03 100644 --- a/test/framework/src/main/java/org/elasticsearch/index/RandomCreateIndexGenerator.java +++ b/test/framework/src/main/java/org/elasticsearch/index/RandomCreateIndexGenerator.java @@ -29,6 +29,7 @@ import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_REPLICAS; import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_SHARDS; +import static org.elasticsearch.test.ESTestCase.frequently; import static org.elasticsearch.test.ESTestCase.randomAlphaOfLength; import static org.elasticsearch.test.ESTestCase.randomBoolean; import static org.elasticsearch.test.ESTestCase.randomIntBetween; @@ -45,9 +46,14 @@ public static CreateIndexRequest randomCreateIndexRequest() throws IOException { String index = randomAlphaOfLength(5); CreateIndexRequest request = new CreateIndexRequest(index); randomAliases(request); - if (randomBoolean()) { + if (frequently()) { String type = randomAlphaOfLength(5); - request.mapping(type, randomMapping(type)); + if (randomBoolean()) { + request.mapping(type, randomMapping()); + } else { + request.mapping(type, randomMapping(type)); + + } } if (randomBoolean()) { request.settings(randomIndexSettings()); @@ -76,6 +82,16 @@ public static Settings randomIndexSettings() { return builder.build(); } + public static XContentBuilder randomMapping() throws IOException { + XContentBuilder builder = XContentFactory.jsonBuilder(); + builder.startObject(); + + randomMappingFields(builder, true); + + builder.endObject(); + return builder; + } + public static XContentBuilder randomMapping(String type) throws IOException { XContentBuilder builder = XContentFactory.jsonBuilder(); builder.startObject().startObject(type); From 58dc49496cf77747a25c9ccbeb6ee32f9c7c3125 Mon Sep 17 00:00:00 2001 From: Julie Tibshirani Date: Fri, 21 Dec 2018 18:08:13 -0800 Subject: [PATCH 4/7] Make sure empty mappings are accepted. --- .../index/mapper/DocumentMapperParser.java | 8 +++++-- .../admin/indices/create/CreateIndexIT.java | 24 ++++++++++++++++--- .../MetaDataIndexTemplateServiceTests.java | 22 ----------------- .../index/mapper/MapperServiceTests.java | 22 +---------------- 4 files changed, 28 insertions(+), 48 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java b/server/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java index 3a674b876d718..e63d5a279f3cd 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java @@ -188,9 +188,13 @@ private Tuple> extractMapping(String type, String so @SuppressWarnings({"unchecked"}) private Tuple> extractMapping(String type, Map 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> mapping; if (type == null || type.equals(rootName)) { diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexIT.java b/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexIT.java index e4ce89fbbb0a0..72a92a13b3a39 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexIT.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexIT.java @@ -134,9 +134,27 @@ public void testNonNestedMappings() throws Exception { .endObject())); GetMappingsResponse response = client().admin().indices().prepareGetMappings("test").get(); - ImmutableOpenMap> mappings = response.mappings(); - assertTrue(mappings.containsKey("test")); - assertTrue(mappings.get("test").containsKey("_doc")); + + ImmutableOpenMap mappings = response.mappings().get("test"); + assertNotNull(mappings); + + MappingMetaData metadata = mappings.get("_doc"); + assertNotNull(metadata); + assertFalse(metadata.sourceAsMap().isEmpty()); + } + + public void testEmptyMappings() throws Exception { + assertAcked(prepareCreate("test") + .addMapping("_doc", XContentFactory.jsonBuilder().startObject().endObject())); + + GetMappingsResponse response = client().admin().indices().prepareGetMappings("test").get(); + + ImmutableOpenMap mappings = response.mappings().get("test"); + assertNotNull(mappings); + + MappingMetaData metadata = mappings.get("_doc"); + assertNotNull(metadata); + assertTrue(metadata.sourceAsMap().isEmpty()); } public void testInvalidShardCountSettings() throws Exception { diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/template/put/MetaDataIndexTemplateServiceTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/template/put/MetaDataIndexTemplateServiceTests.java index 6302766be9017..a929ee63c576e 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/template/put/MetaDataIndexTemplateServiceTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/template/put/MetaDataIndexTemplateServiceTests.java @@ -97,17 +97,6 @@ public void testIndexTemplateWithAliasNameEqualToTemplatePattern() { 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 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 void testBrokenMapping() throws Exception { 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 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"); diff --git a/server/src/test/java/org/elasticsearch/index/mapper/MapperServiceTests.java b/server/src/test/java/org/elasticsearch/index/mapper/MapperServiceTests.java index b5eeef0fa2847..2c1a75b40d4c0 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/MapperServiceTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/MapperServiceTests.java @@ -39,8 +39,6 @@ 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 void testUnmappedFieldType() { 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> 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") From 2b395aac8398a3d6509bd50806acdc64fbf74564 Mon Sep 17 00:00:00 2001 From: Julie Tibshirani Date: Fri, 21 Dec 2018 18:58:46 -0800 Subject: [PATCH 5/7] Avoid automatically nesting mappings when provided in flat format. --- .../indices/mapping/put/PutMappingRequest.java | 12 ++++++++++++ .../action/admin/indices/create/CreateIndexIT.java | 14 ++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/put/PutMappingRequest.java b/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/put/PutMappingRequest.java index 926ae175d65ad..237e720ae2a58 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/put/PutMappingRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/put/PutMappingRequest.java @@ -184,6 +184,18 @@ public PutMappingRequest source(Object... source) { return source(buildFromSimplifiedDef(type, source)); } + /** + * @param source + * consisting of field/properties pairs (e.g. "field1", + * "type=string,store=true") + * @throws IllegalArgumentException + * if the number of the source arguments is not divisible by two + * @return the mappings definition + */ + public static XContentBuilder buildFromSimplifiedDef(Object... source) { + return buildFromSimplifiedDef(null, source); + } + /** * @param type * the mapping type diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexIT.java b/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexIT.java index 72a92a13b3a39..578768ddb9eeb 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexIT.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexIT.java @@ -157,6 +157,20 @@ public void testEmptyMappings() throws Exception { assertTrue(metadata.sourceAsMap().isEmpty()); } + public void testFlatMappingFormat() throws Exception { + assertAcked(prepareCreate("test") + .addMapping("_doc", "field", "type=keyword")); + + GetMappingsResponse response = client().admin().indices().prepareGetMappings("test").get(); + + ImmutableOpenMap mappings = response.mappings().get("test"); + assertNotNull(mappings); + + MappingMetaData metadata = mappings.get("_doc"); + assertNotNull(metadata); + assertFalse(metadata.sourceAsMap().isEmpty()); + } + public void testInvalidShardCountSettings() throws Exception { int value = randomIntBetween(-10, 0); try { From 2f799ab541223953ab76f2565853e8e6d55e8868 Mon Sep 17 00:00:00 2001 From: Julie Tibshirani Date: Thu, 3 Jan 2019 13:10:45 -0800 Subject: [PATCH 6/7] Fix an omission from the previous commit around flat mappings. --- .../action/admin/indices/create/CreateIndexRequest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java b/server/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java index 9e7ab111f1cfd..bf82d70521648 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java @@ -269,7 +269,7 @@ public CreateIndexRequest mapping(String type, Map source) { * ("field1", "type=string,store=true"). */ public CreateIndexRequest mapping(String type, Object... source) { - mapping(type, PutMappingRequest.buildFromSimplifiedDef(type, source)); + mapping(type, PutMappingRequest.buildFromSimplifiedDef(source)); return this; } From 6c258cade597c07359814645fefbeec6ea6f696f Mon Sep 17 00:00:00 2001 From: Julie Tibshirani Date: Thu, 3 Jan 2019 14:16:54 -0800 Subject: [PATCH 7/7] Fix an error in CreateIndexIT introduced while merging in master. --- .../action/admin/indices/create/CreateIndexIT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexIT.java b/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexIT.java index 0a2527109d2e7..ada78767ca501 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexIT.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexIT.java @@ -170,7 +170,7 @@ public void testEmptyMappings() throws Exception { MappingMetaData metadata = mappings.get("_doc"); assertNotNull(metadata); - assertFalse(metadata.sourceAsMap().isEmpty()); + assertTrue(metadata.sourceAsMap().isEmpty()); } public void testFlatMappingFormat() throws Exception {