SGF-366 - Unable to create local-only, client-based Region Indexes using SDG's <gfe:index> and corresponding IndexFactoryBean functionality.
Signed-off-by: John Blum <jblum@pivotal.io>
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.data.gemfire;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
@@ -30,103 +32,131 @@ import com.gemstone.gemfire.cache.query.IndexExistsException;
|
||||
import com.gemstone.gemfire.cache.query.QueryService;
|
||||
|
||||
/**
|
||||
* Factory bean for easy declarative creation of GemFire Indexes.
|
||||
* Spring FactoryBean for easy declarative creation of GemFire Indexes.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see org.springframework.beans.factory.InitializingBean
|
||||
* @see org.springframework.beans.factory.BeanNameAware
|
||||
* @see org.springframework.beans.factory.FactoryBean
|
||||
* @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, BeanNameAware, FactoryBean<Index> {
|
||||
public class IndexFactoryBean implements InitializingBean, FactoryBean<Index>, BeanNameAware {
|
||||
|
||||
private boolean override = true;
|
||||
|
||||
private Index index;
|
||||
|
||||
private IndexType indexType;
|
||||
|
||||
private QueryService queryService;
|
||||
|
||||
private RegionService cache;
|
||||
|
||||
private String beanName;
|
||||
private String name;
|
||||
private String expression;
|
||||
private String from;
|
||||
private String imports;
|
||||
private String type;
|
||||
private boolean override = true;
|
||||
private String name;
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (queryService == null) {
|
||||
if (cache != null) {
|
||||
queryService = cache.getQueryService();
|
||||
}
|
||||
Assert.notNull(cache, "The GemFire Cache reference must not be null!");
|
||||
|
||||
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!");
|
||||
|
||||
if (IndexType.isKey(indexType)) {
|
||||
Assert.isNull(imports, "The 'imports' property is not supported for a Key Index.");
|
||||
}
|
||||
|
||||
Assert.notNull(queryService, "Query service required for index creation");
|
||||
Assert.hasText(expression, "Index expression is required");
|
||||
Assert.hasText(from, "Index from clause (regionPath) is required");
|
||||
String indexName = (StringUtils.hasText(name) ? name : beanName);
|
||||
|
||||
if (StringUtils.hasText(type)) {
|
||||
if (type.equalsIgnoreCase("KEY") || type.equalsIgnoreCase("PRIMARY_KEY")) {
|
||||
Assert.isNull(imports, "The imports property is not supported for a key index");
|
||||
}
|
||||
}
|
||||
|
||||
String indexName = StringUtils.hasText(name) ? name : beanName;
|
||||
|
||||
Assert.hasText(indexName, "Index bean id or name is required");
|
||||
Assert.hasText(indexName, "The Index bean id or name is required!");
|
||||
|
||||
index = createIndex(queryService, indexName);
|
||||
}
|
||||
|
||||
private Index createIndex(QueryService queryService, String indexName) throws Exception {
|
||||
QueryService lookupQueryService() {
|
||||
return (queryService != null ? queryService
|
||||
: (cache instanceof ClientCache ? ((ClientCache) cache).getLocalQueryService()
|
||||
: cache.getQueryService()));
|
||||
}
|
||||
|
||||
Index createIndex(QueryService queryService, String indexName) throws Exception {
|
||||
Index existingIndex = getExistingIndex(queryService, indexName);
|
||||
|
||||
Index existingIndex = null;
|
||||
|
||||
for (Index idx : queryService.getIndexes()) {
|
||||
if (idx.getName().equals(indexName)) {
|
||||
existingIndex = idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (existingIndex != null) {
|
||||
if (!override) {
|
||||
return existingIndex;
|
||||
} else {
|
||||
if (override) {
|
||||
queryService.removeIndex(existingIndex);
|
||||
}
|
||||
else {
|
||||
return existingIndex;
|
||||
}
|
||||
}
|
||||
|
||||
Index index = null;
|
||||
try {
|
||||
if ("KEY".equalsIgnoreCase(type) || "PRIMARY_KEY".equalsIgnoreCase(type)) {
|
||||
|
||||
index = queryService.createKeyIndex(indexName, expression, from);
|
||||
|
||||
} else if ("HASH".equalsIgnoreCase(type)) {
|
||||
if (StringUtils.hasText(imports)) {
|
||||
index = queryService.createHashIndex(indexName, expression, from, imports);
|
||||
} else {
|
||||
index = queryService.createHashIndex(indexName, expression, from);
|
||||
}
|
||||
} else {
|
||||
if (StringUtils.hasText(imports)) {
|
||||
index = queryService.createIndex(indexName, expression, from, imports);
|
||||
} else {
|
||||
index = queryService.createIndex(indexName, expression, from);
|
||||
}
|
||||
if (IndexType.isKey(indexType)) {
|
||||
return queryService.createKeyIndex(indexName, expression, from);
|
||||
}
|
||||
return index;
|
||||
|
||||
} catch (IndexExistsException e) {
|
||||
for (Index idx : queryService.getIndexes()) {
|
||||
if (idx.getName().equals(indexName)) {
|
||||
return idx;
|
||||
}
|
||||
else if (IndexType.isHash(indexType)) {
|
||||
return createHashIndex(queryService, indexName, expression, from, imports);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
else {
|
||||
return createFunctionalIndex(queryService, indexName, expression, from, imports);
|
||||
}
|
||||
}
|
||||
catch (IndexExistsException e) {
|
||||
return getExistingIndex(queryService, indexName);
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (existingIndex != null) {
|
||||
if (CollectionUtils.isEmpty(queryService.getIndexes())
|
||||
|| !queryService.getIndexes().contains(existingIndex)) {
|
||||
Collection<Index> indexes = queryService.getIndexes();
|
||||
|
||||
if (CollectionUtils.isEmpty(indexes) || !indexes.contains(existingIndex)) {
|
||||
queryService.getIndexes().add(existingIndex);
|
||||
return existingIndex;
|
||||
}
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
else {
|
||||
return queryService.createIndex(indexName, expression, from);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
else {
|
||||
return queryService.createHashIndex(indexName, expression, from);
|
||||
}
|
||||
}
|
||||
|
||||
Index getExistingIndex(QueryService queryService, String indexName) {
|
||||
for (Index index : queryService.getIndexes()) {
|
||||
if (index.getName().equalsIgnoreCase(indexName)) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
return null;
|
||||
}
|
||||
|
||||
public Index getObject() {
|
||||
@@ -195,7 +225,18 @@ public class IndexFactoryBean implements InitializingBean, BeanNameAware, Factor
|
||||
* @param type the type to set
|
||||
*/
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
setType(IndexType.valueOfIgnoreCase(type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of GemFire Index to create.
|
||||
*
|
||||
* @param indexType the IndexType enumerated value indicating the type of GemFire Index
|
||||
* that will be created by this Spring FactoryBean.
|
||||
* @see org.springframework.data.gemfire.IndexType
|
||||
*/
|
||||
public void setType(IndexType indexType) {
|
||||
this.indexType = indexType;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,4 +245,5 @@ public class IndexFactoryBean implements InitializingBean, BeanNameAware, Factor
|
||||
public void setOverride(boolean override) {
|
||||
this.override = override;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
151
src/main/java/org/springframework/data/gemfire/IndexType.java
Normal file
151
src/main/java/org/springframework/data/gemfire/IndexType.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* The IndexType class is an enumerated type of GemFire Index Types.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see com.gemstone.gemfire.cache.query.IndexType
|
||||
* @since 1.5.2
|
||||
*/
|
||||
@SuppressWarnings({ "deprecation", "unused" })
|
||||
public enum IndexType {
|
||||
FUNCTIONAL(com.gemstone.gemfire.cache.query.IndexType.FUNCTIONAL),
|
||||
HASH(com.gemstone.gemfire.cache.query.IndexType.HASH),
|
||||
PRIMARY_KEY(com.gemstone.gemfire.cache.query.IndexType.PRIMARY_KEY),
|
||||
KEY(com.gemstone.gemfire.cache.query.IndexType.PRIMARY_KEY);
|
||||
|
||||
private final com.gemstone.gemfire.cache.query.IndexType gemfireIndexType;
|
||||
|
||||
/**
|
||||
* Constructs an instance of the IndexType enum initialized with the given GemFire IndexType.
|
||||
*
|
||||
* @param gemfireIndexType the corresponding GemFire IndexType
|
||||
* @see com.gemstone.gemfire.cache.query.IndexType
|
||||
*/
|
||||
IndexType(final com.gemstone.gemfire.cache.query.IndexType gemfireIndexType) {
|
||||
this.gemfireIndexType = gemfireIndexType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Null-safe operation to determine if the IndexType is a "FUNCTIONAL" Index.
|
||||
*
|
||||
* @param indexType the IndexType to evaluate.
|
||||
* @return a boolean value indicating whether the IndexType is a "FUNCTIONAL" Index.
|
||||
* @see #isFunctional()
|
||||
*/
|
||||
public static boolean isFunctional(final IndexType indexType) {
|
||||
return (indexType != null && indexType.isFunctional());
|
||||
}
|
||||
|
||||
/**
|
||||
* Null-safe operation to determine if the IndexType is a "HASH" Index.
|
||||
*
|
||||
* @param indexType the IndexType to evaluate.
|
||||
* @return a boolean value indicating whether the IndexType is a "HASH" Index.
|
||||
* @see #isHash()
|
||||
*/
|
||||
public static boolean isHash(final IndexType indexType) {
|
||||
return (indexType != null && indexType.isHash());
|
||||
}
|
||||
|
||||
/**
|
||||
* Null-safe operation to determine if the IndexType is a "KEY" Index.
|
||||
*
|
||||
* @param indexType the IndexType to evaluate.
|
||||
* @return a boolean value indicating whether the IndexType is a "KEY" Index.
|
||||
* @see #isFunctional()
|
||||
*/
|
||||
public static boolean isKey(final IndexType indexType) {
|
||||
return (indexType != null && indexType.isKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an IndexType given the corresponding GemFire IndexType or null if no SDG IndexType
|
||||
* corresponds to the GemFire IndexType.
|
||||
*
|
||||
* @param gemfireIndexType the GemFire IndexType.
|
||||
* @return a IndexType matching the GemFire IndexType or null if the GemFire IndexType does not match
|
||||
* any IndexType in this enumeration.
|
||||
* @see com.gemstone.gemfire.cache.query.IndexType
|
||||
*/
|
||||
public static IndexType valueOf(final com.gemstone.gemfire.cache.query.IndexType gemfireIndexType) {
|
||||
for (IndexType indexType : values()) {
|
||||
if (indexType.getGemfireIndexType().equals(gemfireIndexType)) {
|
||||
return indexType;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an IndexType matching the given String.
|
||||
*
|
||||
* @param value the String value describing the matching IndexType.
|
||||
* @return an IndexType matching the given String.
|
||||
* @see java.lang.String#equalsIgnoreCase(String)
|
||||
*/
|
||||
public static IndexType valueOfIgnoreCase(final String value) {
|
||||
for (IndexType indexType : values()) {
|
||||
if (indexType.name().equalsIgnoreCase(value)) {
|
||||
return indexType;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the matching GemFire IndexType for this IndexType enumerated value.
|
||||
*
|
||||
* @return the matching GemFire IndexType.
|
||||
* @see com.gemstone.gemfire.cache.query.IndexType
|
||||
*/
|
||||
public com.gemstone.gemfire.cache.query.IndexType getGemfireIndexType() {
|
||||
return gemfireIndexType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this IndexType is "FUNCTIONAL".
|
||||
*
|
||||
* @return a boolean value indicating whether this IndexType is "FUNCTIONAL".
|
||||
*/
|
||||
public boolean isFunctional() {
|
||||
return this.equals(FUNCTIONAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this IndexType is a "HASH" Index.
|
||||
*
|
||||
* @return a boolean value indicating whether this IndexType is a "HASH" Index.
|
||||
*/
|
||||
public boolean isHash() {
|
||||
return this.equals(HASH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this IndexType is a "KEY" Index.
|
||||
*
|
||||
* @return a boolean value indicating whether this IndexType is a "KEY" Index.
|
||||
*/
|
||||
public boolean isKey() {
|
||||
return (this.equals(KEY) || this.equals(PRIMARY_KEY));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* The IndexTypeConverter class is a Spring Converter implementation as well as a JavaBeans PropertyEditor
|
||||
* that converts a given String value into a proper IndexType.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see java.beans.PropertyEditorSupport
|
||||
* @see org.springframework.core.convert.converter.Converter
|
||||
* @see org.springframework.data.gemfire.IndexType
|
||||
* @since 1.5.2
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class IndexTypeConverter extends PropertyEditorSupport implements Converter<String, IndexType> {
|
||||
|
||||
/**
|
||||
* Asserts that the given String value was successfully converted into a IndexType.
|
||||
*
|
||||
* @param value the String value to convert into an appropriate IndexType.
|
||||
* @param indexType the converted IndexType.
|
||||
* @return the IndexType is non-null.
|
||||
* @throws java.lang.IllegalArgumentException if the IndexType argument was null, indicating that
|
||||
* the given String value could not be converted into an appropriate IndexType.
|
||||
* @see org.springframework.data.gemfire.IndexType
|
||||
*/
|
||||
private IndexType assertConverted(final String value, final IndexType indexType) {
|
||||
Assert.notNull(indexType, String.format("Failed to convert String (%1$s) into an IndexType!", value));
|
||||
return indexType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given String value into an appropriate IndexType
|
||||
*
|
||||
* @param value the String to convert into a corresponding IndexType enumerated value.
|
||||
* @return an IndexType converted from the given String value.
|
||||
* @throws java.lang.IllegalArgumentException if the given String could not be converted into
|
||||
* an appropriate IndexType enumerated value.
|
||||
* @see #assertConverted(String, IndexType)
|
||||
* @see org.springframework.data.gemfire.IndexType#valueOfIgnoreCase(String)
|
||||
* @see org.springframework.util.StringUtils#trimWhitespace(String)
|
||||
*/
|
||||
@Override
|
||||
public IndexType convert(final String value) {
|
||||
return assertConverted(value, IndexType.valueOfIgnoreCase(StringUtils.trimWhitespace(value)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this PropertyEditor as a IndexType enumerated value converted from the given String text.
|
||||
*
|
||||
* @param text the String to convert into a corresponding IndexType enumerated value.
|
||||
* @throws java.lang.IllegalArgumentException if the given String could not be converted into
|
||||
* an appropriate IndexType enumerated value.
|
||||
* @see #convert(String)
|
||||
* @see #setValue(Object)
|
||||
*/
|
||||
@Override
|
||||
public void setAsText(final String text) throws IllegalArgumentException {
|
||||
setValue(convert(text));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,589 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.same;
|
||||
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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
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.QueryService;
|
||||
|
||||
/**
|
||||
* The IndexFactoryBeanTest class is a test suite of test cases testing the contract and functionality
|
||||
* of the IndexFactoryBean class.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.springframework.data.gemfire.IndexFactoryBean
|
||||
* @see com.gemstone.gemfire.cache.Cache
|
||||
* @see com.gemstone.gemfire.cache.client.ClientCache
|
||||
* @see com.gemstone.gemfire.cache.query.Index
|
||||
* @see com.gemstone.gemfire.cache.query.QueryService
|
||||
* @since 1.5.2
|
||||
*/
|
||||
public class IndexFactoryBeanTest {
|
||||
|
||||
@Test
|
||||
public void testAfterPropertiesSet() throws Exception {
|
||||
QueryService mockQueryService = mock(QueryService.class, "testAfterPropertiesSet.MockQueryService");
|
||||
|
||||
Cache mockCache = mock(Cache.class, "testAfterPropertiesSet.MockCache");
|
||||
|
||||
when(mockCache.getQueryService()).thenReturn(mockQueryService);
|
||||
|
||||
final Index mockIndex = mock(Index.class, "testAfterPropertiesSet.MockIndex");
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean() {
|
||||
@Override Index createIndex(final QueryService queryService, final String indexName) throws Exception {
|
||||
return mockIndex;
|
||||
}
|
||||
};
|
||||
|
||||
indexFactoryBean.setCache(mockCache);
|
||||
indexFactoryBean.setName("TestIndex");
|
||||
indexFactoryBean.setExpression("id");
|
||||
indexFactoryBean.setFrom("/Example");
|
||||
indexFactoryBean.setType("key");
|
||||
indexFactoryBean.afterPropertiesSet();
|
||||
|
||||
assertEquals(mockIndex, indexFactoryBean.getObject());
|
||||
assertEquals(mockIndex, indexFactoryBean.getObject()); // assert Index really is a 'Singleton'
|
||||
assertTrue(Index.class.isAssignableFrom(indexFactoryBean.getObjectType()));
|
||||
assertTrue(indexFactoryBean.isSingleton());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAfterPropertiesSetWithNullCache() throws Exception {
|
||||
try {
|
||||
new IndexFactoryBean().afterPropertiesSet();
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertEquals("The GemFire Cache reference must not be null!", expected.getMessage());
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAfterPropertiesSetWithNullQueryService() throws Exception {
|
||||
try {
|
||||
Cache mockCache = mock(Cache.class, "testAfterPropertiesSetWithNullQueryService.MockCache");
|
||||
|
||||
when(mockCache.getQueryService()).thenReturn(null);
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
indexFactoryBean.setCache(mockCache);
|
||||
indexFactoryBean.afterPropertiesSet();
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertEquals("A QueryService is required for Index creation!", expected.getMessage());
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAfterPropertiesSetWithUnspecifiedExpression() throws Exception {
|
||||
try {
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"testAfterPropertiesSetWithUnspecifiedExpression.MockQueryService");
|
||||
|
||||
Cache mockCache = mock(Cache.class, "testAfterPropertiesSetWithUnspecifiedExpression.MockCache");
|
||||
|
||||
when(mockCache.getQueryService()).thenReturn(mockQueryService);
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
indexFactoryBean.setCache(mockCache);
|
||||
indexFactoryBean.afterPropertiesSet();
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertEquals("The Index 'expression' is required!", expected.getMessage());
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAfterPropertiesSetWithUnspecifiedFromClause() throws Exception {
|
||||
try {
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"testAfterPropertiesSetWithUnspecifiedFromClause.MockQueryService");
|
||||
|
||||
Cache mockCache = mock(Cache.class, "testAfterPropertiesSetWithUnspecifiedFromClause.MockCache");
|
||||
|
||||
when(mockCache.getQueryService()).thenReturn(mockQueryService);
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
indexFactoryBean.setCache(mockCache);
|
||||
indexFactoryBean.setExpression("id");
|
||||
indexFactoryBean.afterPropertiesSet();
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertEquals("The Index 'from' clause (a Region's full-path) is required!", expected.getMessage());
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAfterPropertiesSetWithUnspecifiedIndexName() throws Exception {
|
||||
try {
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"testAfterPropertiesSetWithUnspecifiedIndexName.MockQueryService");
|
||||
|
||||
Cache mockCache = mock(Cache.class, "testAfterPropertiesSetWithUnspecifiedIndexName.MockCache");
|
||||
|
||||
when(mockCache.getQueryService()).thenReturn(mockQueryService);
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
indexFactoryBean.setCache(mockCache);
|
||||
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());
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAfterPropertiesSetWithInvalidTypeUsingImports() throws Exception {
|
||||
try {
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"testAfterPropertiesSetWithInvalidTypeUsingImports.MockQueryService");
|
||||
|
||||
Cache mockCache = mock(Cache.class, "testAfterPropertiesSetWithInvalidTypeUsingImports.MockCache");
|
||||
|
||||
when(mockCache.getQueryService()).thenReturn(mockQueryService);
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
indexFactoryBean.setCache(mockCache);
|
||||
indexFactoryBean.setExpression("id");
|
||||
indexFactoryBean.setFrom("/Example");
|
||||
indexFactoryBean.setImports("org.example.DomainType");
|
||||
indexFactoryBean.setType("PriMary_Key");
|
||||
indexFactoryBean.afterPropertiesSet();
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertEquals("The 'imports' property is not supported for a Key Index.", expected.getMessage());
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLookupQueryService() {
|
||||
QueryService mockQueryServiceOne = mock(QueryService.class, "testLookupQueryService.MockQueryService.One");
|
||||
QueryService mockQueryServiceTwo = mock(QueryService.class, "testLookupQueryService.MockQueryService.Two");
|
||||
|
||||
Cache mockCache = mock(Cache.class, "testLookupQueryService.MockCache");
|
||||
|
||||
when(mockCache.getQueryService()).thenReturn(mockQueryServiceTwo);
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
indexFactoryBean.setCache(mockCache);
|
||||
indexFactoryBean.setQueryService(mockQueryServiceOne);
|
||||
|
||||
assertSame(mockQueryServiceOne, indexFactoryBean.lookupQueryService());
|
||||
|
||||
verify(mockCache, never()).getQueryService();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLookupQueryServiceOnClientCache() {
|
||||
QueryService mockQueryService = mock(QueryService.class, "testLookupQueryServiceOnClientCache.MockQueryService");
|
||||
|
||||
ClientCache mockClientCache = mock(ClientCache.class, "testLookupQueryServiceOnClientCache.MockClientCache");
|
||||
|
||||
when(mockClientCache.getLocalQueryService()).thenReturn(mockQueryService);
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
indexFactoryBean.setCache(mockClientCache);
|
||||
|
||||
assertSame(mockQueryService, indexFactoryBean.lookupQueryService());
|
||||
|
||||
verify(mockClientCache, times(1)).getLocalQueryService();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLookupQueryServiceOnPeerCache() {
|
||||
QueryService mockQueryService = mock(QueryService.class, "testLookupQueryServiceOnPeerCache.MockQueryService");
|
||||
|
||||
Cache mockCache = mock(Cache.class, "testLookupQueryServiceOnPeerCache.MockCache");
|
||||
|
||||
when(mockCache.getQueryService()).thenReturn(mockQueryService);
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
indexFactoryBean.setCache(mockCache);
|
||||
indexFactoryBean.setQueryService(null);
|
||||
|
||||
assertSame(mockQueryService, indexFactoryBean.lookupQueryService());
|
||||
|
||||
verify(mockCache, times(1)).getQueryService();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateIndexReturnsNewKeyIndex() throws Exception {
|
||||
Index mockIndex = mock(Index.class, "testCreateIndexReturnsNewKeyIndex.MockIndex");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "testCreateIndexReturnsNewKeyIndex.MockQueryService");
|
||||
|
||||
when(mockQueryService.getIndexes()).thenReturn(Collections.<Index>emptyList());
|
||||
when(mockQueryService.createKeyIndex(eq("KeyIndex"), eq("id"), eq("/Example"))).thenReturn(mockIndex);
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
indexFactoryBean.setExpression("id");
|
||||
indexFactoryBean.setFrom("/Example");
|
||||
indexFactoryBean.setName("KeyIndex");
|
||||
indexFactoryBean.setOverride(false);
|
||||
indexFactoryBean.setType("key");
|
||||
|
||||
Index actualIndex = indexFactoryBean.createIndex(mockQueryService, "KeyIndex");
|
||||
|
||||
assertSame(mockIndex, actualIndex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateIndexReturnsNewHashIndex() throws Exception {
|
||||
Index mockIndex = mock(Index.class, "testCreateIndexReturnsNewHashIndex.MockIndex");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "testCreateIndexReturnsNewHashIndex.MockQueryService");
|
||||
|
||||
when(mockQueryService.getIndexes()).thenReturn(Collections.<Index>emptyList());
|
||||
when(mockQueryService.createHashIndex(eq("HashIndex"), eq("name"), eq("/Animals"), eq("org.example.Dog")))
|
||||
.thenReturn(mockIndex);
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
indexFactoryBean.setExpression("name");
|
||||
indexFactoryBean.setFrom("/Animals");
|
||||
indexFactoryBean.setImports("org.example.Dog");
|
||||
indexFactoryBean.setName("HashIndex");
|
||||
indexFactoryBean.setOverride(false);
|
||||
indexFactoryBean.setType("HasH");
|
||||
|
||||
Index actualIndex = indexFactoryBean.createIndex(mockQueryService, "HashIndex");
|
||||
|
||||
assertSame(mockIndex, actualIndex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateIndexReturnsNewFunctionalIndex() throws Exception {
|
||||
Index mockIndex = mock(Index.class, "testCreateIndexReturnsNewFunctionalIndex.MockIndex");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"testCreateIndexReturnsNewFunctionalIndex.MockQueryService");
|
||||
|
||||
when(mockQueryService.getIndexes()).thenReturn(Collections.<Index>emptyList());
|
||||
when(mockQueryService.createIndex(eq("FunctionalIndex"), eq("someField"), eq("/Example")))
|
||||
.thenReturn(mockIndex);
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
indexFactoryBean.setExpression("someField");
|
||||
indexFactoryBean.setFrom("/Example");
|
||||
indexFactoryBean.setImports(" ");
|
||||
indexFactoryBean.setName("FunctionalIndex");
|
||||
indexFactoryBean.setOverride(false);
|
||||
indexFactoryBean.setType((String) null);
|
||||
|
||||
Index actualIndex = indexFactoryBean.createIndex(mockQueryService, "FunctionalIndex");
|
||||
|
||||
assertSame(mockIndex, actualIndex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateIndexReturnsExistingIndex() throws Exception {
|
||||
Index mockExistingIndex = mock(Index.class, "testCreateIndexReturnsExistingIndex.MockIndex.Existing");
|
||||
Index mockIndexTwo = mock(Index.class, "testCreateIndexReturnsExistingIndex.MockIndex.Two");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "testCreateIndexReturnsExistingIndex.MockQueryService");
|
||||
|
||||
when(mockExistingIndex.getName()).thenReturn("ExistingIndex");
|
||||
when(mockIndexTwo.getName()).thenReturn("IndexTwo");
|
||||
when(mockQueryService.getIndexes()).thenReturn(Arrays.asList(mockExistingIndex, mockIndexTwo));
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
indexFactoryBean.setName("ExistingIndex");
|
||||
indexFactoryBean.setOverride(false);
|
||||
|
||||
Index actualIndex = indexFactoryBean.createIndex(mockQueryService, "ExistingIndex");
|
||||
|
||||
assertSame(mockExistingIndex, actualIndex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateIndexReturnsExistingIndexForIndexExistsException() throws Exception {
|
||||
Index mockExistingIndex = mock(Index.class,
|
||||
"testCreateIndexReturnsExistingIndexForIndexExistsException.MockIndex.Existing");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"testCreateIndexReturnsExistingIndexForIndexExistsException.MockQueryService");
|
||||
|
||||
when(mockExistingIndex.getName()).thenReturn("ExistingIndex");
|
||||
when(mockQueryService.getIndexes()).thenReturn(Collections.singletonList(mockExistingIndex));
|
||||
when(mockQueryService.createKeyIndex(eq("ExistingIndex"), eq("id"), eq("/Example")))
|
||||
.thenThrow(new IndexExistsException("test"));
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
indexFactoryBean.setExpression("id");
|
||||
indexFactoryBean.setFrom("/Example");
|
||||
indexFactoryBean.setName("ExistingIndex");
|
||||
indexFactoryBean.setOverride(true);
|
||||
indexFactoryBean.setType("PRIMARY_KEY");
|
||||
|
||||
Index actualIndex = indexFactoryBean.createIndex(mockQueryService, "ExistingIndex");
|
||||
|
||||
assertSame(mockExistingIndex, actualIndex);
|
||||
|
||||
verify(mockExistingIndex, times(2)).getName();
|
||||
verify(mockQueryService, times(2)).getIndexes();
|
||||
verify(mockQueryService, times(1)).removeIndex(same(mockExistingIndex));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateIndexOverridesExistingIndex() throws Exception {
|
||||
Index mockExistingIndex = mock(Index.class, "testCreateIndexOverridesExistingIndex.MockIndex.Existing");
|
||||
Index mockOverridingIndex = mock(Index.class, "testCreateIndexOverridesExistingIndex.MockIndex.Overriding");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"testCreateIndexOverridesExistingIndex.MockQueryService");
|
||||
|
||||
when(mockExistingIndex.getName()).thenReturn("ExistingIndex");
|
||||
when(mockOverridingIndex.getName()).thenReturn("OverridingIndex");
|
||||
when(mockQueryService.getIndexes()).thenReturn(Collections.singletonList(mockExistingIndex));
|
||||
when(mockQueryService.createHashIndex(eq("ExistingIndex"), eq("someField"), eq("/Example"),
|
||||
eq("org.example.DomainType"))).thenReturn(mockOverridingIndex);
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
indexFactoryBean.setExpression("someField");
|
||||
indexFactoryBean.setFrom("/Example");
|
||||
indexFactoryBean.setImports("org.example.DomainType");
|
||||
indexFactoryBean.setName("OverridingIndex");
|
||||
indexFactoryBean.setType("HASH");
|
||||
|
||||
Index actualIndex = indexFactoryBean.createIndex(mockQueryService, "ExistingIndex");
|
||||
|
||||
assertSame(mockOverridingIndex, actualIndex);
|
||||
|
||||
verify(mockQueryService, times(1)).getIndexes();
|
||||
verify(mockQueryService, times(1)).removeIndex(same(mockExistingIndex));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateIndexAddsExistingIndexOnException() throws Exception {
|
||||
final Index mockExistingIndex = mock(Index.class, "testCreateIndexAddsExistingIndexOnException.MockIndex.Existing");
|
||||
final Index mockIndexTwo = mock(Index.class, "testCreateIndexAddsExistingIndexOnException.MockIndex.Two");
|
||||
|
||||
final List<Index> indexes = new ArrayList<Index>(1);
|
||||
|
||||
indexes.add(mockIndexTwo);
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class,
|
||||
"testCreateIndexAddsExistingIndexOnException.MockQueryService");
|
||||
|
||||
when(mockExistingIndex.getName()).thenReturn("ExistingIndex");
|
||||
when(mockIndexTwo.getName()).thenReturn("IndexTwo");
|
||||
|
||||
when(mockQueryService.getIndexes()).then(new Answer<Collection<Index>>() {
|
||||
private boolean called = false;
|
||||
|
||||
private synchronized boolean wasCalledOnce() {
|
||||
boolean localCalled = this.called;
|
||||
this.called = true;
|
||||
return localCalled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Index> answer(final InvocationOnMock invocationOnMock) throws Throwable {
|
||||
return (wasCalledOnce() ? indexes : Collections.singletonList(mockExistingIndex));
|
||||
}
|
||||
});
|
||||
|
||||
when(mockQueryService.createIndex(eq("ExistingIndex"), eq("someField"), eq("/Example")))
|
||||
.thenThrow(new RuntimeException("test"));
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
indexFactoryBean.setExpression("someField");
|
||||
indexFactoryBean.setFrom("/Example");
|
||||
indexFactoryBean.setName("ExistingIndex");
|
||||
indexFactoryBean.setOverride(true);
|
||||
indexFactoryBean.setType("FUNCTIONAL");
|
||||
|
||||
assertEquals(1, indexes.size());
|
||||
assertFalse(indexes.contains(mockExistingIndex));
|
||||
|
||||
Index actualIndex = indexFactoryBean.createIndex(mockQueryService, "ExistingIndex");
|
||||
|
||||
assertSame(mockExistingIndex, actualIndex);
|
||||
assertEquals(2, indexes.size());
|
||||
assertTrue(indexes.contains(mockExistingIndex));
|
||||
|
||||
verify(mockQueryService, times(3)).getIndexes();
|
||||
verify(mockQueryService, times(1)).removeIndex(same(mockExistingIndex));
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void testCreateIndexThrowsException() throws Exception {
|
||||
Index mockExistingIndex = mock(Index.class, "testCreateIndexThrowsException.MockIndex.Existing");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "testCreateIndexThrowsException.MockQueryService");
|
||||
|
||||
when(mockExistingIndex.getName()).thenReturn("ExistingIndex");
|
||||
when(mockQueryService.getIndexes()).thenReturn(Collections.singletonList(mockExistingIndex));
|
||||
when(mockQueryService.createIndex(eq("ExistingIndex"), eq("someField"), eq("/Example")))
|
||||
.thenThrow(new RuntimeException("test"));
|
||||
|
||||
IndexFactoryBean indexFactoryBean = new IndexFactoryBean();
|
||||
|
||||
indexFactoryBean.setExpression("someField");
|
||||
indexFactoryBean.setFrom("/Example");
|
||||
indexFactoryBean.setName("ExistingIndex");
|
||||
|
||||
try {
|
||||
indexFactoryBean.createIndex(mockQueryService, "ExistingIndex");
|
||||
}
|
||||
catch (RuntimeException expected) {
|
||||
assertEquals("test", expected.getMessage());
|
||||
throw expected;
|
||||
}
|
||||
finally {
|
||||
verify(mockQueryService, times(2)).getIndexes();
|
||||
verify(mockQueryService, times(1)).removeIndex(same(mockExistingIndex));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateFunctionalIndex() throws Exception {
|
||||
Index mockIndex = mock(Index.class, "testCreateFunctionalIndex.MockIndex");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "testCreateFunctionalIndex.MockQueryService");
|
||||
|
||||
when(mockQueryService.createIndex(eq("FunctionalIndex"), eq("purchaseDate"), eq("/Orders")))
|
||||
.thenReturn(mockIndex);
|
||||
|
||||
Index actualIndex = new IndexFactoryBean().createFunctionalIndex(mockQueryService, "FunctionalIndex",
|
||||
"purchaseDate", "/Orders", null);
|
||||
|
||||
assertSame(mockIndex, actualIndex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateFunctionalIndexWithImports() throws Exception {
|
||||
Index mockIndex = mock(Index.class, "testCreateFunctionalIndexWithImports.MockIndex");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "testCreateFunctionalIndexWithImports.MockQueryService");
|
||||
|
||||
when(mockQueryService.createIndex(eq("FunctionalIndexWithImports"), eq("purchaseDate"), eq("/Orders"),
|
||||
eq("org.example.Order"))).thenReturn(mockIndex);
|
||||
|
||||
Index actualIndex = new IndexFactoryBean().createFunctionalIndex(mockQueryService, "FunctionalIndexWithImports",
|
||||
"purchaseDate", "/Orders", "org.example.Order");
|
||||
|
||||
assertSame(mockIndex, actualIndex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateHashIndex() throws Exception {
|
||||
Index mockIndex = mock(Index.class, "testCreateHashIndex.MockIndex");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "testCreateHashIndex.MockQueryService");
|
||||
|
||||
when(mockQueryService.createHashIndex(eq("HashIndex"), eq("name"), eq("/People"))).thenReturn(mockIndex);
|
||||
|
||||
Index actualIndex = new IndexFactoryBean().createHashIndex(mockQueryService, "HashIndex",
|
||||
"name", "/People", " ");
|
||||
|
||||
assertSame(mockIndex, actualIndex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateHashIndexWithImports() throws Exception {
|
||||
Index mockIndex = mock(Index.class, "testCreateHashIndexWithImports.MockIndex");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "testCreateHashIndexWithImports.MockQueryService");
|
||||
|
||||
when(mockQueryService.createHashIndex(eq("HashIndexWithImports"), eq("name"), eq("/People"),
|
||||
eq("org.example.Person"))).thenReturn(mockIndex);
|
||||
|
||||
Index actualIndex = new IndexFactoryBean().createHashIndex(mockQueryService, "HashIndexWithImports",
|
||||
"name", "/People", "org.example.Person");
|
||||
|
||||
assertSame(mockIndex, actualIndex);
|
||||
}
|
||||
|
||||
@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");
|
||||
|
||||
QueryService mockQueryService = mock(QueryService.class, "testGetExistingIndex.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, " "));
|
||||
assertNull(indexFactoryBean.getExistingIndex(mockQueryService, "Primary Index"));
|
||||
assertNull(indexFactoryBean.getExistingIndex(mockQueryService, "Secondary_Index"));
|
||||
assertNull(indexFactoryBean.getExistingIndex(mockQueryService, "QuadIndex"));
|
||||
assertSame(mockIndexOne, indexFactoryBean.getExistingIndex(mockQueryService, "PRIMARYINDEX"));
|
||||
assertSame(mockIndexTwo, indexFactoryBean.getExistingIndex(mockQueryService, "SecondaryIndex"));
|
||||
assertSame(mockIndexThree, indexFactoryBean.getExistingIndex(mockQueryService, "ternaryindex"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* The IndexTypeConverterTest class is a test suite of test cases testing the contract and functionality
|
||||
* of the IndexTypeConverter class.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.springframework.data.gemfire.IndexType
|
||||
* @see org.springframework.data.gemfire.IndexTypeConverter
|
||||
* @since 1.5.2
|
||||
*/
|
||||
public class IndexTypeConverterTest {
|
||||
|
||||
private final IndexTypeConverter converter = new IndexTypeConverter();
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
converter.setValue(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvert() {
|
||||
assertEquals(IndexType.FUNCTIONAL, converter.convert("FUNCTIONAL"));
|
||||
assertEquals(IndexType.HASH, converter.convert("hASh"));
|
||||
assertEquals(IndexType.KEY, converter.convert("Key"));
|
||||
assertEquals(IndexType.PRIMARY_KEY, converter.convert("primary_KEY"));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testConvertWithInvalidValue() {
|
||||
try {
|
||||
converter.convert("function");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertEquals("Failed to convert String (function) into an IndexType!", expected.getMessage());
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetAsText() {
|
||||
assertNull(converter.getValue());
|
||||
converter.setAsText("HasH");
|
||||
assertEquals(IndexType.HASH, converter.getValue());
|
||||
converter.setAsText("key");
|
||||
assertEquals(IndexType.KEY, converter.getValue());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testSetAsTextWithIllegalValue() {
|
||||
try {
|
||||
converter.setAsText("invalid");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertEquals("Failed to convert String (invalid) into an IndexType!", expected.getMessage());
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* The IndexTypeTest class is a test suite of test cases testing the contract and functionality
|
||||
* of the IndexType enum class.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.springframework.data.gemfire.IndexType
|
||||
* @since 1.5.2
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class IndexTypeTest {
|
||||
|
||||
@Test
|
||||
public void testGetGemFireIndexType() {
|
||||
assertEquals(com.gemstone.gemfire.cache.query.IndexType.FUNCTIONAL, IndexType.FUNCTIONAL.getGemfireIndexType());
|
||||
assertEquals(com.gemstone.gemfire.cache.query.IndexType.HASH, IndexType.HASH.getGemfireIndexType());
|
||||
assertEquals(com.gemstone.gemfire.cache.query.IndexType.PRIMARY_KEY, IndexType.KEY.getGemfireIndexType());
|
||||
assertEquals(com.gemstone.gemfire.cache.query.IndexType.PRIMARY_KEY, IndexType.PRIMARY_KEY.getGemfireIndexType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValueOfGemFireIndexType() {
|
||||
assertNull(IndexType.valueOf((com.gemstone.gemfire.cache.query.IndexType) null));
|
||||
assertEquals(IndexType.FUNCTIONAL, IndexType.valueOf(com.gemstone.gemfire.cache.query.IndexType.FUNCTIONAL));
|
||||
assertEquals(IndexType.HASH, IndexType.valueOf(com.gemstone.gemfire.cache.query.IndexType.HASH));
|
||||
assertEquals(IndexType.PRIMARY_KEY, IndexType.valueOf(com.gemstone.gemfire.cache.query.IndexType.PRIMARY_KEY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValueOfIgnoreCase() {
|
||||
assertEquals(IndexType.FUNCTIONAL, IndexType.valueOfIgnoreCase("functional"));
|
||||
assertEquals(IndexType.HASH, IndexType.valueOfIgnoreCase("HasH"));
|
||||
assertEquals(IndexType.KEY, IndexType.valueOfIgnoreCase("Key"));
|
||||
assertEquals(IndexType.PRIMARY_KEY, IndexType.valueOfIgnoreCase("PriMary_Key"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValueOfIgnoreCaseWithInvalidValues() {
|
||||
assertNull(IndexType.valueOfIgnoreCase(null));
|
||||
assertNull(IndexType.valueOfIgnoreCase(""));
|
||||
assertNull(IndexType.valueOfIgnoreCase(" "));
|
||||
assertNull(IndexType.valueOfIgnoreCase("Prime_Index"));
|
||||
assertNull(IndexType.valueOfIgnoreCase("SECONDARY_INDEX"));
|
||||
assertNull(IndexType.valueOfIgnoreCase("unique_index"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsFunctional() {
|
||||
assertTrue(IndexType.FUNCTIONAL.isFunctional());
|
||||
assertFalse(IndexType.HASH.isFunctional());
|
||||
assertFalse(IndexType.KEY.isFunctional());
|
||||
assertFalse(IndexType.PRIMARY_KEY.isFunctional());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsNullSafeFunctional() {
|
||||
assertFalse(IndexType.isFunctional(null));
|
||||
assertTrue(IndexType.isFunctional(IndexType.FUNCTIONAL));
|
||||
assertFalse(IndexType.isFunctional(IndexType.HASH));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsHash() {
|
||||
assertFalse(IndexType.FUNCTIONAL.isHash());
|
||||
assertTrue(IndexType.HASH.isHash());
|
||||
assertFalse(IndexType.KEY.isHash());
|
||||
assertFalse(IndexType.PRIMARY_KEY.isHash());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsNullSafeHash() {
|
||||
assertFalse(IndexType.isHash(null));
|
||||
assertTrue(IndexType.isHash(IndexType.HASH));
|
||||
assertFalse(IndexType.isHash(IndexType.KEY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsKey() {
|
||||
assertFalse(IndexType.FUNCTIONAL.isKey());
|
||||
assertFalse(IndexType.HASH.isKey());
|
||||
assertTrue(IndexType.KEY.isKey());
|
||||
assertTrue(IndexType.PRIMARY_KEY.isKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsNullSafeKey() {
|
||||
assertFalse(IndexType.isKey(null));
|
||||
assertFalse(IndexType.isKey(IndexType.FUNCTIONAL));
|
||||
assertTrue(IndexType.isKey(IndexType.KEY));
|
||||
assertTrue(IndexType.isKey(IndexType.PRIMARY_KEY));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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.client;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.gemfire.ForkUtil;
|
||||
import org.springframework.data.gemfire.fork.SpringCacheServerProcess;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.gemstone.gemfire.cache.GemFireCache;
|
||||
import com.gemstone.gemfire.cache.client.ClientCache;
|
||||
import com.gemstone.gemfire.cache.query.Index;
|
||||
import com.gemstone.gemfire.cache.query.IndexType;
|
||||
import com.gemstone.gemfire.cache.query.QueryService;
|
||||
|
||||
/**
|
||||
* The ClientCacheIndexingTest class is a test suite of test cases testing the creation and application of indexes
|
||||
* on client Regions of a GemFire ClientCache using the <gfe:index/> tag element in the Spring Data GemFire
|
||||
* XML namespace and configuration meta-data, which is backed by the IndexFactoryBean.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.junit.runner.RunWith
|
||||
* @see org.springframework.data.gemfire.IndexFactoryBean
|
||||
* @see org.springframework.test.context.ContextConfiguration
|
||||
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
|
||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||
* @see com.gemstone.gemfire.cache.client.ClientCache
|
||||
* @see com.gemstone.gemfire.cache.query.Index
|
||||
* @see com.gemstone.gemfire.cache.query.QueryService
|
||||
* @since 1.5.2
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
@SuppressWarnings("unused")
|
||||
public class ClientCacheIndexingTest {
|
||||
|
||||
private static final Object MUTEX = new Object();
|
||||
|
||||
@Autowired
|
||||
private ClientCache clientCache;
|
||||
|
||||
@Autowired
|
||||
private Index exampleIndex;
|
||||
|
||||
@BeforeClass
|
||||
public static void setup() throws IOException {
|
||||
ForkUtil.startCacheServer(String.format("%1$s %2$s", SpringCacheServerProcess.class.getName(),
|
||||
"/org/springframework/data/gemfire/client/ClientCacheIndexingTest-server-context.xml"));
|
||||
waitForServerStart(TimeUnit.SECONDS.toMillis(20));
|
||||
System.out.println("GemFire Cache Server Process for ClientCache Indexing should be running...");
|
||||
}
|
||||
|
||||
private static void waitForServerStart(final long milliseconds) {
|
||||
long timeout = (System.currentTimeMillis() + milliseconds);
|
||||
|
||||
while (System.currentTimeMillis() < timeout
|
||||
&& ForkUtil.controlFileExists(SpringCacheServerProcess.class.getName())) {
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.timedWait(MUTEX, 500);
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDown() {
|
||||
ForkUtil.sendSignal();
|
||||
}
|
||||
|
||||
protected Index getIndex(final GemFireCache gemfireCache, final String indexName) {
|
||||
QueryService queryService = (gemfireCache instanceof ClientCache
|
||||
? ((ClientCache) gemfireCache).getLocalQueryService() : gemfireCache.getQueryService());
|
||||
|
||||
for (Index index : queryService.getIndexes()) {
|
||||
if (index.getName().equals(indexName)) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testIndexByName() {
|
||||
assertNotNull("The GemFire ClientCache was not properly configured and initialized!", clientCache);
|
||||
|
||||
Index actualIndex = getIndex(clientCache, "ExampleIndex");
|
||||
|
||||
assertNotNull(actualIndex);
|
||||
assertEquals("ExampleIndex", actualIndex.getName());
|
||||
assertEquals(IndexType.HASH, actualIndex.getType());
|
||||
assertSame(exampleIndex, actualIndex);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:gfe="http://www.springframework.org/schema/gemfire"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
|
||||
">
|
||||
|
||||
<gfe:pool id="serverConnectionPool">
|
||||
<gfe:server host="localhost" port="42424"/>
|
||||
</gfe:pool>
|
||||
|
||||
<gfe:client-cache pool-name="serverConnectionPool"/>
|
||||
|
||||
<gfe:client-region id="Example" shortcut="LOCAL"/>
|
||||
|
||||
<gfe:index id="ExampleIndex" expression="id" from="/Example" type="HASH"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:gfe="http://www.springframework.org/schema/gemfire"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
|
||||
">
|
||||
|
||||
<util:properties id="gemfireProperties">
|
||||
<prop key="name">ClientCacheIndexingTestServer</prop>
|
||||
<prop key="mcast-port">0</prop>
|
||||
<prop key="log-level">warning</prop>
|
||||
</util:properties>
|
||||
|
||||
<gfe:cache properties-ref="gemfireProperties"/>
|
||||
|
||||
<gfe:cache-server auto-startup="true" bind-address="localhost" port="42424" host-name-for-clients="localhost"
|
||||
max-connections="1"/>
|
||||
|
||||
</beans>
|
||||
Reference in New Issue
Block a user