SGF-390 - Improve unit test coverage for the PoolFactoryBean class.
This commit is contained in:
@@ -19,8 +19,6 @@ package org.springframework.data.gemfire;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
@@ -38,6 +36,7 @@ import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.data.gemfire.util.CollectionUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
@@ -487,7 +486,7 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware,
|
||||
|
||||
/* (non-Javadoc) */
|
||||
private void registerTransactionListeners(Cache cache) {
|
||||
for (TransactionListener transactionListener : nullSafeCollection(transactionListeners)) {
|
||||
for (TransactionListener transactionListener : CollectionUtils.nullSafeCollection(transactionListeners)) {
|
||||
cache.getCacheTransactionManager().addListener(transactionListener);
|
||||
}
|
||||
}
|
||||
@@ -501,7 +500,7 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware,
|
||||
|
||||
/* (non-Javadoc) */
|
||||
private void registerJndiDataSources() {
|
||||
for (JndiDataSource jndiDataSource : nullSafeCollection(jndiDataSources)) {
|
||||
for (JndiDataSource jndiDataSource : CollectionUtils.nullSafeCollection(jndiDataSources)) {
|
||||
String typeAttributeValue = jndiDataSource.getAttributes().get("type");
|
||||
JndiDataSourceType jndiDataSourceType = JndiDataSourceType.valueOfIgnoreCase(typeAttributeValue);
|
||||
|
||||
@@ -514,10 +513,6 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware,
|
||||
}
|
||||
}
|
||||
|
||||
protected <T> Collection<T> nullSafeCollection(final Collection<T> collection) {
|
||||
return (collection != null ? collection : Collections.<T>emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
if (close) {
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.Properties;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.data.gemfire.CacheFactoryBean;
|
||||
import org.springframework.data.gemfire.config.GemfireConstants;
|
||||
import org.springframework.data.gemfire.util.CollectionUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -180,11 +181,11 @@ public class ClientCacheFactoryBean extends CacheFactoryBean {
|
||||
clientCacheFactory.setPoolSubscriptionRedundancy(pool.getSubscriptionRedundancy());
|
||||
clientCacheFactory.setPoolThreadLocalConnections(pool.getThreadLocalConnections());
|
||||
|
||||
for (InetSocketAddress socketAddress : nullSafeCollection(pool.getLocators())) {
|
||||
for (InetSocketAddress socketAddress : CollectionUtils.nullSafeCollection(pool.getLocators())) {
|
||||
clientCacheFactory.addPoolLocator(socketAddress.getHostName(), socketAddress.getPort());
|
||||
}
|
||||
|
||||
for (InetSocketAddress socketAddress : nullSafeCollection(pool.getServers())) {
|
||||
for (InetSocketAddress socketAddress : CollectionUtils.nullSafeCollection(pool.getServers())) {
|
||||
clientCacheFactory.addPoolServer(socketAddress.getHostName(), socketAddress.getPort());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.springframework.data.gemfire.client;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -29,8 +28,8 @@ import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.data.gemfire.util.CollectionUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.gemstone.gemfire.cache.client.Pool;
|
||||
@@ -59,7 +58,7 @@ public class PoolFactoryBean implements FactoryBean<Pool>, InitializingBean, Dis
|
||||
private static final Log log = LogFactory.getLog(PoolFactoryBean.class);
|
||||
|
||||
// indicates whether the Pool has been created internally (by this FactoryBean) or not
|
||||
private volatile boolean internalPool = true;
|
||||
private volatile boolean springBasedPool = true;
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
@@ -109,7 +108,7 @@ public class PoolFactoryBean implements FactoryBean<Pool>, InitializingBean, Dis
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (!StringUtils.hasText(name)) {
|
||||
Assert.hasText(beanName, "The Pool name is required!");
|
||||
Assert.hasText(beanName, "Pool 'name' is required");
|
||||
name = beanName;
|
||||
}
|
||||
|
||||
@@ -121,7 +120,7 @@ public class PoolFactoryBean implements FactoryBean<Pool>, InitializingBean, Dis
|
||||
log.debug(String.format("A Pool with name '%1$s' already exists; using existing Pool.", name));
|
||||
}
|
||||
|
||||
internalPool = false;
|
||||
springBasedPool = false;
|
||||
pool = existingPool;
|
||||
}
|
||||
else {
|
||||
@@ -130,12 +129,12 @@ public class PoolFactoryBean implements FactoryBean<Pool>, InitializingBean, Dis
|
||||
}
|
||||
|
||||
if (CollectionUtils.isEmpty(locators) && CollectionUtils.isEmpty(servers)) {
|
||||
throw new IllegalArgumentException("At least one locator or server is required!");
|
||||
throw new IllegalArgumentException("at least one GemFire Locator or Server is required");
|
||||
}
|
||||
|
||||
internalPool = true;
|
||||
springBasedPool = true;
|
||||
|
||||
PoolFactory poolFactory = PoolManager.createFactory();
|
||||
PoolFactory poolFactory = createPoolFactory();
|
||||
|
||||
poolFactory.setFreeConnectionTimeout(freeConnectionTimeout);
|
||||
poolFactory.setIdleTimeout(idleTimeout);
|
||||
@@ -156,33 +155,41 @@ public class PoolFactoryBean implements FactoryBean<Pool>, InitializingBean, Dis
|
||||
poolFactory.setSubscriptionRedundancy(subscriptionRedundancy);
|
||||
poolFactory.setThreadLocalConnections(threadLocalConnections);
|
||||
|
||||
for (InetSocketAddress connection : nullSafeCollection(locators)) {
|
||||
for (InetSocketAddress connection : CollectionUtils.nullSafeCollection(locators)) {
|
||||
poolFactory.addLocator(connection.getHostName(), connection.getPort());
|
||||
}
|
||||
|
||||
for (InetSocketAddress connection : nullSafeCollection(servers)) {
|
||||
for (InetSocketAddress connection : CollectionUtils.nullSafeCollection(servers)) {
|
||||
poolFactory.addServer(connection.getHostName(), connection.getPort());
|
||||
}
|
||||
|
||||
// eagerly initialize ClientCache (if needed)
|
||||
if (InternalDistributedSystem.getAnyInstance() == null) {
|
||||
doDistributedSystemConnect(resolveGemfireProperties());
|
||||
}
|
||||
// eagerly initialize the GemFire DistributedSystem (if needed)
|
||||
resolveDistributedSystem();
|
||||
|
||||
pool = poolFactory.create(name);
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() throws Exception {
|
||||
if (internalPool && pool != null) {
|
||||
if (!pool.isDestroyed()) {
|
||||
pool.releaseThreadLocalConnection();
|
||||
pool.destroy(keepAlive);
|
||||
/* (non-Javadoc) */
|
||||
protected PoolFactory createPoolFactory() {
|
||||
return PoolManager.createFactory();
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(String.format("Destroyed Pool '%1$s'.", name));
|
||||
}
|
||||
}
|
||||
/* (non-Javadoc) */
|
||||
void resolveDistributedSystem() {
|
||||
if (InternalDistributedSystem.getAnyInstance() == null) {
|
||||
doDistributedSystemConnect(resolveGemfireProperties());
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
Properties resolveGemfireProperties() {
|
||||
try {
|
||||
ClientCacheFactoryBean clientCacheFactoryBean = beanFactory.getBean(ClientCacheFactoryBean.class);
|
||||
return clientCacheFactoryBean.getProperties();
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,26 +202,22 @@ public class PoolFactoryBean implements FactoryBean<Pool>, InitializingBean, Dis
|
||||
* @see com.gemstone.gemfire.distributed.DistributedSystem#connect(java.util.Properties)
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
static void doDistributedSystemConnect(Properties properties) {
|
||||
void doDistributedSystemConnect(Properties properties) {
|
||||
Properties gemfireProperties = (properties != null ? (Properties) properties.clone() : new Properties());
|
||||
gemfireProperties.setProperty("locators", "");
|
||||
gemfireProperties.setProperty("mcast-port", "0");
|
||||
DistributedSystem.connect(gemfireProperties);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
private <T> Collection<T> nullSafeCollection(final Collection<T> list) {
|
||||
return (list != null ? list : Collections.<T>emptyList());
|
||||
}
|
||||
public void destroy() throws Exception {
|
||||
if (springBasedPool && pool != null && !pool.isDestroyed()) {
|
||||
pool.releaseThreadLocalConnection();
|
||||
pool.destroy(keepAlive);
|
||||
pool = null;
|
||||
|
||||
/* (non-Javadoc) */
|
||||
private Properties resolveGemfireProperties() {
|
||||
try {
|
||||
ClientCacheFactoryBean clientCacheFactoryBean = beanFactory.getBean(ClientCacheFactoryBean.class);
|
||||
return clientCacheFactoryBean.getProperties();
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
return null;
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(String.format("Destroyed Pool '%1$s'.", name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,79 +10,99 @@
|
||||
* 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.util;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
/**
|
||||
* @author David Turanski
|
||||
* The ArrayUtils class is a utility class for working with Object arrays.
|
||||
*
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see java.lang.reflect.Array
|
||||
*/
|
||||
|
||||
|
||||
public abstract class ArrayUtils {
|
||||
|
||||
/**
|
||||
* Insert an element into an array. The element is inserted at the
|
||||
* given position, all elements afterwards are moved to the right.
|
||||
*
|
||||
* @param originalArray array to insert into
|
||||
* @param pos position at which to insert the element
|
||||
* @param element element to add
|
||||
* @return the new array
|
||||
*/
|
||||
public static Object[] insert(Object[] originalArray, int pos, Object element) {
|
||||
Object[] newArray = (Object[]) java.lang.reflect.Array.newInstance(
|
||||
originalArray.getClass().getComponentType(), originalArray.length + 1);
|
||||
/**
|
||||
* Insert an element into the given array at position (index). The element is inserted at the given position
|
||||
* and all elements afterwards are moved to the right.
|
||||
*
|
||||
* @param originalArray the array in which to insert the element.
|
||||
* @param position an integer index (position) at which to insert the element in the array.
|
||||
* @param element the element to insert into the array.
|
||||
* @return a new array with the element inserted at position.
|
||||
* @see java.lang.System#arraycopy(Object, int, Object, int, int)
|
||||
* @see java.lang.reflect.Array#newInstance(Class, int)
|
||||
*/
|
||||
public static Object[] insert(Object[] originalArray, int position, Object element) {
|
||||
Object[] newArray = (Object[]) Array.newInstance(originalArray.getClass().getComponentType(),
|
||||
originalArray.length + 1);
|
||||
|
||||
|
||||
// copy everything before the given position
|
||||
if (pos > 0) {
|
||||
System.arraycopy(originalArray, 0, newArray, 0, pos); // does not copy originalArray[pos], where we insert
|
||||
}
|
||||
|
||||
// insert
|
||||
newArray[pos] = element;
|
||||
// copy all elements before the given position (here, position refers to the length, or number of elements
|
||||
// to be copied, excluding the element at originalArray[position]
|
||||
if (position > 0) {
|
||||
System.arraycopy(originalArray, 0, newArray, 0, position);
|
||||
}
|
||||
|
||||
// copy remaining elements
|
||||
if (pos < originalArray.length) {
|
||||
System.arraycopy(originalArray, pos, // originalArray[pos] first element copied
|
||||
newArray, pos + 1, // newArray[pos + 1] first destination
|
||||
originalArray.length - pos); // number of elements left
|
||||
}
|
||||
// insert
|
||||
newArray[position] = element;
|
||||
|
||||
|
||||
return newArray;
|
||||
}
|
||||
// copy remaining elements from originalArray, starting at position, to new array
|
||||
if (position < originalArray.length) {
|
||||
System.arraycopy(originalArray, position, newArray, position + 1, originalArray.length - position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove element from an array. The element is removed at the
|
||||
* specified position, and all remaining elements are moved to the left.
|
||||
*
|
||||
* @param originalArray array to remove from
|
||||
* @param pos position to remove
|
||||
* @return the new array
|
||||
*/
|
||||
public static Object[] remove(Object[] originalArray, int pos) {
|
||||
Object[] newArray = (Object[])java.lang.reflect.Array.newInstance(
|
||||
originalArray.getClass().getComponentType(), originalArray.length - 1);
|
||||
return newArray;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determines whether the given array is empty or not.
|
||||
*
|
||||
* @param array the array to evaluate for emptiness.
|
||||
* @return a boolean value indicating whether the given array is empty.
|
||||
* @see #length(Object...)
|
||||
*/
|
||||
public static boolean isEmpty(Object... array) {
|
||||
return (length(array) == 0);
|
||||
}
|
||||
|
||||
// Copy everything before
|
||||
if (pos > 0) {
|
||||
System.arraycopy(originalArray, 0, newArray, 0, pos); // originalArray[pos - 1] is last element copied
|
||||
}
|
||||
/**
|
||||
* Null-safe operation to determine an array's length.
|
||||
*
|
||||
* @param array the array to determine it's length.
|
||||
* @return the length of the given array or 0 if the array reference is null.
|
||||
*/
|
||||
public static int length(Object... array) {
|
||||
return (array != null ? array.length : 0);
|
||||
}
|
||||
|
||||
|
||||
// Copy everything after
|
||||
if (pos < originalArray.length - 1) {
|
||||
System.arraycopy(originalArray, pos + 1, // originalArray[pos + 1] is first element copied
|
||||
newArray, pos, // first position to copy into
|
||||
originalArray.length - 1 - pos);
|
||||
}
|
||||
/**
|
||||
* Remove an element from the given array at position (index). The element is removed at the specified position
|
||||
* and all remaining elements are shifted to the left.
|
||||
*
|
||||
* @param originalArray the array from which to remove the element.
|
||||
* @param position the integer index (position) indicating the element to remove from the array.
|
||||
* @return a new array with the element at position in the originalArray removed.
|
||||
* @see java.lang.System#arraycopy(Object, int, Object, int, int)
|
||||
* @see java.lang.reflect.Array#newInstance(Class, int)
|
||||
*/
|
||||
public static Object[] remove(Object[] originalArray, int position) {
|
||||
Object[] newArray = (Object[]) Array.newInstance(originalArray.getClass().getComponentType(),
|
||||
originalArray.length - 1);
|
||||
|
||||
|
||||
return newArray;
|
||||
}
|
||||
// copy all elements before position (here, position refers to the length, or number of elements to be copied
|
||||
if (position > 0) {
|
||||
System.arraycopy(originalArray, 0, newArray, 0, position);
|
||||
}
|
||||
|
||||
// copy remaining elements after position from the originalArray
|
||||
if (position < originalArray.length - 1) {
|
||||
System.arraycopy(originalArray, position + 1, newArray, position, originalArray.length - 1 - position);
|
||||
}
|
||||
|
||||
return newArray;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* The CollectionUtils class is a utility class for working with Java Collections Framework and classes.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see java.util.Collection
|
||||
* @see java.util.Collections
|
||||
* @see org.springframework.util.CollectionUtils
|
||||
* @since 1.7.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class CollectionUtils extends org.springframework.util.CollectionUtils {
|
||||
|
||||
/**
|
||||
* A null-safe operation returning the original Collection is non-null or an empty Collection
|
||||
* (implemented with List) if null.
|
||||
*
|
||||
* @param <T> the element class type of the Collection.
|
||||
* @param collection the Collection to evaluate for being null.
|
||||
* @return the given Collection if not null, otherwise return an empty Collection (List).
|
||||
* @see java.util.Collections#emptyList()
|
||||
*/
|
||||
public static <T> Collection<T> nullSafeCollection(final Collection<T> collection) {
|
||||
return (collection != null ? collection : Collections.<T>emptyList());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user