added dynamic region and jndi binding support

This commit is contained in:
David Turanski
2012-07-03 10:01:49 -04:00
parent 1467ec0668
commit bb34beb224
13 changed files with 490 additions and 157 deletions

View File

@@ -97,6 +97,8 @@ dependencies {
// Spring Data
compile "org.springframework.data:spring-data-commons-core:${springDataCommonsVersion}"
//
testCompile "org.apache.derby:derbyLocale_zh_TW:10.9.1.0"
}
javaprojects = rootProject

View File

@@ -16,7 +16,9 @@
package org.springframework.data.gemfire;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.logging.Log;
@@ -41,13 +43,15 @@ import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.CacheClosedException;
import com.gemstone.gemfire.cache.CacheFactory;
import com.gemstone.gemfire.cache.CacheTransactionManager;
import com.gemstone.gemfire.cache.Declarable;
import com.gemstone.gemfire.cache.DynamicRegionFactory;
import com.gemstone.gemfire.cache.GemFireCache;
import com.gemstone.gemfire.cache.TransactionListener;
import com.gemstone.gemfire.cache.TransactionWriter;
import com.gemstone.gemfire.distributed.DistributedMember;
import com.gemstone.gemfire.distributed.DistributedSystem;
import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
import com.gemstone.gemfire.internal.datasource.ConfigProperty;
import com.gemstone.gemfire.internal.jndi.JNDIInvoker;
import com.gemstone.gemfire.pdx.PdxSerializable;
import com.gemstone.gemfire.pdx.PdxSerializer;
@@ -125,12 +129,81 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
if (messageSyncInterval != null) {
cacheImpl.setMessageSyncInterval(messageSyncInterval);
}
}
}
if (initializer != null) {
// Props are null because already configured in Spring
cacheImpl.setInitializer(initializer, null);
public static class DynamicRegionSupport {
private String diskDir;
private String poolName;
private Boolean persistent = Boolean.TRUE;
private Boolean registerInterest = Boolean.TRUE;
public String getDiskDir() {
return diskDir;
}
public void setDiskDir(String diskDir) {
this.diskDir = diskDir;
}
public Boolean getPersistent() {
return persistent;
}
public void setPersistent(Boolean persistent) {
this.persistent = persistent;
}
public Boolean getRegisterInterest() {
return registerInterest;
}
public void setRegisterInterest(Boolean registerInterest) {
this.registerInterest = registerInterest;
}
public String getPoolName() {
return poolName;
}
public void setPoolName(String poolName) {
this.poolName = poolName;
}
public void initializeDynamicRegionFactory() {
DynamicRegionFactory.Config config = null;
if (diskDir == null) {
config = new DynamicRegionFactory.Config(null, poolName, persistent, registerInterest);
}
else {
config = new DynamicRegionFactory.Config(new File(diskDir), poolName, persistent, registerInterest);
}
DynamicRegionFactory.get().open(config);
}
}
public static class JndiDataSource {
private Map<String, String> attributes;
private List<ConfigProperty> props;
public Map<String, String> getAttributes() {
return attributes;
}
public void setAttributes(Map<String, String> attributes) {
this.attributes = attributes;
}
public List<ConfigProperty> getProps() {
return props;
}
public void setProps(List<ConfigProperty> props) {
this.props = props;
}
}
@@ -177,7 +250,13 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
protected TransactionWriter transactionWriter;
protected Declarable initializer;
protected Float evictionHeapPercentage;
protected Float criticalHeapPercentage;
protected DynamicRegionSupport dynamicRegionSupport;
protected List<JndiDataSource> jndiDataSources;
@Override
public void afterPropertiesSet() throws Exception {
@@ -203,6 +282,9 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
msg = "Retrieved existing";
}
catch (CacheClosedException ex) {
initializeDynamicRegionFactory();
Object factory = createFactory(cfgProps);
// GemFire 6.6 specific options
@@ -238,16 +320,52 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
log.debug("Initialized cache from " + cacheXml);
}
}
setHeapPercentages();
registerTransactionListeners();
registerTransactionWriter();
registerJndiDataSources();
}
finally {
th.setContextClassLoader(oldTCCL);
}
}
private void registerJndiDataSources() {
if (jndiDataSources != null) {
for (JndiDataSource jndiDataSource : jndiDataSources) {
JNDIInvoker.mapDatasource(jndiDataSource.getAttributes(), jndiDataSource.getProps());
}
}
}
/**
* If dynamic regions are enabled, create a DynamicRegionFactory before
* creating the cache
*/
private void initializeDynamicRegionFactory() {
if (dynamicRegionSupport != null) {
dynamicRegionSupport.initializeDynamicRegionFactory();
}
}
private void setHeapPercentages() {
if (criticalHeapPercentage != null) {
Assert.isTrue(criticalHeapPercentage > 0.0 && criticalHeapPercentage <= 100.0,
"invalid value specified for criticalHeapPercentage :" + criticalHeapPercentage
+ ". Must be > 0.0 and <= 100.0");
cache.getResourceManager().setCriticalHeapPercentage(criticalHeapPercentage);
}
if (evictionHeapPercentage != null) {
Assert.isTrue(evictionHeapPercentage > 0.0 && evictionHeapPercentage <= 100.0,
"invalid value specified for evictionHeapPercentage :" + evictionHeapPercentage
+ ". Must be > 0.0 and <= 100.0");
cache.getResourceManager().setEvictionHeapPercentage(evictionHeapPercentage);
}
}
/**
* Register a transaction writer if declared
*/
@@ -471,6 +589,14 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
this.searchTimeout = searchTimeout;
}
public void setEvictionHeapPercentage(Float evictionHeapPercentage) {
this.evictionHeapPercentage = evictionHeapPercentage;
}
public void setCriticalHeapPercentage(Float criticalHeapPercentage) {
this.criticalHeapPercentage = criticalHeapPercentage;
}
public void setTransactionListeners(List<TransactionListener> transactionListeners) {
this.transactionListeners = transactionListeners;
}
@@ -479,8 +605,11 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
this.transactionWriter = transactionWriter;
}
public void setInitializer(Declarable initializer) {
this.initializer = initializer;
public void setDynamicRegionSupport(DynamicRegionSupport dynamicRegionSupport) {
this.dynamicRegionSupport = dynamicRegionSupport;
}
public void setJndiDataSources(List<JndiDataSource> jndiDataSources) {
this.jndiDataSources = jndiDataSources;
}
}

