Implements JIRA improvement SGF-223 enabling Spring Data GemFire to create GemFire Disk Store directory locations automatically (based on nested <gfe:disk-dir> elements inside the <gfe:disk-store> element specified in Spring config) without the user having to create the disk directories for the location manually, unlike GemFire's native configuration options (such as cache.xml).
This commit is contained in:
@@ -40,7 +40,7 @@ import com.gemstone.gemfire.cache.GemFireCache;
|
||||
* @see org.springframework.beans.factory.InitializingBean
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class DiskStoreFactoryBean implements FactoryBean<DiskStore>, InitializingBean, BeanNameAware {
|
||||
public class DiskStoreFactoryBean implements BeanNameAware , FactoryBean<DiskStore>, InitializingBean {
|
||||
|
||||
private Boolean allowForceCompaction;
|
||||
private Boolean autoCompact;
|
||||
@@ -66,7 +66,7 @@ public class DiskStoreFactoryBean implements FactoryBean<DiskStore>, Initializin
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return DiskStore.class;
|
||||
return (diskStore != null ? diskStore.getClass() : DiskStore.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -84,33 +84,34 @@ public class DiskStoreFactoryBean implements FactoryBean<DiskStore>, Initializin
|
||||
if (allowForceCompaction != null) {
|
||||
diskStoreFactory.setAllowForceCompaction(allowForceCompaction);
|
||||
}
|
||||
if (autoCompact != null) {
|
||||
diskStoreFactory.setAutoCompact(autoCompact);
|
||||
}
|
||||
if (compactionThreshold != null) {
|
||||
diskStoreFactory.setCompactionThreshold(compactionThreshold);
|
||||
}
|
||||
if (autoCompact != null) {
|
||||
diskStoreFactory.setAutoCompact(autoCompact);
|
||||
if (maxOplogSize != null) {
|
||||
diskStoreFactory.setMaxOplogSize(maxOplogSize);
|
||||
}
|
||||
if (queueSize != null) {
|
||||
diskStoreFactory.setQueueSize(queueSize);
|
||||
}
|
||||
if (writeBufferSize != null) {
|
||||
diskStoreFactory.setWriteBufferSize(writeBufferSize);
|
||||
}
|
||||
if (timeInterval != null) {
|
||||
diskStoreFactory.setTimeInterval(timeInterval);
|
||||
}
|
||||
if (maxOplogSize != null) {
|
||||
diskStoreFactory.setMaxOplogSize(maxOplogSize);
|
||||
if (writeBufferSize != null) {
|
||||
diskStoreFactory.setWriteBufferSize(writeBufferSize);
|
||||
}
|
||||
|
||||
if (!CollectionUtils.isEmpty(diskDirs)) {
|
||||
File[] diskDirFiles = new File[diskDirs.size()];
|
||||
int[] diskDirSizes = new int[diskDirs.size()];
|
||||
|
||||
for (int i = 0; i < diskDirs.size(); i++) {
|
||||
DiskDir diskDir = diskDirs.get(i);
|
||||
diskDirFiles[i] = new File(diskDir.location);
|
||||
diskDirSizes[i] = diskDir.maxSize == null ? DiskStoreFactory.DEFAULT_DISK_DIR_SIZE : diskDir.maxSize;
|
||||
for (int index = 0; index < diskDirs.size(); index++) {
|
||||
DiskDir diskDir = diskDirs.get(index);
|
||||
diskDirFiles[index] = new File(diskDir.location);
|
||||
diskDirSizes[index] = (diskDir.maxSize != null ? diskDir.maxSize
|
||||
: DiskStoreFactory.DEFAULT_DISK_DIR_SIZE);
|
||||
}
|
||||
|
||||
diskStoreFactory.setDiskDirsAndSizes(diskDirFiles, diskDirSizes);
|
||||
@@ -118,7 +119,7 @@ public class DiskStoreFactoryBean implements FactoryBean<DiskStore>, Initializin
|
||||
|
||||
diskStore = diskStoreFactory.create(getName());
|
||||
|
||||
Assert.notNull(diskStore, String.format("The DiskStore with name '%1$s' failed to be created successfully.",
|
||||
Assert.notNull(diskStore, String.format("DiskStore with name '%1$s' failed to be created successfully.",
|
||||
diskStore.getName()));
|
||||
}
|
||||
|
||||
@@ -178,15 +179,14 @@ public class DiskStoreFactoryBean implements FactoryBean<DiskStore>, Initializin
|
||||
final Integer maxSize;
|
||||
final String location;
|
||||
|
||||
public DiskDir(String location, int maxSize) {
|
||||
this.location = location;
|
||||
this.maxSize = maxSize;
|
||||
}
|
||||
|
||||
public DiskDir(String location) {
|
||||
this.location = location;
|
||||
this.maxSize = null;
|
||||
}
|
||||
public DiskDir(String location, int maxSize) {
|
||||
this.location = location;
|
||||
this.maxSize = maxSize;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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 java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.data.gemfire.DiskStoreFactoryBean.DiskDir;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* The DiskStoreBeanPostProcessor class post processes any GemFire Disk Store DiskDir Spring beans defined
|
||||
* in the application context to ensure that the Disk Store directory location (disk-dir) actually exists
|
||||
* before creating the Disk Store.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor
|
||||
* @see org.springframework.data.gemfire.DiskStoreFactoryBean.DiskDir
|
||||
* @since 1.5.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class DiskStoreBeanPostProcessor implements BeanPostProcessor {
|
||||
|
||||
protected final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(String.format("Post Processing Bean (%1$s) of Type (%2$s) with Name (%3$s)...%n", bean,
|
||||
ObjectUtils.nullSafeClassName(bean), beanName));
|
||||
}
|
||||
|
||||
if (bean instanceof DiskDir) {
|
||||
createIfNotExists((DiskDir) bean);
|
||||
}
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
private void createIfNotExists(final DiskDir diskDirectory) {
|
||||
String location = readField(diskDirectory, "location");
|
||||
|
||||
File diskDirectoryFile = new File(location);
|
||||
|
||||
Assert.isTrue(diskDirectoryFile.isDirectory() || diskDirectoryFile.mkdirs(),
|
||||
String.format("Failed to create Disk Directory (%1$s)%n!", location));
|
||||
|
||||
if (log.isInfoEnabled()) {
|
||||
log.info(String.format("The Disk Directory either exists or was created @ Location (%1$s).%n", location));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T readField(final Object obj, final String fieldName) {
|
||||
try {
|
||||
Class type = obj.getClass();
|
||||
Field field;
|
||||
|
||||
do {
|
||||
field = type.getDeclaredField(fieldName);
|
||||
type = type.getSuperclass(); // traverse up the object class hierarchy
|
||||
}
|
||||
while (field == null && !Object.class.equals(type));
|
||||
|
||||
if (field == null) {
|
||||
throw new NoSuchFieldException(String.format("Field (%1$s) does not exist on Object of type (%2$s)!",
|
||||
fieldName, ObjectUtils.nullSafeClassName(obj)));
|
||||
}
|
||||
|
||||
field.setAccessible(true);
|
||||
|
||||
return (T) field.get(obj);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(String.format("Failed to read field (%1$s) on Object of type (%2$s)!",
|
||||
fieldName, ObjectUtils.nullSafeClassName(obj)), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,9 +16,12 @@
|
||||
package org.springframework.data.gemfire.config;
|
||||
|
||||
import java.util.List;
|
||||
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.support.ManagedList;
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
@@ -33,9 +36,28 @@ import org.w3c.dom.Element;
|
||||
*
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see org.springframework.beans.factory.support.AbstractBeanDefinition
|
||||
* @see org.springframework.beans.factory.support.BeanDefinitionBuilder
|
||||
* @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser
|
||||
* @see org.springframework.data.gemfire.DiskStoreFactoryBean
|
||||
* @see org.w3c.dom.Element
|
||||
*/
|
||||
public class DiskStoreParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
private static final AtomicBoolean registered = new AtomicBoolean(false);
|
||||
|
||||
private static void registerDiskStoreBeanPostProcessor(final ParserContext parserContext) {
|
||||
if (registered.compareAndSet(false, true)) {
|
||||
AbstractBeanDefinition diskStoreBeanPostProcessor = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(DiskStoreBeanPostProcessor.class)
|
||||
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
.getBeanDefinition();
|
||||
|
||||
BeanDefinitionReaderUtils.registerWithGeneratedName(diskStoreBeanPostProcessor,
|
||||
parserContext.getRegistry());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return DiskStoreFactoryBean.class;
|
||||
@@ -45,6 +67,8 @@ public class DiskStoreParser extends AbstractSingleBeanDefinitionParser {
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
super.doParse(element, parserContext, builder);
|
||||
|
||||
registerDiskStoreBeanPostProcessor(parserContext);
|
||||
|
||||
builder.setLazyInit(false);
|
||||
|
||||
ParsingUtils.setPropertyReference(element, builder, "cache-ref", "cache");
|
||||
|
||||
Reference in New Issue
Block a user