/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF 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.apache.geode.cache.lucene;
import org.apache.geode.cache.RegionShortcut;
import org.apache.geode.cache.lucene.test.LuceneTestUtilities;
import org.apache.geode.test.dunit.SerializableRunnableIF;
import org.apache.geode.test.junit.categories.DistributedTest;
import org.apache.geode.util.test.TestUtil;
import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.core.KeywordAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import static org.apache.geode.cache.lucene.test.LuceneTestUtilities.*;
import static junitparams.JUnitParamsRunner.$;
import static org.junit.Assert.*;
@Category(DistributedTest.class)
@RunWith(JUnitParamsRunner.class)
public class LuceneIndexCreationDUnitTest extends LuceneDUnitTest {
@Override
protected void initDataStore(SerializableRunnableIF createIndex) throws Exception {
createIndex.run();
getCache().createRegionFactory(RegionShortcut.PARTITION).create(REGION_NAME);
}
@Test
@Parameters({"1", "2", "10"})
public void verifyThatIndexObjectsAreListedWhenPresentInTheSystem(int numberOfIndexes) {
SerializableRunnableIF createIndex = getMultipleIndexes(numberOfIndexes);
dataStore1.invoke(() -> initDataStore(createIndex));
dataStore1.invoke(() -> verifyIndexList(numberOfIndexes));
dataStore2.invoke(() -> initDataStore(createIndex));
dataStore2.invoke(() -> verifyIndexList(numberOfIndexes));
}
@Test
@Parameters({"1", "2", "10"})
public void verifyThatIndexObjectIsRetrievedWhenPresentInTheSystem(int numberOfIndexes) {
SerializableRunnableIF createIndex = getMultipleIndexes(numberOfIndexes);
dataStore1.invoke(() -> initDataStore(createIndex));
dataStore1.invoke(() -> verifyIndexes(numberOfIndexes));
dataStore2.invoke(() -> initDataStore(createIndex));
dataStore2.invoke(() -> verifyIndexes(numberOfIndexes));
}
@Test
public void verifyThatEmptyListIsOutputWhenThereAreNoIndexesInTheSystem() {
dataStore1.invoke(() -> verifyIndexList(0));
dataStore2.invoke(() -> verifyIndexList(0));
}
@Test
public void verifyNullIsReturnedWhenGetIndexIsCalledAndNoIndexesArePresent() {
dataStore1.invoke(() -> {
LuceneService luceneService = LuceneServiceProvider.get(getCache());
assertNull(luceneService.getIndex(INDEX_NAME, REGION_NAME));
});
dataStore2.invoke(() -> {
LuceneService luceneService = LuceneServiceProvider.get(getCache());
assertNull(luceneService.getIndex(INDEX_NAME, REGION_NAME));
});
}
@Test
public void verifyNullIsReturnedWhenGetIndexIsCalledWithNoMatchingIndex() {
SerializableRunnableIF createIndex = get2FieldsIndexes();
dataStore1.invoke(() -> createIndex);
dataStore2.invoke(() -> createIndex);
dataStore1.invoke(() -> {
LuceneService luceneService = LuceneServiceProvider.get(getCache());
assertNull(luceneService.getIndex(INDEX_NAME + "_A", REGION_NAME));
});
dataStore2.invoke(() -> {
LuceneService luceneService = LuceneServiceProvider.get(getCache());
assertNull(luceneService.getIndex(INDEX_NAME + "_A", REGION_NAME));
});
}
@Test
public void verifyDifferentFieldsFails() {
SerializableRunnableIF createIndex1 = getFieldsIndexWithOneField();
dataStore1.invoke(() -> initDataStore(createIndex1));
SerializableRunnableIF createIndex2 = getFieldsIndexWithTwoFields();
dataStore2
.invoke(() -> initDataStore(createIndex2, CANNOT_CREATE_LUCENE_INDEX_DIFFERENT_FIELDS));
}
@Test
public void verifyDifferentFieldAnalyzerSizesFails1() {
SerializableRunnableIF createIndex1 = getAnalyzersIndexWithTwoFields();
dataStore1.invoke(() -> initDataStore(createIndex1));
SerializableRunnableIF createIndex2 = getAnalyzersIndexWithOneField();
dataStore2
.invoke(() -> initDataStore(createIndex2, CANNOT_CREATE_LUCENE_INDEX_DIFFERENT_FIELDS_2));
}
@Test
public void verifyDifferentFieldAnalyzerSizesFails2() {
SerializableRunnableIF createIndex1 = getAnalyzersIndexWithOneField();
dataStore1.invoke(() -> initDataStore(createIndex1));
SerializableRunnableIF createIndex2 = getAnalyzersIndexWithTwoFields();
dataStore2
.invoke(() -> initDataStore(createIndex2, CANNOT_CREATE_LUCENE_INDEX_DIFFERENT_FIELDS));
}
@Test
public void verifyDifferentFieldAnalyzersFails1() {
SerializableRunnableIF createIndex1 = getAnalyzersIndexWithOneField(StandardAnalyzer.class);
dataStore1.invoke(() -> initDataStore(createIndex1));
SerializableRunnableIF createIndex2 = getAnalyzersIndexWithOneField(KeywordAnalyzer.class);
dataStore2.invoke(
() -> initDataStore(createIndex2, CANNOT_CREATE_LUCENE_INDEX_DIFFERENT_ANALYZERS_2));
}
@Test
public void verifyDifferentFieldAnalyzersFails2() {
SerializableRunnableIF createIndex1 = getAnalyzersIndexWithNullField1();
dataStore1.invoke(() -> initDataStore(createIndex1));
SerializableRunnableIF createIndex2 = getAnalyzersIndexWithNullField2();
dataStore2
.invoke(() -> initDataStore(createIndex2, CANNOT_CREATE_LUCENE_INDEX_DIFFERENT_ANALYZERS));
}
@Test
public void verifyDifferentFieldAnalyzersFails3() {
SerializableRunnableIF createIndex1 = getAnalyzersIndexWithNullField2();
dataStore1.invoke(() -> initDataStore(createIndex1));
SerializableRunnableIF createIndex2 = getAnalyzersIndexWithNullField1();
dataStore2.invoke(() -> initDataStore(createIndex2,
LuceneTestUtilities.CANNOT_CREATE_LUCENE_INDEX_DIFFERENT_ANALYZERS_3));
}
@Test
public void verifyDifferentIndexNamesFails() {
SerializableRunnableIF createIndex1 = () -> {
LuceneService luceneService = LuceneServiceProvider.get(getCache());
luceneService.createIndex(INDEX_NAME + "1", REGION_NAME, "field1");
};
dataStore1.invoke(() -> initDataStore(createIndex1));
SerializableRunnableIF createIndex2 = () -> {
LuceneService luceneService = LuceneServiceProvider.get(getCache());
luceneService.createIndex(INDEX_NAME + "2", REGION_NAME, "field1");
};
dataStore2
.invoke(() -> initDataStore(createIndex2, CANNOT_CREATE_LUCENE_INDEX_DIFFERENT_NAMES));
}
@Test
public void verifyDifferentIndexesFails1() {
SerializableRunnableIF createIndex1 = getFieldsIndexWithOneField();
dataStore1.invoke(() -> initDataStore(createIndex1));
SerializableRunnableIF createIndex2 = () -> {
/* Do nothing */};
dataStore2
.invoke(() -> initDataStore(createIndex2, CANNOT_CREATE_LUCENE_INDEX_DIFFERENT_INDEXES_1));
}
@Test
public void verifyDifferentIndexesFails2() {
SerializableRunnableIF createIndex1 = getFieldsIndexWithOneField();
dataStore1.invoke(() -> initDataStore(createIndex1));
SerializableRunnableIF createIndex2 = () -> {
LuceneService luceneService = LuceneServiceProvider.get(getCache());
luceneService.createIndex(INDEX_NAME, REGION_NAME, "field1");
luceneService.createIndex(INDEX_NAME + "2", REGION_NAME, "field2");
};
dataStore2
.invoke(() -> initDataStore(createIndex2, CANNOT_CREATE_LUCENE_INDEX_DIFFERENT_INDEXES_2));
}
@Test
public void verifyMemberWithoutIndexCreatedFirstFails() {
SerializableRunnableIF createIndex1 = () -> {
/* Do nothing */};
dataStore1.invoke(() -> initDataStore(createIndex1));
SerializableRunnableIF createIndex2 = getFieldsIndexWithOneField();
dataStore2
.invoke(() -> initDataStore(createIndex2, CANNOT_CREATE_LUCENE_INDEX_DIFFERENT_INDEXES_3));
}
@Test
@Parameters(method = "getIndexes")
public void verifySameIndexesSucceeds(SerializableRunnableIF createIndex) {
dataStore1.invoke(() -> initDataStore(createIndex));
dataStore2.invoke(() -> initDataStore(createIndex));
}
protected final Object[] getIndexes() {
return $(new Object[] {getFieldsIndexWithOneField()},
new Object[] {getFieldsIndexWithTwoFields()}, new Object[] {get2FieldsIndexes()},
new Object[] {getAnalyzersIndexWithOneField()},
new Object[] {getAnalyzersIndexWithTwoFields()},
new Object[] {getAnalyzersIndexWithNullField1()});
}
@Test
@Parameters(method = "getXmlAndExceptionMessages")
public void verifyXml(String cacheXmlFileBaseName, String exceptionMessage) {
dataStore1.invoke(() -> initCache(getXmlFileForTest(cacheXmlFileBaseName + ".1")));
dataStore2
.invoke(() -> initCache(getXmlFileForTest(cacheXmlFileBaseName + ".2"), exceptionMessage));
}
@Test
public void verifyXMLMultipleIndexList() {
dataStore1.invoke(() -> initCache(getXmlFileForTest("verifyXMLMultipleIndexList")));
dataStore2.invoke(() -> initCache(getXmlFileForTest("verifyXMLMultipleIndexList")));
dataStore1.invoke(() -> verifyIndexList(2));
dataStore2.invoke(() -> verifyIndexList(2));
}
@Test
public void verifyXMLMultipleIndexes() {
dataStore1.invoke(() -> initCache(getXmlFileForTest("verifyXMLMultipleIndexList")));
dataStore2.invoke(() -> initCache(getXmlFileForTest("verifyXMLMultipleIndexList")));
dataStore1.invoke(() -> verifyIndexes(2));
dataStore2.invoke(() -> verifyIndexes(2));
}
@Test
public void verifyXMLEmptyIndexList() {
dataStore1.invoke(() -> initCache(getXmlFileForTest("verifyXMLEmptyIndexList")));
dataStore2.invoke(() -> initCache(getXmlFileForTest("verifyXMLEmptyIndexList")));
dataStore1.invoke(() -> verifyIndexList(0));
dataStore2.invoke(() -> verifyIndexList(0));
}
protected final Object[] getXmlAndExceptionMessages() {
return $(
new Object[] {"verifyDifferentFieldsFails", CANNOT_CREATE_LUCENE_INDEX_DIFFERENT_FIELDS},
new Object[] {"verifyDifferentFieldAnalyzerSizesFails1",
CANNOT_CREATE_LUCENE_INDEX_DIFFERENT_FIELDS_2},
new Object[] {"verifyDifferentFieldAnalyzerSizesFails2",
CANNOT_CREATE_LUCENE_INDEX_DIFFERENT_FIELDS},
new Object[] {"verifyDifferentFieldAnalyzersFails1",
CANNOT_CREATE_LUCENE_INDEX_DIFFERENT_ANALYZERS_2},
// Currently setting a null analyzer is not a valid xml configuration: <lucene:field
// name="field2" analyzer="null"/>
// new Object[] { "verifyDifferentFieldAnalyzersFails2",
// CANNOT_CREATE_LUCENE_INDEX_DIFFERENT_ANALYZERS_1 },
// new Object[] { "verifyDifferentFieldAnalyzersFails3",
// CANNOT_CREATE_LUCENE_INDEX_DIFFERENT_ANALYZERS_2 },
new Object[] {"verifyDifferentIndexNamesFails", CANNOT_CREATE_LUCENE_INDEX_DIFFERENT_NAMES},
new Object[] {"verifyDifferentIndexesFails1",
CANNOT_CREATE_LUCENE_INDEX_DIFFERENT_INDEXES_1},
new Object[] {"verifyDifferentIndexesFails2",
CANNOT_CREATE_LUCENE_INDEX_DIFFERENT_INDEXES_2});
}
@Test
public void verifyStandardAnalyzerAndNullOnSameFieldPasses() {
SerializableRunnableIF createIndex1 = getAnalyzersIndexWithNullField1();
dataStore1.invoke(() -> initDataStore(createIndex1));
SerializableRunnableIF createIndex2 = getAnalyzersIndexWithTwoFields2();
dataStore2.invoke(() -> initDataStore(createIndex2));
}
@Test
public void verifyStandardAnalyzerAndNullOnSameFieldPasses2() {
SerializableRunnableIF createIndex1 = getAnalyzersIndexWithTwoFields2();
dataStore1.invoke(() -> initDataStore(createIndex1));
SerializableRunnableIF createIndex2 = getAnalyzersIndexWithNullField1();
dataStore2.invoke(() -> initDataStore(createIndex2));
}
protected String getXmlFileForTest(String testName) {
return TestUtil.getResourcePath(getClass(),
getClassSimpleName() + "." + testName + ".cache.xml");
}
protected String getClassSimpleName() {
return getClass().getSimpleName();
}
protected void initDataStore(SerializableRunnableIF createIndex, String message)
throws Exception {
createIndex.run();
try {
getCache().createRegionFactory(RegionShortcut.PARTITION).create(REGION_NAME);
fail("Should not have been able to create index");
} catch (IllegalStateException e) {
assertEquals(message, e.getMessage());
}
}
protected void initCache(String cacheXmlFileName) throws FileNotFoundException {
getCache().loadCacheXml(new FileInputStream(cacheXmlFileName));
}
protected void initCache(String cacheXmlFileName, String message) throws FileNotFoundException {
try {
getCache().loadCacheXml(new FileInputStream(cacheXmlFileName));
fail("Should not have been able to create cache");
} catch (IllegalStateException e) {
assertEquals(message, e.getMessage());
}
}
protected SerializableRunnableIF getFieldsIndexWithOneField() {
return () -> {
LuceneService luceneService = LuceneServiceProvider.get(getCache());
luceneService.createIndex(INDEX_NAME, REGION_NAME, "field1");
};
}
protected SerializableRunnableIF getFieldsIndexWithTwoFields() {
return () -> {
LuceneService luceneService = LuceneServiceProvider.get(getCache());
luceneService.createIndex(INDEX_NAME, REGION_NAME, "field1", "field2");
};
}
protected SerializableRunnableIF get2FieldsIndexes() {
return () -> {
LuceneService luceneService = LuceneServiceProvider.get(getCache());
luceneService.createIndex(INDEX_NAME + "_1", REGION_NAME, "field1");
luceneService.createIndex(INDEX_NAME + "_2", REGION_NAME, "field2");
};
}
protected SerializableRunnableIF getMultipleIndexes(final int numberOfIndexes) {
return () -> {
LuceneService luceneService = LuceneServiceProvider.get(getCache());
for (int count = 1; count <= numberOfIndexes; count++) {
luceneService.createIndex(INDEX_NAME + "_" + count, REGION_NAME, "field" + count);
}
};
}
protected void verifyIndexList(final int expectedSize) {
LuceneService luceneService = LuceneServiceProvider.get(getCache());
Collection<LuceneIndex> indexList = luceneService.getAllIndexes();
assertEquals(indexList.size(), expectedSize);
}
protected void verifyIndexes(final int numberOfIndexes) {
LuceneService luceneService = LuceneServiceProvider.get(getCache());
for (int count = 1; count <= numberOfIndexes; count++) {
assertEquals(luceneService.getIndex(INDEX_NAME + "_" + count, REGION_NAME).getName(),
INDEX_NAME + "_" + count);
}
}
protected SerializableRunnableIF getAnalyzersIndexWithNullField1() {
return () -> {
LuceneService luceneService = LuceneServiceProvider.get(getCache());
Map<String, Analyzer> analyzers = new HashMap<>();
analyzers.put("field1", null);
analyzers.put("field2", new KeywordAnalyzer());
luceneService.createIndex(INDEX_NAME, REGION_NAME, analyzers);
};
}
protected SerializableRunnableIF getAnalyzersIndexWithNullField2() {
return () -> {
LuceneService luceneService = LuceneServiceProvider.get(getCache());
Map<String, Analyzer> analyzers = new HashMap<>();
analyzers.put("field1", new KeywordAnalyzer());
analyzers.put("field2", null);
luceneService.createIndex(INDEX_NAME, REGION_NAME, analyzers);
};
}
protected SerializableRunnableIF getAnalyzersIndexWithOneField(
Class<? extends Analyzer> analyzerClass) {
return () -> {
LuceneService luceneService = LuceneServiceProvider.get(getCache());
Map<String, Analyzer> analyzers = new HashMap<>();
analyzers.put("field1", analyzerClass.newInstance());
luceneService.createIndex(INDEX_NAME, REGION_NAME, analyzers);
};
}
protected SerializableRunnableIF getAnalyzersIndexWithOneField() {
return () -> {
LuceneService luceneService = LuceneServiceProvider.get(getCache());
Map<String, Analyzer> analyzers = new HashMap<>();
analyzers.put("field1", new KeywordAnalyzer());
luceneService.createIndex(INDEX_NAME, REGION_NAME, analyzers);
};
}
protected SerializableRunnableIF getAnalyzersIndexWithTwoFields() {
return () -> {
LuceneService luceneService = LuceneServiceProvider.get(getCache());
Map<String, Analyzer> analyzers = new HashMap<>();
analyzers.put("field1", new KeywordAnalyzer());
analyzers.put("field2", new KeywordAnalyzer());
luceneService.createIndex(INDEX_NAME, REGION_NAME, analyzers);
};
}
protected SerializableRunnableIF getAnalyzersIndexWithTwoFields2() {
return () -> {
LuceneService luceneService = LuceneServiceProvider.get(getCache());
Map<String, Analyzer> analyzers = new HashMap<>();
analyzers.put("field1", new StandardAnalyzer());
analyzers.put("field2", new KeywordAnalyzer());
luceneService.createIndex(INDEX_NAME, REGION_NAME, analyzers);
};
}
}