View File

@@ -22,13 +22,18 @@ import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.gemfire.CacheFactoryBean;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import com.gemstone.gemfire.internal.datasource.ConfigProperty;
/**
* Parser for &lt;cache;gt; definitions.
@@ -52,15 +57,18 @@ class CacheParser extends AbstractSimpleBeanDefinitionParser {
ParsingUtils.setPropertyReference(element, builder, "properties-ref", "properties");
ParsingUtils.setPropertyReference(element, builder, "pdx-serializer", "pdxSerializer");
ParsingUtils.setPropertyValue(element, builder, "pdx-disk-store", "pdxDiskStoreName");
ParsingUtils.setPropertyValue(element, builder, "pdx-persistent", "pdxPersistent");
ParsingUtils.setPropertyValue(element, builder, "pdx-read-serialized", "pdxReadSerialized");
ParsingUtils.setPropertyValue(element, builder, "pdx-ignore-unread-fields", "pdxIgnoreUnreadFields");
ParsingUtils.setPropertyValue(element, builder, "use-bean-factory-locator", "useBeanFactoryLocator");
ParsingUtils.setPropertyValue(element, builder, "copy-on-read", "copyOnRead");
ParsingUtils.setPropertyValue(element, builder, "lock-timeout", "lockTimeout");
ParsingUtils.setPropertyValue(element, builder, "lock-lease", "lockLease");
ParsingUtils.setPropertyValue(element, builder, "message-sync-interval", "messageSyncInterval");
ParsingUtils.setPropertyValue(element, builder, "search-timeout", "searchTimeout");
ParsingUtils.setPropertyValue(element, builder, "pdx-persistent");
ParsingUtils.setPropertyValue(element, builder, "pdx-read-serialized");
ParsingUtils.setPropertyValue(element, builder, "pdx-ignore-unread-fields");
ParsingUtils.setPropertyValue(element, builder, "use-bean-factory-locator");
ParsingUtils.setPropertyValue(element, builder, "copy-on-read");
ParsingUtils.setPropertyValue(element, builder, "lock-timeout");
ParsingUtils.setPropertyValue(element, builder, "lock-lease");
ParsingUtils.setPropertyValue(element, builder, "message-sync-interval");
ParsingUtils.setPropertyValue(element, builder, "search-timeout");
ParsingUtils.setPropertyValue(element, builder, "critical-heap-percentage");
ParsingUtils.setPropertyValue(element, builder, "eviction-heap-percentage");
List<Element> txListeners = DomUtils.getChildElementsByTagName(element, "transaction-listener");
if (!CollectionUtils.isEmpty(txListeners)) {
ManagedList<Object> transactionListeners = new ManagedList<Object>();
@@ -76,10 +84,80 @@ class CacheParser extends AbstractSimpleBeanDefinitionParser {
ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, txWriter, builder));
}
Element initializer = DomUtils.getChildElementByTagName(element, "initializer");
if (initializer != null) {
builder.addPropertyValue("initializer",
ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, initializer, builder));
parseDynamicRegionFactory(element, builder);
parseJndiBindings(element, builder);
}
private void parseDynamicRegionFactory(Element element, BeanDefinitionBuilder builder) {
Element dynamicRegionFactory = DomUtils.getChildElementByTagName(element, "dynamic-region-factory");
if (dynamicRegionFactory != null) {
BeanDefinitionBuilder dynamicRegionSupport = buildDynamicRegionSupport(dynamicRegionFactory);
postProcessDynamicRegionSupport(element, dynamicRegionSupport);
builder.addPropertyValue("dynamicRegionSupport", dynamicRegionSupport.getBeanDefinition());
}
}
/**
* @param dynamicRegionSupport BDB for &lt;dynamic-region-factory&gt;
* element
*/
protected void postProcessDynamicRegionSupport(Element element, BeanDefinitionBuilder dynamicRegionSupport) {
}
private BeanDefinitionBuilder buildDynamicRegionSupport(Element dynamicRegionFactory) {
BeanDefinitionBuilder result = null;
if (dynamicRegionFactory != null) {
BeanDefinitionBuilder dynamicRegionSupport = BeanDefinitionBuilder
.genericBeanDefinition(CacheFactoryBean.DynamicRegionSupport.class);
String diskDir = dynamicRegionFactory.getAttribute("disk-dir");
if (StringUtils.hasText(diskDir)) {
dynamicRegionSupport.addPropertyValue("diskDir", diskDir);
}
String persistent = dynamicRegionFactory.getAttribute("persistent");
if (StringUtils.hasText(persistent)) {
dynamicRegionSupport.addPropertyValue("persistent", persistent);
}
String registerInterest = dynamicRegionFactory.getAttribute("register-interest");
if (StringUtils.hasText(registerInterest)) {
dynamicRegionSupport.addPropertyValue("registerInterest", registerInterest);
}
result = dynamicRegionSupport;
}
return result;
}
private void parseJndiBindings(Element element, BeanDefinitionBuilder builder) {
List<Element> jndiBindings = DomUtils.getChildElementsByTagName(element, "jndi-binding");
if (!CollectionUtils.isEmpty(jndiBindings)) {
ManagedList<Object> jndiDataSources = new ManagedList<Object>();
ManagedMap<String, String> jndiAttributes = new ManagedMap<String, String>();
for (Element jndiBinding : jndiBindings) {
BeanDefinitionBuilder jndiDataSource = BeanDefinitionBuilder
.genericBeanDefinition(CacheFactoryBean.JndiDataSource.class);
NamedNodeMap nnm = jndiBinding.getAttributes();
for (int i = 0; i < nnm.getLength(); i++) {
Attr attr = (Attr) nnm.item(i);
jndiAttributes.put(attr.getLocalName(), attr.getValue());
}
jndiDataSource.addPropertyValue("attributes", jndiAttributes);
List<Element> jndiProps = DomUtils.getChildElementsByTagName(element, "jndi-prop");
if (!CollectionUtils.isEmpty(jndiProps)) {
ManagedList<ConfigProperty> props = new ManagedList<ConfigProperty>();
for (Element jndiProp : jndiProps) {
String key = jndiProp.getAttribute("key");
String value = jndiProp.getNodeValue();
String type = StringUtils.hasText(jndiProp.getAttribute("type")) ? jndiProp
.getAttribute("type") : String.class.getName();
props.add(new ConfigProperty(key, value, type));
}
jndiDataSource.addPropertyValue("props", props);
}
jndiDataSources.add(jndiDataSource.getBeanDefinition());
}
builder.addPropertyValue("jndiDataSources", jndiDataSources);
}
}

