DATAGEODE-14 - Improve IndexFactoryBean's resilience and options for handling GemFire IndexExistsExceptions and IndexNameConflictExceptions.
Related JIRA: https://jira.spring.io/browse/SGF-637 (cherry picked from commit e868c58db9d245adab005b6a5ae1cc0a94275cf3) Signed-off-by: John Blum <jblum@pivotal.io>
This commit is contained in:
@@ -16,25 +16,21 @@
|
||||
|
||||
package org.springframework.data.gemfire;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.sameInstance;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeCollection;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.apache.geode.cache.Cache;
|
||||
import org.apache.geode.cache.GemFireCache;
|
||||
import org.apache.geode.cache.query.Index;
|
||||
import org.apache.geode.cache.query.IndexExistsException;
|
||||
import org.apache.geode.cache.query.IndexNameConflictException;
|
||||
import org.apache.geode.cache.query.QueryService;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -43,26 +39,49 @@ import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* The IndexConflictsIntegrationTest class...
|
||||
* Integration tests with test cases testing the numerous conflicting {@link Index} configurations.
|
||||
*
|
||||
* An {@link IndexExistsException} is thrown when 2 or more {@link Index Indexes} share the same definition
|
||||
* but have different names.
|
||||
*
|
||||
* An {@link IndexNameConflictException} is thrown when 2 or more {@link Index Indexes} share the same name
|
||||
* but have potentially different definitions.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @link https://jira.spring.io/browse/SGF-432
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
* @see org.apache.geode.cache.query.Index
|
||||
* @see org.springframework.context.ConfigurableApplicationContext
|
||||
* @see org.springframework.context.annotation.Bean
|
||||
* @see org.springframework.context.annotation.Configuration
|
||||
* @see org.springframework.context.annotation.Import
|
||||
* @see <a href="https://jira.spring.io/browse/SGF-432">IndexFactoryBean traps IndexExistsException instead of IndexNameConflictException</a>
|
||||
* @see <a href="https://jira.spring.io/browse/SGF-637">Improve IndexFactoryBean's resilience and options for handling GemFire IndexExistsExceptions and IndexNameConflictExceptions</a>
|
||||
* @since 1.6.3
|
||||
*/
|
||||
public class IndexConflictsIntegrationTest {
|
||||
|
||||
protected void assertIndex(Index index, String expectedName, String expectedExpression, String expectedFromClause,
|
||||
private static final AtomicBoolean IGNORE = new AtomicBoolean(false);
|
||||
private static final AtomicBoolean OVERRIDE = new AtomicBoolean(false);
|
||||
|
||||
private ConfigurableApplicationContext applicationContext;
|
||||
|
||||
private void assertIndex(Index index, String expectedName, String expectedExpression, String expectedFromClause,
|
||||
IndexType expectedType) {
|
||||
|
||||
assertThat(index, is(notNullValue()));
|
||||
assertThat(index.getName(), is(equalTo(expectedName)));
|
||||
assertThat(index.getIndexedExpression(), is(equalTo(expectedExpression)));
|
||||
assertThat(index.getFromClause(), is(equalTo(expectedFromClause)));
|
||||
assertThat(IndexType.valueOf(index.getType()), is(equalTo(expectedType)));
|
||||
assertThat(index).isNotNull();
|
||||
assertThat(index.getName()).isEqualTo(expectedName);
|
||||
assertThat(index.getIndexedExpression()).isEqualTo(expectedExpression);
|
||||
assertThat(index.getFromClause()).isEqualTo(expectedFromClause);
|
||||
assertThat(IndexType.valueOf(index.getType())).isEqualTo(expectedType);
|
||||
}
|
||||
|
||||
protected boolean close(ConfigurableApplicationContext applicationContext) {
|
||||
private void assertIndexCount(int count) {
|
||||
assertThat(getIndexCount()).isEqualTo(count);
|
||||
}
|
||||
|
||||
private boolean close(ConfigurableApplicationContext applicationContext) {
|
||||
|
||||
if (applicationContext != null) {
|
||||
applicationContext.close();
|
||||
return !(applicationContext.isActive() || applicationContext.isRunning());
|
||||
@@ -71,185 +90,260 @@ public class IndexConflictsIntegrationTest {
|
||||
return true;
|
||||
}
|
||||
|
||||
private Index getIndex(String indexName) {
|
||||
|
||||
for (Index index : nullSafeCollection(getQueryService().getIndexes())) {
|
||||
if (index.getName().equalsIgnoreCase(indexName)) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private int getIndexCount() {
|
||||
return nullSafeCollection(getQueryService().getIndexes()).size();
|
||||
}
|
||||
|
||||
private QueryService getQueryService() {
|
||||
return this.applicationContext.getBean("gemfireCache", GemFireCache.class).getQueryService();
|
||||
}
|
||||
|
||||
private boolean hasIndex(String indexName) {
|
||||
return (getIndex(indexName) != null);
|
||||
}
|
||||
|
||||
private ConfigurableApplicationContext newApplicationContext(Class<?>... annotatedClasses) {
|
||||
return new AnnotationConfigApplicationContext(annotatedClasses);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
System.getProperties().remove("gemfire.cache.region.index.override");
|
||||
|
||||
assertThat(System.getProperties().containsKey("gemfire.cache.region.index.override"), is(false));
|
||||
assertThat(IGNORE.get()).isFalse();
|
||||
assertThat(OVERRIDE.get()).isFalse();
|
||||
}
|
||||
|
||||
@Test(expected = BeanCreationException.class)
|
||||
public void indexDefinitionConflictThrowsException() {
|
||||
ConfigurableApplicationContext applicationContext = null;
|
||||
@After
|
||||
public void tearDown() {
|
||||
|
||||
OVERRIDE.set(false);
|
||||
IGNORE.set(false);
|
||||
|
||||
assertThat(close(this.applicationContext)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void indexDefinitionConflictIgnoresIndex() {
|
||||
|
||||
assertThat(IGNORE.compareAndSet(false, true)).isTrue();
|
||||
|
||||
this.applicationContext = newApplicationContext(IndexDefinitionConflictConfiguration.class);
|
||||
|
||||
assertThat(this.applicationContext.containsBean("customerIdIndex")).isTrue();
|
||||
assertThat(this.applicationContext.containsBean("customerIdentifierIndex")).isTrue();
|
||||
assertIndexCount(1);
|
||||
assertThat(hasIndex("customerIdIndex")).isTrue();
|
||||
assertThat(hasIndex("customerIdentifierIndex")).isFalse();
|
||||
|
||||
Index customersIdIndex = getIndex("customerIdIndex");
|
||||
|
||||
assertIndex(customersIdIndex, "customerIdIndex",
|
||||
"id", "/Customers", IndexType.PRIMARY_KEY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void indexDefinitionConflictOverridesIndex() {
|
||||
|
||||
assertThat(OVERRIDE.compareAndSet(false, true)).isTrue();
|
||||
|
||||
this.applicationContext = newApplicationContext(IndexDefinitionConflictConfiguration.class);
|
||||
|
||||
assertThat(this.applicationContext.containsBean("customerIdIndex")).isTrue();
|
||||
assertThat(this.applicationContext.containsBean("customerIdentifierIndex")).isTrue();
|
||||
assertIndexCount(1);
|
||||
assertThat(hasIndex("customerIdIndex")).isFalse();
|
||||
assertThat(hasIndex("customerIdentifierIndex")).isTrue();
|
||||
|
||||
Index customersIdentifierIndex = getIndex("customerIdentifierIndex");
|
||||
|
||||
assertIndex(customersIdentifierIndex, "customerIdentifierIndex",
|
||||
"id", "/Customers", IndexType.PRIMARY_KEY);
|
||||
}
|
||||
|
||||
@Test(expected = IndexExistsException.class)
|
||||
public void indexDefinitionConflictThrowsIndexExistsException() throws Throwable {
|
||||
try {
|
||||
applicationContext = new AnnotationConfigApplicationContext(
|
||||
IndexDefinitionConflictGemFireConfiguration.class);
|
||||
this.applicationContext = newApplicationContext(IndexDefinitionConflictConfiguration.class);
|
||||
}
|
||||
catch (BeanCreationException expected) {
|
||||
assertThat(expected.getMessage(), containsString("Error creating bean with name 'customerIdentityIndex'"
|
||||
+ " defined in org.springframework.data.gemfire.IndexConflictsIntegrationTest$IndexDefinitionConflictGemFireConfiguration:"
|
||||
+ " Invocation of init method failed"));
|
||||
assertThat(expected.getCause(), is(instanceOf(GemfireIndexException.class)));
|
||||
assertThat(expected.getCause().getMessage(),
|
||||
containsString("An Index with a different name having the same definition"
|
||||
+ " as this Index (customerIdentityIndex) already exists"));
|
||||
assertThat(expected.getCause().getCause(), is(instanceOf(IndexExistsException.class)));
|
||||
assertThat(expected.getCause().getCause().getMessage(), is(equalTo("Similar Index Exists")));
|
||||
|
||||
throw expected;
|
||||
}
|
||||
finally {
|
||||
assertThat(close(applicationContext), is(true));
|
||||
assertThat(expected).hasMessageStartingWith("Error creating bean with name 'customerIdentifierIndex'");
|
||||
|
||||
assertThat(expected).hasCauseInstanceOf(GemfireIndexException.class);
|
||||
|
||||
String existingIndexDefinition = String.format(IndexFactoryBean.BASIC_INDEX_DEFINITION,
|
||||
"id", "/Customers", IndexType.PRIMARY_KEY);
|
||||
|
||||
assertThat(expected.getCause()).hasMessageStartingWith(String.format(
|
||||
"An Index with a different name [customerIdIndex] having the same definition [%s] already exists",
|
||||
existingIndexDefinition));
|
||||
|
||||
assertThat(expected.getCause()).hasCauseInstanceOf(IndexExistsException.class);
|
||||
|
||||
assertThat(expected.getCause().getCause()).hasMessage("Similar Index Exists");
|
||||
|
||||
assertThat(expected.getCause().getCause()).hasNoCause();
|
||||
|
||||
throw expected.getCause().getCause();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void indexNameConflictOverridesExistingIndex() {
|
||||
ConfigurableApplicationContext applicationContext = null;
|
||||
public void indexNameConflictIgnoresIndex() {
|
||||
|
||||
try {
|
||||
applicationContext = new AnnotationConfigApplicationContext(IndexNameConflictGemFireConfiguration.class);
|
||||
assertThat(IGNORE.compareAndSet(false, true)).isTrue();
|
||||
|
||||
assertThat(applicationContext.getBeansOfType(Index.class).size(), is(equalTo(2)));
|
||||
this.applicationContext = newApplicationContext(IndexNameConflictConfiguration.class);
|
||||
|
||||
Cache gemfireCache = applicationContext.getBean("gemfireCache", Cache.class);
|
||||
assertThat(this.applicationContext.containsBean("customerLastNameIndex")).isTrue();
|
||||
assertThat(this.applicationContext.containsBean("customerFirstNameIndex")).isTrue();
|
||||
assertIndexCount(1);
|
||||
assertThat(hasIndex(IndexNameConflictConfiguration.INDEX_NAME)).isTrue();
|
||||
|
||||
assertThat(gemfireCache.getQueryService().getIndexes().size(), is(equalTo(1)));
|
||||
Index customerLastNameIndex = getIndex(IndexNameConflictConfiguration.INDEX_NAME);
|
||||
|
||||
Index customerLastNameIndex = applicationContext.getBean("customerLastNameIndex", Index.class);
|
||||
|
||||
assertIndex(customerLastNameIndex, IndexNameConflictGemFireConfiguration.INDEX_NAME,
|
||||
"lastName", "/Customers", IndexType.HASH);
|
||||
|
||||
Index customerFirstNameIndex = applicationContext.getBean("customerFirstNameIndex", Index.class);
|
||||
|
||||
assertIndex(customerFirstNameIndex, IndexNameConflictGemFireConfiguration.INDEX_NAME,
|
||||
"firstName", "/Customers", IndexType.FUNCTIONAL);
|
||||
|
||||
assertThat(customerFirstNameIndex, is(not(sameInstance(customerLastNameIndex))));
|
||||
assertThat(gemfireCache.getQueryService().getIndexes().iterator().next(),
|
||||
is(sameInstance(customerFirstNameIndex)));
|
||||
}
|
||||
finally {
|
||||
assertThat(close(applicationContext), is(true));
|
||||
}
|
||||
assertIndex(customerLastNameIndex, IndexNameConflictConfiguration.INDEX_NAME,
|
||||
"lastName", "/Customers", IndexType.HASH);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void indexNameConflictReturnsExistingIndex() {
|
||||
ConfigurableApplicationContext applicationContext = null;
|
||||
public void indexNameConflictOverridesIndex() {
|
||||
|
||||
assertThat(OVERRIDE.compareAndSet(false, true)).isTrue();
|
||||
|
||||
this.applicationContext = newApplicationContext(IndexNameConflictConfiguration.class);
|
||||
|
||||
assertThat(this.applicationContext.getBeansOfType(Index.class)).hasSize(2);
|
||||
assertThat(this.applicationContext.containsBean("customerLastNameIndex")).isTrue();
|
||||
assertThat(this.applicationContext.containsBean("customerFirstNameIndex")).isTrue();
|
||||
assertIndexCount(1);
|
||||
assertThat(hasIndex(IndexNameConflictConfiguration.INDEX_NAME)).isTrue();
|
||||
|
||||
Index customerFirstNameIndex = getIndex(IndexNameConflictConfiguration.INDEX_NAME);
|
||||
|
||||
assertIndex(customerFirstNameIndex, IndexNameConflictConfiguration.INDEX_NAME,
|
||||
"firstName", "/Customers", IndexType.FUNCTIONAL);
|
||||
}
|
||||
|
||||
@Test(expected = IndexNameConflictException.class)
|
||||
public void indexNameConflictThrowsIndexNameConflictException() throws Throwable {
|
||||
try {
|
||||
System.setProperty("gemfire.cache.region.index.override", Boolean.FALSE.toString());
|
||||
|
||||
assertThat(System.getProperty("gemfire.cache.region.index.override", "true"),
|
||||
is(equalTo(Boolean.FALSE.toString())));
|
||||
|
||||
applicationContext = new AnnotationConfigApplicationContext(IndexNameConflictGemFireConfiguration.class);
|
||||
|
||||
assertThat(applicationContext.getBeansOfType(Index.class).size(), is(equalTo(2)));
|
||||
|
||||
Cache gemfireCache = applicationContext.getBean("gemfireCache", Cache.class);
|
||||
|
||||
assertThat(gemfireCache.getQueryService().getIndexes().size(), is(equalTo(1)));
|
||||
|
||||
Index customerLastNameIndex = applicationContext.getBean("customerLastNameIndex", Index.class);
|
||||
|
||||
assertIndex(customerLastNameIndex, IndexNameConflictGemFireConfiguration.INDEX_NAME,
|
||||
"lastName", "/Customers", IndexType.HASH);
|
||||
|
||||
Index customerFirstNameIndex = applicationContext.getBean("customerFirstNameIndex", Index.class);
|
||||
|
||||
assertIndex(customerFirstNameIndex, IndexNameConflictGemFireConfiguration.INDEX_NAME,
|
||||
"lastName", "/Customers", IndexType.HASH);
|
||||
|
||||
assertThat(customerFirstNameIndex, is(sameInstance(customerLastNameIndex)));
|
||||
assertThat(gemfireCache.getQueryService().getIndexes().iterator().next(),
|
||||
is(sameInstance(customerLastNameIndex)));
|
||||
this.applicationContext = newApplicationContext(IndexNameConflictConfiguration.class);
|
||||
}
|
||||
finally {
|
||||
System.getProperties().remove("gemfire.cache.region.index.override");
|
||||
catch (BeanCreationException expected) {
|
||||
|
||||
if (applicationContext != null) {
|
||||
applicationContext.close();
|
||||
}
|
||||
assertThat(expected).hasMessageStartingWith("Error creating bean with name 'customerFirstNameIndex'");
|
||||
|
||||
assertThat(expected).hasCauseInstanceOf(GemfireIndexException.class);
|
||||
|
||||
assertThat(expected.getCause()).hasMessageStartingWith(String.format(
|
||||
"An Index with the same name [%s] having possibly a different definition already exists;",
|
||||
IndexNameConflictConfiguration.INDEX_NAME));
|
||||
|
||||
assertThat(expected.getCause()).hasCauseInstanceOf(IndexNameConflictException.class);
|
||||
|
||||
assertThat(expected.getCause().getCause()).hasMessage(String.format("Index named ' %s ' already exists.",
|
||||
IndexNameConflictConfiguration.INDEX_NAME));
|
||||
|
||||
assertThat(expected.getCause().getCause()).hasNoCause();
|
||||
|
||||
throw expected.getCause().getCause();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@SuppressWarnings("unused")
|
||||
public static class BaseGemFireConfiguration {
|
||||
public static class GemFireConfiguration {
|
||||
|
||||
@Bean
|
||||
public Properties gemfireProperties() {
|
||||
|
||||
Properties gemfireProperties = new Properties();
|
||||
|
||||
gemfireProperties.setProperty("name", IndexConflictsIntegrationTest.class.getSimpleName());
|
||||
gemfireProperties.setProperty("mcast-port", "0");
|
||||
gemfireProperties.setProperty("log-level", "warning");
|
||||
|
||||
return gemfireProperties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CacheFactoryBean gemfireCache() {
|
||||
|
||||
CacheFactoryBean cacheFactoryBean = new CacheFactoryBean();
|
||||
|
||||
cacheFactoryBean.setClose(true);
|
||||
cacheFactoryBean.setProperties(gemfireProperties());
|
||||
cacheFactoryBean.setUseBeanFactoryLocator(false);
|
||||
|
||||
return cacheFactoryBean;
|
||||
}
|
||||
|
||||
@Bean(name = "Customers")
|
||||
public ReplicatedRegionFactoryBean customersRegion(Cache gemfireCache) {
|
||||
public ReplicatedRegionFactoryBean customersRegion(GemFireCache gemfireCache) {
|
||||
|
||||
ReplicatedRegionFactoryBean customersRegionFactory = new ReplicatedRegionFactoryBean();
|
||||
|
||||
customersRegionFactory.setCache(gemfireCache);
|
||||
customersRegionFactory.setName("Customers");
|
||||
customersRegionFactory.setClose(false);
|
||||
customersRegionFactory.setPersistent(false);
|
||||
|
||||
return customersRegionFactory;
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(BaseGemFireConfiguration.class)
|
||||
@Import(GemFireConfiguration.class)
|
||||
@SuppressWarnings("unused")
|
||||
public static class IndexDefinitionConflictGemFireConfiguration {
|
||||
public static class IndexDefinitionConflictConfiguration {
|
||||
|
||||
@Bean
|
||||
public IndexFactoryBean customerIdIndex(Cache gemfireCache) {
|
||||
public IndexFactoryBean customerIdIndex(GemFireCache gemfireCache) {
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
indexFactoryBean.setCache(gemfireCache);
|
||||
indexFactoryBean.setExpression("id");
|
||||
indexFactoryBean.setFrom("/Customers");
|
||||
indexFactoryBean.setType(IndexType.PRIMARY_KEY);
|
||||
|
||||
return indexFactoryBean;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@DependsOn("customerIdIndex")
|
||||
public IndexFactoryBean customerIdentityIndex(Cache gemfireCache) {
|
||||
public IndexFactoryBean customerIdentifierIndex(GemFireCache gemfireCache) {
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
indexFactoryBean.setCache(gemfireCache);
|
||||
indexFactoryBean.setExpression("id");
|
||||
indexFactoryBean.setIgnoreIfExists(IGNORE.get());
|
||||
indexFactoryBean.setFrom("/Customers");
|
||||
indexFactoryBean.setOverride(OVERRIDE.get());
|
||||
indexFactoryBean.setType(IndexType.PRIMARY_KEY);
|
||||
|
||||
return indexFactoryBean;
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(BaseGemFireConfiguration.class)
|
||||
@Import(GemFireConfiguration.class)
|
||||
@SuppressWarnings("unused")
|
||||
public static class IndexNameConflictGemFireConfiguration {
|
||||
public static class IndexNameConflictConfiguration {
|
||||
|
||||
protected static final String INDEX_NAME = "CustomerNameIdx";
|
||||
|
||||
@Bean
|
||||
public PropertyPlaceholderConfigurer propertyPlaceholderConfigurer() {
|
||||
return new PropertyPlaceholderConfigurer();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IndexFactoryBean customerLastNameIndex(Cache gemfireCache,
|
||||
@Value("${gemfire.cache.region.index.override:true}") boolean override) {
|
||||
public IndexFactoryBean customerLastNameIndex(GemFireCache gemfireCache) {
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
@@ -257,7 +351,6 @@ public class IndexConflictsIntegrationTest {
|
||||
indexFactoryBean.setExpression("lastName");
|
||||
indexFactoryBean.setFrom("/Customers");
|
||||
indexFactoryBean.setName(INDEX_NAME);
|
||||
indexFactoryBean.setOverride(override);
|
||||
indexFactoryBean.setType(IndexType.HASH);
|
||||
|
||||
return indexFactoryBean;
|
||||
@@ -265,20 +358,19 @@ public class IndexConflictsIntegrationTest {
|
||||
|
||||
@Bean
|
||||
@DependsOn("customerLastNameIndex")
|
||||
public IndexFactoryBean customerFirstNameIndex(Cache gemfireCache,
|
||||
@Value("${gemfire.cache.region.index.override:true}") boolean override) {
|
||||
public IndexFactoryBean customerFirstNameIndex(GemFireCache gemfireCache) {
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
indexFactoryBean.setCache(gemfireCache);
|
||||
indexFactoryBean.setExpression("firstName");
|
||||
indexFactoryBean.setFrom("/Customers");
|
||||
indexFactoryBean.setIgnoreIfExists(IGNORE.get());
|
||||
indexFactoryBean.setName(INDEX_NAME);
|
||||
indexFactoryBean.setOverride(override);
|
||||
indexFactoryBean.setOverride(OVERRIDE.get());
|
||||
indexFactoryBean.setType(IndexType.FUNCTIONAL);
|
||||
|
||||
return indexFactoryBean;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -28,7 +28,6 @@ import static org.mockito.Mockito.when;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -43,7 +42,10 @@ import org.apache.geode.cache.lucene.LuceneIndex;
|
||||
import org.apache.geode.cache.lucene.LuceneIndexFactory;
|
||||
import org.apache.geode.cache.lucene.LuceneService;
|
||||
import org.apache.geode.cache.query.Index;
|
||||
import org.apache.geode.cache.query.IndexExistsException;
|
||||
import org.apache.geode.cache.query.IndexNameConflictException;
|
||||
import org.apache.geode.cache.query.QueryService;
|
||||
import org.apache.geode.internal.concurrent.ConcurrentHashSet;
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
@@ -76,7 +78,7 @@ import org.springframework.data.gemfire.config.annotation.test.entities.Replicat
|
||||
*/
|
||||
public class EnableIndexingConfigurationUnitTests {
|
||||
|
||||
private static final Set<Index> indexes = new HashSet<>();
|
||||
private static final Set<Index> indexes = new ConcurrentHashSet<>();
|
||||
|
||||
private ConfigurableApplicationContext applicationContext;
|
||||
|
||||
@@ -102,16 +104,19 @@ public class EnableIndexingConfigurationUnitTests {
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected void assertIndex(Index index, String name, String expression, String from, IndexType indexType) {
|
||||
assertThat(index).isNotNull();
|
||||
assertThat(index.getName()).isEqualTo(name);
|
||||
assertThat(index.getIndexedExpression()).isEqualTo(expression);
|
||||
assertThat(index.getFromClause()).isEqualTo(from);
|
||||
assertThat(index.getType()).isEqualTo(indexType.getGemfireIndexType());
|
||||
private static Index findIndexByName(String indexName) {
|
||||
|
||||
for (Index index : indexes) {
|
||||
if (index.getName().equalsIgnoreCase(indexName)) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected void assertLuceneIndex(LuceneIndex index, String name, String regionPath, String... fields) {
|
||||
private void assertLuceneIndex(LuceneIndex index, String name, String regionPath, String... fields) {
|
||||
assertThat(index).isNotNull();
|
||||
assertThat(index.getName()).isEqualTo(name);
|
||||
assertThat(index.getRegionPath()).isEqualTo(regionPath);
|
||||
@@ -120,68 +125,87 @@ public class EnableIndexingConfigurationUnitTests {
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected ConfigurableApplicationContext newApplicationContext(Class<?>... annotatedClasses) {
|
||||
private void assertOqlIndex(Index index, String name, String expression, String from, IndexType indexType) {
|
||||
assertThat(index).isNotNull();
|
||||
assertThat(index.getName()).isEqualTo(name);
|
||||
assertThat(index.getIndexedExpression()).isEqualTo(expression);
|
||||
assertThat(index.getFromClause()).isEqualTo(from);
|
||||
assertThat(index.getType()).isEqualTo(indexType.getGemfireIndexType());
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
private ConfigurableApplicationContext newApplicationContext(Class<?>... annotatedClasses) {
|
||||
ConfigurableApplicationContext applicationContext = new AnnotationConfigApplicationContext(annotatedClasses);
|
||||
applicationContext.registerShutdownHook();
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistentEntityIndexesCreatedSuccessfully() {
|
||||
applicationContext = newApplicationContext(IndexedPersistentEntityConfiguration.class);
|
||||
public void persistentEntityIndexesAreCreated() {
|
||||
|
||||
applicationContext = newApplicationContext(IndexingEnabledWithIndexedPersistentEntityConfiguration.class);
|
||||
|
||||
assertLuceneIndexes(applicationContext);
|
||||
assertOqlIndexes(applicationContext);
|
||||
}
|
||||
|
||||
private void assertLuceneIndexes(ConfigurableApplicationContext applicationContext) {
|
||||
|
||||
LuceneIndex luceneIndex = applicationContext.getBean("TitleLuceneIdx", LuceneIndex.class);
|
||||
|
||||
assertLuceneIndex(luceneIndex, "TitleLuceneIdx", "Customers", "title");
|
||||
}
|
||||
|
||||
private void assertOqlIndexes(ConfigurableApplicationContext applicationContext) {
|
||||
Index customersIdIdx = applicationContext.getBean("CustomersIdKeyIdx", Index.class);
|
||||
|
||||
assertIndex(customersIdIdx, "CustomersIdKeyIdx", "id", "Customers", IndexType.KEY);
|
||||
Index customersIdIndex = applicationContext.getBean("CustomersIdKeyIdx", Index.class);
|
||||
|
||||
Index customersFirstNameIdx = applicationContext.getBean("CustomersFirstNameFunctionalIdx", Index.class);
|
||||
assertOqlIndex(customersIdIndex, "CustomersIdKeyIdx", "id", "Customers", IndexType.KEY);
|
||||
|
||||
assertIndex(customersFirstNameIdx, "CustomersFirstNameFunctionalIdx", "first_name",
|
||||
Index customersFirstNameIndex = applicationContext.getBean("CustomersFirstNameFunctionalIdx", Index.class);
|
||||
|
||||
assertOqlIndex(customersFirstNameIndex, "CustomersFirstNameFunctionalIdx", "first_name",
|
||||
"/LoyalCustomers", IndexType.FUNCTIONAL);
|
||||
|
||||
Index lastNameIdx = applicationContext.getBean("LastNameIdx", Index.class);
|
||||
Index lastNameIndex = applicationContext.getBean("LastNameIdx", Index.class);
|
||||
|
||||
assertIndex(lastNameIdx, "LastNameIdx", "surname", "Customers", IndexType.HASH);
|
||||
assertOqlIndex(lastNameIndex, "LastNameIdx", "surname", "Customers", IndexType.HASH);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistentEntityIndexesWillNotBeCreated() {
|
||||
applicationContext = newApplicationContext(NoIndexesCreatedForIndexedPersistentEntityConfiguration.class);
|
||||
public void persistentEntityIndexesAreNotCreated() {
|
||||
|
||||
applicationContext = newApplicationContext(IndexingNotEnabledWithIndexedPersistentEntityConfiguration.class);
|
||||
|
||||
Map<String, Index> indexes = applicationContext.getBeansOfType(Index.class);
|
||||
|
||||
assertThat(indexes).isNotNull();
|
||||
assertThat(indexes.isEmpty()).isTrue();
|
||||
assertThat(indexes).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void indexAnnotatedEntityPropertyDoesNotOverrideIndexBeanDefinition() {
|
||||
applicationContext = newApplicationContext(IndexAnnotatedEntityPropertyDoesNotOverrideBeanDefinitionConfiguration.class);
|
||||
public void indexAnnotatedEntityPropertyIsIgnoredWithExistingIndexHavingSameDefinition() {
|
||||
|
||||
Index lastNameIdx = applicationContext.getBean("LastNameIdx", Index.class);
|
||||
applicationContext = newApplicationContext(
|
||||
IndexAnnotatedEntityPropertyIsIgnoredWithExistingIndexHavingSameDefinitionConfiguration.class);
|
||||
|
||||
assertIndex(lastNameIdx, "LastNameIdx", "last_name", "/People", IndexType.HASH);
|
||||
}
|
||||
Index firstNameIndex = applicationContext.getBean("LoyalCustomersFirstNameFunctionalIdx", Index.class);
|
||||
|
||||
@Test
|
||||
public void indexAnnotatedEntityPropertyOverridesIndexBeanDefinition() {
|
||||
applicationContext = newApplicationContext(IndexAnnotatedEntityPropertyOverridesIndexBeanDefinitionConfiguration.class);
|
||||
|
||||
Index customersFirstNameIdx = applicationContext.getBean("CustomersFirstNameFunctionalIdx", Index.class);
|
||||
|
||||
assertIndex(customersFirstNameIdx, "CustomersFirstNameFunctionalIdx",
|
||||
assertOqlIndex(firstNameIndex, "LoyalCustomersFirstNameFunctionalIdx",
|
||||
"first_name", "/LoyalCustomers", IndexType.FUNCTIONAL);
|
||||
|
||||
assertThat(findIndexByName("CustomersFirstNameFunctionalIdx")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void indexAnnotatedEntityPropertyIsIgnoredWithExistingIndexHavingSameName() {
|
||||
|
||||
applicationContext = newApplicationContext(
|
||||
IndexAnnotatedEntityPropertyIsIgnoredWithExistingIndexHavingSameNameConfiguration.class);
|
||||
|
||||
Index lastNameIndex = applicationContext.getBean("LastNameIdx", Index.class);
|
||||
|
||||
assertOqlIndex(lastNameIndex, "LastNameIdx", "last_name", "/People", IndexType.HASH);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -195,10 +219,10 @@ public class EnableIndexingConfigurationUnitTests {
|
||||
}
|
||||
|
||||
Cache mockQueryService(Cache mockCache) throws Exception {
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class);
|
||||
|
||||
when(mockCache.getQueryService()).thenReturn(mockQueryService);
|
||||
when(mockQueryService.getIndexes()).thenReturn(indexes);
|
||||
|
||||
when(mockQueryService.createHashIndex(anyString(), anyString(), anyString()))
|
||||
.thenAnswer(new HashIndexAnswer());
|
||||
@@ -209,11 +233,24 @@ public class EnableIndexingConfigurationUnitTests {
|
||||
when(mockQueryService.createKeyIndex(anyString(), anyString(), anyString()))
|
||||
.thenAnswer(new KeyIndexAnswer());
|
||||
|
||||
when(mockQueryService.getIndexes()).thenReturn(indexes);
|
||||
|
||||
doAnswer(invocation -> {
|
||||
|
||||
Index indexToRemove = invocation.getArgument(0);
|
||||
|
||||
indexes.remove(findIndexByName(indexToRemove.getName()));
|
||||
|
||||
return null;
|
||||
|
||||
}).when(mockQueryService).removeIndex(any(Index.class));
|
||||
|
||||
return mockCache;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Cache mockRegionFactory(Cache mockCache) {
|
||||
|
||||
RegionFactory mockRegionFactory = mock(RegionFactory.class);
|
||||
|
||||
when(mockCache.createRegionFactory()).thenReturn(mockRegionFactory);
|
||||
@@ -273,16 +310,22 @@ public class EnableIndexingConfigurationUnitTests {
|
||||
|
||||
@Override
|
||||
public Index answer(InvocationOnMock invocation) throws Throwable {
|
||||
|
||||
IndexType indexType = getType();
|
||||
|
||||
String name = invocation.getArgument(0);
|
||||
String expression = invocation.getArgument(1);
|
||||
String from = invocation.getArgument(2);
|
||||
|
||||
validateIndexDefinition(name, expression, from, indexType);
|
||||
validateIndexName(name);
|
||||
|
||||
Index mockIndex = mock(Index.class, name);
|
||||
|
||||
when(mockIndex.getName()).thenReturn(name);
|
||||
when(mockIndex.getIndexedExpression()).thenReturn(expression);
|
||||
when(mockIndex.getFromClause()).thenReturn(from);
|
||||
when(mockIndex.getType()).thenReturn(getType().getGemfireIndexType());
|
||||
when(mockIndex.getType()).thenReturn(indexType.getGemfireIndexType());
|
||||
|
||||
indexes.add(mockIndex);
|
||||
|
||||
@@ -291,6 +334,30 @@ public class EnableIndexingConfigurationUnitTests {
|
||||
|
||||
abstract IndexType getType();
|
||||
|
||||
private void validateIndexDefinition(String name, String expression, String fromClause, IndexType type)
|
||||
throws IndexExistsException {
|
||||
|
||||
for (Index index : indexes) {
|
||||
if (index.getIndexedExpression().equalsIgnoreCase(expression)
|
||||
&& index.getFromClause().equalsIgnoreCase(fromClause)
|
||||
&& index.getType().equals(type.getGemfireIndexType())) {
|
||||
|
||||
throw new IndexExistsException(String.format(
|
||||
"Index [%1$s] has the same definition as existing Index [%2$s]",
|
||||
name, index.getName()));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validateIndexName(String name) throws IndexNameConflictException {
|
||||
|
||||
for (Index index : indexes) {
|
||||
if (index.getName().equalsIgnoreCase(name)) {
|
||||
throw new IndexNameConflictException(String.format("Index with name [%s] already exists", name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class FunctionalIndexAnswer extends AbstractIndexAnswer {
|
||||
@@ -322,7 +389,7 @@ public class EnableIndexingConfigurationUnitTests {
|
||||
excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {
|
||||
ClientRegionEntity.class, CollocatedPartitionRegionEntity.class, GenericRegionEntity.class,
|
||||
LocalRegionEntity.class, ReplicateRegionEntity.class }))
|
||||
static class IndexedPersistentEntityConfiguration extends GemFireConfiguration {
|
||||
private static class IndexingEnabledWithIndexedPersistentEntityConfiguration extends GemFireConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@@ -330,7 +397,7 @@ public class EnableIndexingConfigurationUnitTests {
|
||||
excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {
|
||||
ClientRegionEntity.class, CollocatedPartitionRegionEntity.class, GenericRegionEntity.class,
|
||||
LocalRegionEntity.class, ReplicateRegionEntity.class }))
|
||||
static class NoIndexesCreatedForIndexedPersistentEntityConfiguration extends GemFireConfiguration {
|
||||
private static class IndexingNotEnabledWithIndexedPersistentEntityConfiguration extends GemFireConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@@ -339,42 +406,46 @@ public class EnableIndexingConfigurationUnitTests {
|
||||
excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {
|
||||
ClientRegionEntity.class, CollocatedPartitionRegionEntity.class, GenericRegionEntity.class,
|
||||
LocalRegionEntity.class, ReplicateRegionEntity.class }))
|
||||
static class IndexAnnotatedEntityPropertyDoesNotOverrideBeanDefinitionConfiguration extends GemFireConfiguration {
|
||||
static class IndexAnnotatedEntityPropertyIsIgnoredWithExistingIndexHavingSameDefinitionConfiguration
|
||||
extends GemFireConfiguration {
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("unused")
|
||||
IndexFactoryBean firstNameIndex(GemFireCache gemfireCache) {
|
||||
|
||||
IndexFactoryBean firstNameIndex = new IndexFactoryBean();
|
||||
|
||||
firstNameIndex.setCache(gemfireCache);
|
||||
firstNameIndex.setName("LoyalCustomersFirstNameFunctionalIdx");
|
||||
firstNameIndex.setExpression("first_name");
|
||||
firstNameIndex.setFrom("/LoyalCustomers");
|
||||
firstNameIndex.setType(IndexType.FUNCTIONAL);
|
||||
|
||||
return firstNameIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@EnableIndexing
|
||||
@EnableEntityDefinedRegions(basePackageClasses = NonEntity.class,
|
||||
excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {
|
||||
ClientRegionEntity.class, CollocatedPartitionRegionEntity.class, GenericRegionEntity.class,
|
||||
LocalRegionEntity.class, ReplicateRegionEntity.class }))
|
||||
static class IndexAnnotatedEntityPropertyIsIgnoredWithExistingIndexHavingSameNameConfiguration
|
||||
extends GemFireConfiguration {
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("unused")
|
||||
IndexFactoryBean lastNameIndex(GemFireCache gemfireCache) {
|
||||
|
||||
IndexFactoryBean lastNameIndex = new IndexFactoryBean();
|
||||
|
||||
lastNameIndex.setCache(gemfireCache);
|
||||
lastNameIndex.setName("LastNameIdx");
|
||||
lastNameIndex.setExpression("last_name");
|
||||
lastNameIndex.setFrom("/People");
|
||||
lastNameIndex.setName("LastNameIdx");
|
||||
lastNameIndex.setType(IndexType.HASH);
|
||||
|
||||
return lastNameIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@EnableIndexing
|
||||
@EnableEntityDefinedRegions(basePackageClasses = NonEntity.class,
|
||||
excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {
|
||||
ClientRegionEntity.class, CollocatedPartitionRegionEntity.class, GenericRegionEntity.class,
|
||||
LocalRegionEntity.class, ReplicateRegionEntity.class }))
|
||||
static class IndexAnnotatedEntityPropertyOverridesIndexBeanDefinitionConfiguration extends GemFireConfiguration {
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("unused")
|
||||
IndexFactoryBean firstNameIndex(GemFireCache gemfireCache) {
|
||||
IndexFactoryBean firstNameIndex = new IndexFactoryBean();
|
||||
|
||||
firstNameIndex.setCache(gemfireCache);
|
||||
firstNameIndex.setExpression("given_name");
|
||||
firstNameIndex.setFrom("/ProspectiveCustomers");
|
||||
firstNameIndex.setName("CustomersFirstNameFunctionalIdx");
|
||||
firstNameIndex.setType(IndexType.HASH);
|
||||
|
||||
return firstNameIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public class PartitionRegionEntity {
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
@Indexed(expression = "first_name", from = "/LoyalCustomers", override = true, type = IndexType.FUNCTIONAL)
|
||||
@Indexed(expression = "first_name", from = "/LoyalCustomers", type = IndexType.FUNCTIONAL)
|
||||
private String firstName;
|
||||
|
||||
@Indexed(name = "LastNameIdx", expression = "surname")
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.data.gemfire.config.xml;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@@ -24,13 +25,16 @@ import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.query.Index;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.data.gemfire.IndexFactoryBean;
|
||||
import org.springframework.data.gemfire.test.GemfireTestApplicationContextInitializer;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* The IndexNamespaceTest is a test suite of test cases testing the functionality of GemFire Index creation using
|
||||
* the Spring Data GemFire XML namespace (XSD).
|
||||
* Integration tests with test cases testing the functionality of GemFire Index creation using
|
||||
* the Spring Data GemFire XML namespace (XSD) and the {@link IndexParser}.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author David Turanski
|
||||
@@ -42,30 +46,42 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration(locations="index-ns.xml", initializers=GemfireTestApplicationContextInitializer.class)
|
||||
@SuppressWarnings({ "deprecation", "unused" })
|
||||
public class IndexNamespaceTest {
|
||||
|
||||
private static final String TEST_REGION_NAME = "IndexedRegion";
|
||||
|
||||
@Resource(name = "simple")
|
||||
private Index simple;
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Resource(name = "basic")
|
||||
private Index basic;
|
||||
|
||||
@Resource(name = "complex")
|
||||
private Index complex;
|
||||
|
||||
@Test
|
||||
public void testBasicIndex() throws Exception {
|
||||
assertEquals("simple", simple.getName());
|
||||
assertEquals("status", simple.getIndexedExpression());
|
||||
assertEquals(Region.SEPARATOR + TEST_REGION_NAME, simple.getFromClause());
|
||||
assertEquals(TEST_REGION_NAME, simple.getRegion().getName());
|
||||
assertEquals(org.apache.geode.cache.query.IndexType.FUNCTIONAL, simple.getType());
|
||||
public void basicIndexIsCorrect() throws Exception {
|
||||
assertEquals("basic", basic.getName());
|
||||
assertEquals("status", basic.getIndexedExpression());
|
||||
assertEquals(Region.SEPARATOR + TEST_REGION_NAME, basic.getFromClause());
|
||||
assertEquals(TEST_REGION_NAME, basic.getRegion().getName());
|
||||
assertEquals(org.apache.geode.cache.query.IndexType.FUNCTIONAL, basic.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComplexIndex() throws Exception {
|
||||
public void basicIndexFactoryBeanIsCorrect() {
|
||||
|
||||
IndexFactoryBean basicIndexFactoryBean = applicationContext.getBean("&basic", IndexFactoryBean.class);
|
||||
|
||||
assertThat(basicIndexFactoryBean.isIgnoreIfExists()).isFalse();
|
||||
assertThat(basicIndexFactoryBean.isOverride()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void complexIndexIsCorrect() throws Exception {
|
||||
assertEquals("complex-index", complex.getName());
|
||||
assertEquals("tsi.name", complex.getIndexedExpression());
|
||||
assertEquals(Region.SEPARATOR + TEST_REGION_NAME + " tsi", complex.getFromClause());
|
||||
@@ -73,4 +89,13 @@ public class IndexNamespaceTest {
|
||||
assertEquals(org.apache.geode.cache.query.IndexType.HASH, complex.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void indexWithIgnoreAndOverrideIsCorrect() {
|
||||
|
||||
IndexFactoryBean indexFactoryBean =
|
||||
applicationContext.getBean("&index-with-ignore-and-override", IndexFactoryBean.class);
|
||||
|
||||
assertThat(indexFactoryBean.isIgnoreIfExists()).isTrue();
|
||||
assertThat(indexFactoryBean.isOverride()).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,6 +129,7 @@ public class LuceneOperationsIntegrationTests {
|
||||
|
||||
@Test
|
||||
public void findsDoctorDoesAsTypePersonSuccessfully() {
|
||||
|
||||
Collection<Person> doctorDoes = template.queryForValues("title: Doctor*", "title");
|
||||
|
||||
assertThat(doctorDoes).isNotNull();
|
||||
@@ -139,6 +140,7 @@ public class LuceneOperationsIntegrationTests {
|
||||
@Test
|
||||
@SuppressWarnings("all")
|
||||
public void findsMasterDoesAsTypeUserSuccessfully() {
|
||||
|
||||
List<User> masterDoes = template.query("title: Master*", "title", User.class);
|
||||
|
||||
assertThat(masterDoes).isNotNull();
|
||||
|
||||
@@ -133,6 +133,26 @@ public class AbstractFactoryBeanSupportUnitTests {
|
||||
verify(mockLog, times(1)).info(eq("info log test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void logsWarningWhenWarnIsEnabled() {
|
||||
when(mockLog.isWarnEnabled()).thenReturn(true);
|
||||
|
||||
factoryBeanSupport.logWarning("%s log test", "warn");
|
||||
|
||||
verify(mockLog, times(1)).isWarnEnabled();
|
||||
verify(mockLog, times(1)).warn(eq("warn log test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void logsWarningWhenErrorIsEnabled() {
|
||||
when(mockLog.isErrorEnabled()).thenReturn(true);
|
||||
|
||||
factoryBeanSupport.logError("%s log test", "error");
|
||||
|
||||
verify(mockLog, times(1)).isErrorEnabled();
|
||||
verify(mockLog, times(1)).error(eq("error log test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void suppressesDebugLoggingWhenDebugIsDisabled() {
|
||||
when(mockLog.isDebugEnabled()).thenReturn(false);
|
||||
@@ -153,6 +173,26 @@ public class AbstractFactoryBeanSupportUnitTests {
|
||||
verify(mockLog, never()).info(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void suppressesWarnLoggingWhenWarnIsDisabled() {
|
||||
when(mockLog.isWarnEnabled()).thenReturn(false);
|
||||
|
||||
factoryBeanSupport.logWarning(() -> "test");
|
||||
|
||||
verify(mockLog, times(1)).isWarnEnabled();
|
||||
verify(mockLog, never()).warn(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void suppressesErrorLoggingWhenInfoIsDisabled() {
|
||||
when(mockLog.isErrorEnabled()).thenReturn(false);
|
||||
|
||||
factoryBeanSupport.logError(() -> "test");
|
||||
|
||||
verify(mockLog, times(1)).isErrorEnabled();
|
||||
verify(mockLog, never()).error(any());
|
||||
}
|
||||
|
||||
private static class TestFactoryBeanSupport<T> extends AbstractFactoryBeanSupport<T> {
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user