Skip to content

Commit 90c5453

Browse files
committed
Expose the reason why a mapping merge is issued.
This would be useful in order to only perform some validations in the case of a mapping update and in cases when a mapping is restored eg. after a restart, such as discussed in #15989. This replaces the current `applyDefault` parameter which can be derived from the mapping merge reason: the default mapping should be applied only in case of a mapping update, if the mapping does not exist yet and if this is not the default mapping.
1 parent 7257bba commit 90c5453

29 files changed

+121
-102
lines changed

core/src/main/java/org/elasticsearch/cluster/metadata/MetaDataCreateIndexService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ public ClusterState execute(ClusterState currentState) throws Exception {
314314
// first, add the default mapping
315315
if (mappings.containsKey(MapperService.DEFAULT_MAPPING)) {
316316
try {
317-
mapperService.merge(MapperService.DEFAULT_MAPPING, new CompressedXContent(XContentFactory.jsonBuilder().map(mappings.get(MapperService.DEFAULT_MAPPING)).string()), false, request.updateAllTypes());
317+
mapperService.merge(MapperService.DEFAULT_MAPPING, new CompressedXContent(XContentFactory.jsonBuilder().map(mappings.get(MapperService.DEFAULT_MAPPING)).string()), MapperService.MergeReason.MAPPING_UPDATE, request.updateAllTypes());
318318
} catch (Exception e) {
319319
removalReason = "failed on parsing default mapping on index creation";
320320
throw new MapperParsingException("Failed to parse mapping [{}]: {}", e, MapperService.DEFAULT_MAPPING, e.getMessage());
@@ -326,7 +326,7 @@ public ClusterState execute(ClusterState currentState) throws Exception {
326326
}
327327
try {
328328
// apply the default here, its the first time we parse it
329-
mapperService.merge(entry.getKey(), new CompressedXContent(XContentFactory.jsonBuilder().map(entry.getValue()).string()), true, request.updateAllTypes());
329+
mapperService.merge(entry.getKey(), new CompressedXContent(XContentFactory.jsonBuilder().map(entry.getValue()).string()), MapperService.MergeReason.MAPPING_UPDATE, request.updateAllTypes());
330330
} catch (Exception e) {
331331
removalReason = "failed on parsing mappings on index creation";
332332
throw new MapperParsingException("Failed to parse mapping [{}]: {}", e, entry.getKey(), e.getMessage());

core/src/main/java/org/elasticsearch/cluster/metadata/MetaDataIndexAliasesService.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,9 @@ public ClusterState execute(final ClusterState currentState) {
9999
// temporarily create the index and add mappings so we can parse the filter
100100
try {
101101
indexService = indicesService.createIndex(indexMetaData.getIndex(), indexMetaData.getSettings(), clusterService.localNode().id());
102-
if (indexMetaData.getMappings().containsKey(MapperService.DEFAULT_MAPPING)) {
103-
indexService.mapperService().merge(MapperService.DEFAULT_MAPPING, indexMetaData.getMappings().get(MapperService.DEFAULT_MAPPING).source(), false, false);
104-
}
105102
for (ObjectCursor<MappingMetaData> cursor : indexMetaData.getMappings().values()) {
106103
MappingMetaData mappingMetaData = cursor.value;
107-
indexService.mapperService().merge(mappingMetaData.type(), mappingMetaData.source(), false, false);
104+
indexService.mapperService().merge(mappingMetaData.type(), mappingMetaData.source(), MapperService.MergeReason.MAPPING_RECOVERY, false);
108105
}
109106
} catch (Exception e) {
110107
logger.warn("[{}] failed to temporary create in order to apply alias action", e, indexMetaData.getIndex());

core/src/main/java/org/elasticsearch/cluster/metadata/MetaDataIndexUpgradeService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ private void checkMappingsCompatibility(IndexMetaData indexMetaData) {
330330
try (MapperService mapperService = new MapperService(index, settings, analysisService, similarityLookupService, scriptService, mapperRegistry)) {
331331
for (ObjectCursor<MappingMetaData> cursor : indexMetaData.getMappings().values()) {
332332
MappingMetaData mappingMetaData = cursor.value;
333-
mapperService.merge(mappingMetaData.type(), mappingMetaData.source(), false, false);
333+
mapperService.merge(mappingMetaData.type(), mappingMetaData.source(), MapperService.MergeReason.MAPPING_RECOVERY, false);
334334
}
335335
}
336336
}

core/src/main/java/org/elasticsearch/cluster/metadata/MetaDataMappingService.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ ClusterState executeRefresh(final ClusterState currentState, final List<RefreshT
137137
removeIndex = true;
138138
for (ObjectCursor<MappingMetaData> metaData : indexMetaData.getMappings().values()) {
139139
// don't apply the default mapping, it has been applied when the mapping was created
140-
indexService.mapperService().merge(metaData.value.type(), metaData.value.source(), false, true);
140+
indexService.mapperService().merge(metaData.value.type(), metaData.value.source(), MapperService.MergeReason.MAPPING_RECOVERY, true);
141141
}
142142
}
143143

@@ -220,7 +220,7 @@ public BatchResult<PutMappingClusterStateUpdateRequest> execute(ClusterState cur
220220
IndexService indexService = indicesService.createIndex(indexMetaData.getIndex(), indexMetaData.getSettings(), clusterService.localNode().id());
221221
// add mappings for all types, we need them for cross-type validation
222222
for (ObjectCursor<MappingMetaData> mapping : indexMetaData.getMappings().values()) {
223-
indexService.mapperService().merge(mapping.value.type(), mapping.value.source(), false, request.updateAllTypes());
223+
indexService.mapperService().merge(mapping.value.type(), mapping.value.source(), MapperService.MergeReason.MAPPING_RECOVERY, request.updateAllTypes());
224224
}
225225
}
226226
}
@@ -301,7 +301,7 @@ private ClusterState applyRequest(ClusterState currentState, PutMappingClusterSt
301301
if (existingMapper != null) {
302302
existingSource = existingMapper.mappingSource();
303303
}
304-
DocumentMapper mergedMapper = indexService.mapperService().merge(mappingType, mappingUpdateSource, true, request.updateAllTypes());
304+
DocumentMapper mergedMapper = indexService.mapperService().merge(mappingType, mappingUpdateSource, MapperService.MergeReason.MAPPING_UPDATE, request.updateAllTypes());
305305
CompressedXContent updatedSource = mergedMapper.mappingSource();
306306

307307
if (existingSource != null) {

core/src/main/java/org/elasticsearch/index/mapper/MapperService.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,22 @@
8181
*/
8282
public class MapperService extends AbstractIndexComponent implements Closeable {
8383

84+
/**
85+
* The reason why a mapping is being merged.
86+
*/
87+
public enum MergeReason {
88+
/**
89+
* Create or update a mapping.
90+
*/
91+
MAPPING_UPDATE,
92+
/**
93+
* Recovery of an existing mapping, for instance because of a restart,
94+
* if a shard was moved to a different node or for administrative
95+
* purposes.
96+
*/
97+
MAPPING_RECOVERY;
98+
}
99+
84100
public static final String DEFAULT_MAPPING = "_default_";
85101
public static final String INDEX_MAPPER_DYNAMIC_SETTING = "index.mapper.dynamic";
86102
public static final boolean INDEX_MAPPER_DYNAMIC_DEFAULT = true;
@@ -242,7 +258,7 @@ public void removeTypeListener(DocumentTypeListener listener) {
242258
typeListeners.remove(listener);
243259
}
244260

245-
public DocumentMapper merge(String type, CompressedXContent mappingSource, boolean applyDefault, boolean updateAllTypes) {
261+
public DocumentMapper merge(String type, CompressedXContent mappingSource, MergeReason reason, boolean updateAllTypes) {
246262
if (DEFAULT_MAPPING.equals(type)) {
247263
// verify we can parse it
248264
// NOTE: never apply the default here
@@ -260,9 +276,13 @@ public DocumentMapper merge(String type, CompressedXContent mappingSource, boole
260276
return mapper;
261277
} else {
262278
synchronized (this) {
263-
// only apply the default mapping if we don't have the type yet
264-
applyDefault &= mappers.containsKey(type) == false;
265-
return merge(parse(type, mappingSource, applyDefault), updateAllTypes);
279+
final boolean applyDefault =
280+
// the default was already applied if we are recovering
281+
reason != MergeReason.MAPPING_RECOVERY
282+
// only apply the default mapping if we don't have the type yet
283+
&& mappers.containsKey(type) == false;
284+
DocumentMapper mergeWith = parse(type, mappingSource, applyDefault);
285+
return merge(mergeWith, updateAllTypes);
266286
}
267287
}
268288
}

core/src/main/java/org/elasticsearch/indices/cluster/IndicesClusterStateService.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,8 +384,7 @@ private boolean processMapping(String index, MapperService mapperService, String
384384
} else {
385385
logger.debug("[{}] {} mapping [{}] (source suppressed due to length, use TRACE level if needed)", index, op, mappingType);
386386
}
387-
// we don't apply default, since it has been applied when the mappings were parsed initially
388-
mapperService.merge(mappingType, mappingSource, false, true);
387+
mapperService.merge(mappingType, mappingSource, MapperService.MergeReason.MAPPING_RECOVERY, true);
389388
if (!mapperService.documentMapper(mappingType).mappingSource().equals(mappingSource)) {
390389
logger.debug("[{}] parsed mapping [{}], and got different sources\noriginal:\n{}\nparsed:\n{}", index, mappingType, mappingSource, mapperService.documentMapper(mappingType).mappingSource());
391390
requiresRefresh = true;

core/src/test/java/org/elasticsearch/index/fielddata/ParentChildFieldDataTests.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
3232
import org.elasticsearch.common.compress.CompressedXContent;
3333
import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData;
34+
import org.elasticsearch.index.mapper.MapperService;
3435
import org.elasticsearch.index.mapper.Uid;
3536
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
3637
import org.elasticsearch.index.mapper.internal.UidFieldMapper;
@@ -57,10 +58,10 @@ public class ParentChildFieldDataTests extends AbstractFieldDataTestCase {
5758
@Before
5859
public void before() throws Exception {
5960
mapperService.merge(
60-
childType, new CompressedXContent(PutMappingRequest.buildFromSimplifiedDef(childType, "_parent", "type=" + parentType).string()), true, false
61+
childType, new CompressedXContent(PutMappingRequest.buildFromSimplifiedDef(childType, "_parent", "type=" + parentType).string()), MapperService.MergeReason.MAPPING_UPDATE, false
6162
);
6263
mapperService.merge(
63-
grandChildType, new CompressedXContent(PutMappingRequest.buildFromSimplifiedDef(grandChildType, "_parent", "type=" + childType).string()), true, false
64+
grandChildType, new CompressedXContent(PutMappingRequest.buildFromSimplifiedDef(grandChildType, "_parent", "type=" + childType).string()), MapperService.MergeReason.MAPPING_UPDATE, false
6465
);
6566

6667
Document d = new Document();

core/src/test/java/org/elasticsearch/index/mapper/DynamicMappingTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ public void testMixTemplateMultiFieldAndMappingReuse() throws Exception {
477477
.endObject()
478478
.endArray()
479479
.endObject().endObject();
480-
indexService.mapperService().merge("type1", new CompressedXContent(mappings1.bytes()), true, false);
480+
indexService.mapperService().merge("type1", new CompressedXContent(mappings1.bytes()), MapperService.MergeReason.MAPPING_UPDATE, false);
481481
XContentBuilder mappings2 = jsonBuilder().startObject()
482482
.startObject("type2")
483483
.startObject("properties")
@@ -486,7 +486,7 @@ public void testMixTemplateMultiFieldAndMappingReuse() throws Exception {
486486
.endObject()
487487
.endObject()
488488
.endObject().endObject();
489-
indexService.mapperService().merge("type2", new CompressedXContent(mappings2.bytes()), true, false);
489+
indexService.mapperService().merge("type2", new CompressedXContent(mappings2.bytes()), MapperService.MergeReason.MAPPING_UPDATE, false);
490490

491491
XContentBuilder json = XContentFactory.jsonBuilder().startObject()
492492
.field("field", "foo")
@@ -497,7 +497,7 @@ public void testMixTemplateMultiFieldAndMappingReuse() throws Exception {
497497
ParsedDocument parsed = mapper.parse(source);
498498
assertNotNull(parsed.dynamicMappingsUpdate());
499499

500-
indexService.mapperService().merge("type1", new CompressedXContent(parsed.dynamicMappingsUpdate().toString()), false, false);
500+
indexService.mapperService().merge("type1", new CompressedXContent(parsed.dynamicMappingsUpdate().toString()), MapperService.MergeReason.MAPPING_UPDATE, false);
501501
mapper = indexService.mapperService().documentMapper("type1");
502502
assertNotNull(mapper.mappers().getMapper("field.raw"));
503503
parsed = mapper.parse(source);

core/src/test/java/org/elasticsearch/index/mapper/MapperServiceTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,15 @@ public void testTypes() throws Exception {
110110
MapperService mapperService = indexService1.mapperService();
111111
assertEquals(Collections.emptySet(), mapperService.types());
112112

113-
mapperService.merge("type1", new CompressedXContent("{\"type1\":{}}"), true, false);
113+
mapperService.merge("type1", new CompressedXContent("{\"type1\":{}}"), MapperService.MergeReason.MAPPING_UPDATE, false);
114114
assertNull(mapperService.documentMapper(MapperService.DEFAULT_MAPPING));
115115
assertEquals(Collections.singleton("type1"), mapperService.types());
116116

117-
mapperService.merge(MapperService.DEFAULT_MAPPING, new CompressedXContent("{\"_default_\":{}}"), true, false);
117+
mapperService.merge(MapperService.DEFAULT_MAPPING, new CompressedXContent("{\"_default_\":{}}"), MapperService.MergeReason.MAPPING_UPDATE, false);
118118
assertNotNull(mapperService.documentMapper(MapperService.DEFAULT_MAPPING));
119119
assertEquals(Collections.singleton("type1"), mapperService.types());
120120

121-
mapperService.merge("type2", new CompressedXContent("{\"type2\":{}}"), true, false);
121+
mapperService.merge("type2", new CompressedXContent("{\"type2\":{}}"), MapperService.MergeReason.MAPPING_UPDATE, false);
122122
assertNotNull(mapperService.documentMapper(MapperService.DEFAULT_MAPPING));
123123
assertEquals(new HashSet<>(Arrays.asList("type1", "type2")), mapperService.types());
124124
}

core/src/test/java/org/elasticsearch/index/mapper/copyto/CopyToMapperTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,11 +321,11 @@ public void testCopyToFieldMerge() throws Exception {
321321
.endObject().endObject().endObject().string();
322322

323323
MapperService mapperService = createIndex("test").mapperService();
324-
DocumentMapper docMapperBefore = mapperService.merge("type1", new CompressedXContent(mappingBefore), true, false);
324+
DocumentMapper docMapperBefore = mapperService.merge("type1", new CompressedXContent(mappingBefore), MapperService.MergeReason.MAPPING_UPDATE, false);
325325

326326
assertEquals(Arrays.asList("foo", "bar"), docMapperBefore.mappers().getMapper("copy_test").copyTo().copyToFields());
327327

328-
DocumentMapper docMapperAfter = mapperService.merge("type1", new CompressedXContent(mappingAfter), false, false);
328+
DocumentMapper docMapperAfter = mapperService.merge("type1", new CompressedXContent(mappingAfter), MapperService.MergeReason.MAPPING_UPDATE, false);
329329

330330
assertEquals(Arrays.asList("baz", "bar"), docMapperAfter.mappers().getMapper("copy_test").copyTo().copyToFields());
331331
assertEquals(Arrays.asList("foo", "bar"), docMapperBefore.mappers().getMapper("copy_test").copyTo().copyToFields());

0 commit comments

Comments
 (0)