+ initial commit

This commit is contained in:
costin
2010-06-29 20:58:20 +03:00
commit 8ddeae76a1
41 changed files with 3241 additions and 0 deletions

10
.classpath Normal file
View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java"/>
<classpathentry kind="src" output="target/classes" path="src/main/resources"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
target
bin

29
.project Normal file
View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>spring-gemfire</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.maven.ide.eclipse.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.springframework.ide.eclipse.core.springbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.springframework.ide.eclipse.core.springnature</nature>
<nature>org.maven.ide.eclipse.maven2Nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,13 @@
#Sun Jun 06 11:27:13 EEST 2010
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.5

View File

@@ -0,0 +1,9 @@
#Fri Jun 04 17:37:03 EEST 2010
activeProfiles=
eclipse.preferences.version=1
fullBuildGoals=process-test-resources
includeModules=false
resolveWorkspaceProjects=true
resourceFilterGoals=process-resources resources\:testResources
skipCompilerPlugin=true
version=1

13
.springBeans Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<beansProjectDescription>
<version>1</version>
<pluginVersion><![CDATA[2.3.2.201003220227-RELEASE]]></pluginVersion>
<configSuffixes>
<configSuffix><![CDATA[xml]]></configSuffix>
</configSuffixes>
<enableImports><![CDATA[false]]></enableImports>
<configs>
</configs>
<configSets>
</configSets>
</beansProjectDescription>

86
pom.xml Normal file
View File

