From 9e4530c12c5d940b0f6684a18b7cfc28af391d81 Mon Sep 17 00:00:00 2001 From: John Blum Date: Tue, 19 May 2015 17:29:12 -0700 Subject: [PATCH] SGF-370 - Add multi-Index definition and creation support. Refactored Index definition around a 'single' QueryService instance obtained from the GemFire Cache instance and refactored existing tests and added new tests accordingly. --- .../data/gemfire/IndexFactoryBean.java | 174 +++++-- ...eateDefinedIndexesApplicationListener.java | 29 +- .../data/gemfire/config/GemfireConstants.java | 1 + .../data/gemfire/IndexFactoryBeanTest.java | 439 ++++++++++++------ ...DefinedIndexesApplicationListenerTest.java | 131 ++---- .../CreateDefinedIndexesIntegrationTest.java | 17 +- 6 files changed, 514 insertions(+), 277 deletions(-) diff --git a/src/main/java/org/springframework/data/gemfire/IndexFactoryBean.java b/src/main/java/org/springframework/data/gemfire/IndexFactoryBean.java index 798ed16e..f063e5ce 100644 --- a/src/main/java/org/springframework/data/gemfire/IndexFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/IndexFactoryBean.java @@ -18,11 +18,17 @@ package org.springframework.data.gemfire; import java.util.Collection; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.data.gemfire.config.GemfireConstants; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import com.gemstone.gemfire.cache.Region; @@ -40,19 +46,23 @@ import com.gemstone.gemfire.cache.query.QueryService; * @author Costin Leau * @author David Turanski * @author John Blum - * @see org.springframework.beans.factory.InitializingBean + * @see org.springframework.beans.factory.BeanFactoryAware * @see org.springframework.beans.factory.BeanNameAware * @see org.springframework.beans.factory.FactoryBean + * @see org.springframework.beans.factory.InitializingBean + * @see org.springframework.data.gemfire.IndexFactoryBean.IndexWrapper * @see com.gemstone.gemfire.cache.RegionService * @see com.gemstone.gemfire.cache.query.Index * @see com.gemstone.gemfire.cache.query.QueryService * @since 1.0.0 */ -public class IndexFactoryBean implements InitializingBean, FactoryBean, BeanNameAware { +public class IndexFactoryBean implements InitializingBean, FactoryBean, BeanNameAware, BeanFactoryAware { private boolean define = false; private boolean override = true; + private BeanFactory beanFactory; + private Index index; private IndexType indexType; @@ -73,27 +83,49 @@ public class IndexFactoryBean implements InitializingBean, FactoryBean, B queryService = lookupQueryService(); - Assert.notNull(queryService, "QueryService is required to create an Index!"); - Assert.hasText(expression, "Index 'expression' is required!"); - Assert.hasText(from, "Index 'from' clause (a Region's full-path) is required!"); + Assert.notNull(queryService, "QueryService is required to create an Index"); + Assert.hasText(expression, "Index 'expression' is required"); + Assert.hasText(from, "Index 'from' clause is required"); if (IndexType.isKey(indexType)) { - Assert.isNull(imports, "The 'imports' property is not supported for a Key Index."); + Assert.isNull(imports, "'imports' are not supported with a KEY Index"); } indexName = (StringUtils.hasText(name) ? name : beanName); - Assert.hasText(indexName, "The Index bean id or name is required!"); + Assert.hasText(indexName, "Index 'name' is required"); index = createIndex(queryService, indexName); } - QueryService lookupQueryService() { + /* (non-Javadoc) */ + QueryService doLookupQueryService() { return (queryService != null ? queryService - : (cache instanceof ClientCache ? ((ClientCache) cache).getLocalQueryService() - : cache.getQueryService())); + : (cache instanceof ClientCache ? ((ClientCache) cache).getLocalQueryService() : cache.getQueryService())); } + /* (non-Javadoc) */ + QueryService lookupQueryService() { + if (getBeanFactory().containsBean(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE)) { + return getBeanFactory().getBean(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE, + QueryService.class); + } + else { + return registerQueryServiceBean(doLookupQueryService()); + } + } + + /* (non-Javadoc) */ + QueryService registerQueryServiceBean(QueryService queryService) { + if (isDefine()) { + ((ConfigurableBeanFactory) getBeanFactory()).registerSingleton( + GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE, queryService); + } + + return queryService; + } + + /* (non-Javadoc) */ Index createIndex(QueryService queryService, String indexName) throws Exception { Index existingIndex = getExistingIndex(queryService, indexName); @@ -108,13 +140,7 @@ public class IndexFactoryBean implements InitializingBean, FactoryBean, B try { if (IndexType.isKey(indexType)) { - if (isDefine()) { - queryService.defineKeyIndex(indexName, expression, from); - return new IndexWrapper(queryService, indexName); - } - else { - return queryService.createKeyIndex(indexName, expression, from); - } + return createKeyIndex(queryService, indexName, expression, from); } else if (IndexType.isHash(indexType)) { return createHashIndex(queryService, indexName, expression, from, imports); @@ -140,50 +166,70 @@ public class IndexFactoryBean implements InitializingBean, FactoryBean, B } } - Index createFunctionalIndex(QueryService queryService, String indexName, String expression, String from, - String imports) throws Exception { - if (StringUtils.hasText(imports)) { - if (isDefine()) { - queryService.defineIndex(indexName, expression, from , imports); - } - else { - return queryService.createIndex(indexName, expression, from, imports); - } + /* (non-Javadoc) */ + Index createKeyIndex(QueryService queryService, String indexName, String expression, String from) throws Exception { + if (isDefine()) { + queryService.defineKeyIndex(indexName, expression, from); + return new IndexWrapper(queryService, indexName); } else { - if (isDefine()) { - queryService.defineIndex(indexName, expression, from); - } - else { - return queryService.createIndex(indexName, expression, from); - } + return queryService.createKeyIndex(indexName, expression, from); } - - return new IndexWrapper(queryService, indexName); } + /* (non-Javadoc) */ Index createHashIndex(QueryService queryService, String indexName, String expression, String from, - String imports) throws Exception { - if (StringUtils.hasText(imports)) { - if (isDefine()) { + String imports) throws Exception { + + boolean hasImports = StringUtils.hasText(imports); + + if (isDefine()) { + if (hasImports) { queryService.defineHashIndex(indexName, expression, from, imports); } else { - return queryService.createHashIndex(indexName, expression, from, imports); + queryService.defineHashIndex(indexName, expression, from); } + + return new IndexWrapper(queryService, indexName); } else { - if (isDefine()) { - queryService.defineHashIndex(indexName, expression, from); + if (hasImports) { + return queryService.createHashIndex(indexName, expression, from, imports); } else { return queryService.createHashIndex(indexName, expression, from); } } - - return new IndexWrapper(queryService, indexName); } + /* (non-Javadoc) */ + Index createFunctionalIndex(QueryService queryService, String indexName, String expression, String from, + String imports) throws Exception { + + boolean hasImports = StringUtils.hasText(imports); + + if (isDefine()) { + if (hasImports) { + queryService.defineIndex(indexName, expression, from , imports); + } + else { + queryService.defineIndex(indexName, expression, from); + } + + return new IndexWrapper(queryService, indexName); + } + else { + if (hasImports) { + return queryService.createIndex(indexName, expression, from, imports); + } + else { + return queryService.createIndex(indexName, expression, from); + } + } + } + + /* (non-Javadoc) */ Index getExistingIndex(QueryService queryService, String indexName) { for (Index index : queryService.getIndexes()) { if (index.getName().equalsIgnoreCase(indexName)) { @@ -225,6 +271,20 @@ public class IndexFactoryBean implements InitializingBean, FactoryBean, B this.queryService = service; } + /* (non-Javadoc) */ + @Override + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + this.beanFactory = beanFactory; + } + + /* (non-Javadoc) */ + protected BeanFactory getBeanFactory() { + Assert.state(beanFactory != null, "'beanFactory' was not properly initialized"); + return beanFactory; + } + + /* (non-Javadoc) */ + @Override public void setBeanName(String name) { this.beanName = name; } @@ -398,6 +458,36 @@ public class IndexFactoryBean implements InitializingBean, FactoryBean, B public com.gemstone.gemfire.cache.query.IndexType getType() { return getIndex().getType(); } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + + if (!(obj instanceof IndexWrapper || obj instanceof Index)) { + return false; + } + + if (obj instanceof IndexWrapper) { + return (getIndexName().equals(((IndexWrapper) obj).getIndexName())); + } + + return getIndex().equals(obj); + } + + @Override + public int hashCode() { + int hashValue = 37; + hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getIndexName()); + hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(index); + return hashValue; + } + + @Override + public String toString() { + return (index != null ? String.valueOf(index) : getIndexName()); + } } } diff --git a/src/main/java/org/springframework/data/gemfire/config/CreateDefinedIndexesApplicationListener.java b/src/main/java/org/springframework/data/gemfire/config/CreateDefinedIndexesApplicationListener.java index d48ea472..d8c2eb89 100644 --- a/src/main/java/org/springframework/data/gemfire/config/CreateDefinedIndexesApplicationListener.java +++ b/src/main/java/org/springframework/data/gemfire/config/CreateDefinedIndexesApplicationListener.java @@ -18,13 +18,10 @@ package org.springframework.data.gemfire.config; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; -import com.gemstone.gemfire.cache.CacheFactory; -import com.gemstone.gemfire.cache.GemFireCache; -import com.gemstone.gemfire.cache.client.ClientCache; import com.gemstone.gemfire.cache.query.QueryService; /** @@ -34,8 +31,6 @@ import com.gemstone.gemfire.cache.query.QueryService; * @author John Blum * @see org.springframework.context.ApplicationListener * @see org.springframework.context.event.ContextRefreshedEvent - * @see com.gemstone.gemfire.cache.GemFireCache - * @see com.gemstone.gemfire.cache.client.ClientCache * @see com.gemstone.gemfire.cache.query.QueryService * @since 1.7.0 */ @@ -57,12 +52,11 @@ public class CreateDefinedIndexesApplicationListener implements ApplicationListe @Override public void onApplicationEvent(final ContextRefreshedEvent event) { try { - GemFireCache cache = getCache(event); + QueryService localQueryService = getQueryService(event); - QueryService queryService = (cache instanceof ClientCache ? ((ClientCache) cache).getLocalQueryService() - : cache.getQueryService()); - - queryService.createDefinedIndexes(); + if (localQueryService != null) { + localQueryService.createDefinedIndexes(); + } } catch (Exception ignore) { logger.warn(String.format("unable to create defined Indexes (if any): %1$s", ignore.getMessage())); @@ -75,13 +69,12 @@ public class CreateDefinedIndexesApplicationListener implements ApplicationListe } /* (non-Javadoc) */ - protected GemFireCache getCache(final ContextRefreshedEvent event) { - try { - return event.getApplicationContext().getBean(GemFireCache.class); - } - catch (BeansException e) { - return CacheFactory.getAnyInstance(); - } + private QueryService getQueryService(final ContextRefreshedEvent event) { + ApplicationContext localApplicationContext = event.getApplicationContext(); + + return (localApplicationContext.containsBean(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE) ? + localApplicationContext.getBean(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE, + QueryService.class) : null); } } diff --git a/src/main/java/org/springframework/data/gemfire/config/GemfireConstants.java b/src/main/java/org/springframework/data/gemfire/config/GemfireConstants.java index bcce9372..c68706e6 100644 --- a/src/main/java/org/springframework/data/gemfire/config/GemfireConstants.java +++ b/src/main/java/org/springframework/data/gemfire/config/GemfireConstants.java @@ -25,6 +25,7 @@ package org.springframework.data.gemfire.config; public interface GemfireConstants { static final String DEFAULT_GEMFIRE_CACHE_NAME = "gemfireCache"; + static final String DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE = "gemfireIndexDefinitionQueryService"; static final String DEFAULT_GEMFIRE_FUNCTION_SERVICE_NAME = "gemfireFunctionService"; static final String DEFAULT_GEMFIRE_POOL_NAME = "DEFAULT"; static final String DEFAULT_GEMFIRE_TRANSACTION_MANAGER_NAME = "gemfireTransactionManager"; diff --git a/src/test/java/org/springframework/data/gemfire/IndexFactoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/IndexFactoryBeanTest.java index db5aab4a..21c1b410 100644 --- a/src/test/java/org/springframework/data/gemfire/IndexFactoryBeanTest.java +++ b/src/test/java/org/springframework/data/gemfire/IndexFactoryBeanTest.java @@ -24,6 +24,8 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.same; import static org.mockito.Mockito.doAnswer; @@ -39,11 +41,15 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; import org.junit.After; import org.junit.Test; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.data.gemfire.config.GemfireConstants; import org.springframework.data.util.ReflectionUtils; import com.gemstone.gemfire.cache.Cache; @@ -60,6 +66,7 @@ import com.gemstone.gemfire.cache.query.QueryService; * * @author John Blum * @see org.junit.Test + * @see org.springframework.beans.factory.BeanFactory * @see org.springframework.data.gemfire.IndexFactoryBean * @see com.gemstone.gemfire.cache.Cache * @see com.gemstone.gemfire.cache.client.ClientCache @@ -69,40 +76,65 @@ import com.gemstone.gemfire.cache.query.QueryService; */ public class IndexFactoryBeanTest { + private Cache mockCache = mock(Cache.class, "IndexFactoryBeanTest.MockCache"); + private IndexFactoryBean indexFactoryBean = new IndexFactoryBean(); + private QueryService mockQueryService = mock(QueryService.class, "IndexFactoryBeanTest.MockQueryService"); + + protected IndexFactoryBean newIndexFactoryBean() { + IndexFactoryBean indexFactoryBean = new IndexFactoryBean() { + @Override QueryService lookupQueryService() { + return mockQueryService; + } + }; + + indexFactoryBean.setCache(mockCache); + + return indexFactoryBean; + } + @After public void tearDown() { + indexFactoryBean.setBeanFactory(null); + indexFactoryBean.setCache(null); indexFactoryBean.setDefine(false); } @Test public void afterPropertiesSetIsSuccessful() throws Exception { - Cache mockCache = mock(Cache.class, "afterPropertiesSet.MockCache"); + BeanFactory mockBeanFactory = mock(BeanFactory.class, "testAfterPropertiesSetIsSuccessful.MockBeanFactory"); - QueryService mockQueryService = mock(QueryService.class, "afterPropertiesSet.MockQueryService"); + Cache mockCache = mock(Cache.class, "testAfterPropertiesSetIsSuccessful.MockCache"); + Index mockIndex = mock(Index.class, "testAfterPropertiesSetIsSuccessful.MockIndex"); + + QueryService mockQueryService = mock(QueryService.class, "testAfterPropertiesSetIsSuccessful.MockQueryService"); + + when(mockBeanFactory.containsBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE))).thenReturn(false); when(mockCache.getQueryService()).thenReturn(mockQueryService); + when(mockQueryService.createKeyIndex(eq("TestKeyIndex"), eq("id"), eq("/Example"))).thenReturn(mockIndex); - final Index mockIndex = mock(Index.class, "afterPropertiesSet.MockIndex"); - - IndexFactoryBean indexFactoryBean = new IndexFactoryBean() { - @Override Index createIndex(final QueryService queryService, final String indexName) throws Exception { - return mockIndex; - } - }; + IndexFactoryBean indexFactoryBean = new IndexFactoryBean(); + indexFactoryBean.setBeanFactory(mockBeanFactory); indexFactoryBean.setCache(mockCache); - indexFactoryBean.setName("TestIndex"); + indexFactoryBean.setDefine(false); indexFactoryBean.setExpression("id"); indexFactoryBean.setFrom("/Example"); + indexFactoryBean.setName("TestKeyIndex"); indexFactoryBean.setType("key"); indexFactoryBean.afterPropertiesSet(); assertEquals(mockIndex, indexFactoryBean.getObject()); - assertEquals(mockIndex, indexFactoryBean.getObject()); // assert Index really is a 'Singleton' + assertSame(mockIndex, indexFactoryBean.getObject()); // assert Index really is a 'Singleton' assertTrue(Index.class.isAssignableFrom(indexFactoryBean.getObjectType())); assertTrue(indexFactoryBean.isSingleton()); + + verify(mockBeanFactory, times(1)).containsBean( + eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE)); + verify(mockCache, times(1)).getQueryService(); + verify(mockQueryService, times(1)).createKeyIndex(eq("TestKeyIndex"), eq("id"), eq("/Example")); } @Test(expected = IllegalArgumentException.class) @@ -119,17 +151,17 @@ public class IndexFactoryBeanTest { @Test(expected = IllegalArgumentException.class) public void afterPropertiesSetWithNullQueryService() throws Exception { try { - Cache mockCache = mock(Cache.class, "afterPropertiesSetWithNullQueryService.MockCache"); - - when(mockCache.getQueryService()).thenReturn(null); - - IndexFactoryBean indexFactoryBean = new IndexFactoryBean(); + IndexFactoryBean indexFactoryBean = new IndexFactoryBean() { + @Override QueryService lookupQueryService() { + return null; + } + }; indexFactoryBean.setCache(mockCache); indexFactoryBean.afterPropertiesSet(); } catch (IllegalArgumentException expected) { - assertEquals("QueryService is required to create an Index!", expected.getMessage()); + assertEquals("QueryService is required to create an Index", expected.getMessage()); throw expected; } } @@ -137,20 +169,10 @@ public class IndexFactoryBeanTest { @Test(expected = IllegalArgumentException.class) public void afterPropertiesSetWithUnspecifiedExpression() throws Exception { try { - Cache mockCache = mock(Cache.class, "afterPropertiesSetWithUnspecifiedExpression.MockCache"); - - QueryService mockQueryService = mock(QueryService.class, - "afterPropertiesSetWithUnspecifiedExpression.MockQueryService"); - - when(mockCache.getQueryService()).thenReturn(mockQueryService); - - IndexFactoryBean indexFactoryBean = new IndexFactoryBean(); - - indexFactoryBean.setCache(mockCache); - indexFactoryBean.afterPropertiesSet(); + newIndexFactoryBean().afterPropertiesSet(); } catch (IllegalArgumentException expected) { - assertEquals("Index 'expression' is required!", expected.getMessage()); + assertEquals("Index 'expression' is required", expected.getMessage()); throw expected; } } @@ -158,21 +180,12 @@ public class IndexFactoryBeanTest { @Test(expected = IllegalArgumentException.class) public void afterPropertiesSetWithUnspecifiedFromClause() throws Exception { try { - Cache mockCache = mock(Cache.class, "afterPropertiesSetWithUnspecifiedFromClause.MockCache"); - - QueryService mockQueryService = mock(QueryService.class, - "afterPropertiesSetWithUnspecifiedFromClause.MockQueryService"); - - when(mockCache.getQueryService()).thenReturn(mockQueryService); - - IndexFactoryBean indexFactoryBean = new IndexFactoryBean(); - - indexFactoryBean.setCache(mockCache); + IndexFactoryBean indexFactoryBean = newIndexFactoryBean(); indexFactoryBean.setExpression("id"); indexFactoryBean.afterPropertiesSet(); } catch (IllegalArgumentException expected) { - assertEquals("Index 'from' clause (a Region's full-path) is required!", expected.getMessage()); + assertEquals("Index 'from' clause is required", expected.getMessage()); throw expected; } } @@ -180,59 +193,40 @@ public class IndexFactoryBeanTest { @Test(expected = IllegalArgumentException.class) public void afterPropertiesSetWithUnspecifiedIndexName() throws Exception { try { - Cache mockCache = mock(Cache.class, "afterPropertiesSetWithUnspecifiedIndexName.MockCache"); - - QueryService mockQueryService = mock(QueryService.class, - "afterPropertiesSetWithUnspecifiedIndexName.MockQueryService"); - - when(mockCache.getQueryService()).thenReturn(mockQueryService); - - IndexFactoryBean indexFactoryBean = new IndexFactoryBean(); - - indexFactoryBean.setCache(mockCache); + IndexFactoryBean indexFactoryBean = newIndexFactoryBean(); indexFactoryBean.setExpression("id"); indexFactoryBean.setFrom("/Example"); - indexFactoryBean.setImports("org.example.DomainType"); - indexFactoryBean.setType("hash"); indexFactoryBean.afterPropertiesSet(); } catch (IllegalArgumentException expected) { - assertEquals("The Index bean id or name is required!", expected.getMessage()); + assertEquals("Index 'name' is required", expected.getMessage()); throw expected; } } @Test(expected = IllegalArgumentException.class) - public void afterPropertiesSetWithInvalidTypeUsingImports() throws Exception { + public void afterPropertiesSetUsingImportsWithInvalidType() throws Exception { try { - Cache mockCache = mock(Cache.class, "afterPropertiesSetWithInvalidTypeUsingImports.MockCache"); - - QueryService mockQueryService = mock(QueryService.class, - "afterPropertiesSetWithInvalidTypeUsingImports.MockQueryService"); - - when(mockCache.getQueryService()).thenReturn(mockQueryService); - - IndexFactoryBean indexFactoryBean = new IndexFactoryBean(); - - indexFactoryBean.setCache(mockCache); + IndexFactoryBean indexFactoryBean = newIndexFactoryBean(); indexFactoryBean.setExpression("id"); indexFactoryBean.setFrom("/Example"); indexFactoryBean.setImports("org.example.DomainType"); + indexFactoryBean.setName("TestIndex"); indexFactoryBean.setType("PriMary_Key"); indexFactoryBean.afterPropertiesSet(); } catch (IllegalArgumentException expected) { - assertEquals("The 'imports' property is not supported for a Key Index.", expected.getMessage()); + assertEquals("'imports' are not supported with a KEY Index", expected.getMessage()); throw expected; } } @Test - public void testLookupQueryService() { + public void doLookupQueryService() { QueryService mockQueryServiceOne = mock(QueryService.class, "testLookupQueryService.MockQueryService.One"); QueryService mockQueryServiceTwo = mock(QueryService.class, "testLookupQueryService.MockQueryService.Two"); - Cache mockCache = mock(Cache.class, "testLookupQueryService.MockCache"); + Cache mockCache = mock(Cache.class, "testDoLookupQueryService.MockCache"); when(mockCache.getQueryService()).thenReturn(mockQueryServiceTwo); @@ -241,33 +235,35 @@ public class IndexFactoryBeanTest { indexFactoryBean.setCache(mockCache); indexFactoryBean.setQueryService(mockQueryServiceOne); - assertSame(mockQueryServiceOne, indexFactoryBean.lookupQueryService()); + assertSame(mockQueryServiceOne, indexFactoryBean.doLookupQueryService()); verify(mockCache, never()).getQueryService(); } @Test - public void lookupQueryServiceOnClientCache() { - ClientCache mockClientCache = mock(ClientCache.class, "lookupQueryServiceOnClientCache.MockClientCache"); + public void doLookupQueryServiceOnClientCache() { + ClientCache mockClientCache = mock(ClientCache.class, "testDoLookupQueryServiceOnClientCache.MockClientCache"); - QueryService mockQueryService = mock(QueryService.class, "lookupQueryServiceOnClientCache.MockQueryService"); + QueryService mockQueryService = mock(QueryService.class, "testDoLookupQueryServiceOnClientCache.MockQueryService"); when(mockClientCache.getLocalQueryService()).thenReturn(mockQueryService); IndexFactoryBean indexFactoryBean = new IndexFactoryBean(); indexFactoryBean.setCache(mockClientCache); + indexFactoryBean.setQueryService(null); - assertSame(mockQueryService, indexFactoryBean.lookupQueryService()); + assertSame(mockQueryService, indexFactoryBean.doLookupQueryService()); verify(mockClientCache, times(1)).getLocalQueryService(); + verify(mockClientCache, never()).getQueryService(); } @Test - public void lookupQueryServiceOnPeerCache() { - Cache mockCache = mock(Cache.class, "lookupQueryServiceOnPeerCache.MockCache"); + public void doLookupQueryServiceOnPeerCache() { + Cache mockCache = mock(Cache.class, "testDoLookupQueryServiceOnPeerCache.MockCache"); - QueryService mockQueryService = mock(QueryService.class, "lookupQueryServiceOnPeerCache.MockQueryService"); + QueryService mockQueryService = mock(QueryService.class, "testDoLookupQueryServiceOnPeerCache.MockQueryService"); when(mockCache.getQueryService()).thenReturn(mockQueryService); @@ -276,11 +272,93 @@ public class IndexFactoryBeanTest { indexFactoryBean.setCache(mockCache); indexFactoryBean.setQueryService(null); - assertSame(mockQueryService, indexFactoryBean.lookupQueryService()); + assertSame(mockQueryService, indexFactoryBean.doLookupQueryService()); verify(mockCache, times(1)).getQueryService(); } + @Test + public void lookupQueryServiceFromBeanFactory() { + BeanFactory mockBeanFactory = mock(BeanFactory.class, "testLookupQueryServiceFromBeanFactory.MockBeanFactory"); + + QueryService mockQueryService = mock(QueryService.class, "testLookupQueryServiceFromBeanFactory.MockQueryService"); + + when(mockBeanFactory.containsBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE))) + .thenReturn(true); + when(mockBeanFactory.getBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE), + eq(QueryService.class))).thenReturn(mockQueryService); + + IndexFactoryBean indexFactoryBean = new IndexFactoryBean(); + + indexFactoryBean.setBeanFactory(mockBeanFactory); + + QueryService actualQueryService = indexFactoryBean.lookupQueryService(); + + assertSame(mockQueryService, actualQueryService); + + verify(mockBeanFactory, times(1)).containsBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE)); + verify(mockBeanFactory, times(1)).getBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE), + eq(QueryService.class)); + } + + @Test + public void lookupQueryServiceFromCache() { + BeanFactory mockBeanFactory = mock(BeanFactory.class, "testLookupQueryServiceFromCache.MockBeanFactory"); + + when(mockBeanFactory.containsBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE))) + .thenReturn(false); + + IndexFactoryBean indexFactoryBean = new IndexFactoryBean(); + + indexFactoryBean.setBeanFactory(mockBeanFactory); + indexFactoryBean.setDefine(false); + indexFactoryBean.setQueryService(mockQueryService); + + QueryService actualQueryService = indexFactoryBean.lookupQueryService(); + + assertSame(mockQueryService, actualQueryService); + + verify(mockBeanFactory, times(1)).containsBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE)); + verify(mockBeanFactory, never()).getBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE), + eq(QueryService.class)); + } + + @Test + public void registerQueryServiceBeanWhenIndexIsCreated() { + ConfigurableBeanFactory mockBeanFactory = mock(ConfigurableBeanFactory.class, + "testRegisterQueryServiceBeanWhenIndexIsCreated.MockBeanFactory"); + + QueryService mockQueryService = mock(QueryService.class, "testRegisterQueryServiceBeanWhenIndexIsCreated.MockQueryService"); + + IndexFactoryBean indexFactoryBean = new IndexFactoryBean(); + + indexFactoryBean.setBeanFactory(mockBeanFactory); + indexFactoryBean.setDefine(false); + + assertSame(mockQueryService, indexFactoryBean.registerQueryServiceBean(mockQueryService)); + + verify(mockBeanFactory, never()).registerSingleton( + eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE), same(mockQueryService)); + } + + @Test + public void registerQueryServiceBeanWhenIndexIsDefined() { + ConfigurableBeanFactory mockBeanFactory = mock(ConfigurableBeanFactory.class, + "testRegisterQueryServiceBeanWhenIndexIsDefined.MockBeanFactory"); + + QueryService mockQueryService = mock(QueryService.class, "testRegisterQueryServiceBeanWhenIndexIsDefined.MockQueryService"); + + IndexFactoryBean indexFactoryBean = new IndexFactoryBean(); + + indexFactoryBean.setBeanFactory(mockBeanFactory); + indexFactoryBean.setDefine(true); + + assertSame(mockQueryService, indexFactoryBean.registerQueryServiceBean(mockQueryService)); + + verify(mockBeanFactory, times(1)).registerSingleton( + eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE), same(mockQueryService)); + } + @Test public void createIndexReturningNewKeyIndex() throws Exception { Index mockIndex = mock(Index.class, "createIndexReturningNewKeyIndex.MockIndex"); @@ -529,37 +607,11 @@ public class IndexFactoryBeanTest { } } - @Test - public void createIndexDefinesKeyIndex() throws Exception { - QueryService mockQueryService = mock(QueryService.class, "createIndexDefinesKeyIndex.MockQueryService"); - - when(mockQueryService.getIndexes()).thenReturn(Collections.emptyList()); - - IndexFactoryBean indexFactoryBean = new IndexFactoryBean(); - - indexFactoryBean.setDefine(true); - indexFactoryBean.setExpression("id"); - indexFactoryBean.setFrom("/Example"); - indexFactoryBean.setName("MockIndex"); - indexFactoryBean.setType("key"); - - Index actualIndex = indexFactoryBean.createIndex(mockQueryService, "MockIndex"); - - assertTrue(actualIndex instanceof IndexFactoryBean.IndexWrapper); - - IndexFactoryBean.IndexWrapper indexWrapper = (IndexFactoryBean.IndexWrapper) actualIndex; - - assertSame(mockQueryService, indexWrapper.getQueryService()); - assertEquals("MockIndex", indexWrapper.getIndexName()); - - verify(mockQueryService, times(1)).defineKeyIndex(eq("MockIndex"), eq("id"), eq("/Example")); - } - @Test public void createFunctionalIndex() throws Exception { - Index mockIndex = mock(Index.class, "createFunctionalIndex.MockIndex"); + Index mockIndex = mock(Index.class, "testCreateFunctionalIndex.MockIndex"); - QueryService mockQueryService = mock(QueryService.class, "createFunctionalIndex.MockQueryService"); + QueryService mockQueryService = mock(QueryService.class, "testCreateFunctionalIndex.MockQueryService"); when(mockQueryService.createIndex(eq("FunctionalIndex"), eq("purchaseDate"), eq("/Orders"))) .thenReturn(mockIndex); @@ -570,13 +622,14 @@ public class IndexFactoryBeanTest { assertSame(mockIndex, actualIndex); verify(mockQueryService, times(1)).createIndex(eq("FunctionalIndex"), eq("purchaseDate"), eq("/Orders")); + verify(mockQueryService, never()).defineIndex(anyString(), anyString(), anyString()); } @Test public void createFunctionalIndexWithImports() throws Exception { - Index mockIndex = mock(Index.class, "createFunctionalIndexWithImports.MockIndex"); + Index mockIndex = mock(Index.class, "testCreateFunctionalIndexWithImports.MockIndex"); - QueryService mockQueryService = mock(QueryService.class, "createFunctionalIndexWithImports.MockQueryService"); + QueryService mockQueryService = mock(QueryService.class, "testCreateFunctionalIndexWithImports.MockQueryService"); when(mockQueryService.createIndex(eq("FunctionalIndexWithImports"), eq("purchaseDate"), eq("/Orders"), eq("org.example.Order"))).thenReturn(mockIndex); @@ -588,11 +641,12 @@ public class IndexFactoryBeanTest { verify(mockQueryService, times(1)).createIndex(eq("FunctionalIndexWithImports"), eq("purchaseDate"), eq("/Orders"), eq("org.example.Order")); + verify(mockQueryService, never()).defineIndex(anyString(), anyString(), anyString(), anyString()); } @Test public void defineFunctionalIndex() throws Exception { - QueryService mockQueryService = mock(QueryService.class, "defineFunctionalIndex.MockQueryService"); + QueryService mockQueryService = mock(QueryService.class, "testDefineFunctionalIndex.MockQueryService"); doAnswer(new Answer() { @Override public Void answer(final InvocationOnMock invocation) throws Throwable { @@ -609,12 +663,13 @@ public class IndexFactoryBeanTest { assertSame(mockQueryService, ((IndexFactoryBean.IndexWrapper) actualIndex).getQueryService()); assertEquals("FunctionalIndex", ((IndexFactoryBean.IndexWrapper) actualIndex).getIndexName()); + verify(mockQueryService, never()).createIndex(anyString(), anyString(), anyString()); verify(mockQueryService, times(1)).defineIndex(eq("FunctionalIndex"), eq("purchaseDate"), eq("/Orders")); } @Test public void defineFunctionalIndexWithImports() throws Exception { - QueryService mockQueryService = mock(QueryService.class, "defineFunctionalIndexWithImports.MockQueryService"); + QueryService mockQueryService = mock(QueryService.class, "testDefineFunctionalIndexWithImports.MockQueryService"); doAnswer(new Answer() { @Override public Void answer(final InvocationOnMock invocation) throws Throwable { @@ -625,38 +680,39 @@ public class IndexFactoryBeanTest { indexFactoryBean.setDefine(true); - Index actualIndex = indexFactoryBean.createFunctionalIndex(mockQueryService, "FunctionalIndex", + Index actualIndex = indexFactoryBean.createFunctionalIndex(mockQueryService, "FunctionalIndexWithImports", "purchaseDate", "/Orders", "org.example.Order"); assertTrue(actualIndex instanceof IndexFactoryBean.IndexWrapper); assertSame(mockQueryService, ((IndexFactoryBean.IndexWrapper) actualIndex).getQueryService()); - assertEquals("FunctionalIndex", ((IndexFactoryBean.IndexWrapper) actualIndex).getIndexName()); + assertEquals("FunctionalIndexWithImports", ((IndexFactoryBean.IndexWrapper) actualIndex).getIndexName()); - verify(mockQueryService, times(1)).defineIndex(eq("FunctionalIndex"), eq("purchaseDate"), eq("/Orders"), - eq("org.example.Order")); + verify(mockQueryService, never()).createIndex(anyString(), anyString(), anyString(), anyString()); + verify(mockQueryService, times(1)).defineIndex(eq("FunctionalIndexWithImports"), eq("purchaseDate"), + eq("/Orders"), eq("org.example.Order")); } @Test public void createHashIndex() throws Exception { - Index mockIndex = mock(Index.class, "createHashIndex.MockIndex"); + Index mockIndex = mock(Index.class, "testCreateHashIndex.MockIndex"); - QueryService mockQueryService = mock(QueryService.class, "createHashIndex.MockQueryService"); + QueryService mockQueryService = mock(QueryService.class, "testCreateHashIndex.MockQueryService"); when(mockQueryService.createHashIndex(eq("HashIndex"), eq("name"), eq("/People"))).thenReturn(mockIndex); - Index actualIndex = indexFactoryBean.createHashIndex(mockQueryService, "HashIndex", - "name", "/People", " "); + Index actualIndex = indexFactoryBean.createHashIndex(mockQueryService, "HashIndex", "name", "/People", " "); assertSame(mockIndex, actualIndex); verify(mockQueryService, times(1)).createHashIndex(eq("HashIndex"), eq("name"), eq("/People")); + verify(mockQueryService, never()).defineHashIndex(anyString(), anyString(), anyString()); } @Test public void createHashIndexWithImports() throws Exception { - Index mockIndex = mock(Index.class, "createHashIndexWithImports.MockIndex"); + Index mockIndex = mock(Index.class, "testCreateHashIndexWithImports.MockIndex"); - QueryService mockQueryService = mock(QueryService.class, "createHashIndexWithImports.MockQueryService"); + QueryService mockQueryService = mock(QueryService.class, "testCreateHashIndexWithImports.MockQueryService"); when(mockQueryService.createHashIndex(eq("HashIndexWithImports"), eq("name"), eq("/People"), eq("org.example.Person"))).thenReturn(mockIndex); @@ -668,11 +724,12 @@ public class IndexFactoryBeanTest { verify(mockQueryService, times(1)).createHashIndex(eq("HashIndexWithImports"), eq("name"), eq("/People"), eq("org.example.Person")); + verify(mockQueryService, never()).defineHashIndex(anyString(), anyString(), anyString(), anyString()); } @Test public void defineHashIndex() throws Exception { - QueryService mockQueryService = mock(QueryService.class, "defineHashIndex.MockQueryService"); + QueryService mockQueryService = mock(QueryService.class, "testDefineHashIndex.MockQueryService"); doAnswer(new Answer() { @Override public Void answer(final InvocationOnMock invocation) throws Throwable { @@ -689,39 +746,79 @@ public class IndexFactoryBeanTest { assertSame(mockQueryService, ((IndexFactoryBean.IndexWrapper) actualIndex).getQueryService()); assertEquals("HashIndex", ((IndexFactoryBean.IndexWrapper) actualIndex).getIndexName()); + verify(mockQueryService, never()).createHashIndex(anyString(), anyString(), anyString()); verify(mockQueryService, times(1)).defineHashIndex(eq("HashIndex"), eq("name"), eq("/People")); } @Test public void defineHashIndexWithImports() throws Exception { - QueryService mockQueryService = mock(QueryService.class, "defineHashIndex.MockQueryService"); + QueryService mockQueryService = mock(QueryService.class, "testDefineHashIndexWithImports.MockQueryService"); doAnswer(new Answer() { @Override public Void answer(final InvocationOnMock invocation) throws Throwable { return null; } - }).when(mockQueryService).defineHashIndex(eq("HashIndex"), eq("name"), eq("/People"), eq("org.example.Person")); + }).when(mockQueryService).defineHashIndex(eq("HashIndexWithImports"), eq("name"), eq("/People"), + eq("org.example.Person")); indexFactoryBean.setDefine(true); - Index actualIndex = indexFactoryBean.createHashIndex(mockQueryService, "HashIndex", + Index actualIndex = indexFactoryBean.createHashIndex(mockQueryService, "HashIndexWithImports", "name", "/People", "org.example.Person"); assertTrue(actualIndex instanceof IndexFactoryBean.IndexWrapper); assertSame(mockQueryService, ((IndexFactoryBean.IndexWrapper) actualIndex).getQueryService()); - assertEquals("HashIndex", ((IndexFactoryBean.IndexWrapper) actualIndex).getIndexName()); + assertEquals("HashIndexWithImports", ((IndexFactoryBean.IndexWrapper) actualIndex).getIndexName()); - verify(mockQueryService, times(1)).defineHashIndex(eq("HashIndex"), eq("name"), eq("/People"), + verify(mockQueryService, never()).createHashIndex(anyString(), anyString(), anyString(), anyString()); + verify(mockQueryService, times(1)).defineHashIndex(eq("HashIndexWithImports"), eq("name"), eq("/People"), eq("org.example.Person")); } @Test - public void getExistingIndex() { - Index mockIndexOne = mock(Index.class, "getExistingIndex.MockIndex.One"); - Index mockIndexTwo = mock(Index.class, "getExistingIndex.MockIndex.Two"); - Index mockIndexThree = mock(Index.class, "getExistingIndex.MockIndex.Two"); + public void createKeyIndex() throws Exception { + QueryService mockQueryService = mock(QueryService.class, "testCreateKeyIndex.MockQueryService"); - QueryService mockQueryService = mock(QueryService.class, "getExistingIndex.MockQueryService"); + Index mockIndex = mock(Index.class, "testCreateKeyIndex.MockKeyIndex"); + + when(mockQueryService.createKeyIndex(eq("KeyIndex"), eq("id"), eq("/Example"))).thenReturn(mockIndex); + + indexFactoryBean.setDefine(false); + + Index actualIndex = indexFactoryBean.createKeyIndex(mockQueryService, "KeyIndex", "id", "/Example"); + + assertSame(mockIndex, actualIndex); + + verify(mockQueryService, times(1)).createKeyIndex(eq("KeyIndex"), eq("id"), eq("/Example")); + verify(mockQueryService, never()).defineKeyIndex(anyString(), anyString(), anyString()); + } + + @Test + public void defineKeyIndex() throws Exception { + QueryService mockQueryService = mock(QueryService.class, "testDefineKeyIndex.MockQueryService"); + + indexFactoryBean.setDefine(true); + + Index actualIndex = indexFactoryBean.createKeyIndex(mockQueryService, "KeyIndex", "id", "/Example"); + + assertTrue(actualIndex instanceof IndexFactoryBean.IndexWrapper); + + IndexFactoryBean.IndexWrapper indexWrapper = (IndexFactoryBean.IndexWrapper) actualIndex; + + assertSame(mockQueryService, indexWrapper.getQueryService()); + assertEquals("KeyIndex", indexWrapper.getIndexName()); + + verify(mockQueryService, never()).createKeyIndex(anyString(), anyString(), anyString()); + verify(mockQueryService, times(1)).defineKeyIndex(eq("KeyIndex"), eq("id"), eq("/Example")); + } + + @Test + public void getExistingIndex() { + Index mockIndexOne = mock(Index.class, "testGetExistingIndex.MockIndex.One"); + Index mockIndexTwo = mock(Index.class, "testGetExistingIndex.MockIndex.Two"); + Index mockIndexThree = mock(Index.class, "testGetExistingIndex.MockIndex.Two"); + + QueryService mockQueryService = mock(QueryService.class, "testGetExistingIndex.MockQueryService"); when(mockIndexOne.getName()).thenReturn("PrimaryIndex"); when(mockIndexTwo.getName()).thenReturn("SecondaryIndex"); @@ -741,7 +838,7 @@ public class IndexFactoryBeanTest { @Test public void getObjectLooksUpIndex() throws Exception { - QueryService mockQueryService = mock(QueryService.class, "getObjectLooksUpIndex.MockQueryService"); + QueryService mockQueryService = mock(QueryService.class, "testGetObjectLooksUpIndex.MockQueryService"); when(mockQueryService.getIndexes()).then(new Answer>() { private final AtomicInteger counter = new AtomicInteger(1); @@ -773,6 +870,88 @@ public class IndexFactoryBeanTest { assertTrue(indexFactoryBean.isSingleton()); } + @Test + public void defineMultipleIndexesWithSeparateIndexFactoryBeansSameSpringContext() throws Exception { + ConfigurableBeanFactory mockBeanFactory = mock(ConfigurableBeanFactory.class, + "testDefineMultipleIndexesWithSeparateIndexFactoryBeansSameSpringContext.MockBeanFactory"); + + Cache mockCacheOne = mock(Cache.class, "testDefineMultipleIndexesWithSeparateIndexFactoryBeansSameSpringContext.MockCacheOne"); + Cache mockCacheTwo = mock(Cache.class, "testDefineMultipleIndexesWithSeparateIndexFactoryBeansSameSpringContext.MockCacheTwo"); + + QueryService mockQueryServiceOne = mock(QueryService.class, + "testDefineMultipleIndexesWithSeparateIndexFactoryBeansSameSpringContext.MockQueryServiceOne"); + + QueryService mockQueryServiceTwo = mock(QueryService.class, + "testDefineMultipleIndexesWithSeparateIndexFactoryBeansSameSpringContext.MockQueryServiceTwo"); + + final AtomicReference queryServiceReference = new AtomicReference(null); + + doAnswer(new Answer() { + @Override public Boolean answer(final InvocationOnMock invocation) throws Throwable { + return (queryServiceReference.get() != null); + } + }).when(mockBeanFactory).containsBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE)); + + doAnswer(new Answer() { + @Override public QueryService answer(final InvocationOnMock invocation) throws Throwable { + return queryServiceReference.get(); + } + }).when(mockBeanFactory).getBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE), + eq(QueryService.class)); + + doAnswer(new Answer() { + @Override public Void answer(final InvocationOnMock invocation) throws Throwable { + assertEquals(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE, + invocation.getArgumentAt(0, String.class)); + queryServiceReference.compareAndSet(null, invocation.getArgumentAt(1, QueryService.class)); + return null; + } + }).when(mockBeanFactory).registerSingleton(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE), + any(QueryService.class)); + + when(mockCacheOne.getQueryService()).thenReturn(mockQueryServiceOne); + when(mockCacheTwo.getQueryService()).thenReturn(mockQueryServiceTwo); + + IndexFactoryBean indexFactoryBeanOne = new IndexFactoryBean(); + + indexFactoryBeanOne.setBeanFactory(mockBeanFactory); + indexFactoryBeanOne.setCache(mockCacheOne); + indexFactoryBeanOne.setDefine(true); + indexFactoryBeanOne.setExpression("id"); + indexFactoryBeanOne.setFrom("/People"); + indexFactoryBeanOne.setName("PersonIdIndex"); + indexFactoryBeanOne.setType("Key"); + indexFactoryBeanOne.afterPropertiesSet(); + + IndexFactoryBean indexFactoryBeanTwo = new IndexFactoryBean(); + + indexFactoryBeanTwo.setBeanFactory(mockBeanFactory); + indexFactoryBeanTwo.setCache(mockCacheTwo); + indexFactoryBeanTwo.setDefine(true); + indexFactoryBeanTwo.setExpression("purchaseDate"); + indexFactoryBeanTwo.setFrom("/Orders"); + indexFactoryBeanTwo.setImports("org.example.Order"); + indexFactoryBeanTwo.setName("PurchaseDateIndex"); + indexFactoryBeanTwo.setType("HASH"); + indexFactoryBeanTwo.afterPropertiesSet(); + + verify(mockBeanFactory, times(2)).containsBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE)); + verify(mockBeanFactory, times(1)).getBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE), + eq(QueryService.class)); + verify(mockBeanFactory, times(1)).registerSingleton(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE), + same(mockQueryServiceOne)); + verify(mockCacheOne, times(1)).getQueryService(); + verify(mockCacheTwo, never()).getQueryService(); + verify(mockQueryServiceOne, times(1)).defineKeyIndex(eq("PersonIdIndex"), eq("id"), eq("/People")); + verify(mockQueryServiceOne, times(1)).defineHashIndex(eq("PurchaseDateIndex"), eq("purchaseDate"), eq("/Orders"), + eq("org.example.Order")); + verify(mockQueryServiceTwo, never()).defineHashIndex(anyString(), anyString(), anyString()); + verify(mockQueryServiceTwo, never()).defineHashIndex(anyString(), anyString(), anyString()); + verify(mockQueryServiceTwo, never()).defineIndex(anyString(), anyString(), anyString()); + verify(mockQueryServiceTwo, never()).defineIndex(anyString(), anyString(), anyString(), anyString()); + verify(mockQueryServiceTwo, never()).defineKeyIndex(anyString(), anyString(), anyString()); + } + @Test @SuppressWarnings("deprecation") public void indexWrapperDelegation() { diff --git a/src/test/java/org/springframework/data/gemfire/config/CreateDefinedIndexesApplicationListenerTest.java b/src/test/java/org/springframework/data/gemfire/config/CreateDefinedIndexesApplicationListenerTest.java index 47de3da2..82d50446 100644 --- a/src/test/java/org/springframework/data/gemfire/config/CreateDefinedIndexesApplicationListenerTest.java +++ b/src/test/java/org/springframework/data/gemfire/config/CreateDefinedIndexesApplicationListenerTest.java @@ -16,10 +16,12 @@ package org.springframework.data.gemfire.config; -import static org.junit.Assert.assertSame; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.startsWith; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -29,13 +31,9 @@ import java.util.HashMap; import org.apache.commons.logging.Log; import org.junit.Test; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.context.ApplicationContext; import org.springframework.context.event.ContextRefreshedEvent; -import com.gemstone.gemfire.cache.CacheClosedException; -import com.gemstone.gemfire.cache.GemFireCache; -import com.gemstone.gemfire.cache.client.ClientCache; import com.gemstone.gemfire.cache.query.MultiIndexCreationException; import com.gemstone.gemfire.cache.query.QueryService; @@ -46,10 +44,9 @@ import com.gemstone.gemfire.cache.query.QueryService; * @author John Blum * @see org.junit.Test * @see org.mockito.Mockito - * @see org.springframework.data.gemfire.config.CreateDefinedIndexesApplicationListener * @see org.springframework.context.ApplicationContext * @see org.springframework.context.event.ContextRefreshedEvent - * @see com.gemstone.gemfire.cache.GemFireCache + * @see org.springframework.data.gemfire.config.CreateDefinedIndexesApplicationListener * @see com.gemstone.gemfire.cache.query.QueryService * @since 1.7.0 */ @@ -57,83 +54,77 @@ public class CreateDefinedIndexesApplicationListenerTest { private CreateDefinedIndexesApplicationListener listener = new CreateDefinedIndexesApplicationListener(); - @Test - public void getCacheWithApplicationContext() { - ApplicationContext mockApplicationContext = mock(ApplicationContext.class, - "getCacheWithApplicationContext.MockApplicationContext"); - - ContextRefreshedEvent mockEvent = mock(ContextRefreshedEvent.class, - "getCacheWithApplicationContext.MockContextRefreshedEvent"); - - GemFireCache mockGemFireCache = mock(GemFireCache.class, "getCacheWithApplicationContext.MockGemFireCache"); - - when(mockEvent.getApplicationContext()).thenReturn(mockApplicationContext); - when(mockApplicationContext.getBean(eq(GemFireCache.class))).thenReturn(mockGemFireCache); - - GemFireCache actualGemFireCache = listener.getCache(mockEvent); - - assertSame(mockGemFireCache, actualGemFireCache); - } - - @Test(expected = CacheClosedException.class) - public void getCacheWithApplicationContextThrowingABeansException() { - ApplicationContext mockApplicationContext = mock(ApplicationContext.class, - "getCacheWhenApplicationContextThrowsBeanException.MockApplicationContext"); - - ContextRefreshedEvent mockEvent = mock(ContextRefreshedEvent.class, - "getCacheWhenApplicationContextThrowsBeanException.MockContextRefreshedEvent"); - - when(mockEvent.getApplicationContext()).thenReturn(mockApplicationContext); - when(mockApplicationContext.getBean(eq(GemFireCache.class))).thenThrow( - new NoSuchBeanDefinitionException("gemfireCachce")); - - listener.getCache(mockEvent); - } - @Test public void createDefinedIndexesCalledOnContextRefreshedEvent() throws Exception { ApplicationContext mockApplicationContext = mock(ApplicationContext.class, - "createDefinedIndexesCalledOnContextRefreshedEvent.MockApplicationContext"); + "testCreateDefinedIndexesCalledOnContextRefreshedEvent.MockApplicationContext"); ContextRefreshedEvent mockEvent = mock(ContextRefreshedEvent.class, - "createDefinedIndexesCalledOnContextRefreshedEvent.MockContextRefreshedEvent"); - - GemFireCache mockGemFireCache = mock(GemFireCache.class, - "createDefinedIndexesCalledOnContextRefreshedEvent.MockGemFireCache"); + "testCreateDefinedIndexesCalledOnContextRefreshedEvent.MockContextRefreshedEvent"); QueryService mockQueryService = mock(QueryService.class, - "createDefinedIndexesCalledOnContextRefreshedEvent.MockQueryService"); + "testCreateDefinedIndexesCalledOnContextRefreshedEvent.MockQueryService"); when(mockEvent.getApplicationContext()).thenReturn(mockApplicationContext); - when(mockApplicationContext.getBean(eq(GemFireCache.class))).thenReturn(mockGemFireCache); - when(mockGemFireCache.getQueryService()).thenReturn(mockQueryService); + when(mockApplicationContext.containsBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE))) + .thenReturn(true); + when(mockApplicationContext.getBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE), + eq(QueryService.class))).thenReturn(mockQueryService); listener.onApplicationEvent(mockEvent); + verify(mockEvent, times(1)).getApplicationContext(); + verify(mockApplicationContext, times(1)).containsBean( + eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE)); + verify(mockApplicationContext, times(1)).getBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE), eq(QueryService.class)); verify(mockQueryService, times(1)).createDefinedIndexes(); } + @Test + public void createDefinedIndexesNotCalledOnContextRefreshedEvent() throws Exception { + ApplicationContext mockApplicationContext = mock(ApplicationContext.class, + "testCreateDefinedIndexesUsingClientCacheLocalQueryService.MockApplicationContext"); + + ContextRefreshedEvent mockEvent = mock(ContextRefreshedEvent.class, + "testCreateDefinedIndexesUsingClientCacheLocalQueryService.MockContextRefreshedEvent"); + + QueryService mockQueryService = mock(QueryService.class, + "testCreateDefinedIndexesUsingClientCacheLocalQueryService.MockQueryService"); + + when(mockEvent.getApplicationContext()).thenReturn(mockApplicationContext); + when(mockApplicationContext.containsBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE))) + .thenReturn(false); + when(mockApplicationContext.getBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE), + eq(QueryService.class))).thenReturn(mockQueryService); + + listener.onApplicationEvent(mockEvent); + + verify(mockEvent, times(1)).getApplicationContext(); + verify(mockApplicationContext, times(1)).containsBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE)); + verify(mockApplicationContext, never()).getBean(anyString(), any(QueryService.class)); + verify(mockQueryService, never()).createDefinedIndexes(); + } + @Test public void createDefinedIndexesThrowingAnExceptionIsLogged() throws Exception { ApplicationContext mockApplicationContext = mock(ApplicationContext.class, - "createDefinedIndexesThrowingAnExceptionIsLogged.MockApplicationContext"); + "testCreateDefinedIndexesThrowingAnExceptionIsLogged.MockApplicationContext"); ContextRefreshedEvent mockEvent = mock(ContextRefreshedEvent.class, - "createDefinedIndexesThrowingAnExceptionIsLogged.MockContextRefreshedEvent"); - - GemFireCache mockGemFireCache = mock(GemFireCache.class, - "createDefinedIndexesThrowingAnExceptionIsLogged.MockGemFireCache"); + "testCreateDefinedIndexesThrowingAnExceptionIsLogged.MockContextRefreshedEvent"); QueryService mockQueryService = mock(QueryService.class, - "createDefinedIndexesThrowingAnExceptionIsLogged.MockQueryService"); + "testCreateDefinedIndexesThrowingAnExceptionIsLogged.MockQueryService"); when(mockEvent.getApplicationContext()).thenReturn(mockApplicationContext); - when(mockApplicationContext.getBean(eq(GemFireCache.class))).thenReturn(mockGemFireCache); - when(mockGemFireCache.getQueryService()).thenReturn(mockQueryService); + when(mockApplicationContext.containsBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE))) + .thenReturn(true); + when(mockApplicationContext.getBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE), + eq(QueryService.class))).thenReturn(mockQueryService); when(mockQueryService.createDefinedIndexes()).thenThrow(new MultiIndexCreationException( new HashMap(Collections.singletonMap("TestKey", new RuntimeException("TEST"))))); - final Log mockLog = mock(Log.class, "createDefinedIndexesThrowingAnExceptionIsLogged.MockLog"); + final Log mockLog = mock(Log.class, "testCreateDefinedIndexesThrowingAnExceptionIsLogged.MockLog"); CreateDefinedIndexesApplicationListener listener = new CreateDefinedIndexesApplicationListener() { @Override Log initLogger() { @@ -143,30 +134,10 @@ public class CreateDefinedIndexesApplicationListenerTest { listener.onApplicationEvent(mockEvent); + verify(mockEvent, times(1)).getApplicationContext(); + verify(mockApplicationContext, times(1)).containsBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE)); + verify(mockApplicationContext, times(1)).getBean(eq(GemfireConstants.DEFAULT_GEMFIRE_INDEX_DEFINITION_QUERY_SERVICE), eq(QueryService.class)); verify(mockLog, times(1)).warn(startsWith("unable to create defined Indexes (if any):")); } - @Test - public void createDefinedIndexesUsingClientCacheLocalQueryService() throws Exception { - ApplicationContext mockApplicationContext = mock(ApplicationContext.class, - "createDefinedIndexesUsingClientCacheLocalQueryService.MockApplicationContext"); - - ContextRefreshedEvent mockEvent = mock(ContextRefreshedEvent.class, - "createDefinedIndexesUsingClientCacheLocalQueryService.MockContextRefreshedEvent"); - - ClientCache mockClientCache = mock(ClientCache.class, - "createDefinedIndexesUsingClientCacheLocalQueryService.MockGemFireCache"); - - QueryService mockQueryService = mock(QueryService.class, - "createDefinedIndexesUsingClientCacheLocalQueryService.MockQueryService"); - - when(mockEvent.getApplicationContext()).thenReturn(mockApplicationContext); - when(mockApplicationContext.getBean(eq(GemFireCache.class))).thenReturn(mockClientCache); - when(mockClientCache.getLocalQueryService()).thenReturn(mockQueryService); - - listener.onApplicationEvent(mockEvent); - - verify(mockQueryService, times(1)).createDefinedIndexes(); - } - } diff --git a/src/test/java/org/springframework/data/gemfire/config/CreateDefinedIndexesIntegrationTest.java b/src/test/java/org/springframework/data/gemfire/config/CreateDefinedIndexesIntegrationTest.java index e689537a..a0789622 100644 --- a/src/test/java/org/springframework/data/gemfire/config/CreateDefinedIndexesIntegrationTest.java +++ b/src/test/java/org/springframework/data/gemfire/config/CreateDefinedIndexesIntegrationTest.java @@ -16,12 +16,14 @@ package org.springframework.data.gemfire.config; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.io.Serializable; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.List; @@ -121,13 +123,14 @@ public class CreateDefinedIndexesIntegrationTest { public void indexesCreated() { QueryService queryService = gemfireCache.getQueryService(); - System.out.printf("GemFire Cache Indexes: %1$s%n", queryService.getIndexes()); - System.out.printf("/Example Region Indexes: %1$s%n", queryService.getIndexes(people)); - //assertTrue(definedIndexNames.containsAll(Arrays.asList(id.getName(), birthDate.getName(), fullName.getName()))); - assertSame(id, queryService.getIndex(people, id.getName())); - assertSame(birthDate, queryService.getIndex(people, birthDate.getName())); - assertSame(fullName, queryService.getIndex(people, fullName.getName())); - assertSame(lastName, queryService.getIndex(people, lastName.getName())); + //System.out.printf("GemFire Cache Indexes: %1$s%n", queryService.getIndexes()); + //System.out.printf("/Example Region Indexes: %1$s%n", queryService.getIndexes(people)); + + assertTrue(definedIndexNames.containsAll(Arrays.asList(id.getName(), birthDate.getName(), fullName.getName()))); + assertEquals(id, queryService.getIndex(people, id.getName())); + assertEquals(birthDate, queryService.getIndex(people, birthDate.getName())); + assertEquals(fullName, queryService.getIndex(people, fullName.getName())); + assertEquals(lastName, queryService.getIndex(people, lastName.getName())); } public static class IndexBeanPostProcessor implements BeanPostProcessor {