View File

@@ -19,12 +19,14 @@ package org.springframework.data.gemfire.config;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.gemfire.client.ClientCacheFactoryBean;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* Parser for &lt;client-cache;gt; definitions.
*
* @author Costin Leau
* @author David Turanski
*/
class ClientCacheParser extends CacheParser {
@@ -39,4 +41,12 @@ class ClientCacheParser extends CacheParser {
ParsingUtils.setPropertyValue(element, builder, "pool-name", "poolName");
}
@Override
protected void postProcessDynamicRegionSupport(Element element, BeanDefinitionBuilder dynamicRegionSupport) {
String poolName = element.getAttribute("pool-name");
if (StringUtils.hasText(poolName)) {
dynamicRegionSupport.addPropertyValue("poolName", poolName);
}
}
}

View File

@@ -30,15 +30,43 @@ and may be nested or referenced.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="initializer" type="beanDeclarationType" minOccurs="0" maxOccurs="1">
<xsd:element name="dynamic-region-factory" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation><![CDATA[
Enables Dynamic Regions and specifies their configuration.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="disk-dir" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies the directory path for disk persistence for dynamic regions.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="persistent" type="xsd:string" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Enables persistence for dynamic regions.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="register-interest" type="xsd:string" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies whether dynamic regions register interest in all keys in a corresponding server region.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="jndi-binding" type="jndiBindingType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
Registers a bean as an initializer for the cache. The bean must implement com.gemstone.gemfire.cache.Declarable
and may be nested or referenced.
Configures a data source to be bound to a JNDI context for use with Gemfire transactions
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="jndi-binding" type="jndiBindingType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="copy-on-read" type="xsd:string" use="optional" default="false">
<xsd:annotation>
@@ -82,15 +110,15 @@ when the same cache is used in multiple application context/bean factories insid
<xsd:attribute name="pdx-serializer" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Sets the PDX serializer for the cache. If this serializer is set, it will be consulted to see if it can serialize any
domain classes which are added to the cache in portable data exchange format.
Sets the PDX serializer for the cache. If this serializer is set, it will be consulted to see if it can serialize any
domain classes which are added to the cache in portable data exchange format.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="pdx-disk-store" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Sets the name of the disk store to use for PDX meta data. When serializing objects in the PDX format,
Sets the name of the disk store to use for PDX meta data. When serializing objects in the PDX format,
the type definitions are persisted to disk. This setting controls which disk store is used for that persistence.
If not set, the metadata will go in the default disk store.
]]></xsd:documentation>
@@ -99,7 +127,7 @@ If not set, the metadata will go in the default disk store.
<xsd:attribute name="pdx-persistent" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Control whether the type metadata for PDX objects is persisted to disk. The default for this setting is true.
Control whether the type metadata for PDX objects is persisted to disk. The default for this setting is true.
If you are using a WAN gateway, or persistent regions, you should leave this set to true.
]]></xsd:documentation>
</xsd:annotation>
@@ -110,11 +138,11 @@ If you are using a WAN gateway, or persistent regions, you should leave this set
Sets the object preference to PdxInstance type. When a cached object that was serialized as a PDX is read from the cache
a PdxInstance will be returned instead of the actual domain class. The PdxInstance is an interface that provides run time
access to the fields of a PDX without deserializing the entire PDX. The PdxInstance implementation is a light weight wrapper
that simply refers to the raw bytes of the PDX that are kept in the cache. Using this method applications can choose to
that simply refers to the raw bytes of the PDX that are kept in the cache. Using this method applications can choose to
access PdxInstance instead of Java object.
Note that a PdxInstance is only returned if a serialized PDX is found in the cache. If the cache contains a deserialized PDX,
then a domain class instance is returned instead of a PdxInstance.
Note that a PdxInstance is only returned if a serialized PDX is found in the cache. If the cache contains a deserialized PDX,
then a domain class instance is returned instead of a PdxInstance.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
@@ -122,14 +150,33 @@ then a domain class instance is returned instead of a PdxInstance.
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls whether pdx ignores fields that were unread during deserialization. The default is to preserve unread fields be
including their data during serialization. But if you configure the cache to ignore unread fields then their data will be
including their data during serialization. But if you configure the cache to ignore unread fields then their data will be
lost during serialization.
You should only set this attribute to true if you know this member will only be reading cache data. In this use case you
do not need to pay the cost of preserving the unread fields since you will never be reserializing pdx data.
You should only set this attribute to true if you know this member will only be reading cache data. In this use case you
do not need to pay the cost of preserving the unread fields since you will never be reserializing pdx data.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="critical-heap-percentage">
<xsd:annotation>
<xsd:documentation source="com.gemstone.gemfire.cache.control.ResourceManager"><![CDATA[
Set the percentage of heap at or above which the cache is considered in danger of becoming inoperable
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 com.gemstone.gemfire.cache.control.ResourceManager for more information).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="eviction-heap-percentage">
<xsd:annotation>
<xsd:documentation source="com.gemstone.gemfire.cache.control.ResourceManager"><![CDATA[
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 com.gemstone.gemfire.cache.control.ResourceManager for more information).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<!-- -->
<xsd:element name="cache">
@@ -1713,14 +1760,31 @@ The name of the pool used by the index. Used usually in client scenarios.
<!-- -->
<xsd:complexType name="jndiBindingType">
<xsd:sequence>
<xsd:element name="configProperty" type="configPropertyType" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="jndi-prop" type="configPropertyType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies a vendor-specific property
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="jndi-name" type="xsd:string" use="required"/>
<xsd:attribute name="jndi-name" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
The JNDI name for this datasource. Will be prefixed with "java:/"
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="type" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies the datasource implementation: ManagedDataSource,SimpleDataSource,PooledDataSource,XaPooledDataSource
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="ManagedDataSource"/>
<xsd:enumeration value="SimpeDataSource"/>
<xsd:enumeration value="SimpleDataSource"/>
<xsd:enumeration value="PooledDataSource"/>
<xsd:enumeration value="XaPooledDataSource"/>
</xsd:restriction>
@@ -1741,12 +1805,21 @@ The name of the pool used by the index. Used usually in client scenarios.
<xsd:attribute name="transaction-type" type="xsd:string" use="optional"/>
</xsd:complexType>
<!-- -->
<xsd:complexType name="configPropertyType">
<xsd:sequence>
<xsd:element name="configPropertyName" type="xsd:string"/>
<xsd:element name="configPropertyType" type="xsd:string"/>
<xsd:element name="configPropertyValue" type="xsd:string"/>
</xsd:sequence>
<xsd:complexType name="configPropertyType" mixed="true">
<xsd:attribute name="key" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies The property key
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="type" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies a data type if other than java.lang.String
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<!-- -->
<xsd:simpleType name="baseDataPolicyType">

View File

@@ -16,7 +16,6 @@
package org.springframework.data.gemfire;
import junit.framework.Assert;
import org.junit.Test;
@@ -24,9 +23,10 @@ import org.junit.Test;
import com.gemstone.gemfire.cache.Cache;
/**
* Integration test trying various basic configurations of GemFire through Spring.
* Integration test trying various basic configurations of GemFire through
* Spring.
*
* Made abstract to avoid multiple caches running at the same time.
* Made abstract to avoid multiple caches running at the same time.
*
* @author Costin Leau
*/

View File

@@ -1,94 +0,0 @@
/*
* Copyright 2010-2012 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.assertNotNull;
import static org.junit.Assert.assertSame;
import java.util.Properties;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.Declarable;
/**
* @author David Turanski
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("cache-with-initializer.xml")
public class CacheInitializerTest {
@Autowired
TestInitializer cacheInitializer;
@Resource(name = "gemfire-cache")
Cache cache;
@Test
public void test() throws Exception {
assertNotNull(cache.getInitializer());
assertSame(cacheInitializer, cache.getInitializer());
// assertEquals("cacheInitializer", cacheInitializer.value);
}
public static class TestInitializer implements Declarable, BeanNameAware {
private String name;
public String value;
private String first;
private String last;
@Override
public void setBeanName(String name) {
this.name = name;
}
public String getFirst() {
return first;
}
public void setFirst(String first) {
this.first = first;
}
public String getLast() {
return last;
}
public void setLast(String last) {
this.last = last;
}
@Override
public void init(Properties props) {
this.value = this.name;
};
}
}

View File

@@ -16,8 +16,13 @@
package org.springframework.data.gemfire.config;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.springframework.core.io.Resource;
@@ -79,7 +84,8 @@ public class CacheNamespaceTest extends RecreatingContextTest {
try {
assertNotNull(locator.useBeanFactory("cache-with-name"));
locator.useBeanFactory("no-bl");
} finally {
}
finally {
locator.destroy();
}
}
@@ -99,4 +105,14 @@ public class CacheNamespaceTest extends RecreatingContextTest {
Resource res = TestUtils.readField("cacheXml", cfb);
assertEquals("gemfire-client-cache.xml", res.getFilename());
}
@Test
public void testHeapTunedCache() throws Exception {
assertTrue(ctx.containsBean("heap-tuned-cache"));
CacheFactoryBean cfb = (CacheFactoryBean) ctx.getBean("&heap-tuned-cache");
Float chp = (Float) TestUtils.readField("criticalHeapPercentage", cfb);
Float ehp = (Float) TestUtils.readField("evictionHeapPercentage", cfb);
assertEquals(70, chp, 0.0001);
assertEquals(60, ehp, 0.0001);
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2010-2012 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.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.springframework.data.gemfire.RecreatingContextTest;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.DynamicRegionFactory;
/**
* @author David Turanski
*/
public class DynamicRegionNamespaceTest extends RecreatingContextTest {
@Override
protected String location() {
return "org/springframework/data/gemfire/config/dynamic-region-ns.xml";
}
@Test
public void testBasicCache() throws Exception {
DynamicRegionFactory drf = DynamicRegionFactory.get();
assertFalse(drf.isOpen());
assertNull(drf.getConfig());
ctx.getBean("gemfire-cache", Cache.class);
assertTrue(drf.isOpen());
DynamicRegionFactory.Config config = drf.getConfig();
assertFalse(config.persistBackup);
assertFalse(config.registerInterest);
assertEquals("/foo", config.diskDir.getAbsolutePath());
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2010-2012 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 org.junit.Test;
import org.springframework.data.gemfire.RecreatingContextTest;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.internal.datasource.GemFireBasicDataSource;
/**
* @author David Turanski
*
*/
public class JndiBindingsTest extends RecreatingContextTest {
@Override
protected String location() {
return "org/springframework/data/gemfire/config/jndi-binding-ns.xml";
}
@Test
public void testJndiBindings() throws Exception {
Cache cache = ctx.getBean("gemfire-cache", Cache.class);
assertNotNull(cache.getJNDIContext().lookup("java:/SimpleDataSource"));
GemFireBasicDataSource ds = (GemFireBasicDataSource) cache.getJNDIContext().lookup("java:/SimpleDataSource");
assertEquals("org.apache.derby.jdbc.EmbeddedDriver", ds.getJDBCDriver());
assertEquals(60, ds.getLoginTimeout());
}
}

View File

@@ -27,4 +27,6 @@
<gfe:client-cache id="client-cache"/>
<gfe:client-cache id="client-cache-with-xml" cache-xml-location="classpath:gemfire-client-cache.xml"/>
<gfe:cache id="heap-tuned-cache" critical-heap-percentage="70.0" eviction-heap-percentage="60.0"/>
</beans>

View File

@@ -9,17 +9,7 @@
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">
<!-- all beans are lazy to allow the same config to be used between multiple tests -->
<!-- as there can be only one cache per VM -->
<gfe:cache>
<gfe:initializer ref="cacheInitializer"/>
</gfe:cache>
<gfe:local-region id="local"/>
<bean id="cacheInitializer" class="org.springframework.data.gemfire.config.CacheInitializerTest.TestInitializer">
<property name="first" value="David"/>
<property name="last" value="Turanski"/>
</bean>
<gfe:dynamic-region-factory persistent="false" register-interest="false" disk-dir="/foo"/>
</gfe:cache>
</beans>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:gfe="http://www.springframework.org/schema/gemfire"
xmlns:p="http://www.springframework.org/schema/p"
default-lazy-init="true"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.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">
<gfe:cache>
<gfe:jndi-binding type="SimpleDataSource" jndi-name="SimpleDataSource"
jdbc-driver-class="org.apache.derby.jdbc.EmbeddedDriver"
init-pool-size="2" max-pool-size="7"
idle-timeout-seconds="40"
blocking-timeout-seconds="40"
login-timeout-seconds="60"
conn-pooled-datasource-class="org.apache.derby.jdbc.EmbeddedConnectionPoolDataSource"
xa-datasource-class="org.apache.derby.jdbc.EmbeddedXADataSource"
user-name="mitul"
password="83f0069202c571faf1ae6c42b4ad46030e4e31c17409e19a"
connection-url="jdbc:derby:newDB;create=true"
>
<gfe:jndi-prop key="description">hi</gfe:jndi-prop>
<gfe:jndi-prop key="databaseName">newDB</gfe:jndi-prop>
</gfe:jndi-binding>
</gfe:cache>
</beans>