SGF-370 - Add multi-Index definition and creation support.
This commit is contained in:
@@ -25,10 +25,13 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
import com.gemstone.gemfire.cache.RegionService;
|
||||
import com.gemstone.gemfire.cache.client.ClientCache;
|
||||
import com.gemstone.gemfire.cache.query.Index;
|
||||
import com.gemstone.gemfire.cache.query.IndexExistsException;
|
||||
import com.gemstone.gemfire.cache.query.IndexInvalidException;
|
||||
import com.gemstone.gemfire.cache.query.IndexStatistics;
|
||||
import com.gemstone.gemfire.cache.query.QueryService;
|
||||
|
||||
/**
|
||||
@@ -47,6 +50,7 @@ import com.gemstone.gemfire.cache.query.QueryService;
|
||||
*/
|
||||
public class IndexFactoryBean implements InitializingBean, FactoryBean<Index>, BeanNameAware {
|
||||
|
||||
private boolean define = false;
|
||||
private boolean override = true;
|
||||
|
||||
private Index index;
|
||||
@@ -61,6 +65,7 @@ public class IndexFactoryBean implements InitializingBean, FactoryBean<Index>, B
|
||||
private String expression;
|
||||
private String from;
|
||||
private String imports;
|
||||
private String indexName;
|
||||
private String name;
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
@@ -68,15 +73,15 @@ public class IndexFactoryBean implements InitializingBean, FactoryBean<Index>, B
|
||||
|
||||
queryService = lookupQueryService();
|
||||
|
||||
Assert.notNull(queryService, "A QueryService is required for Index creation!");
|
||||
Assert.hasText(expression, "The Index 'expression' is required!");
|
||||
Assert.hasText(from, "The 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 (a Region's full-path) is required!");
|
||||
|
||||
if (IndexType.isKey(indexType)) {
|
||||
Assert.isNull(imports, "The 'imports' property is not supported for a Key Index.");
|
||||
}
|
||||
|
||||
String indexName = (StringUtils.hasText(name) ? name : beanName);
|
||||
indexName = (StringUtils.hasText(name) ? name : beanName);
|
||||
|
||||
Assert.hasText(indexName, "The Index bean id or name is required!");
|
||||
|
||||
@@ -103,7 +108,13 @@ public class IndexFactoryBean implements InitializingBean, FactoryBean<Index>, B
|
||||
|
||||
try {
|
||||
if (IndexType.isKey(indexType)) {
|
||||
return queryService.createKeyIndex(indexName, expression, from);
|
||||
if (isDefine()) {
|
||||
queryService.defineKeyIndex(indexName, expression, from);
|
||||
return new IndexWrapper(queryService, indexName);
|
||||
}
|
||||
else {
|
||||
return queryService.createKeyIndex(indexName, expression, from);
|
||||
}
|
||||
}
|
||||
else if (IndexType.isHash(indexType)) {
|
||||
return createHashIndex(queryService, indexName, expression, from, imports);
|
||||
@@ -132,21 +143,45 @@ public class IndexFactoryBean implements InitializingBean, FactoryBean<Index>, B
|
||||
Index createFunctionalIndex(QueryService queryService, String indexName, String expression, String from,
|
||||
String imports) throws Exception {
|
||||
if (StringUtils.hasText(imports)) {
|
||||
return queryService.createIndex(indexName, expression, from, imports);
|
||||
if (isDefine()) {
|
||||
queryService.defineIndex(indexName, expression, from , imports);
|
||||
}
|
||||
else {
|
||||
return queryService.createIndex(indexName, expression, from, imports);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return queryService.createIndex(indexName, expression, from);
|
||||
if (isDefine()) {
|
||||
queryService.defineIndex(indexName, expression, from);
|
||||
}
|
||||
else {
|
||||
return queryService.createIndex(indexName, expression, from);
|
||||
}
|
||||
}
|
||||
|
||||
return new IndexWrapper(queryService, indexName);
|
||||
}
|
||||
|
||||
Index createHashIndex(QueryService queryService, String indexName, String expression, String from,
|
||||
String imports) throws Exception {
|
||||
if (StringUtils.hasText(imports)) {
|
||||
return queryService.createHashIndex(indexName, expression, from, imports);
|
||||
if (isDefine()) {
|
||||
queryService.defineHashIndex(indexName, expression, from, imports);
|
||||
}
|
||||
else {
|
||||
return queryService.createHashIndex(indexName, expression, from, imports);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return queryService.createHashIndex(indexName, expression, from);
|
||||
if (isDefine()) {
|
||||
queryService.defineHashIndex(indexName, expression, from);
|
||||
}
|
||||
else {
|
||||
return queryService.createHashIndex(indexName, expression, from);
|
||||
}
|
||||
}
|
||||
|
||||
return new IndexWrapper(queryService, indexName);
|
||||
}
|
||||
|
||||
Index getExistingIndex(QueryService queryService, String indexName) {
|
||||
@@ -160,6 +195,7 @@ public class IndexFactoryBean implements InitializingBean, FactoryBean<Index>, B
|
||||
}
|
||||
|
||||
public Index getObject() {
|
||||
index = (index != null ? index : getExistingIndex(queryService, indexName));
|
||||
return index;
|
||||
}
|
||||
|
||||
@@ -200,6 +236,25 @@ public class IndexFactoryBean implements InitializingBean, FactoryBean<Index>, B
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a boolean condition to indicate whether the Index declared and defined by this FactoryBean will only be
|
||||
* defined initially, or defined and created. If defined-only, the IndexFactoryBean will receive a callback at
|
||||
* the end of the Spring container lifecycle to subsequently "create" all "defined-only" Indexes once, in a
|
||||
* single operation.
|
||||
*
|
||||
* @param define a boolean value indicating the define or define/create status. If true, the Index declared
|
||||
* by this FactoryBean will only be defined initially and subsequently created when this SmartLifecycle bean
|
||||
* receives an appropriate callback from the Spring container; if false, the Index will be created immediately.
|
||||
*/
|
||||
public void setDefine(boolean define) {
|
||||
this.define = define;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected boolean isDefine() {
|
||||
return define;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param expression the expression to set
|
||||
*/
|
||||
@@ -221,6 +276,13 @@ public class IndexFactoryBean implements InitializingBean, FactoryBean<Index>, B
|
||||
this.imports = imports;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param override the override to set
|
||||
*/
|
||||
public void setOverride(boolean override) {
|
||||
this.override = override;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param type the type to set
|
||||
*/
|
||||
@@ -239,11 +301,103 @@ public class IndexFactoryBean implements InitializingBean, FactoryBean<Index>, B
|
||||
this.indexType = indexType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param override the override to set
|
||||
*/
|
||||
public void setOverride(boolean override) {
|
||||
this.override = override;
|
||||
/* (non-Javadoc) */
|
||||
protected static final class IndexWrapper implements Index {
|
||||
|
||||
private Index index;
|
||||
|
||||
private final QueryService queryService;
|
||||
|
||||
private final String indexName;
|
||||
|
||||
protected IndexWrapper(final QueryService queryService, final String indexName) {
|
||||
Assert.notNull(queryService, "QueryService must not be null");
|
||||
Assert.hasText(indexName, "The name of the Index must be specified!");
|
||||
this.queryService = queryService;
|
||||
this.indexName = indexName;
|
||||
|
||||
}
|
||||
|
||||
protected synchronized Index getIndex() {
|
||||
if (this.index == null) {
|
||||
String localIndexName = getIndexName();
|
||||
|
||||
for (Index localIndex : getQueryService().getIndexes()) {
|
||||
if (localIndex.getName().equals(localIndexName)) {
|
||||
this.index = localIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.index == null) {
|
||||
throw new GemfireIndexException(new IndexInvalidException(String.format(
|
||||
"index with name (%1$s) was not found", localIndexName)));
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
protected String getIndexName() {
|
||||
Assert.state(StringUtils.hasText(indexName), "The Index 'name' was not properly initialized!");
|
||||
return indexName;
|
||||
}
|
||||
|
||||
protected QueryService getQueryService() {
|
||||
Assert.state(queryService != null, "The QueryService was not properly initialized!");
|
||||
return queryService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return getIndex().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCanonicalizedFromClause() {
|
||||
return getIndex().getCanonicalizedFromClause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCanonicalizedIndexedExpression() {
|
||||
return getIndex().getCanonicalizedIndexedExpression();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCanonicalizedProjectionAttributes() {
|
||||
return getIndex().getCanonicalizedProjectionAttributes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFromClause() {
|
||||
return getIndex().getFromClause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIndexedExpression() {
|
||||
return getIndex().getIndexedExpression();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProjectionAttributes() {
|
||||
return getIndex().getProjectionAttributes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Region<?, ?> getRegion() {
|
||||
return getIndex().getRegion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IndexStatistics getStatistics() {
|
||||
return getIndex().getStatistics();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public com.gemstone.gemfire.cache.query.IndexType getType() {
|
||||
return getIndex().getType();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2010-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.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.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;
|
||||
|
||||
/**
|
||||
* The CreateDefinedIndexesApplicationListener class is a Spring ApplicationListener used to create
|
||||
* all the GemFire Cache Region Indexes "defined" using the QueryService.defineXXXX(..) methods.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
public class CreateDefinedIndexesApplicationListener implements ApplicationListener<ContextRefreshedEvent> {
|
||||
|
||||
protected final Log logger = initLogger();
|
||||
|
||||
/**
|
||||
* Attempts to create all defined Indexes using the QueryService, defineXXXX(..) API once
|
||||
* the Spring ApplicationContext has been refreshed.
|
||||
*
|
||||
* @param event the ContextRefreshedEvent fired when the Spring ApplicationContext gets refreshed.
|
||||
* @see #getCache(org.springframework.context.event.ContextRefreshedEvent)
|
||||
* @see org.springframework.context.event.ContextRefreshedEvent
|
||||
* @see com.gemstone.gemfire.cache.Cache#getQueryService()
|
||||
* @see com.gemstone.gemfire.cache.client.ClientCache#getLocalQueryService()
|
||||
* @see com.gemstone.gemfire.cache.query.QueryService#createDefinedIndexes()
|
||||
*/
|
||||
@Override
|
||||
public void onApplicationEvent(final ContextRefreshedEvent event) {
|
||||
try {
|
||||
GemFireCache cache = getCache(event);
|
||||
|
||||
QueryService queryService = (cache instanceof ClientCache ? ((ClientCache) cache).getLocalQueryService()
|
||||
: cache.getQueryService());
|
||||
|
||||
queryService.createDefinedIndexes();
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
logger.warn(String.format("unable to create defined Indexes (if any): %1$s", ignore.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
Log initLogger() {
|
||||
return LogFactory.getLog(getClass());
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected GemFireCache getCache(final ContextRefreshedEvent event) {
|
||||
try {
|
||||
return event.getApplicationContext().getBean(GemFireCache.class);
|
||||
}
|
||||
catch (BeansException e) {
|
||||
return CacheFactory.getAnyInstance();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,7 +16,12 @@
|
||||
|
||||
package org.springframework.data.gemfire.config;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.data.gemfire.IndexFactoryBean;
|
||||
@@ -34,6 +39,20 @@ import org.w3c.dom.Element;
|
||||
*/
|
||||
class IndexParser extends AbstractSimpleBeanDefinitionParser {
|
||||
|
||||
private static final AtomicBoolean registered = new AtomicBoolean(false);
|
||||
|
||||
protected static void registerCreateDefinedIndexesApplicationListener(ParserContext parserContext) {
|
||||
if (registered.compareAndSet(false, true)) {
|
||||
AbstractBeanDefinition createDefinedIndexesApplicationListener = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(CreateDefinedIndexesApplicationListener.class)
|
||||
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
.getBeanDefinition();
|
||||
|
||||
BeanDefinitionReaderUtils.registerWithGeneratedName(createDefinedIndexesApplicationListener,
|
||||
parserContext.getRegistry());
|
||||
}
|
||||
|
||||
}
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return IndexFactoryBean.class;
|
||||
}
|
||||
@@ -45,6 +64,7 @@ class IndexParser extends AbstractSimpleBeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
registerCreateDefinedIndexesApplicationListener(parserContext);
|
||||
ParsingUtils.setPropertyReference(element, builder, "cache-ref", "cache");
|
||||
super.doParse(element, parserContext, builder);
|
||||
}
|
||||
|
||||
@@ -2485,10 +2485,10 @@ The name of the index bean definition. If property 'name' is not set, it will be
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="type" type="xsd:string" use="optional">
|
||||
<xsd:attribute name="cache-ref" type="xsd:string" use="optional" default="gemfireCache">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The type of index: FUNCTIONAL, HASH, PRIMARY_KEY.
|
||||
The name of the bean defining the GemFire cache (by default 'gemfireCache').
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
@@ -2499,6 +2499,21 @@ The name of the index.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="pool-name" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the pool used by the index. Used usually in client scenarios.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="define" type="xsd:string" use="optional" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Boolean condition used to lazily create this index once all indexes with define set to true are defined
|
||||
(i.e. declared and defined in the Spring context as Spring beans).
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expression" type="xsd:string" use="required" />
|
||||
<xsd:attribute name="from" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
@@ -2515,17 +2530,10 @@ Indicates whether the index is created even if there is an index with the same n
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="cache-ref" type="xsd:string" use="optional" default="gemfireCache">
|
||||
<xsd:attribute name="type" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the bean defining the GemFire cache (by default 'gemfireCache').
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="pool-name" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the pool used by the index. Used usually in client scenarios.
|
||||
The type of index: FUNCTIONAL, HASH, PRIMARY_KEY.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
|
||||
@@ -16,13 +16,17 @@
|
||||
|
||||
package org.springframework.data.gemfire;
|
||||
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
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.eq;
|
||||
import static org.mockito.Matchers.same;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
@@ -34,15 +38,20 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.data.util.ReflectionUtils;
|
||||
|
||||
import com.gemstone.gemfire.cache.Cache;
|
||||
import com.gemstone.gemfire.cache.client.ClientCache;
|
||||
import com.gemstone.gemfire.cache.query.Index;
|
||||
import com.gemstone.gemfire.cache.query.IndexExistsException;
|
||||
import com.gemstone.gemfire.cache.query.IndexInvalidException;
|
||||
import com.gemstone.gemfire.cache.query.IndexStatistics;
|
||||
import com.gemstone.gemfire.cache.query.QueryService;
|
||||
|
||||
/**
|
||||
@@ -60,15 +69,22 @@ import com.gemstone.gemfire.cache.query.QueryService;
|
||||
*/
|
||||
public class IndexFactoryBeanTest {
|
||||
|
||||
@Test
|
||||
public void testAfterPropertiesSet() throws Exception {
|
||||
QueryService mockQueryService = mock(QueryService.class, "testAfterPropertiesSet.MockQueryService");
|
||||
private IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
Cache mockCache = mock(Cache.class, "testAfterPropertiesSet.MockCache");
|
||||
@After
|
||||
public void tearDown() {
|
||||
indexFactoryBean.setDefine(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void afterPropertiesSetIsSuccessful() throws Exception {
|
||||
Cache mockCache = mock(Cache.class, "afterPropertiesSet.MockCache");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "afterPropertiesSet.MockQueryService");
|
||||
|
||||
when(mockCache.getQueryService()).thenReturn(mockQueryService);
|
||||
|
||||
final Index mockIndex = mock(Index.class, "testAfterPropertiesSet.MockIndex");
|
||||
final Index mockIndex = mock(Index.class, "afterPropertiesSet.MockIndex");
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean() {
|
||||
@Override Index createIndex(final QueryService queryService, final String indexName) throws Exception {
|
||||
@@ -90,7 +106,7 @@ public class IndexFactoryBeanTest {
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAfterPropertiesSetWithNullCache() throws Exception {
|
||||
public void afterPropertiesSetWithNullCache() throws Exception {
|
||||
try {
|
||||
new IndexFactoryBean().afterPropertiesSet();
|
||||
}
|
||||
@@ -101,9 +117,9 @@ public class IndexFactoryBeanTest {
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAfterPropertiesSetWithNullQueryService() throws Exception {
|
||||
public void afterPropertiesSetWithNullQueryService() throws Exception {
|
||||
try {
|
||||
Cache mockCache = mock(Cache.class, "testAfterPropertiesSetWithNullQueryService.MockCache");
|
||||
Cache mockCache = mock(Cache.class, "afterPropertiesSetWithNullQueryService.MockCache");
|
||||
|
||||
when(mockCache.getQueryService()).thenReturn(null);
|
||||
|
||||
@@ -113,18 +129,18 @@ public class IndexFactoryBeanTest {
|
||||
indexFactoryBean.afterPropertiesSet();
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertEquals("A QueryService is required for Index creation!", expected.getMessage());
|
||||
assertEquals("QueryService is required to create an Index!", expected.getMessage());
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAfterPropertiesSetWithUnspecifiedExpression() throws Exception {
|
||||
public void afterPropertiesSetWithUnspecifiedExpression() throws Exception {
|
||||
try {
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"testAfterPropertiesSetWithUnspecifiedExpression.MockQueryService");
|
||||
Cache mockCache = mock(Cache.class, "afterPropertiesSetWithUnspecifiedExpression.MockCache");
|
||||
|
||||
Cache mockCache = mock(Cache.class, "testAfterPropertiesSetWithUnspecifiedExpression.MockCache");
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"afterPropertiesSetWithUnspecifiedExpression.MockQueryService");
|
||||
|
||||
when(mockCache.getQueryService()).thenReturn(mockQueryService);
|
||||
|
||||
@@ -134,18 +150,18 @@ public class IndexFactoryBeanTest {
|
||||
indexFactoryBean.afterPropertiesSet();
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertEquals("The Index 'expression' is required!", expected.getMessage());
|
||||
assertEquals("Index 'expression' is required!", expected.getMessage());
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAfterPropertiesSetWithUnspecifiedFromClause() throws Exception {
|
||||
public void afterPropertiesSetWithUnspecifiedFromClause() throws Exception {
|
||||
try {
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"testAfterPropertiesSetWithUnspecifiedFromClause.MockQueryService");
|
||||
Cache mockCache = mock(Cache.class, "afterPropertiesSetWithUnspecifiedFromClause.MockCache");
|
||||
|
||||
Cache mockCache = mock(Cache.class, "testAfterPropertiesSetWithUnspecifiedFromClause.MockCache");
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"afterPropertiesSetWithUnspecifiedFromClause.MockQueryService");
|
||||
|
||||
when(mockCache.getQueryService()).thenReturn(mockQueryService);
|
||||
|
||||
@@ -156,18 +172,18 @@ public class IndexFactoryBeanTest {
|
||||
indexFactoryBean.afterPropertiesSet();
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertEquals("The Index 'from' clause (a Region's full-path) is required!", expected.getMessage());
|
||||
assertEquals("Index 'from' clause (a Region's full-path) is required!", expected.getMessage());
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAfterPropertiesSetWithUnspecifiedIndexName() throws Exception {
|
||||
public void afterPropertiesSetWithUnspecifiedIndexName() throws Exception {
|
||||
try {
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"testAfterPropertiesSetWithUnspecifiedIndexName.MockQueryService");
|
||||
Cache mockCache = mock(Cache.class, "afterPropertiesSetWithUnspecifiedIndexName.MockCache");
|
||||
|
||||
Cache mockCache = mock(Cache.class, "testAfterPropertiesSetWithUnspecifiedIndexName.MockCache");
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"afterPropertiesSetWithUnspecifiedIndexName.MockQueryService");
|
||||
|
||||
when(mockCache.getQueryService()).thenReturn(mockQueryService);
|
||||
|
||||
@@ -187,12 +203,12 @@ public class IndexFactoryBeanTest {
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAfterPropertiesSetWithInvalidTypeUsingImports() throws Exception {
|
||||
public void afterPropertiesSetWithInvalidTypeUsingImports() throws Exception {
|
||||
try {
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"testAfterPropertiesSetWithInvalidTypeUsingImports.MockQueryService");
|
||||
Cache mockCache = mock(Cache.class, "afterPropertiesSetWithInvalidTypeUsingImports.MockCache");
|
||||
|
||||
Cache mockCache = mock(Cache.class, "testAfterPropertiesSetWithInvalidTypeUsingImports.MockCache");
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"afterPropertiesSetWithInvalidTypeUsingImports.MockQueryService");
|
||||
|
||||
when(mockCache.getQueryService()).thenReturn(mockQueryService);
|
||||
|
||||
@@ -231,10 +247,10 @@ public class IndexFactoryBeanTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLookupQueryServiceOnClientCache() {
|
||||
QueryService mockQueryService = mock(QueryService.class, "testLookupQueryServiceOnClientCache.MockQueryService");
|
||||
public void lookupQueryServiceOnClientCache() {
|
||||
ClientCache mockClientCache = mock(ClientCache.class, "lookupQueryServiceOnClientCache.MockClientCache");
|
||||
|
||||
ClientCache mockClientCache = mock(ClientCache.class, "testLookupQueryServiceOnClientCache.MockClientCache");
|
||||
QueryService mockQueryService = mock(QueryService.class, "lookupQueryServiceOnClientCache.MockQueryService");
|
||||
|
||||
when(mockClientCache.getLocalQueryService()).thenReturn(mockQueryService);
|
||||
|
||||
@@ -248,10 +264,10 @@ public class IndexFactoryBeanTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLookupQueryServiceOnPeerCache() {
|
||||
QueryService mockQueryService = mock(QueryService.class, "testLookupQueryServiceOnPeerCache.MockQueryService");
|
||||
public void lookupQueryServiceOnPeerCache() {
|
||||
Cache mockCache = mock(Cache.class, "lookupQueryServiceOnPeerCache.MockCache");
|
||||
|
||||
Cache mockCache = mock(Cache.class, "testLookupQueryServiceOnPeerCache.MockCache");
|
||||
QueryService mockQueryService = mock(QueryService.class, "lookupQueryServiceOnPeerCache.MockQueryService");
|
||||
|
||||
when(mockCache.getQueryService()).thenReturn(mockQueryService);
|
||||
|
||||
@@ -266,10 +282,10 @@ public class IndexFactoryBeanTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateIndexReturnsNewKeyIndex() throws Exception {
|
||||
Index mockIndex = mock(Index.class, "testCreateIndexReturnsNewKeyIndex.MockIndex");
|
||||
public void createIndexReturningNewKeyIndex() throws Exception {
|
||||
Index mockIndex = mock(Index.class, "createIndexReturningNewKeyIndex.MockIndex");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "testCreateIndexReturnsNewKeyIndex.MockQueryService");
|
||||
QueryService mockQueryService = mock(QueryService.class, "createIndexReturningNewKeyIndex.MockQueryService");
|
||||
|
||||
when(mockQueryService.getIndexes()).thenReturn(Collections.<Index>emptyList());
|
||||
when(mockQueryService.createKeyIndex(eq("KeyIndex"), eq("id"), eq("/Example"))).thenReturn(mockIndex);
|
||||
@@ -285,13 +301,15 @@ public class IndexFactoryBeanTest {
|
||||
Index actualIndex = indexFactoryBean.createIndex(mockQueryService, "KeyIndex");
|
||||
|
||||
assertSame(mockIndex, actualIndex);
|
||||
|
||||
verify(mockQueryService, times(1)).createKeyIndex(eq("KeyIndex"), eq("id"), eq("/Example"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateIndexReturnsNewHashIndex() throws Exception {
|
||||
Index mockIndex = mock(Index.class, "testCreateIndexReturnsNewHashIndex.MockIndex");
|
||||
public void createIndexReturningNewHashIndex() throws Exception {
|
||||
Index mockIndex = mock(Index.class, "createIndexReturningNewHashIndex.MockIndex");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "testCreateIndexReturnsNewHashIndex.MockQueryService");
|
||||
QueryService mockQueryService = mock(QueryService.class, "createIndexReturningNewHashIndex.MockQueryService");
|
||||
|
||||
when(mockQueryService.getIndexes()).thenReturn(Collections.<Index>emptyList());
|
||||
when(mockQueryService.createHashIndex(eq("HashIndex"), eq("name"), eq("/Animals"), eq("org.example.Dog")))
|
||||
@@ -309,14 +327,17 @@ public class IndexFactoryBeanTest {
|
||||
Index actualIndex = indexFactoryBean.createIndex(mockQueryService, "HashIndex");
|
||||
|
||||
assertSame(mockIndex, actualIndex);
|
||||
|
||||
verify(mockQueryService, times(1)).createHashIndex(eq("HashIndex"), eq("name"), eq("/Animals"),
|
||||
eq("org.example.Dog"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateIndexReturnsNewFunctionalIndex() throws Exception {
|
||||
Index mockIndex = mock(Index.class, "testCreateIndexReturnsNewFunctionalIndex.MockIndex");
|
||||
public void createIndexReturningNewFunctionalIndex() throws Exception {
|
||||
Index mockIndex = mock(Index.class, "createIndexReturningNewFunctionalIndex.MockIndex");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"testCreateIndexReturnsNewFunctionalIndex.MockQueryService");
|
||||
"createIndexReturningNewFunctionalIndex.MockQueryService");
|
||||
|
||||
when(mockQueryService.getIndexes()).thenReturn(Collections.<Index>emptyList());
|
||||
when(mockQueryService.createIndex(eq("FunctionalIndex"), eq("someField"), eq("/Example")))
|
||||
@@ -334,14 +355,16 @@ public class IndexFactoryBeanTest {
|
||||
Index actualIndex = indexFactoryBean.createIndex(mockQueryService, "FunctionalIndex");
|
||||
|
||||
assertSame(mockIndex, actualIndex);
|
||||
|
||||
verify(mockQueryService, times(1)).createIndex(eq("FunctionalIndex"), eq("someField"), eq("/Example"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateIndexReturnsExistingIndex() throws Exception {
|
||||
Index mockExistingIndex = mock(Index.class, "testCreateIndexReturnsExistingIndex.MockIndex.Existing");
|
||||
Index mockIndexTwo = mock(Index.class, "testCreateIndexReturnsExistingIndex.MockIndex.Two");
|
||||
public void createIndexReturnsExistingIndex() throws Exception {
|
||||
Index mockExistingIndex = mock(Index.class, "createIndexReturnsExistingIndex.MockIndex.Existing");
|
||||
Index mockIndexTwo = mock(Index.class, "createIndexReturnsExistingIndex.MockIndex.Two");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "testCreateIndexReturnsExistingIndex.MockQueryService");
|
||||
QueryService mockQueryService = mock(QueryService.class, "createIndexReturnsExistingIndex.MockQueryService");
|
||||
|
||||
when(mockExistingIndex.getName()).thenReturn("ExistingIndex");
|
||||
when(mockIndexTwo.getName()).thenReturn("IndexTwo");
|
||||
@@ -358,12 +381,12 @@ public class IndexFactoryBeanTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateIndexReturnsExistingIndexForIndexExistsException() throws Exception {
|
||||
public void createIndexReturnsExistingIndexAndThrowsIndexExistsExceptionOnCreate() throws Exception {
|
||||
Index mockExistingIndex = mock(Index.class,
|
||||
"testCreateIndexReturnsExistingIndexForIndexExistsException.MockIndex.Existing");
|
||||
"createIndexReturnsExistingIndexAndThrowsIndexExistsExceptionOnCreate.MockIndex.Existing");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"testCreateIndexReturnsExistingIndexForIndexExistsException.MockQueryService");
|
||||
"createIndexReturnsExistingIndexAndThrowsIndexExistsExceptionOnCreate.MockQueryService");
|
||||
|
||||
when(mockExistingIndex.getName()).thenReturn("ExistingIndex");
|
||||
when(mockQueryService.getIndexes()).thenReturn(Collections.singletonList(mockExistingIndex));
|
||||
@@ -385,15 +408,15 @@ public class IndexFactoryBeanTest {
|
||||
verify(mockExistingIndex, times(2)).getName();
|
||||
verify(mockQueryService, times(2)).getIndexes();
|
||||
verify(mockQueryService, times(1)).removeIndex(same(mockExistingIndex));
|
||||
verify(mockQueryService, times(1)).createKeyIndex(eq("ExistingIndex"), eq("id"), eq("/Example"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateIndexOverridesExistingIndex() throws Exception {
|
||||
Index mockExistingIndex = mock(Index.class, "testCreateIndexOverridesExistingIndex.MockIndex.Existing");
|
||||
Index mockOverridingIndex = mock(Index.class, "testCreateIndexOverridesExistingIndex.MockIndex.Overriding");
|
||||
public void createIndexOverridesExistingIndex() throws Exception {
|
||||
Index mockExistingIndex = mock(Index.class, "createIndexOverridesExistingIndex.MockIndex.Existing");
|
||||
Index mockOverridingIndex = mock(Index.class, "createIndexOverridesExistingIndex.MockIndex.Overriding");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"testCreateIndexOverridesExistingIndex.MockQueryService");
|
||||
QueryService mockQueryService = mock(QueryService.class, "createIndexOverridesExistingIndex.MockQueryService");
|
||||
|
||||
when(mockExistingIndex.getName()).thenReturn("ExistingIndex");
|
||||
when(mockOverridingIndex.getName()).thenReturn("OverridingIndex");
|
||||
@@ -415,19 +438,21 @@ public class IndexFactoryBeanTest {
|
||||
|
||||
verify(mockQueryService, times(1)).getIndexes();
|
||||
verify(mockQueryService, times(1)).removeIndex(same(mockExistingIndex));
|
||||
verify(mockQueryService, times(1)).createHashIndex(eq("ExistingIndex"), eq("someField"), eq("/Example"),
|
||||
eq("org.example.DomainType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateIndexAddsExistingIndexOnException() throws Exception {
|
||||
final Index mockExistingIndex = mock(Index.class, "testCreateIndexAddsExistingIndexOnException.MockIndex.Existing");
|
||||
final Index mockIndexTwo = mock(Index.class, "testCreateIndexAddsExistingIndexOnException.MockIndex.Two");
|
||||
public void createIndexAddsExistingIndexOnException() throws Exception {
|
||||
final Index mockExistingIndex = mock(Index.class, "createIndexAddsExistingIndexOnException.MockIndex.Existing");
|
||||
final Index mockIndexTwo = mock(Index.class, "createIndexAddsExistingIndexOnException.MockIndex.Two");
|
||||
|
||||
final List<Index> indexes = new ArrayList<Index>(1);
|
||||
|
||||
indexes.add(mockIndexTwo);
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"testCreateIndexAddsExistingIndexOnException.MockQueryService");
|
||||
"createIndexAddsExistingIndexOnException.MockQueryService");
|
||||
|
||||
when(mockExistingIndex.getName()).thenReturn("ExistingIndex");
|
||||
when(mockIndexTwo.getName()).thenReturn("IndexTwo");
|
||||
@@ -469,13 +494,15 @@ public class IndexFactoryBeanTest {
|
||||
|
||||
verify(mockQueryService, times(3)).getIndexes();
|
||||
verify(mockQueryService, times(1)).removeIndex(same(mockExistingIndex));
|
||||
verify(mockQueryService, times(1)).createIndex(eq("ExistingIndex"), eq("someField"), eq("/Example"));
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void testCreateIndexThrowsException() throws Exception {
|
||||
Index mockExistingIndex = mock(Index.class, "testCreateIndexThrowsException.MockIndex.Existing");
|
||||
public void createIndexThrowsExceptionOnAbsoluteFailure() throws Exception {
|
||||
Index mockExistingIndex = mock(Index.class, "createIndexThrowsExceptionOnAbsoluteFailure.MockIndex.Existing");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "testCreateIndexThrowsException.MockQueryService");
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"createIndexThrowsExceptionOnAbsoluteFailure.MockQueryService");
|
||||
|
||||
when(mockExistingIndex.getName()).thenReturn("ExistingIndex");
|
||||
when(mockQueryService.getIndexes()).thenReturn(Collections.singletonList(mockExistingIndex));
|
||||
@@ -498,83 +525,209 @@ public class IndexFactoryBeanTest {
|
||||
finally {
|
||||
verify(mockQueryService, times(2)).getIndexes();
|
||||
verify(mockQueryService, times(1)).removeIndex(same(mockExistingIndex));
|
||||
verify(mockQueryService, times(1)).createIndex(eq("ExistingIndex"), eq("someField"), eq("/Example"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateFunctionalIndex() throws Exception {
|
||||
Index mockIndex = mock(Index.class, "testCreateFunctionalIndex.MockIndex");
|
||||
public void createIndexDefinesKeyIndex() throws Exception {
|
||||
QueryService mockQueryService = mock(QueryService.class, "createIndexDefinesKeyIndex.MockQueryService");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "testCreateFunctionalIndex.MockQueryService");
|
||||
when(mockQueryService.getIndexes()).thenReturn(Collections.<Index>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");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "createFunctionalIndex.MockQueryService");
|
||||
|
||||
when(mockQueryService.createIndex(eq("FunctionalIndex"), eq("purchaseDate"), eq("/Orders")))
|
||||
.thenReturn(mockIndex);
|
||||
|
||||
Index actualIndex = new IndexFactoryBean().createFunctionalIndex(mockQueryService, "FunctionalIndex",
|
||||
Index actualIndex = indexFactoryBean.createFunctionalIndex(mockQueryService, "FunctionalIndex",
|
||||
"purchaseDate", "/Orders", null);
|
||||
|
||||
assertSame(mockIndex, actualIndex);
|
||||
|
||||
verify(mockQueryService, times(1)).createIndex(eq("FunctionalIndex"), eq("purchaseDate"), eq("/Orders"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateFunctionalIndexWithImports() throws Exception {
|
||||
Index mockIndex = mock(Index.class, "testCreateFunctionalIndexWithImports.MockIndex");
|
||||
public void createFunctionalIndexWithImports() throws Exception {
|
||||
Index mockIndex = mock(Index.class, "createFunctionalIndexWithImports.MockIndex");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "testCreateFunctionalIndexWithImports.MockQueryService");
|
||||
QueryService mockQueryService = mock(QueryService.class, "createFunctionalIndexWithImports.MockQueryService");
|
||||
|
||||
when(mockQueryService.createIndex(eq("FunctionalIndexWithImports"), eq("purchaseDate"), eq("/Orders"),
|
||||
eq("org.example.Order"))).thenReturn(mockIndex);
|
||||
|
||||
Index actualIndex = new IndexFactoryBean().createFunctionalIndex(mockQueryService, "FunctionalIndexWithImports",
|
||||
Index actualIndex = indexFactoryBean.createFunctionalIndex(mockQueryService, "FunctionalIndexWithImports",
|
||||
"purchaseDate", "/Orders", "org.example.Order");
|
||||
|
||||
assertSame(mockIndex, actualIndex);
|
||||
|
||||
verify(mockQueryService, times(1)).createIndex(eq("FunctionalIndexWithImports"), eq("purchaseDate"),
|
||||
eq("/Orders"), eq("org.example.Order"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateHashIndex() throws Exception {
|
||||
Index mockIndex = mock(Index.class, "testCreateHashIndex.MockIndex");
|
||||
public void defineFunctionalIndex() throws Exception {
|
||||
QueryService mockQueryService = mock(QueryService.class, "defineFunctionalIndex.MockQueryService");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "testCreateHashIndex.MockQueryService");
|
||||
doAnswer(new Answer<Void>() {
|
||||
@Override public Void answer(final InvocationOnMock invocation) throws Throwable {
|
||||
return null;
|
||||
}
|
||||
}).when(mockQueryService).defineIndex(eq("FunctionalIndex"), eq("purchaseDate"), eq("/Orders"));
|
||||
|
||||
indexFactoryBean.setDefine(true);
|
||||
|
||||
Index actualIndex = indexFactoryBean.createFunctionalIndex(mockQueryService, "FunctionalIndex",
|
||||
"purchaseDate", "/Orders", null);
|
||||
|
||||
assertTrue(actualIndex instanceof IndexFactoryBean.IndexWrapper);
|
||||
assertSame(mockQueryService, ((IndexFactoryBean.IndexWrapper) actualIndex).getQueryService());
|
||||
assertEquals("FunctionalIndex", ((IndexFactoryBean.IndexWrapper) actualIndex).getIndexName());
|
||||
|
||||
verify(mockQueryService, times(1)).defineIndex(eq("FunctionalIndex"), eq("purchaseDate"), eq("/Orders"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defineFunctionalIndexWithImports() throws Exception {
|
||||
QueryService mockQueryService = mock(QueryService.class, "defineFunctionalIndexWithImports.MockQueryService");
|
||||
|
||||
doAnswer(new Answer<Void>() {
|
||||
@Override public Void answer(final InvocationOnMock invocation) throws Throwable {
|
||||
return null;
|
||||
}
|
||||
}).when(mockQueryService).defineIndex(eq("FunctionalIndex"), eq("purchaseDate"), eq("/Orders"),
|
||||
eq("org.example.Order"));
|
||||
|
||||
indexFactoryBean.setDefine(true);
|
||||
|
||||
Index actualIndex = indexFactoryBean.createFunctionalIndex(mockQueryService, "FunctionalIndex",
|
||||
"purchaseDate", "/Orders", "org.example.Order");
|
||||
|
||||
assertTrue(actualIndex instanceof IndexFactoryBean.IndexWrapper);
|
||||
assertSame(mockQueryService, ((IndexFactoryBean.IndexWrapper) actualIndex).getQueryService());
|
||||
assertEquals("FunctionalIndex", ((IndexFactoryBean.IndexWrapper) actualIndex).getIndexName());
|
||||
|
||||
verify(mockQueryService, times(1)).defineIndex(eq("FunctionalIndex"), eq("purchaseDate"), eq("/Orders"),
|
||||
eq("org.example.Order"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createHashIndex() throws Exception {
|
||||
Index mockIndex = mock(Index.class, "createHashIndex.MockIndex");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "createHashIndex.MockQueryService");
|
||||
|
||||
when(mockQueryService.createHashIndex(eq("HashIndex"), eq("name"), eq("/People"))).thenReturn(mockIndex);
|
||||
|
||||
Index actualIndex = new IndexFactoryBean().createHashIndex(mockQueryService, "HashIndex",
|
||||
Index actualIndex = indexFactoryBean.createHashIndex(mockQueryService, "HashIndex",
|
||||
"name", "/People", " ");
|
||||
|
||||
assertSame(mockIndex, actualIndex);
|
||||
|
||||
verify(mockQueryService, times(1)).createHashIndex(eq("HashIndex"), eq("name"), eq("/People"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateHashIndexWithImports() throws Exception {
|
||||
Index mockIndex = mock(Index.class, "testCreateHashIndexWithImports.MockIndex");
|
||||
public void createHashIndexWithImports() throws Exception {
|
||||
Index mockIndex = mock(Index.class, "createHashIndexWithImports.MockIndex");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "testCreateHashIndexWithImports.MockQueryService");
|
||||
QueryService mockQueryService = mock(QueryService.class, "createHashIndexWithImports.MockQueryService");
|
||||
|
||||
when(mockQueryService.createHashIndex(eq("HashIndexWithImports"), eq("name"), eq("/People"),
|
||||
eq("org.example.Person"))).thenReturn(mockIndex);
|
||||
|
||||
Index actualIndex = new IndexFactoryBean().createHashIndex(mockQueryService, "HashIndexWithImports",
|
||||
Index actualIndex = indexFactoryBean.createHashIndex(mockQueryService, "HashIndexWithImports",
|
||||
"name", "/People", "org.example.Person");
|
||||
|
||||
assertSame(mockIndex, actualIndex);
|
||||
|
||||
verify(mockQueryService, times(1)).createHashIndex(eq("HashIndexWithImports"), eq("name"), eq("/People"),
|
||||
eq("org.example.Person"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetExistingIndex() {
|
||||
Index mockIndexOne = mock(Index.class, "testGetExistingIndex.MockIndex.One");
|
||||
Index mockIndexTwo = mock(Index.class, "testGetExistingIndex.MockIndex.Two");
|
||||
Index mockIndexThree = mock(Index.class, "testGetExistingIndex.MockIndex.Two");
|
||||
public void defineHashIndex() throws Exception {
|
||||
QueryService mockQueryService = mock(QueryService.class, "defineHashIndex.MockQueryService");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "testGetExistingIndex.MockQueryService");
|
||||
doAnswer(new Answer<Void>() {
|
||||
@Override public Void answer(final InvocationOnMock invocation) throws Throwable {
|
||||
return null;
|
||||
}
|
||||
}).when(mockQueryService).defineHashIndex(eq("HashIndex"), eq("name"), eq("/People"));
|
||||
|
||||
indexFactoryBean.setDefine(true);
|
||||
|
||||
Index actualIndex = indexFactoryBean.createHashIndex(mockQueryService, "HashIndex",
|
||||
"name", "/People", " ");
|
||||
|
||||
assertTrue(actualIndex instanceof IndexFactoryBean.IndexWrapper);
|
||||
assertSame(mockQueryService, ((IndexFactoryBean.IndexWrapper) actualIndex).getQueryService());
|
||||
assertEquals("HashIndex", ((IndexFactoryBean.IndexWrapper) actualIndex).getIndexName());
|
||||
|
||||
verify(mockQueryService, times(1)).defineHashIndex(eq("HashIndex"), eq("name"), eq("/People"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defineHashIndexWithImports() throws Exception {
|
||||
QueryService mockQueryService = mock(QueryService.class, "defineHashIndex.MockQueryService");
|
||||
|
||||
doAnswer(new Answer<Void>() {
|
||||
@Override public Void answer(final InvocationOnMock invocation) throws Throwable {
|
||||
return null;
|
||||
}
|
||||
}).when(mockQueryService).defineHashIndex(eq("HashIndex"), eq("name"), eq("/People"), eq("org.example.Person"));
|
||||
|
||||
indexFactoryBean.setDefine(true);
|
||||
|
||||
Index actualIndex = indexFactoryBean.createHashIndex(mockQueryService, "HashIndex",
|
||||
"name", "/People", "org.example.Person");
|
||||
|
||||
assertTrue(actualIndex instanceof IndexFactoryBean.IndexWrapper);
|
||||
assertSame(mockQueryService, ((IndexFactoryBean.IndexWrapper) actualIndex).getQueryService());
|
||||
assertEquals("HashIndex", ((IndexFactoryBean.IndexWrapper) actualIndex).getIndexName());
|
||||
|
||||
verify(mockQueryService, times(1)).defineHashIndex(eq("HashIndex"), 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");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "getExistingIndex.MockQueryService");
|
||||
|
||||
when(mockIndexOne.getName()).thenReturn("PrimaryIndex");
|
||||
when(mockIndexTwo.getName()).thenReturn("SecondaryIndex");
|
||||
when(mockIndexThree.getName()).thenReturn("TernaryIndex");
|
||||
when(mockQueryService.getIndexes()).thenReturn(Arrays.asList(mockIndexOne, mockIndexTwo, mockIndexThree));
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
assertNull(indexFactoryBean.getExistingIndex(mockQueryService, null));
|
||||
assertNull(indexFactoryBean.getExistingIndex(mockQueryService, ""));
|
||||
assertNull(indexFactoryBean.getExistingIndex(mockQueryService, " "));
|
||||
@@ -586,4 +739,126 @@ public class IndexFactoryBeanTest {
|
||||
assertSame(mockIndexThree, indexFactoryBean.getExistingIndex(mockQueryService, "ternaryindex"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getObjectLooksUpIndex() throws Exception {
|
||||
QueryService mockQueryService = mock(QueryService.class, "getObjectLooksUpIndex.MockQueryService");
|
||||
|
||||
when(mockQueryService.getIndexes()).then(new Answer<Collection<Index>>() {
|
||||
private final AtomicInteger counter = new AtomicInteger(1);
|
||||
@Override public Collection<Index> answer(final InvocationOnMock invocation) throws Throwable {
|
||||
Index mockIndex = mock(Index.class, "getObjectLooksUpIndex.MockIndex");
|
||||
when(mockIndex.getName()).thenReturn(String.format("MockIndex%1$s", counter.getAndIncrement()));
|
||||
return Collections.singletonList(mockIndex);
|
||||
}
|
||||
});
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
indexFactoryBean.setQueryService(mockQueryService);
|
||||
indexFactoryBean.setName("MockIndex1");
|
||||
ReflectionUtils.setField(IndexFactoryBean.class.getDeclaredField("indexName"), indexFactoryBean, "MockIndex1");
|
||||
|
||||
Index actualIndex = indexFactoryBean.getObject();
|
||||
|
||||
assertNotNull(actualIndex);
|
||||
assertEquals("MockIndex1", actualIndex.getName());
|
||||
|
||||
Index sameIndex = indexFactoryBean.getObject();
|
||||
|
||||
assertSame(actualIndex, sameIndex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void indexFactoryBeanCreatesSingleIndex() {
|
||||
assertTrue(indexFactoryBean.isSingleton());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void indexWrapperDelegation() {
|
||||
Index mockIndex = mock(Index.class, "indexWrapperDelegation.MockIndex");
|
||||
|
||||
IndexStatistics mockIndexStats = mock(IndexStatistics.class, "indexWrapperDelegation.MockIndexStats");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "indexWrapperDelegation.MockQueryService");
|
||||
|
||||
when(mockIndex.getCanonicalizedFromClause()).thenReturn("/Example");
|
||||
when(mockIndex.getCanonicalizedIndexedExpression()).thenReturn("ID");
|
||||
when(mockIndex.getCanonicalizedProjectionAttributes()).thenReturn("identifier");
|
||||
when(mockIndex.getFromClause()).thenReturn("Example");
|
||||
when(mockIndex.getIndexedExpression()).thenReturn("id");
|
||||
when(mockIndex.getName()).thenReturn("MockIndex");
|
||||
when(mockIndex.getProjectionAttributes()).thenReturn("id");
|
||||
when(mockIndex.getStatistics()).thenReturn(mockIndexStats);
|
||||
when(mockIndex.getType()).thenReturn(com.gemstone.gemfire.cache.query.IndexType.HASH);
|
||||
when(mockQueryService.getIndexes()).thenReturn(Collections.singletonList(mockIndex));
|
||||
|
||||
IndexFactoryBean.IndexWrapper indexWrapper = new IndexFactoryBean.IndexWrapper(mockQueryService, "MockIndex");
|
||||
|
||||
assertNotNull(indexWrapper);
|
||||
assertEquals("MockIndex", indexWrapper.getIndexName());
|
||||
assertSame(mockQueryService, indexWrapper.getQueryService());
|
||||
|
||||
Index actualIndex = indexWrapper.getIndex();
|
||||
|
||||
assertSame(mockIndex, actualIndex);
|
||||
assertEquals("/Example", indexWrapper.getCanonicalizedFromClause());
|
||||
assertEquals("ID", indexWrapper.getCanonicalizedIndexedExpression());
|
||||
assertEquals("identifier", indexWrapper.getCanonicalizedProjectionAttributes());
|
||||
assertEquals("Example", indexWrapper.getFromClause());
|
||||
assertEquals("id", indexWrapper.getIndexedExpression());
|
||||
assertEquals("MockIndex", indexWrapper.getName());
|
||||
assertEquals("id", indexWrapper.getProjectionAttributes());
|
||||
assertSame(mockIndexStats, indexWrapper.getStatistics());
|
||||
assertEquals(com.gemstone.gemfire.cache.query.IndexType.HASH, indexWrapper.getType());
|
||||
|
||||
Index sameIndex = indexWrapper.getIndex();
|
||||
|
||||
assertSame(actualIndex, sameIndex);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void createIndexWrapperWithNullQueryService() {
|
||||
try {
|
||||
new IndexFactoryBean.IndexWrapper(null, "TestIndex");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertEquals("QueryService must not be null", expected.getMessage());
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void createIndexWrapperWithUnspecifiedIndexName() {
|
||||
try {
|
||||
new IndexFactoryBean.IndexWrapper(mock(QueryService.class), " ");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertEquals("The name of the Index must be specified!", expected.getMessage());
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = GemfireIndexException.class)
|
||||
public void indexWrapperGetIndexWhenIndexNotFound() {
|
||||
QueryService mockQueryService = mock(QueryService.class, "indexWrapperGetIndexWhenIndexNotFound.MockQueryService");
|
||||
|
||||
when(mockQueryService.getIndexes()).thenReturn(Collections.<Index>emptyList());
|
||||
|
||||
IndexFactoryBean.IndexWrapper indexWrapper = new IndexFactoryBean.IndexWrapper(mockQueryService, "NonExistingIndex");
|
||||
|
||||
assertNotNull(indexWrapper);
|
||||
assertEquals("NonExistingIndex", indexWrapper.getIndexName());
|
||||
assertSame(mockQueryService, indexWrapper.getQueryService());
|
||||
|
||||
try {
|
||||
indexWrapper.getIndex();
|
||||
}
|
||||
catch (GemfireIndexException expected) {
|
||||
assertThat(expected.getMessage(), startsWith("index with name (NonExistingIndex) was not found"));
|
||||
assertTrue(expected.getCause() instanceof IndexInvalidException);
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright 2010-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.config;
|
||||
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.startsWith;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Collections;
|
||||
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;
|
||||
|
||||
/**
|
||||
* The CreateDefinedIndexesApplicationListenerTest class is a test suite of test cases testing the contract
|
||||
* and functionality of the CreateDefinedIndexesApplicationListener class.
|
||||
*
|
||||
* @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 com.gemstone.gemfire.cache.query.QueryService
|
||||
* @since 1.7.0
|
||||
*/
|
||||
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");
|
||||
|
||||
ContextRefreshedEvent mockEvent = mock(ContextRefreshedEvent.class,
|
||||
"createDefinedIndexesCalledOnContextRefreshedEvent.MockContextRefreshedEvent");
|
||||
|
||||
GemFireCache mockGemFireCache = mock(GemFireCache.class,
|
||||
"createDefinedIndexesCalledOnContextRefreshedEvent.MockGemFireCache");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"createDefinedIndexesCalledOnContextRefreshedEvent.MockQueryService");
|
||||
|
||||
when(mockEvent.getApplicationContext()).thenReturn(mockApplicationContext);
|
||||
when(mockApplicationContext.getBean(eq(GemFireCache.class))).thenReturn(mockGemFireCache);
|
||||
when(mockGemFireCache.getQueryService()).thenReturn(mockQueryService);
|
||||
|
||||
listener.onApplicationEvent(mockEvent);
|
||||
|
||||
verify(mockQueryService, times(1)).createDefinedIndexes();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createDefinedIndexesThrowingAnExceptionIsLogged() throws Exception {
|
||||
ApplicationContext mockApplicationContext = mock(ApplicationContext.class,
|
||||
"createDefinedIndexesThrowingAnExceptionIsLogged.MockApplicationContext");
|
||||
|
||||
ContextRefreshedEvent mockEvent = mock(ContextRefreshedEvent.class,
|
||||
"createDefinedIndexesThrowingAnExceptionIsLogged.MockContextRefreshedEvent");
|
||||
|
||||
GemFireCache mockGemFireCache = mock(GemFireCache.class,
|
||||
"createDefinedIndexesThrowingAnExceptionIsLogged.MockGemFireCache");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"createDefinedIndexesThrowingAnExceptionIsLogged.MockQueryService");
|
||||
|
||||
when(mockEvent.getApplicationContext()).thenReturn(mockApplicationContext);
|
||||
when(mockApplicationContext.getBean(eq(GemFireCache.class))).thenReturn(mockGemFireCache);
|
||||
when(mockGemFireCache.getQueryService()).thenReturn(mockQueryService);
|
||||
when(mockQueryService.createDefinedIndexes()).thenThrow(new MultiIndexCreationException(
|
||||
new HashMap<String, Exception>(Collections.singletonMap("TestKey", new RuntimeException("TEST")))));
|
||||
|
||||
final Log mockLog = mock(Log.class, "createDefinedIndexesThrowingAnExceptionIsLogged.MockLog");
|
||||
|
||||
CreateDefinedIndexesApplicationListener listener = new CreateDefinedIndexesApplicationListener() {
|
||||
@Override Log initLogger() {
|
||||
return mockLog;
|
||||
}
|
||||
};
|
||||
|
||||
listener.onApplicationEvent(mockEvent);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user