Merge branch 'master' into client-cache

Conflicts:
	src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java
This commit is contained in:
Costin Leau
2011-07-08 17:10:49 +03:00
81 changed files with 1838 additions and 160 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.
@@ -31,6 +31,8 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import com.gemstone.gemfire.GemFireException;
import com.gemstone.gemfire.cache.Cache;
@@ -38,6 +40,8 @@ import com.gemstone.gemfire.cache.CacheClosedException;
import com.gemstone.gemfire.cache.CacheFactory;
import com.gemstone.gemfire.distributed.DistributedMember;
import com.gemstone.gemfire.distributed.DistributedSystem;
import com.gemstone.gemfire.pdx.PdxSerializable;
import com.gemstone.gemfire.pdx.PdxSerializer;
/**
* Factory used for configuring a Gemfire Cache manager. Allows either retrieval of an existing, opened cache
@@ -55,30 +59,52 @@ import com.gemstone.gemfire.distributed.DistributedSystem;
public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanClassLoaderAware, DisposableBean,
InitializingBean, FactoryBean<Cache>, PersistenceExceptionTranslator {
protected final Log log = LogFactory.getLog(getClass());
private class PdxOptions implements Runnable {
private CacheFactory factory;
PdxOptions(CacheFactory factory) {
this.factory = factory;
}
public void run() {
Assert.isAssignable(PdxSerializer.class, pdxSerializer.getClass(), "Invalid pdx serializer used");
factory.setPdxSerializer((PdxSerializer) pdxSerializer);
factory.setPdxDiskStore(pdxDiskStoreName);
factory.setPdxIgnoreUnreadFields(pdxIgnoreUnreadFields);
factory.setPdxPersistent(pdxPersistent);
factory.setPdxReadSerialized(pdxReadSerialized);
}
}
private static final Log log = LogFactory.getLog(CacheFactoryBean.class);
private Cache cache;
private Resource cacheXml;
private Properties properties;
private DistributedSystem system;
private ClassLoader beanClassLoader;
private GemfireBeanFactoryLocator factoryLocator = new GemfireBeanFactoryLocator();
private GemfireBeanFactoryLocator factoryLocator;
private BeanFactory beanFactory;
private String beanName;
private boolean useBeanFactoryLocator = true;
// PDX options
private Object pdxSerializer;
private Boolean pdxPersistent;
private Boolean pdxReadSerialized;
private Boolean pdxIgnoreUnreadFields;
private String pdxDiskStoreName;
public void afterPropertiesSet() throws Exception {
// initialize locator
factoryLocator.setBeanFactory(beanFactory);
factoryLocator.setBeanName(beanName);
factoryLocator.afterPropertiesSet();
if (useBeanFactoryLocator) {
factoryLocator = new GemfireBeanFactoryLocator();
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()
+ "]");
CacheFactory factory = new CacheFactory(cfgProps);
// use the bean class loader to load Declarable classes
Thread th = Thread.currentThread();
@@ -88,14 +114,28 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
th.setContextClassLoader(beanClassLoader);
// first look for open caches
String msg = null;
cache = fetchExistingCache(system);
if (cache == null) {
cache = createCache(system);
try {
cache = CacheFactory.getAnyInstance();
msg = "Retrieved existing";
} catch (CacheClosedException ex) {
// GemFire 6.6 specific options
if (pdxSerializer != null || pdxPersistent != null || pdxReadSerialized != null
|| pdxIgnoreUnreadFields != null || pdxDiskStoreName != null) {
Assert.isTrue(ClassUtils.isPresent("com.gemstone.gemfire.pdx.PdxSerializer", beanClassLoader),
"Cannot set PDX options since GemFire 6.6 not detected");
new PdxOptions(factory).run();
}
// fall back to cache creation
cache = factory.create();
msg = "Created";
}
else {
msg = "Retrieved existing";
}
DistributedSystem system = cache.getDistributedSystem();
DistributedMember member = system.getDistributedMember();
log.info("Connected to Distributed System [" + system.getName() + "=" + member.getId() + "@"
+ member.getHost() + "]");
log.info(msg + " GemFire v." + CacheFactory.getVersion() + " Cache [" + cache.getName() + "]");
@@ -111,18 +151,6 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
}
}
protected Cache fetchExistingCache(DistributedSystem system) {
try {
return CacheFactory.getInstance(system);
} catch (CacheClosedException ex) {
return null;
}
}
protected Cache createCache(DistributedSystem system) throws Exception {
return CacheFactory.create(system);
}
private Properties mergeProperties() {
Properties cfgProps = (properties != null ? (Properties) properties.clone() : new Properties());
return cfgProps;
@@ -132,15 +160,13 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
if (cache != null && !cache.isClosed()) {
cache.close();
}
cache = null;
if (system != null && system.isConnected()) {
DistributedSystem.releaseThreadsSockets();
system.disconnect();
if (factoryLocator != null) {
factoryLocator.destroy();
factoryLocator = null;
}
system = null;
factoryLocator.destroy();
}
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
@@ -170,18 +196,10 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
return true;
}
protected ClassLoader getBeanClassLoader() {
return beanClassLoader;
}
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
protected BeanFactory getBeanFactory() {
return beanFactory;
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
@@ -207,4 +225,61 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
public void setCacheXml(Resource cacheXml) {
this.cacheXml = cacheXml;
}
/**
* Indicates whether a bean factory locator is enabled (default) for this cache definition or not. The locator stores
* the enclosing bean factory reference to allow auto-wiring of Spring beans into GemFire managed classes. Usually disabled
* when the same cache is used in multiple application context/bean factories inside the same VM.
*
* @param usage true if the bean factory locator is used underneath or not
*/
public void setUseBeanFactoryLocator(boolean usage) {
this.useBeanFactoryLocator = usage;
}
/**
* Sets the {@link PdxSerializable} for this cache. Applicable on GemFire 6.6 or higher.
* The argument is of type object for compatibility with GemFire 6.5.
*
* @param serializer pdx serializer configured for this cache.
*/
public void setPdxSerializer(Object serializer) {
this.pdxSerializer = serializer;
}
/**
* Sets the object preference to PdxInstance type. Applicable on GemFire 6.6 or higher.
*
* @param pdxPersistent the pdxPersistent to set
*/
public void setPdxPersistent(Boolean pdxPersistent) {
this.pdxPersistent = pdxPersistent;
}
/**
* Controls whether the type metadata for PDX objects is persisted to disk. Applicable on GemFire 6.6 or higher.
*
* @param pdxReadSerialized the pdxReadSerialized to set
*/
public void setPdxReadSerialized(Boolean pdxReadSerialized) {
this.pdxReadSerialized = pdxReadSerialized;
}
/**
* Controls whether pdx ignores fields that were unread during deserialization. Applicable on GemFire 6.6 or higher.
*
* @param pdxIgnoreUnreadFields the pdxIgnoreUnreadFields to set
*/
public void setPdxIgnoreUnreadFields(Boolean pdxIgnoreUnreadFields) {
this.pdxIgnoreUnreadFields = pdxIgnoreUnreadFields;
}
/**
* Set the disk store that is used for PDX meta data. Applicable on GemFire 6.6 or higher.
*
* @param pdxDiskStoreName the pdxDiskStoreName to set
*/
public void setPdxDiskStoreName(String pdxDiskStoreName) {
this.pdxDiskStoreName = pdxDiskStoreName;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.
@@ -112,7 +112,8 @@ public class GemfireBeanFactoryLocator implements BeanFactoryLocator, BeanFactor
if (log.isDebugEnabled())
log.debug("adding key=" + name + " w/ reference=" + beanFactory);
if (beanFactories.containsKey(name) || beanFactories.putIfAbsent(name, beanFactory) != null) {
if (beanFactories.containsKey(name) && !beanFactory.equals(beanFactories.get(name))
|| beanFactories.putIfAbsent(name, beanFactory) != null) {
throw new IllegalArgumentException("a beanFactoryReference already exists for key " + factoryName);
}
}
@@ -120,10 +121,11 @@ public class GemfireBeanFactoryLocator implements BeanFactoryLocator, BeanFactor
}
public void destroy() {
for (String name : names) {
beanFactories.remove(name);
if (names != null) {
for (String name : names) {
beanFactories.remove(name);
}
}
if (beanFactory == defaultFactory) {
synchronized (GemfireBeanFactoryLocator.class) {
defaultFactory = null;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2011 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 com.gemstone.gemfire.cache.TransactionException;
/**
* Gemfire-specific subclass of {@link org.springframework.transaction.TransactionException}, indicating a transaction failure at commit time.
*
* @author Costin Leau
*/
public class GemfireTransactionCommitException extends TransactionException {
public GemfireTransactionCommitException() {
super();
}
public GemfireTransactionCommitException(String message, Throwable cause) {
super(message, cause);
}
public GemfireTransactionCommitException(String message) {
super(message);
}
public GemfireTransactionCommitException(Throwable cause) {
super(cause);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.
@@ -22,7 +22,6 @@ 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;
@@ -138,8 +137,7 @@ public class GemfireTransactionManager extends AbstractPlatformTransactionManage
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);
throw new GemfireTransactionCommitException("Unexpected failure on commit of Cache local transaction", ex);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.
@@ -32,6 +32,7 @@ import org.w3c.dom.Element;
*/
class CacheParser extends AbstractSingleBeanDefinitionParser {
@Override
protected Class<?> getBeanClass(Element element) {
return CacheFactoryBean.class;
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright 2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.gemfire.config;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.gemfire.server.CacheServerFactoryBean;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
/**
* Namespace parser for "cache-server" element.
*
* @author Costin Leau
*/
class CacheServerParser extends AbstractSimpleBeanDefinitionParser {
@Override
protected Class<?> getBeanClass(Element element) {
return CacheServerFactoryBean.class;
}
@Override
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
throws BeanDefinitionStoreException {
String name = super.resolveId(element, definition, parserContext);
if (!StringUtils.hasText(name)) {
name = "gemfire-server";
}
return name;
}
@Override
protected boolean isEligibleAttribute(Attr attribute, ParserContext parserContext) {
return super.isEligibleAttribute(attribute, parserContext) && !"groups".equals(attribute.getName())
&& !"cache-ref".equals(attribute.getName());
}
@Override
protected void postProcess(BeanDefinitionBuilder builder, Element element) {
String attr = element.getAttribute("cache-ref");
// add cache reference (fallback to default if nothing is specified)
builder.addPropertyReference("cache", (StringUtils.hasText(attr) ? attr : "gemfire-cache"));
attr = element.getAttribute("groups");
if (StringUtils.hasText(attr)) {
builder.addPropertyValue("serverGroups", StringUtils.commaDelimitedListToStringArray(attr));
}
parseSubscription(builder, element);
}
private void parseSubscription(BeanDefinitionBuilder builder, Element element) {
Element subConfig = DomUtils.getChildElementByTagName(element, "subscription-config");
if (subConfig == null) {
return;
}
ParsingUtils.setPropertyValue(subConfig, builder, "capacity", "subscriptionCapacity");
ParsingUtils.setPropertyValue(subConfig, builder, "disk-store", "subscriptionDiskStore");
String attr = element.getAttribute("eviction-type");
if (StringUtils.hasText(attr)) {
builder.addPropertyValue("subscriptionEvictionPolicy", attr.toUpperCase());
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.
@@ -89,6 +89,8 @@ class ClientRegionParser extends AliasReplacingBeanDefinitionParser {
// client attributes
BeanDefinitionBuilder attrBuilder = BeanDefinitionBuilder.genericBeanDefinition(RegionAttributesFactoryBean.class);
ParsingUtils.parseStatistics(element, attrBuilder);
boolean overwriteDataPolicy = false;
overwriteDataPolicy |= ParsingUtils.parseEviction(parserContext, element, attrBuilder);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.
@@ -32,6 +32,7 @@ class GemfireNamespaceHandler extends NamespaceHandlerSupport {
registerBeanDefinitionParser("partitioned-region", new PartitionedRegionParser());
registerBeanDefinitionParser("client-region", new ClientRegionParser());
registerBeanDefinitionParser("pool", new PoolParser());
registerBeanDefinitionParser("cache-server", new CacheServerParser());
registerBeanDefinitionParser("transaction-manager", new TransactionManagerParser());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.
@@ -217,4 +217,9 @@ abstract class ParsingUtils {
attrBuilder.addPropertyValue("evictionAttributes", evictionDefBuilder.getBeanDefinition());
return true;
}
static void parseStatistics(Element element, BeanDefinitionBuilder attrBuilder) {
setPropertyValue(element, attrBuilder, "statistics", "statisticsEnabled");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.
@@ -78,6 +78,7 @@ class PartitionedRegionParser extends AliasReplacingBeanDefinitionParser {
ParsingUtils.parseEviction(parserContext, element, attrBuilder);
ParsingUtils.parseDiskStorage(element, attrBuilder);
ParsingUtils.parseStatistics(element, attrBuilder);
// partition attributes
BeanDefinitionBuilder parAttrBuilder = BeanDefinitionBuilder.genericBeanDefinition(PartitionAttributesFactoryBean.class);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.
@@ -64,6 +64,8 @@ class ReplicatedRegionParser extends AliasReplacingBeanDefinitionParser {
// add attributes
BeanDefinitionBuilder attrBuilder = BeanDefinitionBuilder.genericBeanDefinition(RegionAttributesFactoryBean.class);
ParsingUtils.parseStatistics(element, attrBuilder);
attr = element.getAttribute("publisher");
if (StringUtils.hasText(attr)) {
attrBuilder.addPropertyValue("publisher", Boolean.valueOf(attr));

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.
@@ -123,7 +123,7 @@ public class InstantiatorFactoryBean implements BeanClassLoaderAware, FactoryBea
* Sets the distribution of the region of this {@link Instantiator} during the container startup.
* Default is false, meaning the registration will not be distributed to other clients.
*
* @see #register(Instantiator, boolean)
* @see Instantiator#register(Instantiator, boolean)
* @param distribute whether the registration is distributable or not
*/
public void setDistribute(boolean distribute) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors.
* Copyright 2010-2011 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.

View File

@@ -0,0 +1,230 @@
/*
* Copyright 2011 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.server;
import java.io.IOException;
import java.util.Collections;
import java.util.Set;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.SmartLifecycle;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.InterestRegistrationListener;
import com.gemstone.gemfire.cache.server.CacheServer;
import com.gemstone.gemfire.cache.server.ClientSubscriptionConfig;
import com.gemstone.gemfire.cache.server.ServerLoadProbe;
/**
* FactoryBean for easy creation and configuration of GemFire {@link CacheServer} instances.
*
* @author Costin Leau
*/
public class CacheServerFactoryBean implements FactoryBean<CacheServer>, InitializingBean, DisposableBean,
SmartLifecycle {
private boolean autoStartup = true;
private int port = CacheServer.DEFAULT_PORT;
private int maxConnections = CacheServer.DEFAULT_MAX_CONNECTIONS;
private int maxThreads = CacheServer.DEFAULT_MAX_THREADS;
private boolean notifyBySubscription = CacheServer.DEFAULT_NOTIFY_BY_SUBSCRIPTION;
private int socketBufferSize = CacheServer.DEFAULT_SOCKET_BUFFER_SIZE;
private int maxTimeBetweenPings = CacheServer.DEFAULT_MAXIMUM_TIME_BETWEEN_PINGS;
private int maxMessageCount = CacheServer.DEFAULT_MAXIMUM_MESSAGE_COUNT;
private int messageTimeToLive = CacheServer.DEFAULT_MESSAGE_TIME_TO_LIVE;
private String[] serverGroups = CacheServer.DEFAULT_GROUPS;
private ServerLoadProbe serverLoadProbe = CacheServer.DEFAULT_LOAD_PROBE;
private long loadPollInterval = CacheServer.DEFAULT_LOAD_POLL_INTERVAL;
private String bindAddress = CacheServer.DEFAULT_BIND_ADDRESS;
private String hostNameForClients = CacheServer.DEFAULT_HOSTNAME_FOR_CLIENTS;
private Set<InterestRegistrationListener> listeners = Collections.emptySet();
private SubscriptionEvictionPolicy evictionPolicy = SubscriptionEvictionPolicy.valueOf(ClientSubscriptionConfig.DEFAULT_EVICTION_POLICY.toUpperCase());
private int subscriptionCapacity = ClientSubscriptionConfig.DEFAULT_CAPACITY;
private Resource subscriptionDiskStore;
private Cache cache;
private CacheServer cacheServer;
public CacheServer getObject() {
return cacheServer;
}
public Class<?> getObjectType() {
return ((this.cacheServer != null) ? cacheServer.getClass() : CacheServer.class);
}
public boolean isSingleton() {
return true;
}
public void afterPropertiesSet() throws IOException {
Assert.notNull(cache, "cache is required");
cacheServer = cache.addCacheServer();
cacheServer.setBindAddress(bindAddress);
cacheServer.setGroups(serverGroups);
cacheServer.setHostnameForClients(hostNameForClients);
cacheServer.setLoadPollInterval(loadPollInterval);
cacheServer.setLoadProbe(serverLoadProbe);
cacheServer.setMaxConnections(maxConnections);
cacheServer.setMaximumMessageCount(maxMessageCount);
cacheServer.setMaximumTimeBetweenPings(maxTimeBetweenPings);
cacheServer.setMaxThreads(maxThreads);
cacheServer.setMessageTimeToLive(messageTimeToLive);
cacheServer.setNotifyBySubscription(notifyBySubscription);
cacheServer.setPort(port);
cacheServer.setSocketBufferSize(socketBufferSize);
for (InterestRegistrationListener listener : listeners) {
cacheServer.registerInterestRegistrationListener(listener);
}
// client config
ClientSubscriptionConfig config = cacheServer.getClientSubscriptionConfig();
config.setCapacity(subscriptionCapacity);
config.setEvictionPolicy(evictionPolicy.name().toLowerCase());
config.setDiskStoreName(subscriptionDiskStore.getFile().getCanonicalPath());
start();
}
public void destroy() {
stop();
cacheServer = null;
}
public boolean isAutoStartup() {
return autoStartup;
}
public void stop(Runnable callback) {
stop();
callback.run();
}
public int getPhase() {
// start the latest
return Integer.MAX_VALUE;
}
public boolean isRunning() {
return (cacheServer != null ? cacheServer.isRunning() : false);
}
public void start() {
try {
cacheServer.start();
} catch (IOException ex) {
throw new BeanInitializationException("Cannot start cache server", ex);
}
}
public void stop() {
if (cacheServer != null) {
cacheServer.stop();
}
}
public void setAutoStartup(boolean autoStartup) {
this.autoStartup = autoStartup;
}
public void setPort(int port) {
this.port = port;
}
public void setMaxConnections(int maxConnections) {
this.maxConnections = maxConnections;
}
public void setMaxThreads(int maxThreads) {
this.maxThreads = maxThreads;
}
public void setNotifyBySubscription(boolean notifyBySubscription) {
this.notifyBySubscription = notifyBySubscription;
}
public void setSocketBufferSize(int socketBufferSize) {
this.socketBufferSize = socketBufferSize;
}
public void setMaxTimeBetweenPings(int maxTimeBetweenPings) {
this.maxTimeBetweenPings = maxTimeBetweenPings;
}
public void setMaxMessageCount(int maxMessageCount) {
this.maxMessageCount = maxMessageCount;
}
public void setMessageTimeToLive(int messageTimeToLive) {
this.messageTimeToLive = messageTimeToLive;
}
public void setServerGroups(String[] serverGroups) {
this.serverGroups = serverGroups;
}
public void setServerLoadProbe(ServerLoadProbe serverLoadProbe) {
this.serverLoadProbe = serverLoadProbe;
}
public void setLoadPollInterval(long loadPollInterval) {
this.loadPollInterval = loadPollInterval;
}
public void setBindAddress(String bindAddress) {
this.bindAddress = bindAddress;
}
public void setHostNameForClients(String hostNameForClients) {
this.hostNameForClients = hostNameForClients;
}
public void setListeners(Set<InterestRegistrationListener> listeners) {
this.listeners = listeners;
}
public void setCache(Cache cache) {
this.cache = cache;
}
/**
* @param evictionPolicy the evictionPolicy to set
*/
public void setSubscriptionEvictionPolicy(SubscriptionEvictionPolicy evictionPolicy) {
this.evictionPolicy = evictionPolicy;
}
/**
* @param subscriptionCapacity the subscriptionCapacity to set
*/
public void setSubscriptionCapacity(int subscriptionCapacity) {
this.subscriptionCapacity = subscriptionCapacity;
}
public void setSubscriptionDiskStore(Resource resource) {
this.subscriptionDiskStore = resource;
}
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright 2011 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.server;
import com.gemstone.gemfire.cache.server.CacheServer;
/**
* Enumeration of the various client subscription policies for {@link CacheServer}.
*
* @author Costin Leau
*/
public enum SubscriptionEvictionPolicy {
NONE, MEM, ENTRY
}

View File

@@ -0,0 +1,5 @@
/**
* Support package for GemFire {@link com.gemstone.gemfire.cache.server.CacheServer}.
*
*/
package org.springframework.data.gemfire.server;

View File

@@ -0,0 +1,85 @@
/*
* Copyright 2011 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.support;
import org.springframework.dao.support.DaoSupport;
import org.springframework.data.gemfire.GemfireTemplate;
import org.springframework.util.Assert;
import com.gemstone.gemfire.cache.Region;
/**
* Convenient super class for GemFire data access objects. Intended for
* GemfireTemplate usage.
*
* <p>Requires a Region to be set, providing a GemfireTemplate based on it to subclasses.
* Can alternatively be initialized directly via a GemfireTemplate, to reuse the latter's
* settings.
*
* <p>This class will create its own GemfireTemplate if an Region reference is passed in.
* A custom GemfireTemplate instance can be used through overriding <code>createGemfireTemplate</code>.
*
* @author Costin Leau
*/
public class GemfireDaoSupport extends DaoSupport {
private GemfireTemplate gemfireTemplate;
/**
* Sets the GemFire Region to be used by this DAO.
* Will automatically create a GemfireTemplate for the given Region.
*
* @param region
*/
public void setRegion(Region<?, ?> region) {
this.gemfireTemplate = createGemfireTemplate(region);
}
/**
* Creates a GemfireTemplate for the given Region.
* <p>Can be overridden in subclasses to provide a GemfireTemplate instance
* with different configuration, or a custom GemfireTemplate subclass.
* @param region the GemFire Region to create a GemfireTemplate for
* @return the new GemfireTemplate instance
* @see #setRegion
*/
protected GemfireTemplate createGemfireTemplate(Region<?, ?> region) {
return new GemfireTemplate(region);
}
/**
* Set the GemfireTemplate for this DAO explicitly,
* as an alternative to specifying a GemFire {@link Region}.
* @see #setRegion
*/
public final void setGemfireTemplate(GemfireTemplate gemfireTemplate) {
this.gemfireTemplate = gemfireTemplate;
}
/**
* Return the GemfireTemplate for this DAO, pre-initialized
* with the Region or set explicitly.
*/
public final GemfireTemplate getGemfireTemplate() {
return gemfireTemplate;
}
@Override
protected final void checkDaoConfig() {
Assert.notNull(gemfireTemplate, "region or gemfireTemplate is required");
}
}