diff --git a/src/main/java/org/springframework/data/gemfire/config/EvictionAttributesFactoryBean.java b/src/main/java/org/springframework/data/gemfire/config/EvictionAttributesFactoryBean.java index 85a86e79..a1de51b8 100644 --- a/src/main/java/org/springframework/data/gemfire/config/EvictionAttributesFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/config/EvictionAttributesFactoryBean.java @@ -25,87 +25,66 @@ import com.gemstone.gemfire.cache.util.ObjectSizer; /** * Simple utility class used for defining nested factory-method like definitions w/o polluting the container with useless beans. - * + *

* @author Costin Leau + * @author John Blum + * @see org.springframework.beans.factory.FactoryBean + * @see org.springframework.beans.factory.InitializingBean + * @see com.gemstone.gemfire.cache.EvictionAttributes + * @see com.gemstone.gemfire.cache.util.ObjectSizer */ +@SuppressWarnings("unused") class EvictionAttributesFactoryBean implements FactoryBean, InitializingBean { - private EvictionAttributes evictionAttr; - - private Integer threshold = null; - private ObjectSizer objectSizer = null; private EvictionAction action = null; + + private EvictionAttributes evictionAttributes; + private EvictionType type = EvictionType.ENTRY_COUNT; - public void afterPropertiesSet() { - if (action == null) { - action = EvictionAction.DEFAULT_EVICTION_ACTION; - } + private Integer threshold = null; - evictionAttr = createAttributes(); + private ObjectSizer objectSizer = null; + + public void afterPropertiesSet() { + this.action = (this.action != null ? action : EvictionAction.DEFAULT_EVICTION_ACTION); + evictionAttributes = createAttributes(); } - private EvictionAttributes createAttributes() { + EvictionAttributes createAttributes() { switch (type) { - case HEAP_PERCENTAGE: - return EvictionAttributes.createLRUHeapAttributes(objectSizer, action); - - case MEMORY_SIZE: - if (threshold != null) { - return EvictionAttributes.createLRUMemoryAttributes(threshold, objectSizer, action); - } - return EvictionAttributes.createLRUMemoryAttributes(objectSizer, action); - - // consider entry count as default - case ENTRY_COUNT: - default: - if (threshold != null) { - return EvictionAttributes.createLRUEntryAttributes(threshold, action); - } - return EvictionAttributes.createLRUEntryAttributes(); + case HEAP_PERCENTAGE: + if (threshold != null) { + throw new IllegalArgumentException( + "The HEAP_PERCENTAGE (LRU_HEAP algorithm) does not support threshold (a.k.a. maximum)!"); + } + return EvictionAttributes.createLRUHeapAttributes(objectSizer, action); + case MEMORY_SIZE: + if (threshold != null) { + return EvictionAttributes.createLRUMemoryAttributes(threshold, objectSizer, action); + } + return EvictionAttributes.createLRUMemoryAttributes(objectSizer, action); + case ENTRY_COUNT: + default: + if (threshold != null) { + return EvictionAttributes.createLRUEntryAttributes(threshold, action); + } + return EvictionAttributes.createLRUEntryAttributes(); } } public EvictionAttributes getObject() { - return evictionAttr; + return evictionAttributes; } public Class getObjectType() { - return (evictionAttr != null ? evictionAttr.getClass() : EvictionAttributes.class); + return (evictionAttributes != null ? evictionAttributes.getClass() : EvictionAttributes.class); } public boolean isSingleton() { return true; } - /** - * @return the threshold - */ - public Integer getThreshold() { - return threshold; - } - - /** - * @param threshold the threshold to set - */ - public void setThreshold(Integer threshold) { - this.threshold = threshold; - } - - /** - * @return the objectSizer - */ - public ObjectSizer getObjectSizer() { - return objectSizer; - } - - /** - * @param objectSizer the objectSizer to set - */ - public void setObjectSizer(ObjectSizer objectSizer) { - this.objectSizer = objectSizer; - } - /** * @return the action */ @@ -120,6 +99,34 @@ class EvictionAttributesFactoryBean implements FactoryBean, this.action = action; } + /** + * @return the objectSizer + */ + public ObjectSizer getObjectSizer() { + return objectSizer; + } + + /** + * @param objectSizer the objectSizer to set + */ + public void setObjectSizer(ObjectSizer objectSizer) { + this.objectSizer = objectSizer; + } + + /** + * @return the threshold + */ + public Integer getThreshold() { + return threshold; + } + + /** + * @param threshold the threshold to set + */ + public void setThreshold(Integer threshold) { + this.threshold = threshold; + } + /** * @return the type */ @@ -133,4 +140,5 @@ class EvictionAttributesFactoryBean implements FactoryBean, public void setType(EvictionType type) { this.type = type; } -} \ No newline at end of file + +} 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 bb07f065..5ea4a361 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 @@ -1464,7 +1464,7 @@ Considers the amount of heap used (through the GemFire resource manager) before - + - + + * @author John Blum + * @see org.junit.Test + * @see org.springframework.data.gemfire.config.EvictionAttributesFactoryBean + * @see com.gemstone.gemfire.cache.EvictionAttributes + * @since 1.3.4 + */ +public class EvictionAttributesFactoryBeanTest { + + @Test + public void testCreateEntryCountHeapAttributes() { + EvictionAttributesFactoryBean factoryBean = new EvictionAttributesFactoryBean(); + + factoryBean.setAction(EvictionAction.NONE); + factoryBean.setObjectSizer(null); + factoryBean.setThreshold(8192); + factoryBean.setType(EvictionType.ENTRY_COUNT); + factoryBean.afterPropertiesSet(); + + EvictionAttributes evictionAttributes = factoryBean.getObject(); + + assertNotNull(evictionAttributes); + assertEquals(EvictionAction.NONE, evictionAttributes.getAction()); + assertNull(evictionAttributes.getObjectSizer()); + assertEquals(8192, evictionAttributes.getMaximum()); + assertEquals(EvictionAlgorithm.LRU_ENTRY, evictionAttributes.getAlgorithm()); + + ObjectSizer mockObjectSizer = mock(ObjectSizer.class, "testCreateEntryCountHeapAttributes"); + + factoryBean.setAction(null); + factoryBean.setObjectSizer(mockObjectSizer); // ObjectSize is not used for ENTRY LRU! + factoryBean.setThreshold(null); + factoryBean.afterPropertiesSet(); + + evictionAttributes = factoryBean.getObject(); + + assertNotNull(evictionAttributes); + assertEquals(EvictionAction.DEFAULT_EVICTION_ACTION, evictionAttributes.getAction()); + assertNull(evictionAttributes.getObjectSizer()); + assertEquals(LRUCapacityController.DEFAULT_MAXIMUM_ENTRIES, evictionAttributes.getMaximum()); + assertEquals(EvictionAlgorithm.LRU_ENTRY, evictionAttributes.getAlgorithm()); + } + + @Test + public void testCreateHeapPercentageEvictionAttributes() { + EvictionAttributesFactoryBean factoryBean = new EvictionAttributesFactoryBean(); + + factoryBean.setAction(EvictionAction.LOCAL_DESTROY); + factoryBean.setObjectSizer(null); + //factoryBean.setThreshold(50); // Threshold is not used in HEAP LRU + factoryBean.setType(EvictionType.HEAP_PERCENTAGE); + factoryBean.afterPropertiesSet(); + + EvictionAttributes evictionAttributes = factoryBean.getObject(); + + assertNotNull(evictionAttributes); + assertEquals(EvictionAction.LOCAL_DESTROY, evictionAttributes.getAction()); + assertNull(evictionAttributes.getObjectSizer()); + assertEquals(EvictionAlgorithm.LRU_HEAP, evictionAttributes.getAlgorithm()); + + ObjectSizer mockObjectSizer = mock(ObjectSizer.class, "testCreateHeapPercentageEvictionAttributes"); + + factoryBean.setAction(null); + factoryBean.setObjectSizer(mockObjectSizer); + factoryBean.setThreshold(null); + factoryBean.afterPropertiesSet(); + + evictionAttributes = factoryBean.getObject(); + + assertNotNull(evictionAttributes); + assertEquals(EvictionAction.DEFAULT_EVICTION_ACTION, evictionAttributes.getAction()); + assertSame(mockObjectSizer, evictionAttributes.getObjectSizer()); + assertEquals(EvictionAlgorithm.LRU_HEAP, evictionAttributes.getAlgorithm()); + } + + @Test(expected = IllegalArgumentException.class) + public void testCreateHeapPercentageEvictionAttributesSettingThreshold() { + EvictionAttributesFactoryBean factoryBean = new EvictionAttributesFactoryBean(); + + try { + factoryBean.setType(EvictionType.HEAP_PERCENTAGE); + factoryBean.setThreshold(85); + factoryBean.afterPropertiesSet(); + } + catch (IllegalArgumentException expected) { + assertEquals("The HEAP_PERCENTAGE (LRU_HEAP algorithm) does not support threshold (a.k.a. maximum)!", + expected.getMessage()); + assertEquals(85, factoryBean.getThreshold().intValue()); + assertEquals(EvictionType.HEAP_PERCENTAGE, factoryBean.getType()); + throw expected; + } + } + + @Test + public void testCreateMemorySizeEvictionAttributes() { + EvictionAttributesFactoryBean factoryBean = new EvictionAttributesFactoryBean(); + + factoryBean.setAction(EvictionAction.OVERFLOW_TO_DISK); + factoryBean.setObjectSizer(null); + factoryBean.setThreshold(512); + factoryBean.setType(EvictionType.MEMORY_SIZE); + factoryBean.afterPropertiesSet(); + + EvictionAttributes evictionAttributes = factoryBean.getObject(); + + assertNotNull(evictionAttributes); + assertEquals(EvictionAction.OVERFLOW_TO_DISK, evictionAttributes.getAction()); + assertNull(evictionAttributes.getObjectSizer()); + assertEquals(512, evictionAttributes.getMaximum()); + assertEquals(EvictionAlgorithm.LRU_MEMORY, evictionAttributes.getAlgorithm()); + + ObjectSizer mockObjectSizer = mock(ObjectSizer.class, "testCreateMemorySizeEvictionAttributes"); + + factoryBean.setAction(null); + factoryBean.setObjectSizer(mockObjectSizer); + factoryBean.setThreshold(null); + factoryBean.afterPropertiesSet(); + + evictionAttributes = factoryBean.getObject(); + + assertNotNull(evictionAttributes); + assertEquals(EvictionAction.DEFAULT_EVICTION_ACTION, evictionAttributes.getAction()); + assertSame(mockObjectSizer, evictionAttributes.getObjectSizer()); + assertEquals(MemLRUCapacityController.DEFAULT_MAXIMUM_MEGABYTES, evictionAttributes.getMaximum()); + assertEquals(EvictionAlgorithm.LRU_MEMORY, evictionAttributes.getAlgorithm()); + } + +} diff --git a/src/test/java/org/springframework/data/gemfire/config/RegionEvictionAttributesNamespaceTest.java b/src/test/java/org/springframework/data/gemfire/config/RegionEvictionAttributesNamespaceTest.java new file mode 100644 index 00000000..cc65ab53 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/config/RegionEvictionAttributesNamespaceTest.java @@ -0,0 +1,139 @@ +/* + * Copyright 2010-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.gemfire.config; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import javax.annotation.Resource; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.data.gemfire.test.GemfireTestApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.gemstone.gemfire.cache.DataPolicy; +import com.gemstone.gemfire.cache.EvictionAction; +import com.gemstone.gemfire.cache.EvictionAlgorithm; +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.internal.cache.EvictionAttributesImpl; +import com.gemstone.gemfire.internal.cache.lru.LRUCapacityController; +import com.gemstone.gemfire.internal.cache.lru.MemLRUCapacityController; + +/** + * The RegionEvictionAttributesNamespaceTest class is a test suite of test cases testing the use of Eviction settings + * (EvictionAttributes) in the SDG XML namespace. + *

+ * @author John Blum + * @since 1.3.4 + */ +@ContextConfiguration(locations = "regions-with-eviction-attributes-ns.xml", + initializers = GemfireTestApplicationContextInitializer.class) +@RunWith(SpringJUnit4ClassRunner.class) +public class RegionEvictionAttributesNamespaceTest { + + @Resource(name = "One") + private Region one; + + @Resource(name = "Two") + private Region two; + + @Resource(name = "Three") + private Region three; + + @Resource(name = "Four") + private Region four; + + @Resource(name = "Five") + private Region five; + + @Resource(name = "Six") + private Region six; + + @Test + public void testEntryCountRegionEvictionAttributes() { + assertNotNull(one); + assertNotNull(one.getAttributes()); + assertEquals(DataPolicy.REPLICATE, one.getAttributes().getDataPolicy()); + assertNotNull(one.getAttributes().getEvictionAttributes()); + assertEquals(EvictionAction.OVERFLOW_TO_DISK, one.getAttributes().getEvictionAttributes().getAction()); + assertEquals(EvictionAlgorithm.LRU_ENTRY, one.getAttributes().getEvictionAttributes().getAlgorithm()); + assertEquals(4096, one.getAttributes().getEvictionAttributes().getMaximum()); + + assertNotNull(two); + assertNotNull(two.getAttributes()); + assertEquals(DataPolicy.PARTITION, two.getAttributes().getDataPolicy()); + assertNotNull(two.getAttributes().getEvictionAttributes()); + assertEquals(EvictionAction.LOCAL_DESTROY, two.getAttributes().getEvictionAttributes().getAction()); + assertEquals(EvictionAlgorithm.LRU_ENTRY, two.getAttributes().getEvictionAttributes().getAlgorithm()); + + if (two.getAttributes().getEvictionAttributes() instanceof EvictionAttributesImpl) { + assertEquals(LRUCapacityController.DEFAULT_MAXIMUM_ENTRIES, + two.getAttributes().getEvictionAttributes().getMaximum()); + } + } + + @Test(expected = UnsupportedOperationException.class) + public void testHeapPercentageRegionEvictionAttributes() { + assertNotNull(three); + assertNotNull(three.getAttributes()); + assertEquals(DataPolicy.REPLICATE, three.getAttributes().getDataPolicy()); + assertNotNull(three.getAttributes().getEvictionAttributes()); + assertEquals(EvictionAction.OVERFLOW_TO_DISK, three.getAttributes().getEvictionAttributes().getAction()); + assertEquals(EvictionAlgorithm.LRU_HEAP, three.getAttributes().getEvictionAttributes().getAlgorithm()); + + assertNotNull(four); + assertNotNull(four.getAttributes()); + assertEquals(DataPolicy.PARTITION, four.getAttributes().getDataPolicy()); + assertNotNull(four.getAttributes().getEvictionAttributes()); + assertEquals(EvictionAction.OVERFLOW_TO_DISK, four.getAttributes().getEvictionAttributes().getAction()); + assertEquals(EvictionAlgorithm.LRU_HEAP, three.getAttributes().getEvictionAttributes().getAlgorithm()); + + try { + four.getAttributes().getEvictionAttributes().getMaximum(); + } + catch (UnsupportedOperationException expected) { + assertEquals("LRUHeap does not support a maximum", expected.getMessage()); + throw expected; + } + } + + @Test + public void testMemorySizeRegionEvictionAttributes() { + assertNotNull(five); + assertNotNull(five.getAttributes()); + assertEquals(DataPolicy.REPLICATE, five.getAttributes().getDataPolicy()); + assertNotNull(five.getAttributes().getEvictionAttributes()); + assertEquals(EvictionAction.OVERFLOW_TO_DISK, five.getAttributes().getEvictionAttributes().getAction()); + assertEquals(EvictionAlgorithm.LRU_MEMORY, five.getAttributes().getEvictionAttributes().getAlgorithm()); + assertEquals(85, five.getAttributes().getEvictionAttributes().getMaximum()); + + assertNotNull(six); + assertNotNull(six.getAttributes()); + assertEquals(DataPolicy.PARTITION, six.getAttributes().getDataPolicy()); + assertNotNull(six.getAttributes().getEvictionAttributes()); + assertEquals(EvictionAction.LOCAL_DESTROY, six.getAttributes().getEvictionAttributes().getAction()); + assertEquals(EvictionAlgorithm.LRU_MEMORY, six.getAttributes().getEvictionAttributes().getAlgorithm()); + + if (six.getAttributes().getEvictionAttributes() instanceof EvictionAttributesImpl) { + assertEquals(MemLRUCapacityController.DEFAULT_MAXIMUM_MEGABYTES, + six.getAttributes().getEvictionAttributes().getMaximum()); + } + } + +} diff --git a/src/test/resources/org/springframework/data/gemfire/config/regions-with-eviction-attributes-ns.xml b/src/test/resources/org/springframework/data/gemfire/config/regions-with-eviction-attributes-ns.xml new file mode 100644 index 00000000..51420b42 --- /dev/null +++ b/src/test/resources/org/springframework/data/gemfire/config/regions-with-eviction-attributes-ns.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +