From 8b1c25e11f6ee73e1165861c4eefa33706c4f2fd Mon Sep 17 00:00:00 2001 From: David Pilato Date: Thu, 6 Feb 2014 09:26:07 +0100 Subject: [PATCH] Upgrading analysis plugins fails When an analysis plugins provides default index settings using `PreBuiltAnalyzerProviderFactory`, `PreBuiltTokenFilterFactoryFactory` or `PreBuiltTokenizerFactoryFactory` it fails when upgrading it with elasticsearch superior or equal to 0.90.5. Related issue: #4936 Fix is needed in core. But, in the meantime, analysis plugins developers can fix that issue by overloading default prebuilt factories. For example: ```java public class StempelAnalyzerProviderFactory extends PreBuiltAnalyzerProviderFactory { private final PreBuiltAnalyzerProvider analyzerProvider; public StempelAnalyzerProviderFactory(String name, AnalyzerScope scope, Analyzer analyzer) { super(name, scope, analyzer); analyzerProvider = new PreBuiltAnalyzerProvider(name, scope, analyzer); } @Override public AnalyzerProvider create(String name, Settings settings) { return analyzerProvider; } public Analyzer analyzer() { return analyzerProvider.get(); } } ``` And instead of: ```java @Inject public PolishIndicesAnalysis(Settings settings, IndicesAnalysisService indicesAnalysisService) { super(settings); indicesAnalysisService.analyzerProviderFactories().put("polish", new PreBuiltAnalyzerProviderFactory("polish", AnalyzerScope.INDICES, new PolishAnalyzer(Lucene.ANALYZER_VERSION))); } ``` do ```java @Inject public PolishIndicesAnalysis(Settings settings, IndicesAnalysisService indicesAnalysisService) { super(settings); indicesAnalysisService.analyzerProviderFactories().put("polish", new StempelAnalyzerProviderFactory("polish", AnalyzerScope.INDICES, new PolishAnalyzer(Lucene.ANALYZER_VERSION))); } ``` Closes #5030 --- .../PreBuiltAnalyzerProviderFactory.java | 9 +-- .../PreBuiltCharFilterFactoryFactory.java | 9 +-- .../PreBuiltTokenFilterFactoryFactory.java | 9 +-- .../PreBuiltTokenizerFactoryFactory.java | 10 ++-- .../indices/analysis/PreBuiltAnalyzers.java | 15 +++++ .../indices/analysis/PreBuiltCharFilters.java | 13 +++++ .../analysis/PreBuiltTokenFilters.java | 12 ++++ .../indices/analysis/PreBuiltTokenizers.java | 12 ++++ .../DummyAnalysisBinderProcessor.java | 47 ++++++++++++++++ .../indices/analysis/DummyAnalysisPlugin.java | 55 +++++++++++++++++++ .../indices/analysis/DummyAnalyzer.java | 37 +++++++++++++ .../analysis/DummyAnalyzerProvider.java | 41 ++++++++++++++ .../analysis/DummyCharFilterFactory.java | 36 ++++++++++++ .../analysis/DummyIndicesAnalysis.java | 43 +++++++++++++++ .../analysis/DummyIndicesAnalysisModule.java | 30 ++++++++++ .../analysis/DummyTokenFilterFactory.java | 33 +++++++++++ .../analysis/DummyTokenizerFactory.java | 37 +++++++++++++ .../PreBuiltAnalyzerIntegrationTests.java | 47 ++++++++++++++++ 18 files changed, 478 insertions(+), 17 deletions(-) create mode 100644 src/test/java/org/elasticsearch/indices/analysis/DummyAnalysisBinderProcessor.java create mode 100644 src/test/java/org/elasticsearch/indices/analysis/DummyAnalysisPlugin.java create mode 100644 src/test/java/org/elasticsearch/indices/analysis/DummyAnalyzer.java create mode 100644 src/test/java/org/elasticsearch/indices/analysis/DummyAnalyzerProvider.java create mode 100644 src/test/java/org/elasticsearch/indices/analysis/DummyCharFilterFactory.java create mode 100644 src/test/java/org/elasticsearch/indices/analysis/DummyIndicesAnalysis.java create mode 100644 src/test/java/org/elasticsearch/indices/analysis/DummyIndicesAnalysisModule.java create mode 100644 src/test/java/org/elasticsearch/indices/analysis/DummyTokenFilterFactory.java create mode 100644 src/test/java/org/elasticsearch/indices/analysis/DummyTokenizerFactory.java diff --git a/src/main/java/org/elasticsearch/index/analysis/PreBuiltAnalyzerProviderFactory.java b/src/main/java/org/elasticsearch/index/analysis/PreBuiltAnalyzerProviderFactory.java index 0a2affc4210..05342ba16e4 100644 --- a/src/main/java/org/elasticsearch/index/analysis/PreBuiltAnalyzerProviderFactory.java +++ b/src/main/java/org/elasticsearch/index/analysis/PreBuiltAnalyzerProviderFactory.java @@ -25,8 +25,6 @@ import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.indices.analysis.PreBuiltAnalyzers; -import java.util.Locale; - /** * */ @@ -42,8 +40,11 @@ public class PreBuiltAnalyzerProviderFactory implements AnalyzerProviderFactory public AnalyzerProvider create(String name, Settings settings) { Version indexVersion = settings.getAsVersion(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT); if (!Version.CURRENT.equals(indexVersion)) { - Analyzer analyzer = PreBuiltAnalyzers.valueOf(name.toUpperCase(Locale.ROOT)).getAnalyzer(indexVersion); - return new PreBuiltAnalyzerProvider(name, AnalyzerScope.INDICES, analyzer); + PreBuiltAnalyzers preBuiltAnalyzers = PreBuiltAnalyzers.getOrDefault(name, null); + if (preBuiltAnalyzers != null) { + Analyzer analyzer = preBuiltAnalyzers.getAnalyzer(indexVersion); + return new PreBuiltAnalyzerProvider(name, AnalyzerScope.INDICES, analyzer); + } } return analyzerProvider; diff --git a/src/main/java/org/elasticsearch/index/analysis/PreBuiltCharFilterFactoryFactory.java b/src/main/java/org/elasticsearch/index/analysis/PreBuiltCharFilterFactoryFactory.java index 47dfeae60bb..107bee1883e 100644 --- a/src/main/java/org/elasticsearch/index/analysis/PreBuiltCharFilterFactoryFactory.java +++ b/src/main/java/org/elasticsearch/index/analysis/PreBuiltCharFilterFactoryFactory.java @@ -24,8 +24,6 @@ import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.indices.analysis.PreBuiltCharFilters; -import java.util.Locale; - public class PreBuiltCharFilterFactoryFactory implements CharFilterFactoryFactory { private final CharFilterFactory charFilterFactory; @@ -38,9 +36,12 @@ public class PreBuiltCharFilterFactoryFactory implements CharFilterFactoryFactor public CharFilterFactory create(String name, Settings settings) { Version indexVersion = settings.getAsVersion(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT); if (!Version.CURRENT.equals(indexVersion)) { - return PreBuiltCharFilters.valueOf(name.toUpperCase(Locale.ROOT)).getCharFilterFactory(indexVersion); + PreBuiltCharFilters preBuiltCharFilters = PreBuiltCharFilters.getOrDefault(name, null); + if (preBuiltCharFilters != null) { + return preBuiltCharFilters.getCharFilterFactory(indexVersion); + } } return charFilterFactory; } -} \ No newline at end of file +} diff --git a/src/main/java/org/elasticsearch/index/analysis/PreBuiltTokenFilterFactoryFactory.java b/src/main/java/org/elasticsearch/index/analysis/PreBuiltTokenFilterFactoryFactory.java index b056f93819b..9c89268d2bc 100644 --- a/src/main/java/org/elasticsearch/index/analysis/PreBuiltTokenFilterFactoryFactory.java +++ b/src/main/java/org/elasticsearch/index/analysis/PreBuiltTokenFilterFactoryFactory.java @@ -24,8 +24,6 @@ import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.indices.analysis.PreBuiltTokenFilters; -import java.util.Locale; - public class PreBuiltTokenFilterFactoryFactory implements TokenFilterFactoryFactory { private final TokenFilterFactory tokenFilterFactory; @@ -38,8 +36,11 @@ public class PreBuiltTokenFilterFactoryFactory implements TokenFilterFactoryFact public TokenFilterFactory create(String name, Settings settings) { Version indexVersion = settings.getAsVersion(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT); if (!Version.CURRENT.equals(indexVersion)) { - return PreBuiltTokenFilters.valueOf(name.toUpperCase(Locale.ROOT)).getTokenFilterFactory(indexVersion); + PreBuiltTokenFilters preBuiltTokenFilters = PreBuiltTokenFilters.getOrDefault(name, null); + if (preBuiltTokenFilters != null) { + return preBuiltTokenFilters.getTokenFilterFactory(indexVersion); + } } return tokenFilterFactory; } -} \ No newline at end of file +} diff --git a/src/main/java/org/elasticsearch/index/analysis/PreBuiltTokenizerFactoryFactory.java b/src/main/java/org/elasticsearch/index/analysis/PreBuiltTokenizerFactoryFactory.java index 3e5b47307e0..4ee66b1d0f3 100644 --- a/src/main/java/org/elasticsearch/index/analysis/PreBuiltTokenizerFactoryFactory.java +++ b/src/main/java/org/elasticsearch/index/analysis/PreBuiltTokenizerFactoryFactory.java @@ -24,8 +24,6 @@ import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.indices.analysis.PreBuiltTokenizers; -import java.util.Locale; - public class PreBuiltTokenizerFactoryFactory implements TokenizerFactoryFactory { private final TokenizerFactory tokenizerFactory; @@ -38,10 +36,12 @@ public class PreBuiltTokenizerFactoryFactory implements TokenizerFactoryFactory public TokenizerFactory create(String name, Settings settings) { Version indexVersion = settings.getAsVersion(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT); if (!Version.CURRENT.equals(indexVersion)) { - TokenizerFactory versionedTokenizerFactory = PreBuiltTokenizers.valueOf(name.toUpperCase(Locale.ROOT)).getTokenizerFactory(indexVersion); - return versionedTokenizerFactory; + PreBuiltTokenizers preBuiltTokenizers = PreBuiltTokenizers.getOrDefault(name, null); + if (preBuiltTokenizers != null) { + return preBuiltTokenizers.getTokenizerFactory(indexVersion); + } } return tokenizerFactory; } -} \ No newline at end of file +} diff --git a/src/main/java/org/elasticsearch/indices/analysis/PreBuiltAnalyzers.java b/src/main/java/org/elasticsearch/indices/analysis/PreBuiltAnalyzers.java index 0f5599795a7..a5aae82d849 100644 --- a/src/main/java/org/elasticsearch/indices/analysis/PreBuiltAnalyzers.java +++ b/src/main/java/org/elasticsearch/indices/analysis/PreBuiltAnalyzers.java @@ -65,6 +65,8 @@ import org.elasticsearch.common.regex.Regex; import org.elasticsearch.index.analysis.StandardHtmlStripAnalyzer; import org.elasticsearch.indices.analysis.PreBuiltCacheFactory.CachingStrategy; +import java.util.Locale; + /** * */ @@ -401,4 +403,17 @@ public enum PreBuiltAnalyzers { return analyzer; } + /** + * Get a pre built Analyzer by its name or fallback to the default one + * @param name Analyzer name + * @param defaultAnalyzer default Analyzer if name not found + */ + public static PreBuiltAnalyzers getOrDefault(String name, PreBuiltAnalyzers defaultAnalyzer) { + try { + return valueOf(name.toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException e) { + return defaultAnalyzer; + } + } + } diff --git a/src/main/java/org/elasticsearch/indices/analysis/PreBuiltCharFilters.java b/src/main/java/org/elasticsearch/indices/analysis/PreBuiltCharFilters.java index 70eea07b3b4..3e8647892e5 100644 --- a/src/main/java/org/elasticsearch/indices/analysis/PreBuiltCharFilters.java +++ b/src/main/java/org/elasticsearch/indices/analysis/PreBuiltCharFilters.java @@ -67,4 +67,17 @@ public enum PreBuiltCharFilters { return charFilterFactory; } + + /** + * Get a pre built CharFilter by its name or fallback to the default one + * @param name CharFilter name + * @param defaultCharFilter default CharFilter if name not found + */ + public static PreBuiltCharFilters getOrDefault(String name, PreBuiltCharFilters defaultCharFilter) { + try { + return valueOf(name.toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException e) { + return defaultCharFilter; + } + } } diff --git a/src/main/java/org/elasticsearch/indices/analysis/PreBuiltTokenFilters.java b/src/main/java/org/elasticsearch/indices/analysis/PreBuiltTokenFilters.java index 1d7ae7662bb..ce195a8aa59 100644 --- a/src/main/java/org/elasticsearch/indices/analysis/PreBuiltTokenFilters.java +++ b/src/main/java/org/elasticsearch/indices/analysis/PreBuiltTokenFilters.java @@ -309,4 +309,16 @@ public enum PreBuiltTokenFilters { return factory; } + /** + * Get a pre built TokenFilter by its name or fallback to the default one + * @param name TokenFilter name + * @param defaultTokenFilter default TokenFilter if name not found + */ + public static PreBuiltTokenFilters getOrDefault(String name, PreBuiltTokenFilters defaultTokenFilter) { + try { + return valueOf(name.toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException e) { + return defaultTokenFilter; + } + } } diff --git a/src/main/java/org/elasticsearch/indices/analysis/PreBuiltTokenizers.java b/src/main/java/org/elasticsearch/indices/analysis/PreBuiltTokenizers.java index baa4c874e52..96438a8a066 100644 --- a/src/main/java/org/elasticsearch/indices/analysis/PreBuiltTokenizers.java +++ b/src/main/java/org/elasticsearch/indices/analysis/PreBuiltTokenizers.java @@ -151,4 +151,16 @@ public enum PreBuiltTokenizers { return tokenizerFactory; } + /** + * Get a pre built Tokenizer by its name or fallback to the default one + * @param name Tokenizer name + * @param defaultTokenizer default Tokenizer if name not found + */ + public static PreBuiltTokenizers getOrDefault(String name, PreBuiltTokenizers defaultTokenizer) { + try { + return valueOf(name.toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException e) { + return defaultTokenizer; + } + } } diff --git a/src/test/java/org/elasticsearch/indices/analysis/DummyAnalysisBinderProcessor.java b/src/test/java/org/elasticsearch/indices/analysis/DummyAnalysisBinderProcessor.java new file mode 100644 index 00000000000..fdb5ab05bde --- /dev/null +++ b/src/test/java/org/elasticsearch/indices/analysis/DummyAnalysisBinderProcessor.java @@ -0,0 +1,47 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.indices.analysis; + +import org.elasticsearch.index.analysis.AnalysisModule; + +/** + */ +public class DummyAnalysisBinderProcessor extends AnalysisModule.AnalysisBinderProcessor { + + @Override + public void processAnalyzers(AnalyzersBindings analyzersBindings) { + analyzersBindings.processAnalyzer("dummy", DummyAnalyzerProvider.class); + } + + @Override + public void processTokenFilters(TokenFiltersBindings tokenFiltersBindings) { + tokenFiltersBindings.processTokenFilter("dummy_token_filter", DummyTokenFilterFactory.class); + } + + @Override + public void processTokenizers(TokenizersBindings tokenizersBindings) { + tokenizersBindings.processTokenizer("dummy_tokenizer", DummyTokenizerFactory.class); + } + + @Override + public void processCharFilters(CharFiltersBindings charFiltersBindings) { + charFiltersBindings.processCharFilter("dummy_char_filter", DummyCharFilterFactory.class); + } +} diff --git a/src/test/java/org/elasticsearch/indices/analysis/DummyAnalysisPlugin.java b/src/test/java/org/elasticsearch/indices/analysis/DummyAnalysisPlugin.java new file mode 100644 index 00000000000..55d22eb8c91 --- /dev/null +++ b/src/test/java/org/elasticsearch/indices/analysis/DummyAnalysisPlugin.java @@ -0,0 +1,55 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.indices.analysis; + +import com.google.common.collect.ImmutableList; +import org.elasticsearch.common.inject.Module; +import org.elasticsearch.index.analysis.AnalysisModule; +import org.elasticsearch.plugins.AbstractPlugin; + +import java.util.Collection; + +public class DummyAnalysisPlugin extends AbstractPlugin { + /** + * The name of the plugin. + */ + @Override + public String name() { + return "analysis-dummy"; + } + + /** + * The description of the plugin. + */ + @Override + public String description() { + return "Analysis Dummy Plugin"; + } + + @Override + public Collection> modules() { + return ImmutableList.>of(DummyIndicesAnalysisModule.class); + } + + public void onModule(AnalysisModule module) { + module.addProcessor(new DummyAnalysisBinderProcessor()); + } + +} diff --git a/src/test/java/org/elasticsearch/indices/analysis/DummyAnalyzer.java b/src/test/java/org/elasticsearch/indices/analysis/DummyAnalyzer.java new file mode 100644 index 00000000000..d413096174d --- /dev/null +++ b/src/test/java/org/elasticsearch/indices/analysis/DummyAnalyzer.java @@ -0,0 +1,37 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.indices.analysis; + +import org.apache.lucene.analysis.util.StopwordAnalyzerBase; +import org.apache.lucene.util.Version; + +import java.io.Reader; + +public class DummyAnalyzer extends StopwordAnalyzerBase { + + protected DummyAnalyzer(Version version) { + super(version); + } + + @Override + protected TokenStreamComponents createComponents(String fieldName, Reader reader) { + return null; + } +} diff --git a/src/test/java/org/elasticsearch/indices/analysis/DummyAnalyzerProvider.java b/src/test/java/org/elasticsearch/indices/analysis/DummyAnalyzerProvider.java new file mode 100644 index 00000000000..0c4b48bb403 --- /dev/null +++ b/src/test/java/org/elasticsearch/indices/analysis/DummyAnalyzerProvider.java @@ -0,0 +1,41 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.indices.analysis; + +import org.elasticsearch.common.lucene.Lucene; +import org.elasticsearch.index.analysis.AnalyzerProvider; +import org.elasticsearch.index.analysis.AnalyzerScope; + +public class DummyAnalyzerProvider implements AnalyzerProvider { + @Override + public String name() { + return "dummy"; + } + + @Override + public AnalyzerScope scope() { + return AnalyzerScope.INDICES; + } + + @Override + public DummyAnalyzer get() { + return new DummyAnalyzer(Lucene.ANALYZER_VERSION); + } +} diff --git a/src/test/java/org/elasticsearch/indices/analysis/DummyCharFilterFactory.java b/src/test/java/org/elasticsearch/indices/analysis/DummyCharFilterFactory.java new file mode 100644 index 00000000000..8c5896e59ec --- /dev/null +++ b/src/test/java/org/elasticsearch/indices/analysis/DummyCharFilterFactory.java @@ -0,0 +1,36 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.indices.analysis; + +import org.elasticsearch.index.analysis.CharFilterFactory; + +import java.io.Reader; + +public class DummyCharFilterFactory implements CharFilterFactory { + @Override + public String name() { + return "dummy_char_filter"; + } + + @Override + public Reader create(Reader reader) { + return null; + } +} diff --git a/src/test/java/org/elasticsearch/indices/analysis/DummyIndicesAnalysis.java b/src/test/java/org/elasticsearch/indices/analysis/DummyIndicesAnalysis.java new file mode 100644 index 00000000000..c48edb11d36 --- /dev/null +++ b/src/test/java/org/elasticsearch/indices/analysis/DummyIndicesAnalysis.java @@ -0,0 +1,43 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.indices.analysis; + +import org.elasticsearch.common.component.AbstractComponent; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.lucene.Lucene; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.index.analysis.*; + +public class DummyIndicesAnalysis extends AbstractComponent { + + @Inject + public DummyIndicesAnalysis(Settings settings, IndicesAnalysisService indicesAnalysisService) { + super(settings); + indicesAnalysisService.analyzerProviderFactories().put("dummy", + new PreBuiltAnalyzerProviderFactory("dummy", AnalyzerScope.INDICES, + new DummyAnalyzer(Lucene.ANALYZER_VERSION))); + indicesAnalysisService.tokenFilterFactories().put("dummy_token_filter", + new PreBuiltTokenFilterFactoryFactory(new DummyTokenFilterFactory())); + indicesAnalysisService.charFilterFactories().put("dummy_char_filter", + new PreBuiltCharFilterFactoryFactory(new DummyCharFilterFactory())); + indicesAnalysisService.tokenizerFactories().put("dummy_tokenizer", + new PreBuiltTokenizerFactoryFactory(new DummyTokenizerFactory())); + } +} diff --git a/src/test/java/org/elasticsearch/indices/analysis/DummyIndicesAnalysisModule.java b/src/test/java/org/elasticsearch/indices/analysis/DummyIndicesAnalysisModule.java new file mode 100644 index 00000000000..9d14f67ec60 --- /dev/null +++ b/src/test/java/org/elasticsearch/indices/analysis/DummyIndicesAnalysisModule.java @@ -0,0 +1,30 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.indices.analysis; + +import org.elasticsearch.common.inject.AbstractModule; + +public class DummyIndicesAnalysisModule extends AbstractModule { + + @Override + protected void configure() { + bind(DummyIndicesAnalysis.class).asEagerSingleton(); + } +} diff --git a/src/test/java/org/elasticsearch/indices/analysis/DummyTokenFilterFactory.java b/src/test/java/org/elasticsearch/indices/analysis/DummyTokenFilterFactory.java new file mode 100644 index 00000000000..489e4dce7b8 --- /dev/null +++ b/src/test/java/org/elasticsearch/indices/analysis/DummyTokenFilterFactory.java @@ -0,0 +1,33 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.indices.analysis; + +import org.apache.lucene.analysis.TokenStream; +import org.elasticsearch.index.analysis.TokenFilterFactory; + +public class DummyTokenFilterFactory implements TokenFilterFactory { + @Override public String name() { + return "dummy_token_filter"; + } + + @Override public TokenStream create(TokenStream tokenStream) { + return null; + } +} diff --git a/src/test/java/org/elasticsearch/indices/analysis/DummyTokenizerFactory.java b/src/test/java/org/elasticsearch/indices/analysis/DummyTokenizerFactory.java new file mode 100644 index 00000000000..95c6a5ed582 --- /dev/null +++ b/src/test/java/org/elasticsearch/indices/analysis/DummyTokenizerFactory.java @@ -0,0 +1,37 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.indices.analysis; + +import org.apache.lucene.analysis.Tokenizer; +import org.elasticsearch.index.analysis.TokenizerFactory; + +import java.io.Reader; + +public class DummyTokenizerFactory implements TokenizerFactory { + @Override + public String name() { + return "dummy_tokenizer"; + } + + @Override + public Tokenizer create(Reader reader) { + return null; + } +} diff --git a/src/test/java/org/elasticsearch/indices/analysis/PreBuiltAnalyzerIntegrationTests.java b/src/test/java/org/elasticsearch/indices/analysis/PreBuiltAnalyzerIntegrationTests.java index b7b880d53bf..af5df68249e 100644 --- a/src/test/java/org/elasticsearch/indices/analysis/PreBuiltAnalyzerIntegrationTests.java +++ b/src/test/java/org/elasticsearch/indices/analysis/PreBuiltAnalyzerIntegrationTests.java @@ -16,6 +16,7 @@ * specific language governing permissions and limitations * under the License. */ + package org.elasticsearch.indices.analysis; import com.google.common.collect.Lists; @@ -41,8 +42,17 @@ import static org.hamcrest.Matchers.notNullValue; /** * */ +@ElasticsearchIntegrationTest.ClusterScope(scope = ElasticsearchIntegrationTest.Scope.SUITE) public class PreBuiltAnalyzerIntegrationTests extends ElasticsearchIntegrationTest { + @Override + protected Settings nodeSettings(int nodeOrdinal) { + return ImmutableSettings.settingsBuilder() + .put("plugin.types", DummyAnalysisPlugin.class.getName()) + .put(super.nodeSettings(nodeOrdinal)) + .build(); + } + @Test public void testThatPreBuiltAnalyzersAreNotClosedOnIndexClose() throws Exception { Map> loadedAnalyzers = Maps.newHashMap(); @@ -108,6 +118,43 @@ public class PreBuiltAnalyzerIntegrationTests extends ElasticsearchIntegrationTe assertLuceneAnalyzersAreNotClosed(loadedAnalyzers); } + /** + * Test case for #5030: Upgrading analysis plugins fails + * See https://github.com/elasticsearch/elasticsearch/issues/5030 + */ + @Test + public void testThatPluginAnalyzersCanBeUpdated() throws Exception { + final XContentBuilder mapping = jsonBuilder().startObject() + .startObject("type") + .startObject("properties") + .startObject("foo") + .field("type", "string") + .field("analyzer", "dummy") + .endObject() + .startObject("bar") + .field("type", "string") + .field("analyzer", "my_dummy") + .endObject() + .endObject() + .endObject() + .endObject(); + + Settings versionSettings = ImmutableSettings.builder() + .put(IndexMetaData.SETTING_VERSION_CREATED, randomVersion()) + .put("index.analysis.analyzer.my_dummy.type", "custom") + .put("index.analysis.analyzer.my_dummy.filter", "my_dummy_token_filter") + .put("index.analysis.analyzer.my_dummy.char_filter", "my_dummy_char_filter") + .put("index.analysis.analyzer.my_dummy.tokenizer", "my_dummy_tokenizer") + .put("index.analysis.tokenizer.my_dummy_tokenizer.type", "dummy_tokenizer") + .put("index.analysis.filter.my_dummy_token_filter.type", "dummy_token_filter") + .put("index.analysis.char_filter.my_dummy_char_filter.type", "dummy_char_filter") + .build(); + + client().admin().indices().prepareCreate("test-analysis-dummy").addMapping("type", mapping).setSettings(versionSettings).get(); + + ensureGreen(); + } + private void assertThatAnalyzersHaveBeenLoaded(Map> expectedLoadedAnalyzers) { for (Map.Entry> entry : expectedLoadedAnalyzers.entrySet()) { for (Version version : entry.getValue()) {