Mappings: Don't ignore merge failures.

This commit is contained in:
Adrien Grand 2015-12-01 12:22:07 +01:00
parent 059a675aa5
commit cebd7bdd7f
2 changed files with 102 additions and 5 deletions

View File

@ -250,13 +250,14 @@ public class MapperService extends AbstractIndexComponent implements Closeable {
DocumentMapper oldMapper = mappers.get(mapper.type()); DocumentMapper oldMapper = mappers.get(mapper.type());
if (oldMapper != null) { if (oldMapper != null) {
MergeResult result = oldMapper.merge(mapper.mapping(), false, updateAllTypes); // simulate first
MergeResult result = oldMapper.merge(mapper.mapping(), true, updateAllTypes);
if (result.hasConflicts()) { if (result.hasConflicts()) {
// TODO: What should we do??? throw new MergeMappingException(result.buildConflicts());
if (logger.isDebugEnabled()) {
logger.debug("merging mapping for type [{}] resulted in conflicts: [{}]", mapper.type(), Arrays.toString(result.buildConflicts()));
}
} }
// then apply for real
result = oldMapper.merge(mapper.mapping(), false, updateAllTypes);
assert result.hasConflicts() == false; // we already simulated
return oldMapper; return oldMapper;
} else { } else {
List<ObjectMapper> newObjectMappers = new ArrayList<>(); List<ObjectMapper> newObjectMappers = new ArrayList<>();

View File

@ -29,7 +29,9 @@ import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.IndexService; import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.mapper.DocumentMapper; import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.MergeMappingException;
import org.elasticsearch.index.mapper.MergeResult; import org.elasticsearch.index.mapper.MergeResult;
import org.elasticsearch.index.mapper.core.LongFieldMapper;
import org.elasticsearch.test.ESSingleNodeTestCase; import org.elasticsearch.test.ESSingleNodeTestCase;
import java.io.IOException; import java.io.IOException;
@ -107,6 +109,100 @@ public class UpdateMappingTests extends ESSingleNodeTestCase {
assertThat(mappingAfterUpdate, equalTo(mappingBeforeUpdate)); assertThat(mappingAfterUpdate, equalTo(mappingBeforeUpdate));
} }
public void testConflictSameType() throws Exception {
XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("properties").startObject("foo").field("type", "long").endObject()
.endObject().endObject().endObject();
MapperService mapperService = createIndex("test", Settings.settingsBuilder().build(), "type", mapping).mapperService();
XContentBuilder update = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("properties").startObject("foo").field("type", "double").endObject()
.endObject().endObject().endObject();
try {
mapperService.merge("type", new CompressedXContent(update.string()), false, false);
fail();
} catch (MergeMappingException e) {
// expected
}
try {
mapperService.merge("type", new CompressedXContent(update.string()), false, false);
fail();
} catch (MergeMappingException e) {
// expected
}
assertTrue(mapperService.documentMapper("type").mapping().root().getMapper("foo") instanceof LongFieldMapper);
}
public void testConflictNewType() throws Exception {
XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("type1")
.startObject("properties").startObject("foo").field("type", "long").endObject()
.endObject().endObject().endObject();
MapperService mapperService = createIndex("test", Settings.settingsBuilder().build(), "type1", mapping).mapperService();
XContentBuilder update = XContentFactory.jsonBuilder().startObject().startObject("type2")
.startObject("properties").startObject("foo").field("type", "double").endObject()
.endObject().endObject().endObject();
try {
mapperService.merge("type2", new CompressedXContent(update.string()), false, false);
fail();
} catch (IllegalArgumentException e) {
// expected
assertTrue(e.getMessage().contains("conflicts with existing mapping in other types"));
}
try {
mapperService.merge("type2", new CompressedXContent(update.string()), false, false);
fail();
} catch (IllegalArgumentException e) {
// expected
assertTrue(e.getMessage().contains("conflicts with existing mapping in other types"));
}
assertTrue(mapperService.documentMapper("type1").mapping().root().getMapper("foo") instanceof LongFieldMapper);
assertNull(mapperService.documentMapper("type2"));
}
// same as the testConflictNewType except that the mapping update is on an existing type
@AwaitsFix(bugUrl="https://github.com/elastic/elasticsearch/issues/15049")
public void testConflictNewTypeUpdate() throws Exception {
XContentBuilder mapping1 = XContentFactory.jsonBuilder().startObject().startObject("type1")
.startObject("properties").startObject("foo").field("type", "long").endObject()
.endObject().endObject().endObject();
XContentBuilder mapping2 = XContentFactory.jsonBuilder().startObject().startObject("type2").endObject().endObject();
MapperService mapperService = createIndex("test", Settings.settingsBuilder().build()).mapperService();
mapperService.merge("type1", new CompressedXContent(mapping1.string()), false, false);
mapperService.merge("type2", new CompressedXContent(mapping2.string()), false, false);
XContentBuilder update = XContentFactory.jsonBuilder().startObject().startObject("type2")
.startObject("properties").startObject("foo").field("type", "double").endObject()
.endObject().endObject().endObject();
try {
mapperService.merge("type2", new CompressedXContent(update.string()), false, false);
fail();
} catch (IllegalArgumentException e) {
// expected
assertTrue(e.getMessage().contains("conflicts with existing mapping in other types"));
}
try {
mapperService.merge("type2", new CompressedXContent(update.string()), false, false);
fail();
} catch (IllegalArgumentException e) {
// expected
assertTrue(e.getMessage().contains("conflicts with existing mapping in other types"));
}
assertTrue(mapperService.documentMapper("type1").mapping().root().getMapper("foo") instanceof LongFieldMapper);
assertNotNull(mapperService.documentMapper("type2"));
assertNull(mapperService.documentMapper("type2").mapping().root().getMapper("foo"));
}
public void testIndexFieldParsingBackcompat() throws IOException { public void testIndexFieldParsingBackcompat() throws IOException {
IndexService indexService = createIndex("test", Settings.settingsBuilder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_4_2.id).build()); IndexService indexService = createIndex("test", Settings.settingsBuilder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_4_2.id).build());
XContentBuilder indexMapping = XContentFactory.jsonBuilder(); XContentBuilder indexMapping = XContentFactory.jsonBuilder();