From 6e0bf24706098befb75cbfa4ea6965e9cccec22d Mon Sep 17 00:00:00 2001 From: John Blum Date: Tue, 28 Jan 2014 17:27:27 -0800 Subject: [PATCH] Fixes JIRA issues SGF-249 involving property placeholder values on Disk Store bean definition attributes, and specifically the compaction-threshold attribute, in the SDG XML namespace. --- .../data/gemfire/DiskStoreFactoryBean.java | 113 ++++++++++-------- .../data/gemfire/config/DiskStoreParser.java | 22 +++- .../gemfire/config/spring-gemfire-1.3.xsd | 31 ++--- .../gemfire/config/spring-gemfire-1.4.xsd | 31 ++--- ...ngPropertyPlaceholdersIntegrationTest.java | 80 +++++++++++++ .../gemfire/DiskStoreFactoryBeanTest.java | 108 +++++++++++++++++ ...tore-using-propertyplaceholders-config.xml | 38 ++++++ 7 files changed, 326 insertions(+), 97 deletions(-) create mode 100644 src/test/java/org/springframework/data/gemfire/DiskStoreBeanUsingPropertyPlaceholdersIntegrationTest.java create mode 100644 src/test/java/org/springframework/data/gemfire/DiskStoreFactoryBeanTest.java create mode 100644 src/test/resources/org/springframework/data/gemfire/diskstore-using-propertyplaceholders-config.xml diff --git a/src/main/java/org/springframework/data/gemfire/DiskStoreFactoryBean.java b/src/main/java/org/springframework/data/gemfire/DiskStoreFactoryBean.java index 7753669d..bed3e564 100644 --- a/src/main/java/org/springframework/data/gemfire/DiskStoreFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/DiskStoreFactoryBean.java @@ -24,40 +24,42 @@ import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import com.gemstone.gemfire.cache.DiskStore; import com.gemstone.gemfire.cache.DiskStoreFactory; import com.gemstone.gemfire.cache.GemFireCache; /** - * FactoryBean for creating a DiskStore + * FactoryBean for creating a GemFire DiskStore. + *

* @author David Turanski + * @author John Blum + * @see org.springframework.beans.factory.BeanNameAware + * @see org.springframework.beans.factory.FactoryBean + * @see org.springframework.beans.factory.InitializingBean */ +@SuppressWarnings("unused") public class DiskStoreFactoryBean implements FactoryBean, InitializingBean, BeanNameAware { private DiskStoreFactory diskStoreFactory; + private Boolean allowForceCompaction; private Boolean autoCompact; - private Boolean allowForceCompaction; - - private Integer maxOplogSize; - - private Integer timeInterval; - - private Integer queueSize; - - private Integer compactionThreshold; - - private Integer writeBufferSize; + private DiskStore diskStore; private GemFireCache cache; - private String name; + private Integer compactionThreshold; + private Integer maxOplogSize; + private Integer queueSize; + private Integer timeInterval; + private Integer writeBufferSize; private List diskDirs; - - private DiskStore diskStore; + + private String name; @Override public DiskStore getObject() throws Exception { @@ -76,7 +78,9 @@ public class DiskStoreFactoryBean implements FactoryBean, Initializin @Override public void afterPropertiesSet() throws Exception { - Assert.notNull(cache, "Cache property must be set"); + Assert.state(cache != null, String.format("A reference to the GemFire Cache must be set for Disk Store '%1$s'.", + getName())); + diskStoreFactory = cache.createDiskStoreFactory(); if (allowForceCompaction != null) { @@ -104,52 +108,32 @@ public class DiskStoreFactoryBean implements FactoryBean, Initializin 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; } + diskStoreFactory.setDiskDirsAndSizes(diskDirFiles, diskDirSizes); } - - diskStore = diskStoreFactory.create(name == null ? DiskStoreFactory.DEFAULT_DISK_STORE_NAME : name); - Assert.notNull(diskStore); + + diskStore = diskStoreFactory.create(getName()); + + Assert.notNull(diskStore, String.format("The DiskStore with name '%1$s' failed to be created successfully.", + diskStore.getName())); } public void setCache(GemFireCache cache) { this.cache = cache; } - public void setAutoCompact(Boolean autoCompact) { - this.autoCompact = autoCompact; - } - public void setAllowForceCompaction(Boolean allowForceCompaction) { this.allowForceCompaction = allowForceCompaction; } - public void setMaxOplogSize(Integer maxOplogSize) { - this.maxOplogSize = maxOplogSize; - } - - public void setTimeInterval(Integer timeInterval) { - this.timeInterval = timeInterval; - } - - public void setQueueSize(Integer queueSize) { - this.queueSize = queueSize; - } - - public void setCompactionThreshold(Integer compactionThreshold) { - this.compactionThreshold = compactionThreshold; - } - - public void setWriteBufferSize(Integer writeBufferSize) { - this.writeBufferSize = writeBufferSize; - } - - public void setDiskDirs(List diskDirs) { - this.diskDirs = diskDirs; + public void setAutoCompact(Boolean autoCompact) { + this.autoCompact = autoCompact; } @Override @@ -157,10 +141,44 @@ public class DiskStoreFactoryBean implements FactoryBean, Initializin this.name = name; } - public static class DiskDir { - final String location; + public void setCompactionThreshold(Integer compactionThreshold) { + validateCompactionThreshold(compactionThreshold); + this.compactionThreshold = compactionThreshold; + } + protected void validateCompactionThreshold(final Integer compactionThreshold) { + Assert.isTrue(compactionThreshold == null || (compactionThreshold >= 0 && compactionThreshold <= 100), + String.format("The DiskStore's (%1$s) compaction threshold (%2$d) must be an integer value between 0 and 100 inclusive.", + this.name, compactionThreshold)); + } + + public void setDiskDirs(List diskDirs) { + this.diskDirs = diskDirs; + } + + public void setMaxOplogSize(Integer maxOplogSize) { + this.maxOplogSize = maxOplogSize; + } + + public void setQueueSize(Integer queueSize) { + this.queueSize = queueSize; + } + + public void setTimeInterval(Integer timeInterval) { + this.timeInterval = timeInterval; + } + + public void setWriteBufferSize(Integer writeBufferSize) { + this.writeBufferSize = writeBufferSize; + } + + /* package-private */ final String getName() { + return (StringUtils.hasText(name) ? name : DiskStoreFactory.DEFAULT_DISK_STORE_NAME); + } + + public static class DiskDir { final Integer maxSize; + final String location; public DiskDir(String location, int maxSize) { this.location = location; @@ -172,4 +190,5 @@ public class DiskStoreFactoryBean implements FactoryBean, Initializin this.maxSize = null; } } + } diff --git a/src/main/java/org/springframework/data/gemfire/config/DiskStoreParser.java b/src/main/java/org/springframework/data/gemfire/config/DiskStoreParser.java index e2f4c977..7149639b 100644 --- a/src/main/java/org/springframework/data/gemfire/config/DiskStoreParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/DiskStoreParser.java @@ -29,11 +29,13 @@ import org.springframework.util.xml.DomUtils; import org.w3c.dom.Element; /** - * Parser for the <disk-store> definitions. + * Parser for <disk-store> bean definitions. + *

* @author David Turanski - * + * @author John Blum */ public class DiskStoreParser extends AbstractSingleBeanDefinitionParser { + @Override protected Class getBeanClass(Element element) { return DiskStoreFactoryBean.class; @@ -42,29 +44,37 @@ public class DiskStoreParser extends AbstractSingleBeanDefinitionParser { @Override protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { super.doParse(element, parserContext, builder); + builder.setLazyInit(false); + ParsingUtils.setPropertyReference(element, builder, "cache-ref", "cache"); - ParsingUtils.setPropertyValue(element, builder, "auto-compact"); ParsingUtils.setPropertyValue(element, builder, "allow-force-compaction"); - ParsingUtils.setPropertyValue(element, builder, "max-oplog-size"); - ParsingUtils.setPropertyValue(element, builder, "time-interval"); - ParsingUtils.setPropertyValue(element, builder, "queue-size"); + ParsingUtils.setPropertyValue(element, builder, "auto-compact"); ParsingUtils.setPropertyValue(element, builder, "compaction-threshold"); + ParsingUtils.setPropertyValue(element, builder, "max-oplog-size"); + ParsingUtils.setPropertyValue(element, builder, "queue-size"); + ParsingUtils.setPropertyValue(element, builder, "time-interval"); ParsingUtils.setPropertyValue(element, builder, "write-buffer-size"); List diskDirElements = DomUtils.getChildElementsByTagName(element, "disk-dir"); if (!CollectionUtils.isEmpty(diskDirElements)) { ManagedList diskDirs = new ManagedList(); + for (Element diskDirElement : diskDirElements) { BeanDefinitionBuilder diskDirBuilder = BeanDefinitionBuilder.genericBeanDefinition(DiskDir.class); + diskDirBuilder.addConstructorArgValue(diskDirElement.getAttribute("location")); + if (diskDirElement.hasAttribute("max-size")) { diskDirBuilder.addConstructorArgValue(diskDirElement.getAttribute("max-size")); } + diskDirs.add(diskDirBuilder.getBeanDefinition()); } + builder.addPropertyValue("diskDirs", diskDirs); } } + } diff --git a/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.3.xsd b/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.3.xsd index 19c71522..bb07f065 100755 --- a/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.3.xsd +++ b/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.3.xsd @@ -1557,16 +1557,14 @@ The maximum size (in megabytes) of data stored in each directory. Default value - + - + - + - + - + - - - - - - - + - + - + - + - + - + - + - + - - - - - - - + - + - + + * @author John Blum + * @see org.junit.Test + * @see org.junit.runner.RunWith + * @see org.springframework.data.gemfire.DiskStoreFactoryBean + * @see org.springframework.data.gemfire.test.GemfireTestApplicationContextInitializer + * @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner + * @see com.gemstone.gemfire.cache.DiskStore + * @link https://jira.springsource.org/browse/SGF-249 + * @since 1.3.4 + */ +@ContextConfiguration(locations = "diskstore-using-propertyplaceholders-config.xml", + initializers = GemfireTestApplicationContextInitializer.class) +@RunWith(SpringJUnit4ClassRunner.class) +@SuppressWarnings("unused") +public class DiskStoreBeanUsingPropertyPlaceholdersIntegrationTest { + + @Autowired + private DiskStore testDataStore; + + @Resource(name="diskStoreConfiguration") + private Map diskStoreConfiguration; + + @SuppressWarnings("unchecked") + protected Object getExpectedValue(final String propertyPlaceholderName) { + return diskStoreConfiguration.get(propertyPlaceholderName); + } + + @Test + public void testDiskStoreBeanWithPropertyPlaceholderConfiguration() { + System.out.printf("Disk Store Configuration: %1$s%n", diskStoreConfiguration); + assertNotNull("The Disk Store was not configured and initialized!", testDataStore); + assertEquals(getExpectedValue("allowForceCompaction"), testDataStore.getAllowForceCompaction()); + assertEquals(getExpectedValue("autoCompact"), testDataStore.getAutoCompact()); + assertEquals(getExpectedValue("compactionThreshold"), testDataStore.getCompactionThreshold()); + assertEquals(getExpectedValue("maxOplogSize"), testDataStore.getMaxOplogSize()); + assertEquals("TestDataStore", testDataStore.getName()); + assertEquals(getExpectedValue("queueSize"), testDataStore.getQueueSize()); + assertEquals(getExpectedValue("timeInterval"), testDataStore.getTimeInterval()); + assertEquals(getExpectedValue("writeBufferSize"), testDataStore.getWriteBufferSize()); + } + +} diff --git a/src/test/java/org/springframework/data/gemfire/DiskStoreFactoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/DiskStoreFactoryBeanTest.java new file mode 100644 index 00000000..fd21161c --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/DiskStoreFactoryBeanTest.java @@ -0,0 +1,108 @@ +/* + * 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 org.junit.Before; +import org.junit.Test; + +/** + * The DiskStoreFactoryBeanTest class is a test suite of test cases testing the contract and functionality of the + * DiskStoreFactoryBean class. + *

+ * + * @author John Blum + * @see org.junit.Test + * @see org.springframework.data.gemfire.DiskStoreFactoryBean + * @since 1.3.4 + */ +public class DiskStoreFactoryBeanTest { + + private final DiskStoreFactoryBean factoryBean = new DiskStoreFactoryBean(); + + @Before + public void setup() { + factoryBean.setBeanName("testDiskStore"); + } + + @Test + public void testValidateCompactionThresholdWhenNull() { + factoryBean.validateCompactionThreshold(null); + } + + @Test + public void testValidateCompactionThresholdWhenValid() { + factoryBean.validateCompactionThreshold(0); + factoryBean.validateCompactionThreshold(50); + factoryBean.validateCompactionThreshold(100); + } + + @Test(expected = IllegalArgumentException.class) + public void testValidateCompactionThresholdWhenLessThan0() { + try { + factoryBean.validateCompactionThreshold(-1); + } + catch (IllegalArgumentException expected) { + assertEquals(String.format("The DiskStore's (%1$s) compaction threshold (%2$d) must be an integer value between 0 and 100 inclusive.", + factoryBean.getName(), -1), expected.getMessage()); + throw expected; + } + } + + @Test(expected = IllegalArgumentException.class) + public void testValidateCompactionThresholdWhenGreaterThan100() { + try { + factoryBean.validateCompactionThreshold(101); + } + catch (IllegalArgumentException expected) { + assertEquals(String.format("The DiskStore's (%1$s) compaction threshold (%2$d) must be an integer value between 0 and 100 inclusive.", + factoryBean.getName(), 101), expected.getMessage()); + throw expected; + } + } + + @Test + public void testSetCompactionThreshold() { + factoryBean.setCompactionThreshold(75); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetCompactionThreadWithIllegalArgument() { + try { + factoryBean.setCompactionThreshold(200); + } + catch (IllegalArgumentException expected) { + assertEquals(String.format( + "The DiskStore's (%1$s) compaction threshold (%2$d) must be an integer value between 0 and 100 inclusive.", + factoryBean.getName(), 200), expected.getMessage()); + throw expected; + } + } + + @Test(expected = IllegalStateException.class) + public void testAfterPropertiesSetWithNoCacheReference() throws Exception { + try { + factoryBean.afterPropertiesSet(); + } + catch (IllegalStateException expected) { + assertEquals("A reference to the GemFire Cache must be set for Disk Store 'testDiskStore'.", expected.getMessage()); + throw expected; + } + } + +} diff --git a/src/test/resources/org/springframework/data/gemfire/diskstore-using-propertyplaceholders-config.xml b/src/test/resources/org/springframework/data/gemfire/diskstore-using-propertyplaceholders-config.xml new file mode 100644 index 00000000..8d0afaba --- /dev/null +++ b/src/test/resources/org/springframework/data/gemfire/diskstore-using-propertyplaceholders-config.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + +