Skip to content

Commit 9aa1f28

Browse files
author
Christoph Büscher
committed
Add unit test for AnalysisRegistry#reloadIndexAnalyzers
1 parent 97f1c58 commit 9aa1f28

File tree

4 files changed

+80
-25
lines changed

4 files changed

+80
-25
lines changed

server/src/main/java/org/elasticsearch/index/analysis/AnalysisRegistry.java

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
import java.io.Closeable;
3636
import java.io.IOException;
37+
import java.util.ArrayList;
3738
import java.util.Arrays;
3839
import java.util.Collections;
3940
import java.util.HashMap;
@@ -46,7 +47,6 @@
4647
import java.util.concurrent.ConcurrentHashMap;
4748
import java.util.function.Function;
4849
import java.util.stream.Collectors;
49-
import java.util.stream.Stream;
5050

5151
import static java.util.Collections.unmodifiableMap;
5252

@@ -535,24 +535,27 @@ private void processNormalizerFactory(
535535
}
536536

537537
/**
538-
* Create an new IndexAnalyzer instance based on the existing one. Analyzers that are in {@link AnalysisMode#SEARCH_TIME} are tried to
539-
* be reloaded. All other analyzers are reused from the old {@link IndexAnalyzers} instance.
538+
* Creates an new IndexAnalyzer instance based on the existing one passed in. If there are no analysis components that need reloading,
539+
* the same instance of {@link IndexAnalyzers} is returned. Otherwise, analyzers that are in {@link AnalysisMode#SEARCH_TIME} are tried
540+
* to be reloaded. All other analyzers are reused from the old {@link IndexAnalyzers} instance.
540541
*/
541-
public IndexAnalyzers rebuildIndexAnalyzers(IndexAnalyzers indexAnalyzers, IndexSettings indexSettings) throws IOException {
542-
542+
public IndexAnalyzers reloadIndexAnalyzers(IndexAnalyzers indexAnalyzers, IndexSettings indexSettings) throws IOException {
543543
// scan analyzers to collect token filters that we need to reload
544-
List<NamedAnalyzer> analyzers = Stream.concat(
545-
Stream.of(indexAnalyzers.getDefaultSearchAnalyzer(), indexAnalyzers.getDefaultIndexAnalyzer()),
546-
indexAnalyzers.getAnalyzers().values().stream()).collect(Collectors.toList());
547-
544+
Map<String, NamedAnalyzer> oldAnalyzers = indexAnalyzers.getAnalyzers();
545+
List<NamedAnalyzer> analyzers = new ArrayList<>(oldAnalyzers.values());
546+
analyzers.add(indexAnalyzers.getDefaultIndexAnalyzer());
547+
analyzers.add(indexAnalyzers.getDefaultSearchAnalyzer());
548548
Set<String> filtersThatNeedReloading = filtersThatNeedReloading(analyzers);
549-
final Map<String, Settings> tokenFiltersToReloading = indexSettings.getSettings().getGroups(INDEX_ANALYSIS_FILTER)
549+
if (filtersThatNeedReloading.size() == 0) {
550+
return indexAnalyzers;
551+
}
552+
final Map<String, Settings> tokenFiltersToReload = indexSettings.getSettings().getGroups(INDEX_ANALYSIS_FILTER)
550553
.entrySet().stream()
551554
.filter(entry -> filtersThatNeedReloading.contains(entry.getKey()))
552555
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
553556

554557
final Map<String, TokenFilterFactory> newTokenFilterFactories = buildMapping(Component.FILTER, indexSettings,
555-
tokenFiltersToReloading, this.tokenFilters, prebuiltAnalysis.preConfiguredTokenFilters);
558+
tokenFiltersToReload, this.tokenFilters, prebuiltAnalysis.preConfiguredTokenFilters);
556559

557560
// fill the rest of the token filter factory map with the entries that are missing (were not reloaded)
558561
for (Entry<String, TokenFilterFactory> entry : indexAnalyzers.getTokenFilterFactoryFactories().entrySet()) {
@@ -567,9 +570,10 @@ public IndexAnalyzers rebuildIndexAnalyzers(IndexAnalyzers indexAnalyzers, Index
567570
NamedAnalyzer newDefaultSearchQuoteAnalyzer = rebuildIfNecessary(indexAnalyzers.getDefaultSearchQuoteAnalyzer(), indexSettings,
568571
currentCharFilterFactories, currentTokenizerFactories, newTokenFilterFactories);
569572
Map<String, NamedAnalyzer> newAnalyzers = new HashMap<>();
570-
for (NamedAnalyzer analyzer : indexAnalyzers.getAnalyzers().values()) {
571-
newAnalyzers.put(analyzer.name(), rebuildIfNecessary(analyzer, indexSettings, currentCharFilterFactories,
572-
currentTokenizerFactories, newTokenFilterFactories));
573+
for (String analyzerName : oldAnalyzers.keySet()) {
574+
NamedAnalyzer analyzer = rebuildIfNecessary(oldAnalyzers.get(analyzerName), indexSettings, currentCharFilterFactories,
575+
currentTokenizerFactories, newTokenFilterFactories);
576+
newAnalyzers.put(analyzerName, analyzer);
573577
}
574578

575579
IndexAnalysisProviders analysisProviders = new IndexAnalysisProviders(currentTokenizerFactories, currentCharFilterFactories,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,7 @@ public synchronized void reloadSearchAnalyzers(AnalysisRegistry registry) th
852852
logger.info("reloading search analyzers");
853853

854854
// refresh indexAnalyzers and search analyzers
855-
this.indexAnalyzers = registry.rebuildIndexAnalyzers(this.indexAnalyzers, indexSettings);
855+
this.indexAnalyzers = registry.reloadIndexAnalyzers(this.indexAnalyzers, indexSettings);
856856
this.searchAnalyzer = new MapperAnalyzerWrapper(this.indexAnalyzers.getDefaultSearchAnalyzer(), p -> p.searchAnalyzer());
857857
this.searchQuoteAnalyzer = new MapperAnalyzerWrapper(this.indexAnalyzers.getDefaultSearchQuoteAnalyzer(),
858858
p -> p.searchQuoteAnalyzer());

server/src/test/java/org/elasticsearch/index/analysis/AnalysisRegistryTests.java

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -325,12 +325,6 @@ public void testRebuildIfNecessary() throws IOException {
325325
assertSame(noReloadingEither, AnalysisRegistry.rebuildIfNecessary(noReloadingEither, null, null, null, null));
326326

327327

328-
Settings indexSettings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)
329-
.put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1).put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 1)
330-
.put("index.analysis.analyzer.reloadableAnalyzer.type", "custom")
331-
.put("index.analysis.analyzer.reloadableAnalyzer.tokenizer", "standard")
332-
.putList("index.analysis.analyzer.reloadableAnalyzer.filter", "myReloadableFilter").build();
333-
334328
final AtomicInteger factoryCounter = new AtomicInteger(0);
335329
TestAnalysis testAnalysis = createTestAnalysis(new Index("test", "_na_"), Settings.EMPTY, new AnalysisPlugin() {
336330

@@ -351,9 +345,14 @@ public TokenFilterFactory get(IndexSettings indexSettings, Environment environme
351345
tokenFilters[0] = testAnalysis.tokenFilter.get("myReloadableFilter");
352346
NamedAnalyzer reloadableAnalyzer = new NamedAnalyzer("reloadableAnalyzer", AnalyzerScope.INDEX,
353347
new CustomAnalyzer("tokenizer", null, null, tokenFilters));
354-
IndexSettings indexSetings = new IndexSettings(IndexMetaData.builder("testIndex").settings(indexSettings).build(), indexSettings);
348+
Settings settings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)
349+
.put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1).put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 1)
350+
.put("index.analysis.analyzer.reloadableAnalyzer.type", "custom")
351+
.put("index.analysis.analyzer.reloadableAnalyzer.tokenizer", "standard")
352+
.putList("index.analysis.analyzer.reloadableAnalyzer.filter", "myReloadableFilter").build();
353+
IndexSettings indexSettings = new IndexSettings(IndexMetaData.builder("testIndex").settings(settings).build(), settings);
355354

356-
NamedAnalyzer rebuilt = AnalysisRegistry.rebuildIfNecessary(reloadableAnalyzer, indexSetings, testAnalysis.charFilter,
355+
NamedAnalyzer rebuilt = AnalysisRegistry.rebuildIfNecessary(reloadableAnalyzer, indexSettings, testAnalysis.charFilter,
357356
testAnalysis.tokenizer, testAnalysis.tokenFilter);
358357
assertEquals(reloadableAnalyzer.name(), rebuilt.name());
359358
assertNotSame(reloadableAnalyzer, rebuilt);
@@ -363,12 +362,62 @@ public TokenFilterFactory get(IndexSettings indexSettings, Environment environme
363362
assertEquals(2, MyReloadableFilter.constructorCounter);
364363
}
365364

365+
public void testRebuildIndexAnalyzers() throws IOException {
366+
367+
final AtomicInteger factoryCounter = new AtomicInteger(0);
368+
AnalysisPlugin testPlugin = new AnalysisPlugin() {
369+
370+
@Override
371+
public Map<String, AnalysisProvider<TokenFilterFactory>> getTokenFilters() {
372+
return Collections.singletonMap("myReloadableFilter", new AnalysisProvider<TokenFilterFactory>() {
373+
374+
@Override
375+
public TokenFilterFactory get(IndexSettings indexSettings, Environment environment, String name, Settings settings)
376+
throws IOException {
377+
factoryCounter.getAndIncrement();
378+
return new MyReloadableFilter();
379+
}
380+
});
381+
}
382+
};
383+
384+
Settings settings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)
385+
.put(Environment.PATH_HOME_SETTING.getKey(), createTempDir().toString())
386+
.put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1).put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 1)
387+
.put("index.analysis.analyzer.reloadableAnalyzer.type", "custom")
388+
.put("index.analysis.analyzer.reloadableAnalyzer.tokenizer", "standard")
389+
.putList("index.analysis.analyzer.reloadableAnalyzer.filter", "myReloadableFilter").build();
390+
AnalysisModule analysisModule = new AnalysisModule(TestEnvironment.newEnvironment(settings), singletonList(testPlugin));
391+
AnalysisRegistry registry = analysisModule.getAnalysisRegistry();
392+
IndexSettings indexSettings = new IndexSettings(IndexMetaData.builder("testIndex").settings(settings).build(), settings);
393+
IndexAnalyzers oldIndexAnalyzers = registry.build(indexSettings);
394+
assertEquals(1, factoryCounter.get());
395+
396+
IndexAnalyzers rebuildAnalyzers = registry.reloadIndexAnalyzers(oldIndexAnalyzers, indexSettings);
397+
assertNotSame(oldIndexAnalyzers, rebuildAnalyzers);
398+
assertEquals(2, factoryCounter.get());
399+
assertSame(oldIndexAnalyzers.getDefaultIndexAnalyzer(), rebuildAnalyzers.getDefaultIndexAnalyzer());
400+
assertSame(oldIndexAnalyzers.getDefaultSearchAnalyzer(), rebuildAnalyzers.getDefaultSearchAnalyzer());
401+
assertSame(oldIndexAnalyzers.getDefaultSearchQuoteAnalyzer(), rebuildAnalyzers.getDefaultSearchQuoteAnalyzer());
402+
assertNotSame(oldIndexAnalyzers.getAnalyzers(), rebuildAnalyzers.getAnalyzers());
403+
assertEquals(oldIndexAnalyzers.getAnalyzers().size(), rebuildAnalyzers.getAnalyzers().size());
404+
NamedAnalyzer oldVersion = oldIndexAnalyzers.get("reloadableAnalyzer");
405+
NamedAnalyzer newVersion = rebuildAnalyzers.get("reloadableAnalyzer");
406+
assertNotSame(oldVersion, newVersion);
407+
assertThat(((CustomAnalyzer) oldVersion.analyzer()).tokenFilters()[0], instanceOf(MyReloadableFilter.class));
408+
assertEquals(1, ((MyReloadableFilter) ((CustomAnalyzer) oldVersion.analyzer()).tokenFilters()[0]).generation);
409+
assertThat(((CustomAnalyzer) newVersion.analyzer()).tokenFilters()[0], instanceOf(MyReloadableFilter.class));
410+
assertEquals(2, ((MyReloadableFilter) ((CustomAnalyzer) newVersion.analyzer()).tokenFilters()[0]).generation);
411+
}
412+
366413
static class MyReloadableFilter implements TokenFilterFactory {
367414

368415
static int constructorCounter = 0;
416+
private final int generation;
369417

370418
MyReloadableFilter() {
371419
constructorCounter++;
420+
generation = constructorCounter;
372421
}
373422

374423
@Override
@@ -378,11 +427,12 @@ public String name() {
378427

379428
@Override
380429
public TokenStream create(TokenStream tokenStream) {
381-
return null;
430+
return tokenStream;
382431
}
383432
@Override
384433
public AnalysisMode getAnalysisMode() {
385434
return AnalysisMode.SEARCH_TIME;
386435
}
387-
};
436+
}
437+
388438
}

test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.carrotsearch.randomizedtesting.generators.RandomPicks;
3030
import com.carrotsearch.randomizedtesting.generators.RandomStrings;
3131
import com.carrotsearch.randomizedtesting.rules.TestRuleAdapter;
32+
3233
import org.apache.logging.log4j.Level;
3334
import org.apache.logging.log4j.LogManager;
3435
import org.apache.logging.log4j.Logger;

0 commit comments

Comments
 (0)