@@ -0,0 +1,86 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.data.gemfire</groupId>
<artifactId>spring-gemfire</artifactId>
<version>1.0.0.M1-SNAPSHOT</version>
<name>Gemfire - Spring Framework Integration</name>
<properties>
<spring.version>3.0.3.RELEASE</spring.version>
<junit.version>4.7</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<!--
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.2</version>
<scope>compile</scope>
</dependency>
-->
<!-- gemfire dependency -->
<dependency>
<groupId>gemstone</groupId>
<artifactId>gemfire</artifactId>
<version>6.0.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,179 @@
/*
* Copyright 2010 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 java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.util.StringUtils;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.CacheClosedException;
import com.gemstone.gemfire.cache.CacheFactory;
import com.gemstone.gemfire.distributed.DistributedMember;
import com.gemstone.gemfire.distributed.DistributedSystem;
/**
* Factory used for configuring a Gemfire Cache manager. Allows either retrieval of an existing, opened cache
* or the creation of a new one.
*
* @author Costin Leau
*/
public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanClassLoaderAware, DisposableBean,
InitializingBean, FactoryBean<Cache> {
private static final Log log = LogFactory.getLog(CacheFactoryBean.class);
private Cache cache;
private String name;
private Resource cacheXml;
private Properties properties;
private DistributedSystem system;
private ClassLoader beanClassLoader;
private GemfireBeanFactoryLocator factoryLocator = new GemfireBeanFactoryLocator();
private BeanFactory beanFactory;
private String beanName;
public void afterPropertiesSet() throws Exception {
// initialize locator
factoryLocator.setBeanFactory(beanFactory);
factoryLocator.setBeanName(beanName);
factoryLocator.afterPropertiesSet();
Properties cfgProps = mergeProperties();
system = DistributedSystem.connect(cfgProps);
DistributedMember member = system.getDistributedMember();
log.info("Connected to Distributed System ['" + system.getName() + "'=" + member.getId() + "@"
+ member.getHost() + "]");
// use the bean class loader to load Declarable classes
Thread th = Thread.currentThread();
ClassLoader oldTCCL = th.getContextClassLoader();
try {
th.setContextClassLoader(beanClassLoader);
// first look for open caches
String msg = null;
try {
cache = CacheFactory.getInstance(system);
msg = "Retrieved existing";
} catch (CacheClosedException ex) {
// fall back to cache creation
cache = CacheFactory.create(system);
msg = "Created";
}
log.info(msg + " Gemfire Cache ['" + cache.getName() + "'] v. " + CacheFactory.getVersion());
// load/init cache.xml
if (cacheXml != null) {
cache.loadCacheXml(cacheXml.getInputStream());
}
if (log.isDebugEnabled())
log.debug("Initialized cache from " + cacheXml);
} finally {
th.setContextClassLoader(oldTCCL);
}
}
private Properties mergeProperties() {
Properties cfgProps = new Properties(properties);
if (StringUtils.hasText(name)) {
cfgProps.setProperty("name", name.trim());
}
return cfgProps;
}
public void destroy() throws Exception {
if (cache != null && !cache.isClosed()) {
cache.close();
}
cache = null;
if (system != null && system.isConnected()) {
system.releaseThreadsSockets();
system.disconnect();
}
system = null;
factoryLocator.destroy();
}
public Cache getObject() throws Exception {
return cache;
}
public Class<? extends Cache> getObjectType() {
return (cache != null ? cache.getClass() : Cache.class);
}
public boolean isSingleton() {
return true;
}
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
public void setBeanName(String name) {
this.beanName = name;
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
/**
* Sets the cache properties.
*
* @param properties the properties to set
*/
public void setProperties(Properties properties) {
this.properties = properties;
}
/**
* Sets the name of the cache.
*
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* Sets the cache configuration.
*
* @param cacheXml the cacheXml to set
*/
public void setCacheXml(Resource cacheXml) {
this.cacheXml = cacheXml;
}
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright 2010 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 org.springframework.util.Assert;
import com.gemstone.gemfire.cache.Region;
/**
* Client extension for Gemfire regions.
*
* @author Costin Leau
*/
public class ClientRegionFactoryBean<K, V> extends RegionFactoryBean<K, V> {
private Interest<K>[] interests;
@Override
protected void postProcess(Region<K, V> region) {
Assert.notEmpty(interests);
for (Interest<K> interest : interests) {
if (interest instanceof RegexInterest) {
// do the cast since it's safe
region.registerInterestRegex((String) interest.getKey(), interest.getPolicy(), interest.isDurable());
}
else {
region.registerInterest(interest.getKey(), interest.getPolicy(), interest.isDurable());
}
}
}
@Override
public void destroy() throws Exception {
Region<K, V> region = getObject();
// unregister interests
try {
if (region != null) {
for (Interest<K> interest : interests) {
if (interest instanceof RegexInterest) {
region.unregisterInterestRegex((String) interest.getKey());
}
else {
region.unregisterInterest(interest.getKey());
}
}
}
// should not really happen since interests are validated at start/registration
} catch (UnsupportedOperationException ex) {
log.warn("Cannot unregister cache interests", ex);
}
super.destroy();
}
/**
* Set the interests for this client region. Both key and regex interest are supported.
*
* @param interests the interests to set
*/
public void setInterests(Interest<K>[] interests) {
this.interests = interests;
}
/**
* @return the interests
*/
Interest<K>[] getInterests() {
return interests;
}
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright 2010 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 java.util.Properties;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.access.BeanFactoryReference;
import com.gemstone.gemfire.cache.CacheCallback;
import com.gemstone.gemfire.cache.Declarable;
/**
* Convenience class for Spring-aware GemFire Declarable components.
* Provides a reference to the current Spring application context, e.g. for bean lookup or resource loading.
*
* Note that in most cases, one can just declare the same components as Spring beans, through
* {@link RegionFactoryBean} which gives access to the full container capabilities and does not enforce the
* {@link Declarable} interface to be implemented.
*
* @author Costin Leau
*/
public abstract class DeclarableSupport implements CacheCallback, Declarable {
private String factoryKey = null;
private BeanFactoryReference bfReference = null;
public DeclarableSupport() {
}
/**
* This implementation uses this method as a lifecycle hook to initialize
* the bean factory locator.
*
* {@inheritDoc}
*
* @see #setFactoryKey(String)
*/
public final void init(Properties props) {
bfReference = new GemfireBeanFactoryLocator().useBeanFactory(factoryKey);
initInstance(props);
}
/**
* Initialize the current instance based on the given properties.
*
* @param props
*/
protected void initInstance(Properties props) {
}
protected BeanFactory getBeanFactory() {
return bfReference.getFactory();
}
public void close() {
bfReference.release();
bfReference = null;
}
/**
* Sets the key under which the enclosing beanFactory can be found.
* Needed only if multiple beanFactories are used with GemFire inside
* the same class loader / class space.
*
* @see GemfireBeanFactoryLocator
* @param key
*/
public void setFactoryKey(String key) {
this.factoryKey = key;
}
}

View File

@@ -0,0 +1,158 @@
/*
* Copyright 2010 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 java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.FatalBeanException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.access.BeanFactoryLocator;
import org.springframework.beans.factory.access.BeanFactoryReference;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
* {@link BeanFactoryLocator} used for storing Spring application context/bean factory for Gemfire
* user components (or {@link com.gemstone.gemfire.cache.Declarable}. As opposed to the "traditional"
* {@link org.springframework.beans.factory.access.SingletonBeanFactoryLocator} this implementation does
* not require any configuration file; it rather assume declaration inside an application context
* (usually through {@link com.gemstone.gemfire.cache.CacheFactory} which it will store under the name
* and aliases of the bean (so the same "registry" can be used for storing multiple BeanFactories).
* If there is only one BeanFactory registered then a null value can be used with {@link #setBeanName(String)}.
*
* <p/> In most cases, one does not need to use this class directly as it is used internally
* by {@link com.gemstone.gemfire.cache.CacheFactory}.
*
* @author Costin Leau
*/
public class GemfireBeanFactoryLocator implements BeanFactoryLocator, BeanFactoryAware, BeanNameAware, DisposableBean,
InitializingBean {
private static final Log log = LogFactory.getLog(GemfireBeanFactoryLocator.class);
// alias/bean name <-> BeanFactory lookup
private static final ConcurrentMap<String, BeanFactory> beanFactories = new ConcurrentHashMap<String, BeanFactory>();
// default factory to return
private static volatile boolean canUseDefaultBeanFactory = true;
private static volatile BeanFactory defaultFactory = null;
private static class SimpleBeanFactoryReference implements BeanFactoryReference {
private BeanFactory bf;
SimpleBeanFactoryReference(BeanFactory bf) {
this.bf = bf;
}
public BeanFactory getFactory() {
Assert.notNull(bf, "beanFactory already released or closed");
return bf;
}
public void release() throws FatalBeanException {
bf = null;
}
}
private BeanFactory beanFactory;
private String[] names;
// default factory name
private String factoryName = GemfireBeanFactoryLocator.class.getName();
public void afterPropertiesSet() {
// add the factory as default if possible (if it's the only one)
synchronized (GemfireBeanFactoryLocator.class) {
canUseDefaultBeanFactory = beanFactories.isEmpty();
if (canUseDefaultBeanFactory) {
if (defaultFactory == null) {
defaultFactory = beanFactory;
if (log.isDebugEnabled())
log.debug("default beanFactoryReference=" + defaultFactory);
}
else {
if (log.isDebugEnabled())
log.debug("more then one beanFactory - default not possible to determine");
canUseDefaultBeanFactory = false;
defaultFactory = null;
}
}
}
// add aliases
if (StringUtils.hasText(factoryName)) {
String[] aliases = beanFactory.getAliases(factoryName);
names = (String[]) ObjectUtils.addObjectToArray(aliases, factoryName);
for (String name : names) {
if (log.isDebugEnabled())
log.debug("adding key=" + name + " w/ reference=" + beanFactory);
if (beanFactories.containsKey(name) || beanFactories.putIfAbsent(name, beanFactory) != null) {
throw new IllegalArgumentException("a beanFactoryReference already exists for key " + factoryName);
}
}
}
}
public void destroy() {
for (String name : names) {
beanFactories.remove(name);
}
if (beanFactory == defaultFactory) {
defaultFactory = null;
}
}
public BeanFactoryReference useBeanFactory(final String factoryKey) throws BeansException {
// see if there is a default FactoryBean
BeanFactory factory;
if (!StringUtils.hasText(factoryKey)) {
if (!canUseDefaultBeanFactory)
throw new IllegalArgumentException(
"a non-null factoryKey needs to be specified as there are more then one factoryKeys available ");
factory = defaultFactory;
}
else {
factory = beanFactories.get(factoryKey);
if (factory == null)
throw new IllegalArgumentException("there is no beanFactory under key " + factoryKey);
}
return new SimpleBeanFactoryReference(factory);
}
public void setBeanName(String name) {
factoryName = name;
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}

View File

@@ -0,0 +1,263 @@
/*
* Copyright 2010 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 org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.dao.InvalidDataAccessResourceUsageException;
import org.springframework.dao.PermissionDeniedDataAccessException;
import org.springframework.dao.PessimisticLockingFailureException;
import org.springframework.dao.TypeMismatchDataAccessException;
import com.gemstone.gemfire.CancelException;
import com.gemstone.gemfire.CopyException;
import com.gemstone.gemfire.GemFireCacheException;
import com.gemstone.gemfire.GemFireCheckedException;
import com.gemstone.gemfire.GemFireConfigException;
import com.gemstone.gemfire.GemFireException;
import com.gemstone.gemfire.GemFireIOException;
import com.gemstone.gemfire.IncompatibleSystemException;
import com.gemstone.gemfire.InternalGemFireException;
import com.gemstone.gemfire.InvalidValueException;
import com.gemstone.gemfire.LicenseException;
import com.gemstone.gemfire.NoSystemException;
import com.gemstone.gemfire.SystemConnectException;
import com.gemstone.gemfire.SystemIsRunningException;
import com.gemstone.gemfire.UnmodifiableException;
import com.gemstone.gemfire.admin.AdminException;
import com.gemstone.gemfire.admin.RegionNotFoundException;
import com.gemstone.gemfire.admin.RuntimeAdminException;
import com.gemstone.gemfire.cache.CacheException;
import com.gemstone.gemfire.cache.CacheExistsException;
import com.gemstone.gemfire.cache.CacheLoaderException;
import com.gemstone.gemfire.cache.CacheRuntimeException;
import com.gemstone.gemfire.cache.CacheWriterException;
import com.gemstone.gemfire.cache.CacheXmlException;
import com.gemstone.gemfire.cache.CommitConflictException;
import com.gemstone.gemfire.cache.CommitIncompleteException;
import com.gemstone.gemfire.cache.DiskAccessException;
import com.gemstone.gemfire.cache.EntryDestroyedException;
import com.gemstone.gemfire.cache.EntryExistsException;
import com.gemstone.gemfire.cache.EntryNotFoundException;
import com.gemstone.gemfire.cache.EntryNotFoundInRegion;
import com.gemstone.gemfire.cache.FailedSynchronizationException;
import com.gemstone.gemfire.cache.OperationAbortedException;
import com.gemstone.gemfire.cache.PartitionedRegionDistributionException;
import com.gemstone.gemfire.cache.PartitionedRegionStorageException;
import com.gemstone.gemfire.cache.RegionDestroyedException;
import com.gemstone.gemfire.cache.RegionExistsException;
import com.gemstone.gemfire.cache.ResourceException;
import com.gemstone.gemfire.cache.RoleException;
import com.gemstone.gemfire.cache.StatisticsDisabledException;
import com.gemstone.gemfire.cache.SynchronizationCommitConflictException;
import com.gemstone.gemfire.cache.VersionException;
import com.gemstone.gemfire.cache.client.ServerConnectivityException;
import com.gemstone.gemfire.cache.execute.FunctionException;
import com.gemstone.gemfire.cache.query.CqClosedException;
import com.gemstone.gemfire.cache.query.IndexMaintenanceException;
import com.gemstone.gemfire.cache.query.QueryException;
import com.gemstone.gemfire.cache.query.QueryExecutionTimeoutException;
import com.gemstone.gemfire.distributed.LeaseExpiredException;
import com.gemstone.gemfire.security.GemFireSecurityException;
/**
* Helper class featuring methods for GemFire Cache or Region handling.
*
* @author Costin Leau
*/
public abstract class GemfireCacheUtils {
/**
* Converts the given (unchecked) Gemfire exception to an appropriate one from the
* <code>org.springframework.dao</code> hierarchy.
*
* @param ex Gemfire unchecked exception
* @return new the corresponding DataAccessException instance
*/
public static DataAccessException convertGemfireAccessException(GemFireException ex) {
if (ex instanceof CacheException) {
if (ex instanceof CacheExistsException) {
return new DataIntegrityViolationException(ex.getMessage(), ex);
}
if (ex instanceof CommitConflictException) {
return new DataIntegrityViolationException(ex.getMessage(), ex);
}
if (ex instanceof CommitIncompleteException) {
return new DataIntegrityViolationException(ex.getMessage(), ex);
}
if (ex instanceof EntryExistsException) {
return new DuplicateKeyException(ex.getMessage(), ex);
}
if (ex instanceof EntryNotFoundException) {
return new DataRetrievalFailureException(ex.getMessage(), ex);
}
if (ex instanceof RegionExistsException) {
return new DataIntegrityViolationException(ex.getMessage(), ex);
}
}
if (ex instanceof CacheRuntimeException) {
if (ex instanceof CacheXmlException) {
return new GemfireSystemException(ex);
}
if (ex instanceof CancelException) {
// all cancellations go wrapped by this exception
return new GemfireCancellationException((CancelException) ex);
}
if (ex instanceof CqClosedException) {
return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
}
if (ex instanceof DiskAccessException) {
return new DataAccessResourceFailureException(ex.getMessage(), ex);
}
if (ex instanceof EntryDestroyedException) {
return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
}
if (ex instanceof FailedSynchronizationException) {
return new PessimisticLockingFailureException(ex.getMessage(), ex);
}
if (ex instanceof IndexMaintenanceException) {
return new GemfireIndexException((IndexMaintenanceException) ex);
}
if (ex instanceof OperationAbortedException) {
// treat user exceptions first
if (ex instanceof CacheLoaderException) {
return new GemfireSystemException(ex);
}
if (ex instanceof CacheWriterException) {
return new GemfireSystemException(ex);
}
// the rest are treated as resource failures
return new DataAccessResourceFailureException(ex.getMessage(), ex);
}
if (ex instanceof PartitionedRegionDistributionException) {
return new DataAccessResourceFailureException(ex.getMessage(), ex);
}
if (ex instanceof PartitionedRegionStorageException) {
return new DataAccessResourceFailureException(ex.getMessage(), ex);
}
if (ex instanceof QueryExecutionTimeoutException) {
return new GemfireQueryException((QueryExecutionTimeoutException) ex);
}
if (ex instanceof RegionDestroyedException) {
return new InvalidDataAccessResourceUsageException(ex.getMessage(), ex);
}
if (ex instanceof RegionNotFoundException) {
return new InvalidDataAccessResourceUsageException(ex.getMessage(), ex);
}
if (ex instanceof ResourceException) {
return new DataAccessResourceFailureException(ex.getMessage(), ex);
}
if (ex instanceof RoleException) {
return new GemfireSystemException(ex);
}
if (ex instanceof StatisticsDisabledException) {
return new GemfireSystemException(ex);
}
if (ex instanceof SynchronizationCommitConflictException) {
return new PessimisticLockingFailureException(ex.getMessage(), ex);
}
}
if (ex instanceof CopyException) {
return new GemfireSystemException(ex);
}
if (ex instanceof EntryNotFoundInRegion) {
return new DataRetrievalFailureException(ex.getMessage(), ex);
}
if (ex instanceof FunctionException) {
return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
}
if (ex instanceof GemFireCacheException) {
return convertGemfireAccessException(((GemFireCacheException) ex).getCacheException());
}
if (ex instanceof GemFireConfigException) {
return new GemfireSystemException(ex);
}
if (ex instanceof GemFireIOException) {
return new DataAccessResourceFailureException(ex.getMessage(), ex);
}
if (ex instanceof GemFireSecurityException) {
return new PermissionDeniedDataAccessException(ex.getMessage(), ex);
}
if (ex instanceof IncompatibleSystemException) {
return new GemfireSystemException(ex);
}
if (ex instanceof InternalGemFireException) {
return new GemfireSystemException(ex);
}
if (ex instanceof InvalidValueException) {
return new TypeMismatchDataAccessException(ex.getMessage(), ex);
}
if (ex instanceof LeaseExpiredException) {
return new PessimisticLockingFailureException(ex.getMessage(), ex);
}
if (ex instanceof LicenseException) {
return new GemfireSystemException(ex);
}
if (ex instanceof NoSystemException) {
return new GemfireSystemException(ex);
}
if (ex instanceof RuntimeAdminException) {
return new GemfireSystemException(ex);
}
if (ex instanceof ServerConnectivityException) {
return new DataAccessResourceFailureException(ex.getMessage(), ex);
}
if (ex instanceof SystemConnectException) {
return new DataAccessResourceFailureException(ex.getMessage(), ex);
}
if (ex instanceof SystemIsRunningException) {
return new GemfireSystemException(ex);
}
if (ex instanceof UnmodifiableException) {
return new GemfireSystemException(ex);
}
// fall back
return new GemfireSystemException(ex);
}
/**
* Converts the given (checked) Gemfire exception to an appropriate one from the
* <code>org.springframework.dao</code> hierarchy.
*
* @param ex Gemfire unchecked exception
* @return new the corresponding DataAccessException instance
*/
public static DataAccessException convertGemfireAccessException(GemFireCheckedException ex) {
// query exceptions
if (ex instanceof QueryException) {
return new GemfireQueryException((QueryException) ex);
}
// version exception
if (ex instanceof VersionException) {
return new DataAccessResourceFailureException(ex.getMessage(), ex);
}
// util.version exception (seems quite similar to the exception above)
if (ex instanceof com.gemstone.gemfire.cache.util.VersionException) {
return new DataAccessResourceFailureException(ex.getMessage(), ex);
}
// admin exception
if (ex instanceof AdminException) {
return new GemfireSystemException(ex);
}
// fall back
return new GemfireSystemException(ex);
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2010 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 org.springframework.dao.InvalidDataAccessResourceUsageException;
import com.gemstone.gemfire.CancelException;
/**
* GemFire-specific class for exceptions caused by system cancellations.
*
* @author Costin Leau
*/
public class GemfireCancellationException extends InvalidDataAccessResourceUsageException {
public GemfireCancellationException(CancelException ex) {
super(ex.getMessage(), ex);
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2010 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 org.springframework.dao.DataIntegrityViolationException;
import com.gemstone.gemfire.cache.query.IndexCreationException;
import com.gemstone.gemfire.cache.query.IndexExistsException;
import com.gemstone.gemfire.cache.query.IndexMaintenanceException;
import com.gemstone.gemfire.cache.query.IndexNameConflictException;
/**
* Gemfire-specific subclass thrown on index creation.
*
* @author Costin Leau
*/
public class GemfireIndexException extends DataIntegrityViolationException {
public GemfireIndexException(IndexCreationException ex) {
super(ex.getMessage(), ex);
}
public GemfireIndexException(IndexExistsException ex) {
super(ex.getMessage(), ex);
}
public GemfireIndexException(IndexNameConflictException ex) {
super(ex.getMessage(), ex);
}
public GemfireIndexException(IndexMaintenanceException ex) {
super(ex.getMessage(), ex);
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2010 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 org.springframework.dao.InvalidDataAccessResourceUsageException;
import com.gemstone.gemfire.cache.query.QueryException;
import com.gemstone.gemfire.cache.query.QueryExecutionTimeoutException;
/**
* GemFire-specific subclass of {@link InvalidDataAccessResourceUsageException} thrown on invalid
* OQL query syntax.
*
* @author Costin Leau
*/
public class GemfireQueryException extends InvalidDataAccessResourceUsageException {
public GemfireQueryException(QueryException ex) {
super(ex.getMessage(), ex);
}
public GemfireQueryException(QueryExecutionTimeoutException ex) {
super(ex.getMessage(), ex);
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2010 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 org.springframework.dao.UncategorizedDataAccessException;
import com.gemstone.gemfire.GemFireCheckedException;
import com.gemstone.gemfire.GemFireException;
/**
* GemFire-specific subclass of UncategorizedDataAccessException, for GemFire system errors that do not match any concrete <code>org.springframework.dao</code> exceptions.
*
* @author Costin Leau
*/
public class GemfireSystemException extends UncategorizedDataAccessException {
public GemfireSystemException(GemFireCheckedException ex) {
super(ex.getMessage(), ex);
}
public GemfireSystemException(GemFireException ex) {
super(ex.getMessage(), ex);
}
}

View File

@@ -0,0 +1,257 @@
/*
* Copyright 2010 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 org.springframework.beans.factory.InitializingBean;
import org.springframework.transaction.CannotCreateTransactionException;
import org.springframework.transaction.NoTransactionException;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionSystemException;
import org.springframework.transaction.support.AbstractPlatformTransactionManager;
import org.springframework.transaction.support.DefaultTransactionStatus;
import org.springframework.transaction.support.ResourceTransactionManager;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.CacheTransactionManager;
import com.gemstone.gemfire.cache.CommitConflictException;
import com.gemstone.gemfire.cache.Region;
/**
* Local transaction manager for Gemfire Enterprise Fabric (GEF). Provides a {@link PlatformTransactionManager}
* implementation for a single Gemfire {@link CacheTransactionManager}.
*
* Binds one or multiple Gemfire regions for the specified {@link Cache} to the thread, potentially allowing for one
* region per cache model.
*
* <p>
* This local strategy is an alternative to executing cache operations within JTA transactions. Its advantage is that
* is able to work in any environment, for example a standalone application or a test suite. It is <i>not</i> able to
* provide XA transactions, for example to share transactions with data access.
*
* <p>
* To prevent dirty reads, by default, the cache is configured to return copies rather then direct references for
* <code>get</code> operations. As a workaround, one could use explicitly deep copy objects before making changes
* to them to avoid unnecessary copying on every fetch.
*
* @see com.gemstone.gemfire.cache.CacheTransactionManager
* @see com.gemstone.gemfire.cache.Cache#setCopyOnRead(boolean)
* @see com.gemstone.gemfire.cache.Region#get(Object)
* @see com.gemstone.gemfire.CopyHelper#copy(Object)
* @see #setCopyOnRead(boolean)
* @see org.springframework.transaction.support.AbstractPlatformTransactionManager
*
* @author Costin Leau
*/
// TODO add lenient behavior if a transaction is already started on the current thread (what should happen then)
public class GemfireTransactionManager extends AbstractPlatformTransactionManager implements InitializingBean,
ResourceTransactionManager {
private Cache cache;
private boolean copyOnRead = true;
/**
* Creates a new GemfireTransactionManager instance.
*/
public GemfireTransactionManager() {
}
/**
* Creates a new GemfireTransactionManager instance.
*
* @param cache
*/
public GemfireTransactionManager(Cache cache) {
this.cache = cache;
afterPropertiesSet();
}
public void afterPropertiesSet() {
Assert.notNull(cache, "Cache property is required");
cache.setCopyOnRead(copyOnRead);
}
@Override
protected Object doGetTransaction() throws TransactionException {
CacheTransactionObject txObject = new CacheTransactionObject();
CacheHolder cacheHolder = (CacheHolder) TransactionSynchronizationManager.getResource(getCache());
txObject.setHolder(cacheHolder);
return txObject;
}
protected boolean isExistingTransaction(Object transaction) throws TransactionException {
CacheTransactionObject txObject = (CacheTransactionObject) transaction;
// Consider a pre-bound cache as transaction.
return (txObject.getHolder() != null);
}
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException {
CacheTransactionObject txObject = (CacheTransactionObject) transaction;
Cache cache = null;
try {
cache = getCache();
if (logger.isDebugEnabled()) {
logger.debug("Acquired Cache [" + cache + "] for local Cache transaction");
}
txObject.setHolder(new CacheHolder());
cache.getCacheTransactionManager().begin();
TransactionSynchronizationManager.bindResource(cache, txObject.getHolder());
}
catch (IllegalStateException ex) {
throw new CannotCreateTransactionException(
"An ongoing transaction already is already associated with the current thread; are there multiple transaction managers ?",
ex);
}
}
@Override
protected void doCommit(DefaultTransactionStatus status) throws TransactionException {
CacheTransactionObject txObject = (CacheTransactionObject) status.getTransaction();
if (status.isDebug()) {
logger.debug("Committing Gemfire local transaction on Cache [" + cache + "]");
}
try {
cache.getCacheTransactionManager().commit();
} catch (IllegalStateException ex) {
throw new NoTransactionException(
"No transaction associated with the current thread; are there multiple transaction managers ?", ex);
} catch (CommitConflictException ex) {
// TODO: can this be replaced with HeuristicCompletionException ?
throw new TransactionSystemException("Unexpected failure on commit of Cache local transaction", ex);
}
}
@Override
protected void doRollback(DefaultTransactionStatus status) throws TransactionException {
CacheTransactionObject txObject = (CacheTransactionObject) status.getTransaction();
if (status.isDebug()) {
logger.debug("Rolling back Cache local transaction for [" + cache + "]");
}
try {
cache.getCacheTransactionManager().rollback();
} catch (IllegalStateException ex) {
throw new NoTransactionException(
"No transaction associated with the current thread; are there multiple transaction managers ?", ex);
}
}
@Override
protected void doSetRollbackOnly(DefaultTransactionStatus status) {
CacheTransactionObject txObject = (CacheTransactionObject) status.getTransaction();
if (status.isDebug()) {
logger.debug("Setting Gemfire local transaction [" + txObject.getHolder() + "] rollback-only");
}
txObject.getHolder().setRollbackOnly();
}
protected void doCleanupAfterCompletion(Object transaction) {
// Remove the cache holder from the thread.
TransactionSynchronizationManager.unbindResource(cache);
}
@Override
protected final boolean useSavepointForNestedTransaction() {
return false;
}
/**
* Returns the Cache that this instance manages local transactions for.
*
* @return Gemfire cache
*/
public Cache getCache() {
return cache;
}
/**
* Sets the Cache that this instance manages local transactions for.
*
* @param cache Gemfire cache
*/
public void setCache(Cache cache) {
this.cache = cache;
}
public Object getResourceFactory() {
return getCache();
}
/**
* Sets the Gemfire {@link Region} (as an alternative in setting in the cache directly).
*
* @param region Gemfire region
*/
public <K, V> void setRegion(Region<K, V> region) {
Assert.notNull(region, "non-null arguments are required");
this.cache = region.getCache();
}
/**
* Indicates whether the cache returns direct references or copies of the objects (default) it manages.
* While copies imply additional work for every fetch operation, direct references can cause dirty reads
* across concurrent threads in the same VM, whether or not transactions are used.
* <p/>
* One could explicitly deep copy objects before making changes (for example by using {@link com.gemstone.gemfire.CopyHelper#copy(Object)}
* in which case this setting can be set to <code>false</code>. However, unless there is a measurable
* performance penalty, the recommendation is to keep this setting to <code>true</code>
*
* @param copyOnRead whether copies (default) rather then direct references will be returned on
* fetch operations
*/
public void setCopyOnRead(boolean copyOnRead) {
this.copyOnRead = copyOnRead;
}
/**
* GemfireTM local transaction object.
*
* @author Costin Leau
*/
private static class CacheTransactionObject {
private CacheHolder cacheHolder;
public CacheHolder getHolder() {
return cacheHolder;
}
public void setHolder(CacheHolder cacheHolder) {
this.cacheHolder = cacheHolder;
}
}
private static class CacheHolder {
private boolean rollbackOnly = false;
public boolean isRollbackOnly() {
return rollbackOnly;
}
public void setRollbackOnly() {
rollbackOnly = true;
}
}
}

View File

@@ -0,0 +1,138 @@
/*
* Copyright 2010 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 org.springframework.beans.factory.InitializingBean;
import org.springframework.core.Constants;
import org.springframework.util.Assert;
import com.gemstone.gemfire.cache.InterestResultPolicy;
/**
* Basic holder class for registering an interest. Useful for configuring Gemfire caches through XML
* and or JavaBeans means.
*
* @author Costin Leau
*/
public class Interest<K> implements InitializingBean {
private static final Constants constants = new Constants(InterestResultPolicy.class);
private K key;
private InterestResultPolicy policy = InterestResultPolicy.DEFAULT;
private boolean durable = false;
public Interest() {
}
public Interest(K key) {
this(key, InterestResultPolicy.DEFAULT, false);
}
public Interest(K key, InterestResultPolicy policy) {
this(key, policy, false);
}
public Interest(K key, String policy) {
this(key, policy, false);
}
public Interest(K key, String policy, boolean durable) {
this.key = key;
this.policy = (InterestResultPolicy) constants.asObject(policy);
this.durable = durable;
afterPropertiesSet();
}
public Interest(K key, InterestResultPolicy policy, boolean durable) {
this.key = key;
this.policy = policy;
this.durable = durable;
afterPropertiesSet();
}
public void afterPropertiesSet() {
Assert.notNull(key, "a non-null key is required");
}
/**
* Returns the key of interest.
*
* @return the key
*/
protected K getKey() {
return key;
}
/**
* Sets the key of interest.
*
* @param key the key to set
*/
public void setKey(K key) {
this.key = key;
}
/**
* Returns the interest policy.
*
* @return the policy
*/
protected InterestResultPolicy getPolicy() {
return policy;
}
/**
* Sets the interest policy. The argument is set as an Object
* to be able to accept both InterestResultType instances but also
* Strings (for XML configurations).
*
* @param policy the policy to set
*/
public void setPolicy(Object policy) {
if (policy instanceof InterestResultPolicy) {
this.policy = (InterestResultPolicy) policy;
}
else {
if (policy instanceof String) {
this.policy = (InterestResultPolicy) constants.asObject((String) policy);
}
else {
throw new IllegalArgumentException("Unknown argument type for property 'policy'" + policy);
}
}
}
/**
* Returns the interest durability.
*
* @return the durable
*/
protected boolean isDurable() {
return durable;
}
/**
* Sets the interest durability.
*
* @param durable the durable to set
*/
public void setDurable(boolean durable) {
this.durable = durable;
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright 2010 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 org.springframework.util.Assert;
/**
* Cache interest based on regular expression rather then individual key types.
*
* @author Costin Leau
*/
public class RegexInterest extends Interest<String> {
@Override
public void afterPropertiesSet() {
super.afterPropertiesSet();
Assert.hasText(getKey(), "A non-empty regex is required");
}
/**
* Returns the regex backing this interest.
* Similar to {@link #getKey()}.
*
* @return interest regex
*/
//TODO: is this really required
public String getRegex() {
return getKey();
}
}

View File

@@ -0,0 +1,214 @@
/*
* Copyright 2010 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 org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import com.gemstone.gemfire.cache.AttributesFactory;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.CacheListener;
import com.gemstone.gemfire.cache.CacheLoader;
import com.gemstone.gemfire.cache.CacheWriter;
import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.RegionAttributes;
/**
* FactoryBean for creating generic Gemfire {@link Region}s.
*
* @author Costin Leau
*/
public class RegionFactoryBean<K, V> implements DisposableBean, FactoryBean<Region<K, V>>, InitializingBean {
protected final Log log = LogFactory.getLog(getClass());
private Cache cache;
private String name;
private boolean destroy = false;
private Resource snapshot;
private CacheListener<K, V> cacheListeners[];
private CacheLoader<K, V> cacheLoader;
private CacheWriter<K, V> cacheWriter;
private RegionAttributes<K, V> attributes;
private Region<K, V> region;
public void afterPropertiesSet() throws Exception {
Assert.notNull(cache, "Cache property must be set");
Assert.hasText(name, "Name property must be set");
// first get cache
region = cache.getRegion(name);
if (region != null) {
log.info("Retrieved region [" + name + "] from cache");
}
// fall back to cache creation if one is not found
else {
if (attributes != null)
AttributesFactory.validateAttributes(attributes);
AttributesFactory<K, V> attrFactory = (attributes != null ? new AttributesFactory<K, V>(attributes)
: new AttributesFactory<K, V>());
if (!ObjectUtils.isEmpty(cacheListeners)) {
for (CacheListener<K, V> listener : cacheListeners) {
attrFactory.addCacheListener(listener);
}
}
if (cacheLoader != null) {
attrFactory.setCacheLoader(cacheLoader);
}
if (cacheWriter != null) {
attrFactory.setCacheWriter(cacheWriter);
}
region = cache.createRegion(name, attrFactory.create());
log.info("Created new cache region [" + name + "]");
if (snapshot != null) {
region.loadSnapshot(snapshot.getInputStream());
}
}
postProcess(region);
}
/**
* Post-process the region object for this factory bean during the initialization process.
* The object is already initialized and configured by the factory bean before this method
* is invoked.
*
* @param region
*/
protected void postProcess(Region<K, V> region) {
// do nothing
}
public void destroy() throws Exception {
if (region != null && destroy) {
region.destroyRegion();
}
region = null;
}
public Region<K, V> getObject() throws Exception {
return region;
}
public Class<?> getObjectType() {
return (region != null ? region.getClass() : Region.class);
}
public boolean isSingleton() {
return true;
}
/**
* Sets the cache used for creating the region.
*
* @see org.springframework.data.gemfire.CacheFactoryBean
* @param cache the cache to set
*/
public void setCache(Cache cache) {
this.cache = cache;
}
/**
* Sets the name of the cache region. If no cache is found under
* the given name, a new one will be created.
*
* @see com.gemstone.gemfire.cache.Region#getFullPath()
*
* @param name the region name
*/
public void setName(String name) {
this.name = name;
}
/**
* Indicates whether the region referred by this factory bean,
* will be destroyed on shutdown (default false).
*
* @param destroy the destroy to set
*/
public void setDestroy(boolean destroy) {
this.destroy = destroy;
}
/**
* Sets the snapshots used for loading a newly <i>created</i> region.
* That is, the snapshot will be used <i>only</i> when a new region is created - if the region
* already exists, no loading will be performed.
*
* @see #setName(String)
* @param snapshot the snapshot to set
*/
public void setSnapshot(Resource snapshot) {
this.snapshot = snapshot;
}
/**
* Sets the cache listeners used for the region used by this factory.
* Used only when a new region is created.Overrides the settings
* specified through {@link #setAttributes(RegionAttributes)}.
*
* @param cacheListeners the cacheListeners to set on a newly created region
*/
public void setCacheListeners(CacheListener<K, V>[] cacheListeners) {
this.cacheListeners = cacheListeners;
}
/**
* Sets the cache loader used for the region used by this factory.
* Used only when a new region is created.Overrides the settings
* specified through {@link #setAttributes(RegionAttributes)}.
*
* @param cacheLoader the cacheLoader to set on a newly created region
*/
public void setCacheLoader(CacheLoader<K, V> cacheLoader) {
this.cacheLoader = cacheLoader;
}
/**
* Sets the cache loader used for the region used by this factory.
* Used only when a new region is created. Overrides the settings
* specified through {@link #setAttributes(RegionAttributes)}.
*
* @param cacheWriter the cacheWriter to set on a newly created region
*/
public void setCacheWriter(CacheWriter<K, V> cacheWriter) {
this.cacheWriter = cacheWriter;
}
/**
* Sets the cache loader used for the region used by this factory.
* Used only when a new region is created.
*
* @param attributes the attributes to set on a newly created region
*/
public void setAttributes(RegionAttributes<K, V> attributes) {
this.attributes = attributes;
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2010 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 java.util.Properties;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.wiring.BeanConfigurerSupport;
import org.springframework.beans.factory.wiring.BeanWiringInfo;
import org.springframework.beans.factory.wiring.BeanWiringInfoResolver;
import com.gemstone.gemfire.cache.Declarable;
/**
* Dedicated {@link Declarable} support class for wiring the declaring instance through
* the Spring container.
* This implementation will first look for a 'bean-name' property which will be used to
* locate a 'template' bean definition. In case the property is not given, a bean named
* after the class will be searched and if none is found, autowiring will be performed,
* based on the settings defined in the Spring container.
*
* @author Costin Leau
*/
public class WiringDeclarableSupport extends DeclarableSupport {
private final String BEAN_NAME_PROP = "bean-name";
@Override
protected void initInstance(Properties props) {
BeanFactory bf = getBeanFactory();
BeanConfigurerSupport configurer = new BeanConfigurerSupport();
configurer.setBeanFactory(bf);
final String beanName = props.getProperty(BEAN_NAME_PROP);
// key specified, search for a bean
if (beanName != null) {
if (!bf.containsBean(beanName)) {
throw new IllegalArgumentException("Cannot find bean named '" + beanName + "'");
}
configurer.setBeanWiringInfoResolver(new BeanWiringInfoResolver() {
public BeanWiringInfo resolveWiringInfo(Object beanInstance) {
return new BeanWiringInfo(beanName);
}
});
}
configurer.afterPropertiesSet();
configurer.configureBean(this);
configurer.destroy();
}
}

View File

@@ -0,0 +1,247 @@
/*
* Copyright 2010 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.serialization;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.asm.ClassWriter;
import org.springframework.asm.FieldVisitor;
import org.springframework.asm.MethodVisitor;
import org.springframework.asm.Opcodes;
import org.springframework.asm.Type;
import org.springframework.beans.BeanUtils;
import org.springframework.util.Assert;
import com.gemstone.gemfire.DataSerializable;
import com.gemstone.gemfire.Instantiator;
/**
* ASM based {@link InstantiatorFactory} implementation. This class relies on ASM 2.x package
* repacked by Spring framework to minimize the number of dependencies and avoid any versioning
* confusion.
*
* @author Costin Leau
*/
public class AsmInstantiatorGenerator implements InstantiatorGenerator, Opcodes {
private static final String PKG = "org/springextensions/gef/serialization";
private static final String CLASS_LABEL = "Instantiator$Synthetic";
private static final String INSTANTIATOR_NAME = Type.getInternalName(Instantiator.class);
private static final String SERIALIZABLE_NAME = Type.getInternalName(Serializable.class);
private static final String CLASS_DESCRIPTOR = Type.getDescriptor(Class.class);
private static final String CLASS_FIELD_NAME = "clazz";
private static final String ID_FIELD_NAME = "classId";
private static final String INIT = "<init>";
private static final String CINIT = "<clinit>";
private static final String NEW_INSTANCE = "newInstance";
private static final String NEW_INSTANCE_DESC = Type.getMethodDescriptor(Type.getType(DataSerializable.class),
new Type[] {});
// generated class counter
private static final AtomicLong counter = new AtomicLong(1);
// class cache
private final ConcurrentMap<Class<? extends DataSerializable>, Instantiator> cache = new ConcurrentHashMap<Class<? extends DataSerializable>, Instantiator>();
private static final class BytecodeClassLoader extends ClassLoader {
public BytecodeClassLoader(ClassLoader loader) {
super(loader);
}
public Class<?> loadClass(String name, byte[] bytecode) {
return defineClass(name, bytecode, 0, bytecode.length);
}
}
private final BytecodeClassLoader classLoader;
public AsmInstantiatorGenerator() {
this(AsmInstantiatorGenerator.class.getClassLoader());
}
public AsmInstantiatorGenerator(ClassLoader classLoader) {
Assert.notNull(classLoader);
this.classLoader = new BytecodeClassLoader(classLoader);
}
public Instantiator getInstantiator(Class<? extends DataSerializable> clazz, int classId) {
Instantiator instantiator = cache.get(clazz);
if (instantiator == null) {
synchronized (cache) {
instantiator = cache.get(clazz);
if (instantiator == null) {
// create Instantiator
instantiator = createInstantiator(clazz, classId);
cache.putIfAbsent(clazz, instantiator);
}
}
}
return instantiator;
}
/**
* Returns an instance of the custom instantiator created for the given class.
*
* @param clazz
* @param classId
* @return
*/
private Instantiator createInstantiator(Class<? extends DataSerializable> clazz, int classId) {
validateClass(clazz);
Class<?> clz = createCustomInstantiatorClass(clazz, classId);
return (Instantiator) BeanUtils.instantiate(clz);
}
/**
* Does basic sanity checks to make sure the constructor can be properly invoked by our generated
* class.
*
* @param clazz
*/
private void validateClass(Class<? extends DataSerializable> clazz) {
Assert.isTrue(!Modifier.isAbstract(clazz.getModifiers()), "Cannot instantiate abstract classes");
Assert.isTrue(Modifier.isPublic(clazz.getModifiers()), "Only public classes are supported");
try {
Constructor<? extends DataSerializable> ctor = clazz.getConstructor();
Assert.isTrue(Modifier.isPublic(ctor.getModifiers()), "Default constructor is not public");
} catch (Exception ex) {
throw new IllegalArgumentException("Class " + clazz + " unsuitable for instantiation", ex);
}
}
/**
* Generates a new Instantiator class for the given custom class.
*
* The generated class has the following definition:
*
* <pre>
* package org.springframework.data.gemfire.serialization;
*
* public class &lt;<i>T</i>>Instantiator$Synthetic<i>Counter</i> extends Instantiator implements Serializable {
*
* private static final Class&lt;<i>T</i>> clazz = T.class;
* private static final int classId = <i>value</i>;
*
* public DateInstantiator() {
* this(clazz, classId);
* }
*
* public DateInstantiator(Class<? extends DataSerializable> c, int classId) {
* super(c, classId);
* }
*
* public <i>T</i> newInstance() {
* return new <i>T</i>();
* }
* }
* </pre>
*
* @param clazz
* @return
*/
Class<?> createCustomInstantiatorClass(Class<? extends DataSerializable> clazz, int classId) {
String classInternalName = PKG + clazz.getSimpleName() + CLASS_LABEL + counter.getAndIncrement();
byte[] bytecode = generateClassBytecode(classInternalName, clazz, classId);
// translate internal name to binary form
return classLoader.loadClass(classInternalName.replace('/', '.'), bytecode);
}
byte[] generateClassBytecode(String className, Class<? extends DataSerializable> clazz, int classId) {
ClassWriter cw = new ClassWriter(false);
cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, className, null, INSTANTIATOR_NAME, new String[] { SERIALIZABLE_NAME });
FieldVisitor fv = cw.visitField(ACC_PRIVATE + ACC_FINAL + ACC_STATIC, CLASS_FIELD_NAME, CLASS_DESCRIPTOR, null,
null);
fv.visitEnd();
fv = cw.visitField(ACC_PRIVATE + ACC_FINAL + ACC_STATIC, ID_FIELD_NAME, Type.INT_TYPE.getDescriptor(), null,
Integer.valueOf(classId));
fv.visitEnd();
String voidNoArgMethodDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {});
// field class loading
MethodVisitor mv = cw.visitMethod(ACC_STATIC, CINIT, voidNoArgMethodDescriptor, null, null);
mv.visitCode();
mv.visitLdcInsn(Type.getType(clazz));
mv.visitFieldInsn(PUTSTATIC, className, CLASS_FIELD_NAME, CLASS_DESCRIPTOR);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 0);
mv.visitEnd();
String voidArgClassAndIntDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {
Type.getType(Class.class), Type.INT_TYPE });
// default constructor
mv = cw.visitMethod(ACC_PUBLIC, INIT, voidNoArgMethodDescriptor, null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETSTATIC, className, CLASS_FIELD_NAME, CLASS_DESCRIPTOR);
mv.visitFieldInsn(GETSTATIC, className, ID_FIELD_NAME, Type.INT_TYPE.getDescriptor());
mv.visitMethodInsn(INVOKESPECIAL, className, INIT, voidArgClassAndIntDescriptor);
mv.visitInsn(RETURN);
mv.visitMaxs(3, 1);
mv.visitEnd();
// two-arg constructor
mv = cw.visitMethod(ACC_PUBLIC, INIT, voidArgClassAndIntDescriptor, null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ILOAD, 2);
mv.visitMethodInsn(INVOKESPECIAL, INSTANTIATOR_NAME, INIT, voidArgClassAndIntDescriptor);
mv.visitInsn(RETURN);
mv.visitMaxs(3, 3);
mv.visitEnd();
Type customClassType = Type.getType(clazz);
String customTypeNoArgDesc = Type.getMethodDescriptor(customClassType, new Type[] {});
// newInstance overloaded method
mv = cw.visitMethod(ACC_PUBLIC, NEW_INSTANCE, customTypeNoArgDesc, null, null);
mv.visitCode();
mv.visitTypeInsn(NEW, customClassType.getInternalName());
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, customClassType.getInternalName(), INIT, voidNoArgMethodDescriptor);
mv.visitInsn(ARETURN);
mv.visitMaxs(2, 1);
mv.visitEnd();
// plus original method signature
mv = cw.visitMethod(ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC, NEW_INSTANCE, NEW_INSTANCE_DESC, null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, className, NEW_INSTANCE, customTypeNoArgDesc);
mv.visitInsn(ARETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
// end class generation
cw.visitEnd();
return cw.toByteArray();
}
}

View File

@@ -0,0 +1,101 @@
/*
* Copyright 2010 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.serialization;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.Serializable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import com.gemstone.gemfire.DataSerializer;
import com.gemstone.gemfire.internal.InternalDataSerializer;
/**
* Generic Serializer for JDK Enums. The class needs to be registered only once - custom enums
* will be then understood by the converter by calling {@link #addEnum(Class)}.
*
* @author Costin Leau
*/
public class EnumSerializer extends DataSerializer implements Serializable {
private static final long serialVersionUID = -7069461993489626976L;
private static final ConcurrentMap<Class<?>, Enum[]> supportedClasses = new ConcurrentHashMap<Class<?>, Enum[]>();
private int id = 1024;
@Override
public boolean toData(Object o, DataOutput out) throws IOException {
if (o instanceof Enum<?>) {
// add enum to the set
Enum<?> enm = (Enum<?>) o;
Class<?> cls = enm.getDeclaringClass();
addEnum(cls);
DataSerializer.writeClass(cls, out);
out.writeInt(enm.ordinal());
}
return false;
}
@SuppressWarnings("unchecked")
@Override
public Object fromData(DataInput in) throws IOException, ClassNotFoundException {
Class cls = DataSerializer.readClass(in);
if (cls.isEnum()) {
addEnum(cls);
int ordinal = in.readInt();
return supportedClasses.get(cls)[ordinal];
}
throw new IOException("Non-enum class read from the stream -" + cls);
}
@SuppressWarnings("unchecked")
public void addEnum(Class enumClass) {
if (!supportedClasses.containsKey(enumClass)) {
supportedClasses.put(enumClass, (Enum[]) enumClass.getEnumConstants());
}
// if registered, re-register the serializer to propagate the changes
if (InternalDataSerializer.getSerializer(getId()) != null) {
if (InternalDataSerializer.getSerializer(enumClass) == null) {
InternalDataSerializer.unregister(getId());
InternalDataSerializer.register(getClass());
}
}
}
@Override
public Class<?>[] getSupportedClasses() {
return supportedClasses.keySet().toArray(new Class<?>[supportedClasses.size()]);
}
@Override
public int getId() {
return id;
}
/**
* Sets the id for this serializer. Default is 1024;
*
* @param id the id to set
*/
public void setId(int id) {
this.id = id;
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2010 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.serialization;
import com.gemstone.gemfire.DataSerializable;
import com.gemstone.gemfire.Instantiator;
/**
* Factory that generates {@link Instantiator} classes to improve instantiation of
* custom types.
*
* @author Costin Leau
*/
public interface InstantiatorGenerator {
/**
* Returns a (potentially new) Instantiator that optimizes the instantiation of the given types.
*
* @return
*/
Instantiator getInstantiator(Class<? extends DataSerializable> clazz, int classId);
}

View File

@@ -0,0 +1,110 @@
/*
* Copyright 2010 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.serialization;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.wiring.BeanConfigurerSupport;
import com.gemstone.gemfire.DataSerializable;
import com.gemstone.gemfire.Instantiator;
/**
* Instantiator that performs instance wiring using the Spring IoC container, allowing common properties
* to be injected before the object is hydrated/deserialized. The newly created instances can be configured
* either by relying on an existing bean definition (which acts as a template) or by providing an embedded
* configuration through annotations.
*
* <p/>
* Can reuse existing instantiators to optimize instance creation. If one is not provided, it will fallback
* to reflection invocation.
*
* @see org.springframework.beans.factory.wiring.BeanConfigurerSupport
* @see org.springframework.beans.factory.wiring.BeanWiringInfoResolver
* @see org.springframework.beans.factory.annotation.Autowired
* @see javax.annotation.Resource
* @see javax.inject.Inject
*
* @author Costin Leau
*/
public class WiringInstantiator extends Instantiator implements BeanFactoryAware, InitializingBean,
DisposableBean {
private final Instantiator instantiator;
private final Class<? extends DataSerializable> clazz;
private BeanConfigurerSupport configurer;
private BeanFactory beanFactory;
public WiringInstantiator(Instantiator instantiator) {
super(instantiator.getInstantiatedClass(), instantiator.getId());
this.instantiator = instantiator;
this.clazz = null;
}
public WiringInstantiator(Class<? extends DataSerializable> c, int classId) {
super(c, classId);
instantiator = null;
clazz = c;
}
public void afterPropertiesSet() {
if (configurer == null) {
configurer = new BeanConfigurerSupport();
configurer.setBeanFactory(beanFactory);
configurer.afterPropertiesSet();
}
}
public void destroy() throws Exception {
configurer.destroy();
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
@Override
public DataSerializable newInstance() {
DataSerializable instance = createInstance();
configurer.configureBean(instance);
return instance;
}
private DataSerializable createInstance() {
if (instantiator != null) {
return instantiator.newInstance();
}
return BeanUtils.instantiate(clazz);
}
/**
* Sets the manager responsible for configuring the newly created instances.
* The given configurer needs to be configured and initialized before-hand.
*
* @param configurer the configurer to set
*/
public void setConfigurer(BeanConfigurerSupport configurer) {
this.configurer = configurer;
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2010 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 org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.gemstone.gemfire.cache.Cache;
/**
* Integration test trying various basic configurations of Gemfire through Spring.
*
* @author Costin Leau
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "basic-cache.xml" })
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
public class CacheIntegrationTest {
@Autowired
private ApplicationContext ctx;
@Test
public void testBasicCache() throws Exception {
ctx.getBean("default-cache");
}
@Test
public void testCacheWithProps() throws Exception {
Cache cache = ctx.getBean("cache-with-props", Cache.class);
// the name property seems to be ignored
// Assert.assertEquals("cache-with-props", cache.getDistributedSystem().getName());
}
@Test
public void testNamedCache() throws Exception {
ctx.getBean("named-cache");
}
@Test
public void testCacheWithXml() throws Exception {
Cache cache = ctx.getBean("cache-with-xml", Cache.class);
//Assert.assertEquals("cache-with-props", cache.getDistributedSystem().getName());
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2010 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 static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* Integration test for declarable support (and GEF bean factory locator).
*
* @author Costin Leau
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "cache-with-declarable-ctx.xml" })
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
public class DeclarableSupportTest {
@Autowired
private BeanFactory ctx;
@Test
public void testUserObject() throws Exception {
assertNotNull(UserObject.THIS);
UserObject obj = UserObject.THIS;
assertSame(ctx, obj.getBeanFactory());
assertSame(ctx.getBean("bean"), obj.getProp2());
assertEquals("Enescu", obj.getProp1());
}
}

View File

@@ -0,0 +1,137 @@
/*
* Copyright 2010 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.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.fail;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.access.BeanFactoryReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.data.gemfire.GemfireBeanFactoryLocator;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Costin Leau
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "locatorContext.xml" })
public class GemfireBeanFactoryLocatorTest {
@Autowired
private ApplicationContext applicationContext;
private GemfireBeanFactoryLocator locator1, locator2;
private String INSTANCE_1 = "instance1";
private String INSTANCE_2 = "instance2";
@Before
public void init() {
locator1 = new GemfireBeanFactoryLocator();
locator1.setBeanName(INSTANCE_1);
locator1.setBeanFactory(applicationContext);
locator1.afterPropertiesSet();
locator2 = new GemfireBeanFactoryLocator();
locator2.setBeanName(INSTANCE_2);
locator2.setBeanFactory(applicationContext);
locator2.afterPropertiesSet();
}
@After
public void destroy() {
BeanFactoryReference ref1;
try {
ref1 = locator1.useBeanFactory(INSTANCE_1);
ref1.release();
BeanFactoryReference ref2 = locator2.useBeanFactory(INSTANCE_2);
ref2.release();
} catch (IllegalArgumentException e) {
// it's okay
}
locator1.destroy();
locator2.destroy();
locator1 = null;
locator2 = null;
}
@Test
public void testBeanFactoryRelease() throws Exception {
}
@Test
public void testFactoryLocator() throws Exception {
BeanFactoryReference reference1 = locator1.useBeanFactory(INSTANCE_1);
BeanFactoryReference reference2 = locator2.useBeanFactory(INSTANCE_2);
BeanFactoryReference aliasRef1 = locator1.useBeanFactory("alias1");
BeanFactoryReference aliasRef2 = locator1.useBeanFactory("alias2");
// verify the static map
BeanFactory factory1 = reference1.getFactory();
BeanFactory factory2 = reference2.getFactory();
BeanFactory factory3 = reference2.getFactory();
// get the alias from different factories
BeanFactory alias1 = aliasRef1.getFactory();
BeanFactory alias2 = aliasRef2.getFactory();
assertSame(factory1, factory2);
assertSame(factory1, factory3);
// verify it's the same bean factory as the application context
assertSame(factory1, applicationContext);
// verify aliases
assertSame(alias1, alias2);
assertSame(factory1, alias1);
aliasRef1.release();
aliasRef2.release();
reference1.release();
reference2.release();
}
@Test
public void testDefaultFactoryLocator() throws Exception {
try {
locator1.useBeanFactory(null);
fail("there are more then one bean factories registered - should have thrown exception");
} catch (IllegalArgumentException e) {
// it's okay
}
}
@Test
public void testFactoryLocatorContract() throws Exception {
BeanFactoryReference factory1 = locator1.useBeanFactory(INSTANCE_1);
assertNotNull(factory1.getFactory());
factory1.release();
try {
factory1.getFactory();
fail("should have received exception");
} catch (IllegalArgumentException e) {
// it's okay
}
}
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright 2010 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 static org.junit.Assert.assertSame;
import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.data.gemfire.ClientRegionFactoryBean;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.gemstone.gemfire.cache.CacheListener;
import com.gemstone.gemfire.cache.CacheLoader;
import com.gemstone.gemfire.cache.CacheLoaderException;
import com.gemstone.gemfire.cache.LoaderHelper;
import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
import com.gemstone.gemfire.cache.util.CacheWriterAdapter;
/**
* @author Costin Leau
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "basic-region.xml" })
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
public class RegionIntegrationTest {
private static class CacheList<K, V> extends CacheListenerAdapter<K, V> {
}
private static class CacheLoad<K, V> implements CacheLoader<K, V> {
public V load(LoaderHelper<K, V> arg0) throws CacheLoaderException {
return null;
}
public void close() {
}
}
private static class CacheWrite<K, V> extends CacheWriterAdapter<K, V> {
}
@Autowired
private ApplicationContext ctx;
@Test
public void testBasicRegion() throws Exception {
Region region = ctx.getBean("basic", Region.class);
assertEquals("basic", region.getName());
}
@Test
public void testExistingRegion() throws Exception {
Region region = ctx.getBean("root", Region.class);
// the name property seems to be ignored
assertEquals("root", region.getName());
}
@Test
public void testRegionWithListeners() throws Exception {
Region region = ctx.getBean("listeners", Region.class);
assertEquals("listeners", region.getName());
CacheListener[] listeners = region.getAttributes().getCacheListeners();
assertEquals(2, listeners.length);
assertSame(CacheList.class, listeners[0].getClass());
assertSame(CacheLoad.class, region.getAttributes().getCacheLoader().getClass());
assertSame(CacheWrite.class, region.getAttributes().getCacheWriter().getClass());
}
//@Test
//TODO: Disabled since for some reason in Spring, I get the bean rather then the client
public void testRegionInterest() throws Exception {
ClientRegionFactoryBean regionFB = (ClientRegionFactoryBean) ctx.getBean("&basic-client");
System.out.println("**** interests are " + Arrays.toString(regionFB.getInterests()));
//BeanDefinition bd = ((BeanDefinitionRegistry) ctx.getAutowireCapableBeanFactory()).getBeanDefinition("basic-client");
// System.out.println(bd.getPropertyValues().getPropertyValue("interests").getValue());
}
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright 2010 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.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.Map;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.AfterTransaction;
import org.springframework.test.context.transaction.BeforeTransaction;
import org.springframework.transaction.annotation.Transactional;
/**
* Simple TX integration test.
*
* @author Costin Leau
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "basic-tx-config.xml" })
@Transactional
public class TxIntegrationTest {
@Resource(name = "rollback-region")
private Map<String, String> rollbackRegion;
@Resource(name = "commit-region")
private Map<String, String> commitRegion;
private boolean txCommit = false;
@BeforeTransaction
public void addItemsToTheCache() {
rollbackRegion.put("Vlaicu", "Aurel");
rollbackRegion.put("Coanda", "Henri");
commitRegion.put("Coanda", "Henri");
commitRegion.put("Vlaicu", "Aurel");
txCommit = false;
}
@Test
public void testTransactionRollback() throws Exception {
rollbackRegion.remove("Coanda");
rollbackRegion.put("Ciurcu", "Alexandru");
}
@Test
@Rollback(value = false)
public void testTransactionCommit() throws Exception {
commitRegion.put("Poenaru", "Petrache");
commitRegion.remove("Coanda");
commitRegion.put("Vlaicu", "A");
txCommit = true;
}
@AfterTransaction
public void testTxOutcome() {
if (txCommit) {
assertFalse(commitRegion.containsKey("Coanda"));
assertTrue(commitRegion.containsKey("Poenaru"));
assertTrue(commitRegion.containsValue("A"));
}
assertTrue(rollbackRegion.containsKey("Coanda"));
assertTrue(rollbackRegion.containsKey("Vlaicu"));
assertFalse(rollbackRegion.containsKey("Ciurcu"));
}
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright 2010 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 org.springframework.data.gemfire.WiringDeclarableSupport;
import com.gemstone.gemfire.cache.CacheLoader;
import com.gemstone.gemfire.cache.CacheLoaderException;
import com.gemstone.gemfire.cache.LoaderHelper;
/**
* User object used for testing Spring wiring.
*
* @author Costin Leau
*/
public class UserObject extends WiringDeclarableSupport implements CacheLoader {
public static UserObject THIS;
private String prop1;
private Object prop2;
public UserObject() {
System.out.println("Initialized");
THIS = this;
}
public Object load(LoaderHelper helper) throws CacheLoaderException {
return new Object();
}
/**
* @return the prop1
*/
public String getProp1() {
return prop1;
}
/**
* @param prop1 the prop1 to set
*/
public void setProp1(String prop1) {
this.prop1 = prop1;
}
/**
* @return the prop2
*/
public Object getProp2() {
return prop2;
}
/**
* @param prop2 the prop2 to set
*/
public void setProp2(Object prop2) {
this.prop2 = prop2;
}
}

View File

@@ -0,0 +1,90 @@
/*
* Copyright 2010 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.serialization;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.Serializable;
import org.junit.Before;
import org.junit.Test;
import org.springframework.data.gemfire.serialization.AsmInstantiatorGenerator;
import com.gemstone.gemfire.DataSerializable;
import com.gemstone.gemfire.Instantiator;
/**
* @author Costin Leau
*/
public class AsmInstantiatorFactoryTest {
public static class SomeClass implements DataSerializable {
public static boolean instantiated = false;
public SomeClass() {
instantiated = true;
}
public void fromData(DataInput in) throws IOException, ClassNotFoundException {
}
public void toData(DataOutput out) throws IOException {
}
}
private AsmInstantiatorGenerator asmFactory = null;
@Before
public void setUp() {
SomeClass.instantiated = false;
asmFactory = new AsmInstantiatorGenerator();
}
@Test
public void testClassGeneration() throws Exception {
Instantiator instantiator = asmFactory.getInstantiator(SomeClass.class, 100);
assertEquals(100, instantiator.getId());
assertEquals(SomeClass.class, instantiator.getInstantiatedClass());
Object instance = instantiator.newInstance();
assertEquals(SomeClass.class, instance.getClass());
assertTrue(SomeClass.instantiated);
}
@Test
public void testGeneratedClassName() throws Exception {
Instantiator instantiator = asmFactory.getInstantiator(SomeClass.class, 100);
assertTrue(instantiator.getClass().getName().contains("$"));
}
@Test
public void testInterfaces() throws Exception {
Instantiator instantiator = asmFactory.getInstantiator(SomeClass.class, 100);
assertTrue(instantiator instanceof Serializable);
}
@Test
public void testCacheInPlace() throws Exception {
Instantiator instance1 = asmFactory.getInstantiator(SomeClass.class, 120);
Instantiator instance2 = asmFactory.getInstantiator(SomeClass.class, 125);
assertSame(instance1, instance2);
}
}

View File

@@ -0,0 +1,118 @@
/*
* Copyright 2010 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.serialization;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.awt.Point;
import java.awt.Shape;
import java.beans.Beans;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.data.gemfire.serialization.AsmInstantiatorGenerator;
import org.springframework.data.gemfire.serialization.WiringInstantiator;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.gemstone.gemfire.DataSerializable;
/**
* @author Costin Leau
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("simple-config.xml")
public class WiringInstantiatorTest {
@Autowired
private ApplicationContext ctx;
@Autowired
private WiringInstantiator instantiator;
public static class AnnotatedBean implements DataSerializable {
@Autowired
Point point;
Shape shape;
@Autowired
void initShape(Shape shape) {
this.shape = shape;
}
public void fromData(DataInput in) throws IOException, ClassNotFoundException {
}
public void toData(DataOutput out) throws IOException {
}
}
public static class TemplateWiringBean implements DataSerializable {
Point point;
Beans beans;
public void setBeans(Beans bs) {
this.beans = bs;
}
public void fromData(DataInput in) throws IOException, ClassNotFoundException {
}
public void toData(DataOutput out) throws IOException {
}
}
@Test
public void testAutowiredBean() throws Exception {
Object instance = instantiator.newInstance();
assertNotNull(instance);
assertTrue(instance instanceof AnnotatedBean);
AnnotatedBean bean = (AnnotatedBean) instance;
assertNotNull(bean.point);
assertNotNull(bean.shape);
assertSame(bean.point, ctx.getBean("point"));
assertSame(bean.shape, ctx.getBean("area"));
}
@Test
public void testTemplateBean() throws Exception {
WiringInstantiator instantiator2 = new WiringInstantiator(
new AsmInstantiatorGenerator().getInstantiator(
TemplateWiringBean.class, 99));
instantiator2.setBeanFactory(ctx.getAutowireCapableBeanFactory());
instantiator2.afterPropertiesSet();
Object instance = instantiator2.newInstance();
assertTrue(instance instanceof TemplateWiringBean);
TemplateWiringBean bean = (TemplateWiringBean) instance;
assertTrue(bean.point == null);
assertNotNull(bean.beans);
assertSame(bean.beans, ctx.getBean("beans"));
}
}

View File

@@ -0,0 +1,32 @@
<?xml version="1.0"?>
<!DOCTYPE cache PUBLIC "-//GemStone Systems, Inc.//GemFire Declarative Caching 5.7//EN" "http://www.gemstone.com/dtd/cache5_7.dtd">
<cache lock-lease="120" lock-timeout="60" search-timeout="300">
<region-attributes id="attTemplate" scope="local" data-policy="normal" initial-capacity="16" load-factor="0.75" concurrency-level="16" statistics-enabled="true">
<key-constraint>java.lang.String</key-constraint>
<cache-loader>
<class-name>org.springframework.data.gemfire.UserObject</class-name>
</cache-loader>
</region-attributes>
<region name="root">
<region-attributes refid="attTemplate" scope="distributed-no-ack">
<region-time-to-live>
<expiration-attributes timeout="0" action="invalidate"/>
</region-time-to-live>
<region-idle-time>
<expiration-attributes timeout="0" action="invalidate"/>
</region-idle-time>
<entry-time-to-live>
<expiration-attributes timeout="0" action="invalidate"/>
</entry-time-to-live>
<entry-idle-time>
<expiration-attributes timeout="0" action="invalidate"/>
</entry-idle-time>
</region-attributes>
<entry>
<key><string>Application Version</string></key>
<value><string>1.0</string></value>
</entry>
</region>
</cache>

View File

@@ -0,0 +1,39 @@
<?xml version="1.0"?>
<!DOCTYPE cache PUBLIC "-//GemStone Systems, Inc.//GemFire Declarative Caching 5.7//EN" "http://www.gemstone.com/dtd/cache5_7.dtd">
<cache lock-lease="120" lock-timeout="60" search-timeout="300">
<region-attributes id="attTemplate" scope="local" data-policy="normal" initial-capacity="16" load-factor="0.75" concurrency-level="16" statistics-enabled="true">
<key-constraint>java.lang.String</key-constraint>
</region-attributes>
<region name="root">
<region-attributes refid="attTemplate" scope="distributed-no-ack">
<region-time-to-live>
<expiration-attributes timeout="0" action="invalidate"/>
</region-time-to-live>
<region-idle-time>
<expiration-attributes timeout="0" action="invalidate"/>
</region-idle-time>
<entry-time-to-live>
<expiration-attributes timeout="0" action="invalidate"/>
</entry-time-to-live>
<entry-idle-time>
<expiration-attributes timeout="0" action="invalidate"/>
</entry-idle-time>
</region-attributes>
<entry>
<key><string>Application Version</string></key>
<value><string>1.0</string></value>
</entry>
<region name="rlocal">
<region-attributes refid="attTemplate">
</region-attributes>
</region>
<region name="rdistnoack">
<region-attributes refid="attTemplate" scope="distributed-no-ack">
</region-attributes>
</region>
<region name="rglobalreplication">
<region-attributes refid="attTemplate" scope="global" data-policy="replicate">
</region-attributes>
</region>
</region>
</cache>

View File

@@ -0,0 +1,31 @@
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-lazy-init="true">
<!-- all beans are lazy to allow the same config to be used between multiple tests -->
<!-- as there can be only one cache per VM -->
<bean id="default-cache" class="org.springframework.data.gemfire.CacheFactoryBean"/>
<bean id="cache-with-props" class="org.springframework.data.gemfire.CacheFactoryBean">
<property name="properties">
<props>
<prop key="name">cache-with-props</prop>
</props>
</property>
</bean>
<bean id="named-cache" class="org.springframework.data.gemfire.CacheFactoryBean" p:name="named-cache">
<property name="properties">
<props>
<prop key="name">cache-with-props</prop>
</props>
</property>
</bean>
<bean id="cache-with-xml" class="org.springframework.data.gemfire.CacheFactoryBean">
<property name="cacheXml" value="classpath:cache.xml"/>
</bean>
</beans>

View File

@@ -0,0 +1,38 @@
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-lazy-init="true">
<!-- all beans are lazy to allow the same config to be used between multiple tests -->
<!-- as there can be only one cache per VM -->
<bean id="cache" class="org.springframework.data.gemfire.CacheFactoryBean"/>
<bean id="basic" class="org.springframework.data.gemfire.RegionFactoryBean" p:cache-ref="cache" p:name="basic"/>
<!-- find existing region -->
<bean id="root" class="org.springframework.data.gemfire.RegionFactoryBean" p:cache-ref="cache" p:name="root"/>
<bean id="listeners" class="org.springframework.data.gemfire.RegionFactoryBean" p:cache-ref="cache" p:name="listeners">
<property name="cacheListeners">
<array>
<bean class="org.springframework.data.gemfire.RegionIntegrationTest$CacheList"/>
<bean class="org.springframework.data.gemfire.RegionIntegrationTest$CacheList"/>
</array>
</property>
<property name="cacheLoader"><bean class="org.springframework.data.gemfire.RegionIntegrationTest$CacheLoad"/></property>
<property name="cacheWriter"><bean class="org.springframework.data.gemfire.RegionIntegrationTest$CacheWrite"/></property>
</bean>
<!-- client configurations -->
<bean id="basic-client" class="org.springframework.data.gemfire.ClientRegionFactoryBean" p:cache-ref="cache" p:name="client-region" lazy-init="true">
<property name="interests">
<array>
<bean class="org.springframework.data.gemfire.Interest" p:key="Vlaicu" p:policy="NONE"/>
<bean class="org.springframework.data.gemfire.RegexInterest" p:key=".*" p:policy="KEYS" p:durable="true"/>
</array>
</property>
</bean>
</beans>

View File

@@ -0,0 +1,14 @@
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-lazy-init="true">
<bean id="cache" class="org.springframework.data.gemfire.CacheFactoryBean"/>
<bean id="transactionManager" class="org.springframework.data.gemfire.GemfireTransactionManager" p:cache-ref="cache"/>
<bean id="rollback-region" class="org.springframework.data.gemfire.RegionFactoryBean" p:name="r-region" p:cache-ref="cache"/>
<bean id="commit-region" class="org.springframework.data.gemfire.RegionFactoryBean" p:name="c-region" p:cache-ref="cache"/>
</beans>

View File

@@ -0,0 +1,15 @@
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="cache-with-declarable" class="org.springframework.data.gemfire.CacheFactoryBean">
<property name="cacheXml" value="classpath:cache-with-declarable.xml"/>
</bean>
<bean id="bean" class="java.lang.Object"/>
<bean abstract="true" class="org.springframework.data.gemfire.UserObject" p:prop1="Enescu" p:prop2-ref="bean"/>
</beans>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!--
Context used for testing GemfireBFLocator - usually, one doesn't have to declare the them inside
the context. see the javadocs for more details.
-->
<beans>
<bean id="instance1" name="alias1, alias2" class="java.lang.Object"/>
<bean id="instance2" class="java.lang.Object"/>
</beans>

View File

@@ -0,0 +1,28 @@
<?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:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<bean id="point" class="java.awt.Point"/>
<bean id="area" class="java.awt.geom.Area"/>
<bean id="beans" class="java.beans.Beans"/>
<bean id="generator" class="org.springframework.data.gemfire.serialization.AsmInstantiatorGenerator"/>
<bean id="instantiator" class="org.springframework.data.gemfire.serialization.WiringInstantiator">
<constructor-arg>
<bean factory-bean="generator" factory-method="getInstantiator">
<constructor-arg value="org.springframework.data.gemfire.serialization.WiringInstantiatorTest$AnnotatedBean"/>
<constructor-arg value="95"/>
</bean>
</constructor-arg>
</bean>
<bean class="org.springframework.data.gemfire.serialization.WiringInstantiatorTest$TemplateWiringBean" abstract="true" p:beans-ref="beans"/>
</beans>