25
25
import org .apache .lucene .analysis .Analyzer ;
26
26
import org .apache .lucene .analysis .DelegatingAnalyzerWrapper ;
27
27
import org .apache .lucene .index .Term ;
28
+ import org .elasticsearch .Assertions ;
28
29
import org .elasticsearch .ElasticsearchGenerationException ;
29
30
import org .elasticsearch .Version ;
30
31
import org .elasticsearch .cluster .metadata .IndexMetaData ;
@@ -192,8 +193,8 @@ public static Map<String, Object> parseMapping(NamedXContentRegistry xContentReg
192
193
/**
193
194
* Update mapping by only merging the metadata that is different between received and stored entries
194
195
*/
195
- public boolean updateMapping (IndexMetaData indexMetaData ) throws IOException {
196
- assert indexMetaData .getIndex ().equals (index ()) : "index mismatch: expected " + index () + " but was " + indexMetaData .getIndex ();
196
+ public boolean updateMapping (final IndexMetaData currentIndexMetaData , final IndexMetaData newIndexMetaData ) throws IOException {
197
+ assert newIndexMetaData .getIndex ().equals (index ()) : "index mismatch: expected " + index () + " but was " + newIndexMetaData .getIndex ();
197
198
// go over and add the relevant mappings (or update them)
198
199
Set <String > existingMappers = new HashSet <>();
199
200
if (mapper != null ) {
@@ -205,17 +206,19 @@ public boolean updateMapping(IndexMetaData indexMetaData) throws IOException {
205
206
final Map <String , DocumentMapper > updatedEntries ;
206
207
try {
207
208
// only update entries if needed
208
- updatedEntries = internalMerge (indexMetaData , MergeReason .MAPPING_RECOVERY , true );
209
+ updatedEntries = internalMerge (newIndexMetaData , MergeReason .MAPPING_RECOVERY , true );
209
210
} catch (Exception e ) {
210
211
logger .warn (() -> new ParameterizedMessage ("[{}] failed to apply mappings" , index ()), e );
211
212
throw e ;
212
213
}
213
214
214
215
boolean requireRefresh = false ;
215
216
217
+ assertMappingVersion (currentIndexMetaData , newIndexMetaData , updatedEntries );
218
+
216
219
for (DocumentMapper documentMapper : updatedEntries .values ()) {
217
220
String mappingType = documentMapper .type ();
218
- CompressedXContent incomingMappingSource = indexMetaData .mapping (mappingType ).source ();
221
+ CompressedXContent incomingMappingSource = newIndexMetaData .mapping (mappingType ).source ();
219
222
220
223
String op = existingMappers .contains (mappingType ) ? "updated" : "added" ;
221
224
if (logger .isDebugEnabled () && incomingMappingSource .compressed ().length < 512 ) {
@@ -240,6 +243,43 @@ public boolean updateMapping(IndexMetaData indexMetaData) throws IOException {
240
243
return requireRefresh ;
241
244
}
242
245
246
+ private void assertMappingVersion (
247
+ final IndexMetaData currentIndexMetaData ,
248
+ final IndexMetaData newIndexMetaData ,
249
+ final Map <String , DocumentMapper > updatedEntries ) {
250
+ if (Assertions .ENABLED && currentIndexMetaData != null ) {
251
+ if (currentIndexMetaData .getMappingVersion () == newIndexMetaData .getMappingVersion ()) {
252
+ // if the mapping version is unchanged, then there should not be any updates and all mappings should be the same
253
+ assert updatedEntries .isEmpty () : updatedEntries ;
254
+ for (final ObjectCursor <MappingMetaData > mapping : newIndexMetaData .getMappings ().values ()) {
255
+ final CompressedXContent currentSource = currentIndexMetaData .mapping (mapping .value .type ()).source ();
256
+ final CompressedXContent newSource = mapping .value .source ();
257
+ assert currentSource .equals (newSource ) :
258
+ "expected current mapping [" + currentSource + "] for type [" + mapping .value .type () + "] "
259
+ + "to be the same as new mapping [" + newSource + "]" ;
260
+ }
261
+ } else {
262
+ // if the mapping version is changed, it should increase, there should be updates, and the mapping should be different
263
+ final long currentMappingVersion = currentIndexMetaData .getMappingVersion ();
264
+ final long newMappingVersion = newIndexMetaData .getMappingVersion ();
265
+ assert currentMappingVersion < newMappingVersion :
266
+ "expected current mapping version [" + currentMappingVersion + "] "
267
+ + "to be less than new mapping version [" + newMappingVersion + "]" ;
268
+ assert updatedEntries .isEmpty () == false ;
269
+ for (final DocumentMapper documentMapper : updatedEntries .values ()) {
270
+ final MappingMetaData currentMapping = currentIndexMetaData .mapping (documentMapper .type ());
271
+ if (currentMapping != null ) {
272
+ final CompressedXContent currentSource = currentMapping .source ();
273
+ final CompressedXContent newSource = documentMapper .mappingSource ();
274
+ assert currentSource .equals (newSource ) == false :
275
+ "expected current mapping [" + currentSource + "] for type [" + documentMapper .type () + "] " +
276
+ "to be different than new mapping" ;
277
+ }
278
+ }
279
+ }
280
+ }
281
+ }
282
+
243
283
public void merge (Map <String , Map <String , Object >> mappings , MergeReason reason ) {
244
284
Map <String , CompressedXContent > mappingSourcesCompressed = new LinkedHashMap <>(mappings .size ());
245
285
for (Map .Entry <String , Map <String , Object >> entry : mappings .entrySet ()) {
0 commit comments