diff --git a/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java b/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java index b2f00184..c16c33e5 100644 --- a/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java @@ -126,7 +126,9 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport private DynamicRegionSupport dynamicRegionSupport; private Float criticalHeapPercentage; + private Float criticalOffHeapPercentage; private Float evictionHeapPercentage; + private Float evictionOffHeapPercentage; private GatewayConflictResolver gatewayConflictResolver; @@ -260,7 +262,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport setCache(postProcess(resolveCache())); - Optional.ofNullable(this.getCache()).ifPresent(cache -> { + Optional.ofNullable(this.getCache()).ifPresent(cache -> { Optional.ofNullable(cache.getDistributedSystem()).map(DistributedSystem::getDistributedMember) .ifPresent(member -> @@ -470,35 +472,59 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport } configureHeapPercentages(cache); + configureOffHeapPercentages(cache); + registerJndiDataSources(); registerTransactionListeners(cache); registerTransactionWriter(cache); - registerJndiDataSources(); return cache; } /* (non-Javadoc) */ private boolean isHeapPercentageValid(Float heapPercentage) { - return (heapPercentage > 0.0f && heapPercentage <= 100.0f); + return (heapPercentage >= 0.0f && heapPercentage <= 100.0f); } /* (non-Javadoc) */ private void configureHeapPercentages(GemFireCache cache) { + Optional.ofNullable(getCriticalHeapPercentage()).ifPresent(criticalHeapPercentage -> { + Assert.isTrue(isHeapPercentageValid(criticalHeapPercentage), String.format( - "criticalHeapPercentage [%s] is not valid; must be > 0.0 and <= 100.0", criticalHeapPercentage)); + "criticalHeapPercentage [%s] is not valid; must be >= 0.0 and <= 100.0", criticalHeapPercentage)); cache.getResourceManager().setCriticalHeapPercentage(criticalHeapPercentage); }); Optional.ofNullable(getEvictionHeapPercentage()).ifPresent(evictionHeapPercentage -> { + Assert.isTrue(isHeapPercentageValid(evictionHeapPercentage), String.format( - "evictionHeapPercentage [%s] is not valid; must be > 0.0 and <= 100.0", evictionHeapPercentage)); + "evictionHeapPercentage [%s] is not valid; must be >= 0.0 and <= 100.0", evictionHeapPercentage)); cache.getResourceManager().setEvictionHeapPercentage(evictionHeapPercentage); }); } + /* (non-Javadoc) */ + private void configureOffHeapPercentages(GemFireCache cache) { + + Optional.ofNullable(getCriticalOffHeapPercentage()).ifPresent(criticalOffHeapPercentage -> { + + Assert.isTrue(isHeapPercentageValid(criticalOffHeapPercentage), String.format( + "criticalOffHeapPercentage [%s] is not valid; must be >= 0.0 and <= 100.0", criticalOffHeapPercentage)); + + cache.getResourceManager().setCriticalOffHeapPercentage(criticalOffHeapPercentage); + }); + + Optional.ofNullable(getEvictionOffHeapPercentage()).ifPresent(evictionOffHeapPercentage -> { + + Assert.isTrue(isHeapPercentageValid(evictionOffHeapPercentage), String.format( + "evictionOffHeapPercentage [%s] is not valid; must be >= 0.0 and <= 100.0", evictionOffHeapPercentage)); + + cache.getResourceManager().setEvictionOffHeapPercentage(evictionOffHeapPercentage); + }); + } + /* (non-Javadoc) */ private void registerJndiDataSources() { @@ -865,6 +891,22 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport return criticalHeapPercentage; } + /** + * Set the cache's critical off-heap percentage property. + * + * @param criticalOffHeapPercentage floating point value indicating the critical off-heap percentage. + */ + public void setCriticalOffHeapPercentage(Float criticalOffHeapPercentage) { + this.criticalOffHeapPercentage = criticalOffHeapPercentage; + } + + /** + * @return the criticalOffHeapPercentage + */ + public Float getCriticalOffHeapPercentage() { + return this.criticalOffHeapPercentage; + } + /** * Sets an instance of the DynamicRegionSupport to support Dynamic Regions in this GemFire Cache. * @@ -917,6 +959,22 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport return evictionHeapPercentage; } + /** + * Set the cache's eviction off-heap percentage property. + * + * @param evictionOffHeapPercentage float-point value indicating the percentage of off-heap use triggering eviction. + */ + public void setEvictionOffHeapPercentage(Float evictionOffHeapPercentage) { + this.evictionOffHeapPercentage = evictionOffHeapPercentage; + } + + /** + * @return the evictionOffHeapPercentage + */ + public Float getEvictionOffHeapPercentage() { + return this.evictionOffHeapPercentage; + } + /** * Requires GemFire 7.0 or higher * @param gatewayConflictResolver defined as Object in the signature for backward diff --git a/src/main/java/org/springframework/data/gemfire/config/xml/CacheParser.java b/src/main/java/org/springframework/data/gemfire/config/xml/CacheParser.java index fa241ce3..bf660352 100644 --- a/src/main/java/org/springframework/data/gemfire/config/xml/CacheParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/xml/CacheParser.java @@ -64,6 +64,7 @@ class CacheParser extends AbstractSingleBeanDefinitionParser { */ @Override protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { + super.doParse(element, builder); registerGemFireBeanFactoryPostProcessors(getRegistry(parserContext)); @@ -74,7 +75,9 @@ class CacheParser extends AbstractSingleBeanDefinitionParser { ParsingUtils.setPropertyValue(element, builder, "close"); ParsingUtils.setPropertyValue(element, builder, "copy-on-read"); ParsingUtils.setPropertyValue(element, builder, "critical-heap-percentage"); + ParsingUtils.setPropertyValue(element, builder, "critical-off-heap-percentage"); ParsingUtils.setPropertyValue(element, builder, "eviction-heap-percentage"); + ParsingUtils.setPropertyValue(element, builder, "eviction-off-heap-percentage"); ParsingUtils.setPropertyValue(element, builder, "enable-auto-reconnect"); ParsingUtils.setPropertyValue(element, builder, "lock-lease"); ParsingUtils.setPropertyValue(element, builder, "lock-timeout"); @@ -127,15 +130,18 @@ class CacheParser extends AbstractSingleBeanDefinitionParser { /* (non-Javadoc) */ void registerGemFireBeanFactoryPostProcessors(BeanDefinitionRegistry registry) { - BeanDefinitionReaderUtils.registerWithGeneratedName(BeanDefinitionBuilder.genericBeanDefinition( - CustomEditorBeanFactoryPostProcessor.class).getBeanDefinition(), registry); + + BeanDefinitionReaderUtils.registerWithGeneratedName( + BeanDefinitionBuilder.genericBeanDefinition(CustomEditorBeanFactoryPostProcessor.class) + .getBeanDefinition(), registry); } /* (non-Javadoc) */ private void parsePdxDiskStore(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { + ParsingUtils.setPropertyValue(element, builder, "pdx-disk-store", "pdxDiskStoreName"); - final String pdxDiskStoreName = element.getAttribute("pdx-disk-store"); + String pdxDiskStoreName = element.getAttribute("pdx-disk-store"); if (!StringUtils.isEmpty(pdxDiskStoreName)) { registerPdxDiskStoreAwareBeanFactoryPostProcessor(getRegistry(parserContext), pdxDiskStoreName); @@ -144,20 +150,25 @@ class CacheParser extends AbstractSingleBeanDefinitionParser { /* (non-Javadoc) */ void registerPdxDiskStoreAwareBeanFactoryPostProcessor(BeanDefinitionRegistry registry, String pdxDiskStoreName) { + BeanDefinitionReaderUtils.registerWithGeneratedName( createPdxDiskStoreAwareBeanFactoryPostProcessorBeanDefinition(pdxDiskStoreName), registry); } /* (non-Javadoc) */ private AbstractBeanDefinition createPdxDiskStoreAwareBeanFactoryPostProcessorBeanDefinition(String pdxDiskStoreName) { - BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition( - PdxDiskStoreAwareBeanFactoryPostProcessor.class); + + BeanDefinitionBuilder builder = + BeanDefinitionBuilder.genericBeanDefinition(PdxDiskStoreAwareBeanFactoryPostProcessor.class); + builder.addConstructorArgValue(pdxDiskStoreName); + return builder.getBeanDefinition(); } /* (non-Javadoc) */ private void parseDynamicRegionFactory(Element element, BeanDefinitionBuilder builder) { + Element dynamicRegionFactory = DomUtils.getChildElementByTagName(element, "dynamic-region-factory"); if (dynamicRegionFactory != null) { @@ -169,7 +180,9 @@ class CacheParser extends AbstractSingleBeanDefinitionParser { /* (non-Javadoc) */ private BeanDefinitionBuilder buildDynamicRegionSupport(Element dynamicRegionFactory) { + if (dynamicRegionFactory != null) { + BeanDefinitionBuilder dynamicRegionSupport = BeanDefinitionBuilder.genericBeanDefinition( CacheFactoryBean.DynamicRegionSupport.class); @@ -205,17 +218,21 @@ class CacheParser extends AbstractSingleBeanDefinitionParser { /* (non-Javadoc) */ private void parseJndiBindings(Element element, BeanDefinitionBuilder builder) { + List jndiBindings = DomUtils.getChildElementsByTagName(element, "jndi-binding"); if (!CollectionUtils.isEmpty(jndiBindings)) { + ManagedList jndiDataSources = new ManagedList(jndiBindings.size()); for (Element jndiBinding : jndiBindings) { + BeanDefinitionBuilder jndiDataSource = BeanDefinitionBuilder.genericBeanDefinition( CacheFactoryBean.JndiDataSource.class); // NOTE 'jndi-name' and 'type' are required by the XSD so we should have at least 2 attributes. NamedNodeMap attributes = jndiBinding.getAttributes(); + ManagedMap jndiAttributes = new ManagedMap(attributes.getLength()); for (int index = 0, length = attributes.getLength(); index < length; index++) { @@ -260,6 +277,7 @@ class CacheParser extends AbstractSingleBeanDefinitionParser { @Override protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) throws BeanDefinitionStoreException { + String name = super.resolveId(element, definition, parserContext); if (!StringUtils.hasText(name)) { diff --git a/src/main/resources/org/springframework/data/gemfire/config/spring-geode-2.0.xsd b/src/main/resources/org/springframework/data/gemfire/config/spring-geode-2.0.xsd index 4d8f799c..89109254 100644 --- a/src/main/resources/org/springframework/data/gemfire/config/spring-geode-2.0.xsd +++ b/src/main/resources/org/springframework/data/gemfire/config/spring-geode-2.0.xsd @@ -187,6 +187,17 @@ Set the percentage of heap at or above which the cache is considered in danger o due to garbage collection pauses or out of memory exceptions. Changing this value can cause a LowMemoryException to be thrown during certain cache operation. This feature requires additional VM flags to perform properly (see the JavaDocs for org.apache.geode.cache.control.ResourceManager for more information). + ]]> + + + + + @@ -197,6 +208,16 @@ JavaDocs for org.apache.geode.cache.control.ResourceManager for more information Set the percentage of heap at or above which the eviction should begin on Regions configured for HeapLRU eviction. This feature requires additional VM flags to perform properly (see the JavaDocs for org.apache.geode.cache.control.ResourceManager for more information). + ]]> + + + + + diff --git a/src/test/java/org/springframework/data/gemfire/CacheFactoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/CacheFactoryBeanTest.java index f61e2f92..86984765 100644 --- a/src/test/java/org/springframework/data/gemfire/CacheFactoryBeanTest.java +++ b/src/test/java/org/springframework/data/gemfire/CacheFactoryBeanTest.java @@ -212,6 +212,7 @@ public class CacheFactoryBeanTest { @Test @SuppressWarnings("deprecation") public void init() throws Exception { + BeanFactory mockBeanFactory = mock(BeanFactory.class); Cache mockCache = mock(Cache.class); CacheTransactionManager mockCacheTransactionManager = mock(CacheTransactionManager.class); @@ -224,7 +225,7 @@ public class CacheFactoryBeanTest { TransactionListener mockTransactionLister = mock(TransactionListener.class); TransactionWriter mockTransactionWriter = mock(TransactionWriter.class); - final CacheFactory mockCacheFactory = mock(CacheFactory.class); + CacheFactory mockCacheFactory = mock(CacheFactory.class); when(mockBeanFactory.getAliases(anyString())).thenReturn(new String[0]); when(mockCacheFactory.create()).thenReturn(mockCache); @@ -245,9 +246,13 @@ public class CacheFactoryBeanTest { final Properties gemfireProperties = new Properties(); CacheFactoryBean cacheFactoryBean = new CacheFactoryBean() { - @Override protected Object createFactory(final Properties actualGemfireProperties) { + + @Override + protected Object createFactory(final Properties actualGemfireProperties) { + assertThat(actualGemfireProperties, is(equalTo(gemfireProperties))); assertThat(getBeanClassLoader(), is(equalTo(ClassLoader.getSystemClassLoader()))); + return mockCacheFactory; } }; @@ -258,9 +263,11 @@ public class CacheFactoryBeanTest { cacheFactoryBean.setCacheXml(mockCacheXml); cacheFactoryBean.setCopyOnRead(true); cacheFactoryBean.setCriticalHeapPercentage(0.90f); + cacheFactoryBean.setCriticalOffHeapPercentage(0.95f); cacheFactoryBean.setDynamicRegionSupport(null); cacheFactoryBean.setEnableAutoReconnect(false); cacheFactoryBean.setEvictionHeapPercentage(0.75f); + cacheFactoryBean.setEvictionOffHeapPercentage(0.90f); cacheFactoryBean.setGatewayConflictResolver(mockGatewayConflictResolver); cacheFactoryBean.setJndiDataSources(null); cacheFactoryBean.setLockLease(15000); @@ -304,10 +311,12 @@ public class CacheFactoryBeanTest { verify(mockCache, times(1)).setLockLease(eq(15000)); verify(mockCache, times(1)).setLockTimeout(eq(5000)); verify(mockCache, times(1)).setMessageSyncInterval(eq(20000)); - verify(mockCache, times(2)).getResourceManager(); + verify(mockCache, times(4)).getResourceManager(); verify(mockCache, times(1)).setSearchTimeout(eq(45000)); verify(mockResourceManager, times(1)).setCriticalHeapPercentage(eq(0.90f)); + verify(mockResourceManager, times(1)).setCriticalOffHeapPercentage(eq(0.95f)); verify(mockResourceManager, times(1)).setEvictionHeapPercentage(eq(0.75f)); + verify(mockResourceManager, times(1)).setEvictionOffHeapPercentage(eq(0.90f)); verify(mockCacheTransactionManager, times(1)).addListener(same(mockTransactionLister)); verify(mockCacheTransactionManager, times(1)).setWriter(same(mockTransactionWriter)); } @@ -500,7 +509,26 @@ public class CacheFactoryBeanTest { cacheFactoryBean.postProcess(mockCache); } catch (IllegalArgumentException expected) { - assertEquals("criticalHeapPercentage [200.0] is not valid; must be > 0.0 and <= 100.0", + assertEquals("criticalHeapPercentage [200.0] is not valid; must be >= 0.0 and <= 100.0", + expected.getMessage()); + + throw expected; + } + finally { + verifyZeroInteractions(mockCache); + } + } + + @Test(expected = IllegalArgumentException.class) + public void postProcessCacheWithInvalidCriticalOffHeapPercentage() throws Exception { + try { + CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); + + cacheFactoryBean.setCriticalOffHeapPercentage(200.0f); + cacheFactoryBean.postProcess(mockCache); + } + catch (IllegalArgumentException expected) { + assertEquals("criticalOffHeapPercentage [200.0] is not valid; must be >= 0.0 and <= 100.0", expected.getMessage()); throw expected; @@ -519,7 +547,26 @@ public class CacheFactoryBeanTest { cacheFactoryBean.postProcess(mockCache); } catch (IllegalArgumentException expected) { - assertEquals("evictionHeapPercentage [-75.0] is not valid; must be > 0.0 and <= 100.0", + assertEquals("evictionHeapPercentage [-75.0] is not valid; must be >= 0.0 and <= 100.0", + expected.getMessage()); + + throw expected; + } + finally { + verifyZeroInteractions(mockCache); + } + } + + @Test(expected = IllegalArgumentException.class) + public void postProcessCacheWithInvalidEvictionOffHeapPercentage() throws Exception { + try { + CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); + + cacheFactoryBean.setEvictionOffHeapPercentage(-75.0f); + cacheFactoryBean.postProcess(mockCache); + } + catch (IllegalArgumentException expected) { + assertEquals("evictionOffHeapPercentage [-75.0] is not valid; must be >= 0.0 and <= 100.0", expected.getMessage()); throw expected; @@ -634,6 +681,7 @@ public class CacheFactoryBeanTest { @Test public void setAndGetCacheFactoryBeanProperties() throws Exception { + BeanFactory mockBeanFactory = mock(BeanFactory.class, "SpringBeanFactory"); GatewayConflictResolver mockGatewayConflictResolver = mock(GatewayConflictResolver.class, "GemFireGatewayConflictResolver"); PdxSerializer mockPdxSerializer = mock(PdxSerializer.class, "GemFirePdxSerializer"); @@ -656,7 +704,9 @@ public class CacheFactoryBeanTest { cacheFactoryBean.setDynamicRegionSupport(new CacheFactoryBean.DynamicRegionSupport()); cacheFactoryBean.setEnableAutoReconnect(true); cacheFactoryBean.setCriticalHeapPercentage(0.95f); + cacheFactoryBean.setCriticalOffHeapPercentage(0.99f); cacheFactoryBean.setEvictionHeapPercentage(0.70f); + cacheFactoryBean.setEvictionOffHeapPercentage(0.80f); cacheFactoryBean.setGatewayConflictResolver(mockGatewayConflictResolver); cacheFactoryBean.setJndiDataSources(Collections.singletonList(new CacheFactoryBean.JndiDataSource())); cacheFactoryBean.setLockLease(15000); @@ -682,9 +732,11 @@ public class CacheFactoryBeanTest { assertTrue(Boolean.FALSE.equals(TestUtils.readField("close", cacheFactoryBean))); assertTrue(cacheFactoryBean.getCopyOnRead()); assertEquals(0.95f, cacheFactoryBean.getCriticalHeapPercentage(), 0.0f); + assertEquals(0.99f, cacheFactoryBean.getCriticalOffHeapPercentage(), 0.0f); assertNotNull(cacheFactoryBean.getDynamicRegionSupport()); assertTrue(cacheFactoryBean.getEnableAutoReconnect()); assertEquals(0.70f, cacheFactoryBean.getEvictionHeapPercentage(), 0.0f); + assertEquals(0.80f, cacheFactoryBean.getEvictionOffHeapPercentage(), 0.0f); assertSame(mockGatewayConflictResolver, cacheFactoryBean.getGatewayConflictResolver()); assertNotNull(cacheFactoryBean.getJndiDataSources()); assertEquals(1, cacheFactoryBean.getJndiDataSources().size()); diff --git a/src/test/java/org/springframework/data/gemfire/config/xml/CacheNamespaceTest.java b/src/test/java/org/springframework/data/gemfire/config/xml/CacheNamespaceTest.java index 3fcf5ae1..e1caa38c 100644 --- a/src/test/java/org/springframework/data/gemfire/config/xml/CacheNamespaceTest.java +++ b/src/test/java/org/springframework/data/gemfire/config/xml/CacheNamespaceTest.java @@ -41,27 +41,36 @@ import org.springframework.data.gemfire.CacheFactoryBean; import org.springframework.data.gemfire.TestUtils; import org.springframework.data.gemfire.client.ClientCacheFactoryBean; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.util.ReflectionTestUtils; /** + * Unit tests for {@link CacheParser}. + * * @author Costin Leau * @author John Blum + * @see org.junit.Test + * @see org.apache.geode.cache.Cache + * @see org.apache.geode.cache.client.ClientCache + * @see org.springframework.data.gemfire.config.xml.CacheParser + * @see org.springframework.data.gemfire.CacheFactoryBean + * @see org.springframework.data.gemfire.client.ClientCacheFactoryBean */ -@RunWith(SpringJUnit4ClassRunner.class) +@RunWith(SpringRunner.class) @ContextConfiguration(locations = "cache-ns.xml") @SuppressWarnings("unused") public class CacheNamespaceTest{ @Autowired - private ApplicationContext context; + private ApplicationContext applicationContext; @Test public void testNoNamedCache() throws Exception { - assertTrue(context.containsBean("gemfireCache")); - assertTrue(context.containsBean("gemfire-cache")); // assert alias is registered - Cache gemfireCache = context.getBean("gemfireCache", Cache.class); + assertTrue(applicationContext.containsBean("gemfireCache")); + assertTrue(applicationContext.containsBean("gemfire-cache")); // assert alias is registered + + Cache gemfireCache = applicationContext.getBean("gemfireCache", Cache.class); assertNotNull(gemfireCache); assertNotNull(gemfireCache.getDistributedSystem()); @@ -69,7 +78,7 @@ public class CacheNamespaceTest{ assertTrue(Boolean.parseBoolean(gemfireCache.getDistributedSystem().getProperties() .getProperty("disable-auto-reconnect"))); - CacheFactoryBean cacheFactoryBean = context.getBean("&gemfireCache", CacheFactoryBean.class); + CacheFactoryBean cacheFactoryBean = applicationContext.getBean("&gemfireCache", CacheFactoryBean.class); assertNull(TestUtils.readField("cacheXml", cacheFactoryBean)); @@ -83,14 +92,15 @@ public class CacheNamespaceTest{ @Test public void testNamedCache() throws Exception { - assertTrue(context.containsBean("cache-with-name")); - Cache gemfireCache = context.getBean("gemfireCache", Cache.class); + assertTrue(applicationContext.containsBean("cache-with-name")); + + Cache gemfireCache = applicationContext.getBean("gemfireCache", Cache.class); assertTrue(Boolean.parseBoolean(gemfireCache.getDistributedSystem().getProperties() .getProperty("disable-auto-reconnect"))); - CacheFactoryBean cacheFactoryBean = context.getBean("&cache-with-name", CacheFactoryBean.class); + CacheFactoryBean cacheFactoryBean = applicationContext.getBean("&cache-with-name", CacheFactoryBean.class); assertNull(TestUtils.readField("cacheXml", cacheFactoryBean)); @@ -104,14 +114,16 @@ public class CacheNamespaceTest{ @Test public void testCacheWithXmlAndProperties() throws Exception { - assertTrue(context.containsBean("cache-with-xml-and-props")); - CacheFactoryBean cacheFactoryBean = context.getBean("&cache-with-xml-and-props", CacheFactoryBean.class); + assertTrue(applicationContext.containsBean("cache-with-xml-and-props")); + + CacheFactoryBean cacheFactoryBean = applicationContext.getBean("&cache-with-xml-and-props", CacheFactoryBean.class); + Resource cacheXmlResource = TestUtils.readField("cacheXml", cacheFactoryBean); assertEquals("gemfire-cache.xml", cacheXmlResource.getFilename()); - assertTrue(context.containsBean("gemfireProperties")); - assertEquals(context.getBean("gemfireProperties"), TestUtils.readField("properties", cacheFactoryBean)); + assertTrue(applicationContext.containsBean("gemfireProperties")); + assertEquals(applicationContext.getBean("gemfireProperties"), TestUtils.readField("properties", cacheFactoryBean)); assertEquals(Boolean.TRUE, TestUtils.readField("pdxReadSerialized", cacheFactoryBean)); assertEquals(Boolean.FALSE, TestUtils.readField("pdxIgnoreUnreadFields", cacheFactoryBean)); assertEquals(Boolean.TRUE, TestUtils.readField("pdxPersistent", cacheFactoryBean)); @@ -120,57 +132,79 @@ public class CacheNamespaceTest{ @Test public void testCacheWithGatewayConflictResolver() { - Cache cache = context.getBean("cache-with-gateway-conflict-resolver", Cache.class); + + Cache cache = applicationContext.getBean("cache-with-gateway-conflict-resolver", Cache.class); assertTrue(cache.getGatewayConflictResolver() instanceof TestGatewayConflictResolver); } @Test public void testCacheWithAutoReconnectDisabled() throws Exception { - assertTrue(context.containsBean("cache-with-auto-reconnect-disabled")); - Cache gemfireCache = context.getBean("cache-with-auto-reconnect-disabled", Cache.class); + assertTrue(applicationContext.containsBean("cache-with-auto-reconnect-disabled")); + + Cache gemfireCache = applicationContext.getBean("cache-with-auto-reconnect-disabled", Cache.class); assertTrue(Boolean.parseBoolean(gemfireCache.getDistributedSystem().getProperties() .getProperty("disable-auto-reconnect"))); - CacheFactoryBean cacheFactoryBean = context.getBean("&cache-with-auto-reconnect-disabled", CacheFactoryBean.class); + CacheFactoryBean cacheFactoryBean = + applicationContext.getBean("&cache-with-auto-reconnect-disabled", CacheFactoryBean.class); assertFalse(cacheFactoryBean.getEnableAutoReconnect()); } @Test public void testCacheWithAutoReconnectEnabled() throws Exception { - assertTrue(context.containsBean("cache-with-auto-reconnect-enabled")); - Cache gemfireCache = context.getBean("cache-with-auto-reconnect-enabled", Cache.class); + assertTrue(applicationContext.containsBean("cache-with-auto-reconnect-enabled")); + + Cache gemfireCache = applicationContext.getBean("cache-with-auto-reconnect-enabled", Cache.class); assertFalse(Boolean.parseBoolean(gemfireCache.getDistributedSystem().getProperties() .getProperty("disable-auto-reconnect"))); - CacheFactoryBean cacheFactoryBean = context.getBean("&cache-with-auto-reconnect-enabled", CacheFactoryBean.class); + CacheFactoryBean cacheFactoryBean = + applicationContext.getBean("&cache-with-auto-reconnect-enabled", CacheFactoryBean.class); assertTrue(cacheFactoryBean.getEnableAutoReconnect()); } @Test public void testHeapTunedCache() throws Exception { - assertTrue(context.containsBean("heap-tuned-cache")); - CacheFactoryBean cacheFactoryBean = context.getBean("&heap-tuned-cache", CacheFactoryBean.class); + assertTrue(applicationContext.containsBean("heap-tuned-cache")); - Float criticalHeapPercentage = TestUtils.readField("criticalHeapPercentage", cacheFactoryBean); - Float evictionHeapPercentage = TestUtils.readField("evictionHeapPercentage", cacheFactoryBean); + CacheFactoryBean cacheFactoryBean = applicationContext.getBean("&heap-tuned-cache", CacheFactoryBean.class); + + Float criticalHeapPercentage = cacheFactoryBean.getCriticalHeapPercentage(); + Float evictionHeapPercentage = cacheFactoryBean.getEvictionHeapPercentage(); assertEquals(70.0f, criticalHeapPercentage, 0.0001); assertEquals(60.0f, evictionHeapPercentage, 0.0001); } + @Test + public void testOffHeapTunedCache() throws Exception { + + assertTrue(applicationContext.containsBean("off-heap-tuned-cache")); + + CacheFactoryBean cacheFactoryBean = applicationContext.getBean("&off-heap-tuned-cache", CacheFactoryBean.class); + + Float criticalOffHeapPercentage = cacheFactoryBean.getCriticalOffHeapPercentage(); + Float evictionOffHeapPercentage = cacheFactoryBean.getEvictionOffHeapPercentage(); + + assertEquals(90.0f, criticalOffHeapPercentage, 0.0001); + assertEquals(50.0f, evictionOffHeapPercentage, 0.0001); + } + @Test(expected = IllegalStateException.class) public void testNoBeanFactoryLocator() throws Exception { - assertTrue(context.containsBean("no-bean-factory-locator-cache")); - CacheFactoryBean cacheFactoryBean = context.getBean("&no-bean-factory-locator-cache", CacheFactoryBean.class); + assertTrue(applicationContext.containsBean("no-bean-factory-locator-cache")); + + CacheFactoryBean cacheFactoryBean = + applicationContext.getBean("&no-bean-factory-locator-cache", CacheFactoryBean.class); assertThat(ReflectionTestUtils.getField(cacheFactoryBean, "beanFactoryLocator"), is(nullValue())); @@ -179,9 +213,11 @@ public class CacheNamespaceTest{ @Test public void namedClientCacheWithNoProperties() throws Exception { - assertTrue(context.containsBean("client-cache-with-name")); - ClientCacheFactoryBean clientCacheFactoryBean = context.getBean("&client-cache-with-name", ClientCacheFactoryBean.class); + assertTrue(applicationContext.containsBean("client-cache-with-name")); + + ClientCacheFactoryBean clientCacheFactoryBean = + applicationContext.getBean("&client-cache-with-name", ClientCacheFactoryBean.class); assertNull(TestUtils.readField("cacheXml", clientCacheFactoryBean)); @@ -193,9 +229,12 @@ public class CacheNamespaceTest{ @Test public void clientCacheWithXmlNoProperties() throws Exception { - assertTrue(context.containsBean("client-cache-with-xml")); - ClientCacheFactoryBean clientCacheFactoryBean = context.getBean("&client-cache-with-xml", ClientCacheFactoryBean.class); + assertTrue(applicationContext.containsBean("client-cache-with-xml")); + + ClientCacheFactoryBean clientCacheFactoryBean = + applicationContext.getBean("&client-cache-with-xml", ClientCacheFactoryBean.class); + Resource cacheXmlResource = TestUtils.readField("cacheXml", clientCacheFactoryBean); assertEquals("gemfire-client-cache.xml", cacheXmlResource.getFilename()); @@ -207,6 +246,7 @@ public class CacheNamespaceTest{ } public static class TestGatewayConflictResolver implements GatewayConflictResolver { + @Override public void onEvent(TimestampedEntryEvent arg0, GatewayConflictHelper arg1) { throw new UnsupportedOperationException("Not Implemented!"); diff --git a/src/test/java/org/springframework/data/gemfire/test/MockCacheFactoryBean.java b/src/test/java/org/springframework/data/gemfire/test/MockCacheFactoryBean.java index b9b4a2c7..e5e2fdea 100644 --- a/src/test/java/org/springframework/data/gemfire/test/MockCacheFactoryBean.java +++ b/src/test/java/org/springframework/data/gemfire/test/MockCacheFactoryBean.java @@ -38,9 +38,11 @@ public class MockCacheFactoryBean extends CacheFactoryBean { setClose(it.isClose()); setCopyOnRead(it.getCopyOnRead()); setCriticalHeapPercentage(it.getCriticalHeapPercentage()); + setCriticalOffHeapPercentage(it.getCriticalOffHeapPercentage()); setDynamicRegionSupport(it.getDynamicRegionSupport()); setEnableAutoReconnect(it.getEnableAutoReconnect()); setEvictionHeapPercentage(it.getEvictionHeapPercentage()); + setEvictionOffHeapPercentage(it.getEvictionOffHeapPercentage()); setGatewayConflictResolver(it.getGatewayConflictResolver()); setJndiDataSources(it.getJndiDataSources()); setLockLease(it.getLockLease()); diff --git a/src/test/resources/org/springframework/data/gemfire/config/xml/cache-ns.xml b/src/test/resources/org/springframework/data/gemfire/config/xml/cache-ns.xml index 94801dbe..18ae4e76 100644 --- a/src/test/resources/org/springframework/data/gemfire/config/xml/cache-ns.xml +++ b/src/test/resources/org/springframework/data/gemfire/config/xml/cache-ns.xml @@ -3,11 +3,11 @@ xmlns:gfe="http://www.springframework.org/schema/geode" xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - default-lazy-init="true" xsi:schemaLocation=" http://www.springframework.org/schema/geode http://www.springframework.org/schema/geode/spring-geode.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> + http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd" +default-lazy-init="true"> @@ -35,6 +35,8 @@ + +