Add framework support for customizable serialization.

The new Serialization framework supports PDX Serialization as a possible configuration option for SSDG in addition to the already existing use of GemFire/Geode's DataSerialization framework.

Resolves Issue #2.
This commit is contained in:
John Blum
2017-08-01 13:10:50 -07:00
parent 9f11a44763
commit 64a7fec70b
24 changed files with 1366 additions and 281 deletions

View File

@@ -13,4 +13,4 @@ springIoVersion=Cairo-BUILD-SNAPSHOT
springSecurityVersion=5.0.0.M3
springSessionVersion=2.0.0.BUILD-SNAPSHOT
springShellVersion=1.2.0.RELEASE
version=2.0.0.BUILD-SNAPSHOT
version=2.0.0.ISSUE-2-BUILD-SNAPSHOT

View File

@@ -87,7 +87,7 @@ public class IntegrationTestConfiguration {
private boolean isGemFireRegion(Object bean, String beanName) {
return (GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME.equals(beanName)
return (GemFireHttpSessionConfiguration.DEFAULT_SESSION_REGION_NAME.equals(beanName)
|| bean instanceof Region);
}

View File

@@ -157,7 +157,7 @@ public final class NativeGemFireServer implements Runnable {
regionFactory.setEntryIdleTimeout(newExpirationAttributes(1800, ExpirationAction.INVALIDATE));
Region region = regionFactory.create(
GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME);
GemFireHttpSessionConfiguration.DEFAULT_SESSION_REGION_NAME);
return gemfireCache;
}

View File

@@ -87,7 +87,7 @@ public abstract class IntegrationTestConfig {
private boolean isGemFireRegion(Object bean, String beanName) {
return (GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME.equals(beanName)
return (GemFireHttpSessionConfiguration.DEFAULT_SESSION_REGION_NAME.equals(beanName)
|| bean instanceof Region);
}

View File

@@ -88,7 +88,7 @@ public class ClientServerReadyBeanPostProcessor implements BeanPostProcessor {
private boolean isGemFireRegion(Object bean, String beanName) {
return (GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME.equals(beanName)
return (GemFireHttpSessionConfiguration.DEFAULT_SESSION_REGION_NAME.equals(beanName)
|| bean instanceof Region);
}

View File

@@ -885,6 +885,16 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
this.lock = (lock != null ? lock : this);
}
/* (non-Javadoc) */
public static GemFireSessionAttributes create() {
return new GemFireSessionAttributes();
}
/* (non-Javadoc) */
public static GemFireSessionAttributes create(Object lock) {
return new GemFireSessionAttributes(lock);
}
/* (non-Javadoc) */
public void setAttribute(String attributeName, Object attributeValue) {

View File

@@ -24,102 +24,63 @@ import java.lang.annotation.Target;
import javax.servlet.http.HttpSession;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionShortcut;
import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.client.ClientRegionShortcut;
import org.apache.geode.cache.client.Pool;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.session.Session;
import org.springframework.session.data.gemfire.serialization.SessionSerializer;
import org.springframework.session.web.http.SessionRepositoryFilter;
/**
* Add this annotation to a Spring {@code @Configuration} class to expose the {@link SessionRepositoryFilter}
* as a bean named {@literal springSessionRepositoryFilter} back the {@link HttpSession}
* by Pivotal GemFire or Apache Geode.
* Add this annotation to a Spring application defined {@code @Configuration} class exposing
* the {@link SessionRepositoryFilter} as a bean named {@literal springSessionRepositoryFilter}
* to back the {@link HttpSession} by Apache Geode or Pivotal GemFire.
*
* In order to use this annotation, a single Pivotal GemFire/Apache Geode {@link org.apache.geode.cache.Cache}
* or {@link org.apache.geode.cache.client.ClientCache} instance must be provided.
* In order to use this annotation, a single Apache Geode / Pivotal GemFire {@link Cache} or {@link ClientCache}
* instance must be provided.
*
* For example:
*
* <pre>
* <code>
* {@literal @Configuration}
* {@literal @PeerCacheApplication}
* {@literal @EnableGemFireHttpSession}
* public class GemFirePeerCacheHttpSessionConfiguration {
* public class PeerCacheHttpSessionConfiguration {
*
* {@literal @Bean}
* public Properties gemfireProperties() {
*
* Properties gemfireProperties = new Properties();
*
* gemfireProperties.setProperty("name", "ExamplePeer");
* gemfireProperties.setProperty("mcast-port", "0");
* gemfireProperties.setProperty("log-level", "warning");
*
* return gemfireProperties;
* }
*
* {@literal @Bean}
* public CacheFactoryBean gemfireCache() throws Exception {
*
* CacheFactoryBean cache = new CacheFactoryBean();
*
* cache.setClose(true);
* cache.setProperties(gemfireProperties());
*
* return cache;
* }
* }
* </code> </pre>
*
* Alternatively, Spring Session can be configured to use Pivotal GemFire/Apache Geode as a cache client
* with a dedicated Pivotal GemFire/Apache Geode cluster and a {@link org.apache.geode.cache.client.ClientCache}.
* Alternatively, Spring Session can be configured to use Apache Geode / Pivotal GemFire as a cache client
* with a dedicated Apache Geode / Pivotal GemFire cluster.
*
* For example:
*
* <code>
* {@literal @Configuration}
* {@literal @ClientCacheApplication}
* {@literal @EnableGemFireHttpSession}
* public class GemFireClientCacheHttpSessionConfiguration {
* public class ClientCacheHttpSessionConfiguration {
*
* {@literal @Bean}
* public Properties gemfireProperties() {
*
* Properties gemfireProperties = new Properties();
*
* gemfireProperties.setProperty("name", "ExampleClient");
* gemfireProperties.setProperty("log-level", "warning");
*
* return gemfireProperties;
* }
*
* {@literal @Bean}
* public ClientCacheFactoryBean gemfireCache() throws Exception {
*
* ClientCacheFactoryBean clientCache = new ClientCacheFactoryBean();
*
* clientCache.setClose(true)
* clientCache.setProperties(gemfireProperties());
*
* return clientCache;
* }
*
* {@literal @Bean}
* public PoolFactoryBean gemfirePool() {
*
* PoolFactoryBean pool = new PoolFactoryBean();
*
* pool.addServer(new ConnectionEndpoint("localhost", 40404);
*
* return pool;
* }
* }
* </code>
*
* More advanced configurations can extend {@link GemFireHttpSessionConfiguration} instead.
*
* @author John Blum
* @see org.apache.geode.cache.Cache
* @see org.apache.geode.cache.Region
* @see org.apache.geode.cache.client.ClientCache
* @see org.apache.geode.cache.client.Pool
* @see org.springframework.context.annotation.Configuration
* @see org.springframework.context.annotation.Import
* @see org.springframework.session.Session
* @see org.springframework.session.config.annotation.web.http.EnableSpringHttpSession
* @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration
* @since 1.1.0
@@ -132,59 +93,74 @@ import org.springframework.session.web.http.SessionRepositoryFilter;
public @interface EnableGemFireHttpSession {
/**
* Defines the GemFire ClientCache Region DataPolicy.
* Defines the {@link ClientCache} {@link Region} data management policy.
*
* @return a ClientRegionShortcut used to specify and configure the ClientCache Region
* DataPolicy.
* @return a {@link ClientRegionShortcut} used to configure the {@link ClientCache} {@link Region}
* data management policy.
* @see org.apache.geode.cache.client.ClientRegionShortcut
*/
ClientRegionShortcut clientRegionShortcut() default ClientRegionShortcut.PROXY;
/**
* Identifies the Session attributes by name that should be indexed for query
* operations. For instance, find all Sessions in GemFire having attribute A defined
* with value X.
* Identifies the {@link Session} attributes by name that will be indexed for query operations.
*
* @return an array of Strings identifying the names of Session attributes to index.
* For instance, find all {@link Session Sessions} in GemFire or Geode having attribute A defined with value X.
*
* @return an array of {@link String Strings} identifying the names of {@link Session} attributes to index.
*/
String[] indexableSessionAttributes() default {};
/**
* Defines the maximum interval in seconds that a {@link Session} can remain inactive
* before it is considered expired. Defaults to 1800 seconds, or 30 minutes.
* Defines the maximum interval in seconds that a {@link Session} can remain inactive before it expires.
*
* @return an integer value defining the maximum inactive interval in seconds
* declaring the {@link Session} expired.
* Defaults to 1800 seconds, or 30 minutes.
*
* @return an integer value defining the maximum inactive interval in seconds before the {@link Session} expires.
*/
int maxInactiveIntervalInSeconds() default 1800;
/**
* Specifies the name of the specific GemFire {@link org.apache.geode.cache.client.Pool} used
* by the Spring Session Data GemFire client Region ('ClusteredSpringSessions') when performing
* cache operations. This is attribute is only used in the client/server topology.
* Specifies the name of the specific {@link Pool} used by the client cache {@link Region}
* (i.e. {@literal ClusteredSpringSessions}) when performing cache data access operations.
*
* @return the name of the GemFire {@link org.apache.geode.cache.client.Pool} to be used
* by the client Region used to manage (HTTP) Sessions.
* @see org.springframework.data.gemfire.config.xml.GemfireConstants#DEFAULT_GEMFIRE_POOL_NAME
* This is attribute is only used in the client/server topology.
*
* @return the name of the {@link Pool} to be used by the client cache Region to send {@link Session} state
* to the cluster of servers.
* @see GemFireHttpSessionConfiguration#DEFAULT_POOL_NAME
*/
String poolName() default GemFireHttpSessionConfiguration.DEFAULT_GEMFIRE_POOL_NAME;
String poolName() default GemFireHttpSessionConfiguration.DEFAULT_POOL_NAME;
/**
* Defines the name of the GemFire (Client)Cache Region used to store Sessions.
* Defines the name of the (client)cache {@link Region} used to store {@link Session} state.
*
* @return a String specifying the name of the GemFire (Client)Cache Region used to
* store Sessions.
* @see org.apache.geode.cache.Region#getName()
* @return a {@link String} specifying the name of the (client)cace {@link Region}
* used to store {@link Session} state.
* @see GemFireHttpSessionConfiguration#DEFAULT_SESSION_REGION_NAME
*/
String regionName() default "ClusteredSpringSessions";
String regionName() default GemFireHttpSessionConfiguration.DEFAULT_SESSION_REGION_NAME;
/**
* Defines the GemFire, Peer Cache Region DataPolicy.
* Defines the {@link Cache} {@link Region} data management policy.
*
* @return a RegionShortcut used to specify and configure the Peer Cache Region
* DataPolicy.
* @return a {@link RegionShortcut} used to specify and configure the {@link Cache} {@link Region}
* data management policy.
* @see org.apache.geode.cache.RegionShortcut
*/
RegionShortcut serverRegionShortcut() default RegionShortcut.PARTITION;
/**
* Defines the bean name of the {@link SessionSerializer} used to serialize {@link Session} state
* between client and server or to disk when persisting or overflowing {@link Session} state.
*
* The bean referred to by its name must be of type {@link SessionSerializer}.
*
* Defaults to {@literal SessionDataSerializer}.
*
* @return a {@link String} containing the bean name of the configured {@link SessionSerializer}.
* @see org.springframework.session.data.gemfire.serialization.data.provider.DataSerializableSessionSerializer
* @see org.springframework.session.data.gemfire.serialization.SessionSerializer
*/
String sessionSerializerBeanName() default GemFireHttpSessionConfiguration.DEFAULT_SESSION_SERIALIZER_BEAN_NAME;
}

View File

@@ -19,12 +19,14 @@ package org.springframework.session.data.gemfire.config.annotation.web.http;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.ExpirationAction;
import org.apache.geode.cache.ExpirationAttributes;
import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionAttributes;
import org.apache.geode.cache.RegionShortcut;
import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.client.ClientRegionShortcut;
import org.apache.geode.cache.client.Pool;
@@ -33,6 +35,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportAware;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
@@ -43,11 +46,15 @@ import org.springframework.data.gemfire.IndexType;
import org.springframework.data.gemfire.RegionAttributesFactoryBean;
import org.springframework.data.gemfire.config.xml.GemfireConstants;
import org.springframework.session.Session;
import org.springframework.session.SessionRepository;
import org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration;
import org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSession;
import org.springframework.session.data.gemfire.GemFireOperationsSessionRepository;
import org.springframework.session.data.gemfire.config.annotation.web.http.support.GemFireCacheTypeAwareRegionFactoryBean;
import org.springframework.session.data.gemfire.config.annotation.web.http.support.SessionAttributesIndexFactoryBean;
import org.springframework.session.data.gemfire.serialization.SessionSerializer;
import org.springframework.session.data.gemfire.serialization.data.provider.DataSerializableSessionSerializer;
import org.springframework.session.data.gemfire.serialization.pdx.provider.PdxSerializableSessionSerializer;
import org.springframework.session.data.gemfire.support.GemFireUtils;
import org.springframework.util.StringUtils;
@@ -89,38 +96,51 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
implements BeanClassLoaderAware, ImportAware {
/**
* The default maximum interval in seconds in which a Session can remain inactive
* before it is considered expired.
* Default maximum interval in seconds in which a {@link Session} can remain inactive before it expires.
*/
public static final int DEFAULT_MAX_INACTIVE_INTERVAL_IN_SECONDS = (int) TimeUnit.MINUTES.toSeconds(30);
protected static final Class<Object> SPRING_SESSION_GEMFIRE_REGION_KEY_CONSTRAINT = Object.class;
protected static final Class<GemFireSession> SPRING_SESSION_GEMFIRE_REGION_VALUE_CONSTRAINT = GemFireSession.class;
/**
* Key and Value class type constraints applied to the {@link Session} {@link Region}.
*/
protected static final Class<Object> SESSION_REGION_KEY_CONSTRAINT = Object.class;
protected static final Class<GemFireSession> SESSION_REGION_VALUE_CONSTRAINT = GemFireSession.class;
/**
* The default {@link ClientRegionShortcut} used to configure the GemFire ClientCache
* Region that will store Spring Sessions.
* Default {@link ClientRegionShortcut} used to configure the data management policy of the {@link ClientCache}
* {@link Region} that will store {@link Session} state.
*/
public static final ClientRegionShortcut DEFAULT_CLIENT_REGION_SHORTCUT = ClientRegionShortcut.PROXY;
/**
* The default {@link RegionShortcut} used to configure the GemFire Cache Region that
* will store Spring Sessions.
* Default {@link RegionShortcut} used to configure the data management policy of the {@link Cache} {@link Region}
* that will store {@link Session} state.
*/
public static final RegionShortcut DEFAULT_SERVER_REGION_SHORTCUT = RegionShortcut.PARTITION;
/**
* Name of the GemFire {@link Pool} used by the client Region for managing Session state information.
* Name of the connection {@link Pool} used by the client {@link Region} to send {@link Session} state
* to the cluster of Geode servers.
*/
public static final String DEFAULT_GEMFIRE_POOL_NAME = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME;
public static final String DEFAULT_POOL_NAME = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME;
/**
* The default name of the Gemfire (Client)Cache Region used to store Sessions.
* Default name of (Client)Cache {@link Region} used to store {@link Session} state.
*/
public static final String DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME = "ClusteredSpringSessions";
public static final String DEFAULT_SESSION_REGION_NAME = "ClusteredSpringSessions";
/**
* The default names of all Session attributes that should be indexed by GemFire.
* Set of defaults for {@link Session} serialization.
*/
public static final String SESSION_DATA_SERIALIZER_BEAN_NAME = "SessionDataSerializer";
public static final String SESSION_PDX_SERIALIZER_BEAN_NAME = "SessionPdxSerializer";
public static final String SESSION_SERIALIZER_QUALIFIER_PROPERTY_NAME =
"spring.session.data.geode.serializer.qualifier";
public static final String DEFAULT_SESSION_SERIALIZER_BEAN_NAME = SESSION_DATA_SERIALIZER_BEAN_NAME;
/**
* Defaults names of all {@link Session} attributes that will be indexed by Apache Geode.
*/
public static final String[] DEFAULT_INDEXABLE_SESSION_ATTRIBUTES = {};
@@ -132,18 +152,18 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
private RegionShortcut serverRegionShortcut = DEFAULT_SERVER_REGION_SHORTCUT;
private String poolName = DEFAULT_GEMFIRE_POOL_NAME;
private String poolName = DEFAULT_POOL_NAME;
private String springSessionGemFireRegionName = DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME;
private String sessionRegionName = DEFAULT_SESSION_REGION_NAME;
private String sessionSerializerBeanName = DEFAULT_SESSION_SERIALIZER_BEAN_NAME;
private String[] indexableSessionAttributes = DEFAULT_INDEXABLE_SESSION_ATTRIBUTES;
/**
* Sets a reference to the {@link ClassLoader} used to load bean definition class
* types in a Spring context.
* Sets a reference to the {@link ClassLoader} used by the Spring container to load bean class types.
*
* @param beanClassLoader the ClassLoader used by the Spring container to load bean
* class types.
* @param beanClassLoader {@link ClassLoader} used by the Spring container to load bean class types.
* @see org.springframework.beans.factory.BeanClassLoaderAware#setBeanClassLoader(ClassLoader)
* @see java.lang.ClassLoader
*/
@@ -152,10 +172,9 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
}
/**
* Gets a reference to the {@link ClassLoader} used to load bean definition class
* types in a Spring context.
* Returns a reference to the {@link ClassLoader} used by the Spring container to load bean class types.
*
* @return the ClassLoader used by the Spring container to load bean class types.
* @return the {@link ClassLoader} used by the Spring container to load bean class types.
* @see java.lang.ClassLoader
*/
protected ClassLoader getBeanClassLoader() {
@@ -163,11 +182,14 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
}
/**
* Sets the {@link ClientRegionShortcut} used to configure the GemFire ClientCache
* Region that will store Spring Sessions.
* Gets the {@link ClientRegionShortcut} used to configure the data management policy of the {@link ClientCache}
* {@link Region} that will store {@link Session} state.
*
* @param shortcut the ClientRegionShortcut used to configure the GemFire ClientCache
* Region.
* Defaults to {@link ClientRegionShortcut#PROXY}.
*
* @param shortcut {@link ClientRegionShortcut} used to configure the data management policy
* of the {@link ClientCache} {@link Region}.
* @see EnableGemFireHttpSession#clientRegionShortcut()
* @see org.apache.geode.cache.client.ClientRegionShortcut
*/
public void setClientRegionShortcut(ClientRegionShortcut shortcut) {
@@ -175,91 +197,92 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
}
/**
* Gets the {@link ClientRegionShortcut} used to configure the GemFire ClientCache
* Region that will store Spring Sessions. Defaults to
* {@link ClientRegionShortcut#PROXY}.
* Gets the {@link ClientRegionShortcut} used to configure the data management policy of the {@link ClientCache}
* {@link Region} that will store {@link Session} state.
*
* @return the ClientRegionShortcut used to configure the GemFire ClientCache Region.
* Defaults to {@link ClientRegionShortcut#PROXY}.
*
* @return the {@link ClientRegionShortcut} used to configure the data management policy
* of the {@link ClientCache} {@link Region}.
* @see org.apache.geode.cache.client.ClientRegionShortcut
* @see EnableGemFireHttpSession#clientRegionShortcut()
*/
protected ClientRegionShortcut getClientRegionShortcut() {
return Optional.ofNullable(this.clientRegionShortcut).orElse(DEFAULT_CLIENT_REGION_SHORTCUT);
}
/**
* Sets the names of all Session attributes that should be indexed by GemFire.
* Sets the names of all {@link Session} attributes that will be indexed.
*
* @param indexableSessionAttributes an array of Strings indicating the names of all
* Session attributes for which an Index will be created by GemFire.
* @param indexableSessionAttributes an array of {@link String Strings} containing the names
* of all {@link Session} attributes for which an Index will be created.
* @see EnableGemFireHttpSession#indexableSessionAttributes()
*/
public void setIndexableSessionAttributes(String[] indexableSessionAttributes) {
this.indexableSessionAttributes = indexableSessionAttributes;
}
/**
* Get the names of all Session attributes that should be indexed by GemFire.
* Get the names of all {@link Session} attributes that will be indexed.
*
* @return an array of Strings indicating the names of all Session attributes for
* which an Index will be created by GemFire. Defaults to an empty String array if
* unspecified.
* @see EnableGemFireHttpSession#indexableSessionAttributes()
* @return an array of {@link String Strings} containing the names of all {@link Session} attributes
* for which an Index will be created. Defaults to an empty array if unspecified.
*/
protected String[] getIndexableSessionAttributes() {
return Optional.ofNullable(this.indexableSessionAttributes).orElse(DEFAULT_INDEXABLE_SESSION_ATTRIBUTES);
}
/**
* Sets the maximum interval in seconds in which a Session can remain inactive before
* it is considered expired.
* Sets the maximum interval in seconds in which a {@link Session} can remain inactive before it expires.
*
* @param maxInactiveIntervalInSeconds an integer value specifying the maximum
* interval in seconds that a Session can remain inactive before it is considered
* expired.
* @param maxInactiveIntervalInSeconds integer value specifying the maximum interval in seconds
* that a {@link Session} can remain inactive before it expires.
* @see EnableGemFireHttpSession#maxInactiveIntervalInSeconds()
*/
public void setMaxInactiveIntervalInSeconds(int maxInactiveIntervalInSeconds) {
this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds;
}
/**
* Gets the maximum interval in seconds in which a {@link Session} can remain inactive
* before it is considered expired.
* Gets the maximum interval in seconds in which a {@link Session} can remain inactive before it expires.
*
* @return an integer value specifying the maximum interval in seconds that a {@link Session} can remain inactive
* before it is considered expired.
* @see EnableGemFireHttpSession#maxInactiveIntervalInSeconds()
* before it expires.
*/
protected int getMaxInactiveIntervalInSeconds() {
return this.maxInactiveIntervalInSeconds;
}
/**
* Sets the name of the GemFire {@link Pool} used by the client Region for managing Sessions
* during cache operations involving the server.
* Sets the name of the {@link Pool} used by the client {@link Region} to send {@link Session}
* to the cluster of servers during cache operations.
*
* @param poolName the name of a GemFire {@link Pool}.
* @see Pool#getName()
* @param poolName {@link String} containing the name of a {@link Pool}.
* @see EnableGemFireHttpSession#poolName()
*/
public void setPoolName(String poolName) {
this.poolName = poolName;
}
/**
* Returns the name of the GemFire {@link Pool} used by the client Region for managing Sessions
* during cache operations involving the server.
* Returns the name of the {@link Pool} used by the client {@link Region} to send {@link Session}
* to the cluster of servers during cache operations.
*
* @return the name of a GemFire {@link Pool}.
* @see Pool#getName()
* @return a {@link String} containing the name of a {@link Pool}.
* @see org.apache.geode.cache.client.Pool#getName()
*/
protected String getPoolName() {
return Optional.ofNullable(this.poolName).filter(StringUtils::hasText).orElse(DEFAULT_GEMFIRE_POOL_NAME);
return Optional.ofNullable(this.poolName).filter(StringUtils::hasText).orElse(DEFAULT_POOL_NAME);
}
/**
* Sets the {@link RegionShortcut} used to configure the GemFire Cache Region that
* will store Spring Sessions.
* Sets the {@link RegionShortcut} used to configure the data management policy of the {@link Cache} {@link Region}
* that will store {@link Session} state.
*
* @param shortcut the RegionShortcut used to configure the GemFire Cache Region.
* Defaults to {@link RegionShortcut#PARTITION}.
*
* @param shortcut {@link RegionShortcut} used to configure the data management policy
* of the {@link Cache} {@link Region}.
* @see EnableGemFireHttpSession#serverRegionShortcut()
* @see org.apache.geode.cache.RegionShortcut
*/
public void setServerRegionShortcut(RegionShortcut shortcut) {
@@ -267,47 +290,85 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
}
/**
* Gets the {@link RegionShortcut} used to configure the GemFire Cache Region that
* will store Spring Sessions. Defaults to {@link RegionShortcut#PARTITION}.
* Gets the {@link RegionShortcut} used to configure the data management policy of the {@link Cache} {@link Region}
* that will store {@link Session} state.
*
* @return the RegionShortcut used to configure the GemFire Cache Region.
* Defaults to {@link RegionShortcut#PARTITION}.
*
* @return the {@link RegionShortcut} used to configure the data management policy
* of the {@link Cache} {@link Region}.
* @see org.apache.geode.cache.RegionShortcut
* @see EnableGemFireHttpSession#serverRegionShortcut()
*/
protected RegionShortcut getServerRegionShortcut() {
return Optional.ofNullable(this.serverRegionShortcut).orElse(DEFAULT_SERVER_REGION_SHORTCUT);
}
/**
* Sets the name of the Gemfire (Client)Cache Region used to store Sessions.
* Sets the name of the (Client)Cache {@link Region} used to store {@link Session} state.
*
* @param springSessionGemFireRegionName a String specifying the name of the GemFire
* (Client)Cache Region used to store the Session.
*/
public void setSpringSessionGemFireRegionName(String springSessionGemFireRegionName) {
this.springSessionGemFireRegionName = springSessionGemFireRegionName;
}
/**
* Gets the name of the Gemfire (Client)Cache Region used to store Sessions. Defaults
* to 'ClusteredSpringSessions'.
*
* @return a String specifying the name of the GemFire (Client)Cache Region used to
* store the Session.
* @see org.apache.geode.cache.Region#getName()
* @param sessionRegionName {@link String} specifying the name of the (Client)Cache {@link Region}
* used to store {@link Session} state.
* @see EnableGemFireHttpSession#regionName()
*/
protected String getSpringSessionGemFireRegionName() {
return Optional.ofNullable(this.springSessionGemFireRegionName).filter(StringUtils::hasText)
.orElse(DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME);
public void setSessionRegionName(String sessionRegionName) {
this.sessionRegionName = sessionRegionName;
}
/**
* Callback with the {@link AnnotationMetadata} of the class containing @Import
* annotation that imported this @Configuration class.
* Returns the name of the (Client)Cache {@link Region} used to store {@link Session} state.
*
* @param importMetadata the AnnotationMetadata of the class importing
* this @Configuration class.
* @return a {@link String} specifying the name of the (Client)Cache {@link Region}
* used to store {@link Session} state.
* @see org.apache.geode.cache.Region#getName()
*/
protected String getSessionRegionName() {
return Optional.ofNullable(this.sessionRegionName).filter(StringUtils::hasText)
.orElse(DEFAULT_SESSION_REGION_NAME);
}
/**
* Sets the {@link String bean name} of the Spring bean declared in the Spring application context
* defining the serialization strategy for serializing the {@link Session}.
*
* The serialization strategy and bean referred to by its name must be an implementation of
* {@link SessionSerializer}.
*
* Defaults to {@literal SessionDataSerializer}.
*
* @param sessionSerializerBeanName {@link String bean name} of the {@link SessionSerializer} used to
* serialize the {@link Session}.
* @see org.springframework.session.data.gemfire.serialization.data.provider.DataSerializableSessionSerializer
* @see org.springframework.session.data.gemfire.serialization.SessionSerializer
*/
public void setSessionSerializerBeanName(String sessionSerializerBeanName) {
this.sessionSerializerBeanName = sessionSerializerBeanName;
}
/**
* Returns the configured {@link String bean name} of the Spring bean declared in the Spring application context
* defining the serialization strategy for serializing the {@link Session}.
*
* The serialization strategy and bean referred to by its name must be an implementation of
* {@link SessionSerializer}.
*
* Defaults to {@literal SessionDataSerializer}.
*
* @return the {@link String bean name} of the {@link SessionSerializer} used to serialize the {@link Session}.
* @see org.springframework.session.data.gemfire.serialization.data.provider.DataSerializableSessionSerializer
* @see org.springframework.session.data.gemfire.serialization.SessionSerializer
*/
protected String getSessionSerializerBeanName() {
return Optional.ofNullable(this.sessionSerializerBeanName).filter(StringUtils::hasText)
.orElse(DEFAULT_SESSION_SERIALIZER_BEAN_NAME);
}
/**
* Callback with the {@link AnnotationMetadata} of the class containing {@link Import @Import} annotation
* that imported this {@link Configuration @Configuration} class.
*
* @param importMetadata {@link AnnotationMetadata} of the application class importing
* this {@link Configuration} class.
* @see org.springframework.core.type.AnnotationMetadata
*/
public void setImportMetadata(AnnotationMetadata importMetadata) {
@@ -329,17 +390,24 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
setServerRegionShortcut(RegionShortcut.class.cast(
enableGemFireHttpSessionAttributes.getEnum("serverRegionShortcut")));
setSpringSessionGemFireRegionName(enableGemFireHttpSessionAttributes.getString("regionName"));
setSessionRegionName(enableGemFireHttpSessionAttributes.getString("regionName"));
setSessionSerializerBeanName(
enableGemFireHttpSessionAttributes.getString("sessionSerializerBeanName"));
System.setProperty(SESSION_SERIALIZER_QUALIFIER_PROPERTY_NAME, getSessionSerializerBeanName());
}
/**
* Defines the Spring SessionRepository bean used to interact with GemFire as a Spring
* Session provider.
* Defines the {@link SessionRepository} bean used to interact with Apache Geode or Pivotal GemFire
* as the Spring Session provider.
*
* @param gemfireOperations an instance of {@link GemfireOperations} used to manage
* Spring Sessions in GemFire.
* @return a GemFireOperationsSessionRepository for managing (clustering/replicating)
* Sessions using GemFire.
* @param gemfireOperations instance of {@link GemfireOperations} used to manage {@link Session} state
* in Apache Geode or Pivotal GemFire.
* @return a {@link GemFireOperationsSessionRepository} for managing (clustering/replicating) {@link Session} state
* in Apache Geode or Pivotal GemFire.
* @see org.springframework.session.data.gemfire.GemFireOperationsSessionRepository
* @see org.springframework.data.gemfire.GemfireOperations
*/
@Bean
public GemFireOperationsSessionRepository sessionRepository(
@@ -354,38 +422,21 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
}
/**
* Defines a Spring GemfireTemplate bean used to interact with GemFire's (Client)Cache
* {@link Region} storing Sessions.
* Defines the {@link Region} used to store and manage {@link Session} state in either a client-server
* or peer-to-peer (p2p) topology.
*
* @param gemfireCache reference to the single GemFire cache instance used by the
* {@link GemfireTemplate} to perform GemFire cache data access operations.
* @return a {@link GemfireTemplate} used to interact with GemFire's (Client)Cache
* {@link Region} storing Sessions.
* @see org.springframework.data.gemfire.GemfireTemplate
* @see org.apache.geode.cache.Region
*/
@Bean
@DependsOn(DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME)
public GemfireTemplate sessionRegionTemplate(GemFireCache gemfireCache) {
return new GemfireTemplate(gemfireCache.getRegion(getSpringSessionGemFireRegionName()));
}
/**
* Defines a Spring GemFire {@link org.apache.geode.cache.Cache} {@link Region}
* bean used to store and manage Sessions using either a client-server or peer-to-peer
* (p2p) topology.
*
* @param gemfireCache a reference to the GemFire
* {@link org.apache.geode.cache.Cache}.
* @param sessionRegionAttributes the GemFire {@link RegionAttributes} used to
* configure the {@link Region}.
* @return a {@link GemFireCacheTypeAwareRegionFactoryBean} used to configure and
* initialize a GemFire Cache {@link Region} for storing and managing Sessions.
* @param gemfireCache reference to the {@link GemFireCache}.
* @param sessionRegionAttributes {@link RegionAttributes} used to configure the {@link Region}.
* @return a {@link GemFireCacheTypeAwareRegionFactoryBean} used to configure and initialize
* the cache {@link Region} used to store and manage {@link Session} state.
* @see org.apache.geode.cache.GemFireCache
* @see org.apache.geode.cache.RegionAttributes
* @see #getClientRegionShortcut()
* @see #getSpringSessionGemFireRegionName()
* @see #getPoolName()
* @see #getServerRegionShortcut()
* @see #getSessionRegionName()
*/
@Bean(name = DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME)
@Bean(name = DEFAULT_SESSION_REGION_NAME)
public GemFireCacheTypeAwareRegionFactoryBean<Object, Session> sessionRegion(GemFireCache gemfireCache,
@Qualifier("sessionRegionAttributes") RegionAttributes<Object, Session> sessionRegionAttributes) {
@@ -396,21 +447,22 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
sessionRegion.setGemfireCache(gemfireCache);
sessionRegion.setPoolName(getPoolName());
sessionRegion.setRegionAttributes(sessionRegionAttributes);
sessionRegion.setRegionName(getSpringSessionGemFireRegionName());
sessionRegion.setRegionName(getSessionRegionName());
sessionRegion.setServerRegionShortcut(getServerRegionShortcut());
return sessionRegion;
}
/**
* Defines a Spring GemFire {@link RegionAttributes} bean used to configure and
* initialize the GemFire cache {@link Region} storing Sessions. Expiration is also
* configured for the {@link Region} on the basis that the GemFire cache
* {@link Region} is a not a proxy, on either the client or server.
* Defines a {@link RegionAttributes} used to configure and initialize the cache {@link Region}
* used to store {@link Session} state.
*
* @param gemfireCache a reference to the GemFire cache.
* @return an instance of {@link RegionAttributes} used to configure and initialize
* the GemFire cache {@link Region} for storing and managing Sessions.
* Expiration is also configured for the {@link Region} on the basis that the cache {@link Region}
* is a not a proxy on either the client or server.
*
* @param gemfireCache reference to the {@link GemFireCache}.
* @return an instance of {@link RegionAttributes} used to configure and initialize cache {@link Region}
* used to store and manage {@link Session} state.
* @see org.springframework.data.gemfire.RegionAttributesFactoryBean
* @see org.apache.geode.cache.GemFireCache
* @see org.apache.geode.cache.PartitionAttributes
@@ -422,8 +474,8 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
RegionAttributesFactoryBean regionAttributes = new RegionAttributesFactoryBean();
regionAttributes.setKeyConstraint(SPRING_SESSION_GEMFIRE_REGION_KEY_CONSTRAINT);
regionAttributes.setValueConstraint(SPRING_SESSION_GEMFIRE_REGION_VALUE_CONSTRAINT);
regionAttributes.setKeyConstraint(SESSION_REGION_KEY_CONSTRAINT);
regionAttributes.setValueConstraint(SESSION_REGION_VALUE_CONSTRAINT);
if (isExpirationAllowed(gemfireCache)) {
regionAttributes.setStatisticsEnabled(true);
@@ -435,21 +487,52 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
}
/**
* Determines whether expiration configuration is allowed to be set on the GemFire
* cache {@link Region} used to store and manage Sessions.
* Determines whether expiration configuration is allowed to be set on the cache {@link Region}
* used to store and manage {@link Session} state.
*
* @param gemfireCache a reference to the GemFire cache.
* @return a boolean indicating if a {@link Region} can be configured for Region entry
* @param gemfireCache reference to the {@link GemFireCache}.
* @return a boolean indicating if a {@link Region} can be configured for {@link Region} entry
* idle-timeout expiration.
* @see GemFireUtils#isClient(GemFireCache)
* @see GemFireUtils#isProxy(ClientRegionShortcut)
* @see GemFireUtils#isProxy(RegionShortcut)
*/
boolean isExpirationAllowed(GemFireCache gemfireCache) {
return !(GemFireUtils.isClient(gemfireCache) ? GemFireUtils.isProxy(getClientRegionShortcut())
return !(GemFireUtils.isClient(gemfireCache)
? GemFireUtils.isProxy(getClientRegionShortcut())
: GemFireUtils.isProxy(getServerRegionShortcut()));
}
/**
* Defines a {@link GemfireTemplate} bean used to interact with the (Client)Cache {@link Region}
* used to store {@link Session} state.
*
* @param gemfireCache reference to the single {@link GemFireCache} instance used by the {@link GemfireTemplate}
* to perform cache {@link Region} data access operations.
* @return a {@link GemfireTemplate} used to interact with the (Client)Cache {@link Region}
* used to store {@link Session} state.
* @see org.springframework.data.gemfire.GemfireTemplate
* @see org.apache.geode.cache.GemFireCache
* @see org.apache.geode.cache.Region
* @see #getSessionRegionName()
*/
@Bean
@DependsOn(DEFAULT_SESSION_REGION_NAME)
public GemfireTemplate sessionRegionTemplate(GemFireCache gemfireCache) {
return new GemfireTemplate(gemfireCache.getRegion(getSessionRegionName()));
}
@Bean(SESSION_DATA_SERIALIZER_BEAN_NAME)
public Object sessionDataSerializer() {
return new PdxSerializableSessionSerializer();
}
@Bean(SESSION_PDX_SERIALIZER_BEAN_NAME)
public Object sessionPdxSerializer() {
return new DataSerializableSessionSerializer();
}
/**
* Defines a GemFire Index bean on the GemFire cache {@link Region} storing and managing Sessions,
* specifically on the 'principalName' property for quick lookup of Sessions by 'principalName'.
@@ -461,19 +544,19 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
* @see org.apache.geode.cache.GemFireCache
*/
@Bean
@DependsOn(DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME)
@DependsOn(DEFAULT_SESSION_REGION_NAME)
public IndexFactoryBean principalNameIndex(GemFireCache gemfireCache) {
IndexFactoryBean index = new IndexFactoryBean();
IndexFactoryBean principalNameIndex = new IndexFactoryBean();
index.setCache(gemfireCache);
index.setName("principalNameIndex");
index.setExpression("principalName");
index.setFrom(GemFireUtils.toRegionPath(getSpringSessionGemFireRegionName()));
index.setOverride(true);
index.setType(IndexType.HASH);
principalNameIndex.setCache(gemfireCache);
principalNameIndex.setName("principalNameIndex");
principalNameIndex.setExpression("principalName");
principalNameIndex.setFrom(GemFireUtils.toRegionPath(getSessionRegionName()));
principalNameIndex.setOverride(true);
principalNameIndex.setType(IndexType.HASH);
return index;
return principalNameIndex;
}
/**
@@ -488,14 +571,14 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
* @see org.apache.geode.cache.GemFireCache
*/
@Bean
@DependsOn(DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME)
@DependsOn(DEFAULT_SESSION_REGION_NAME)
public SessionAttributesIndexFactoryBean sessionAttributesIndex(GemFireCache gemfireCache) {
SessionAttributesIndexFactoryBean sessionAttributesIndex = new SessionAttributesIndexFactoryBean();
sessionAttributesIndex.setGemFireCache(gemfireCache);
sessionAttributesIndex.setIndexableSessionAttributes(getIndexableSessionAttributes());
sessionAttributesIndex.setRegionName(getSpringSessionGemFireRegionName());
sessionAttributesIndex.setRegionName(getSessionRegionName());
return sessionAttributesIndex;
}

View File

@@ -70,11 +70,11 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V>
protected static final RegionShortcut DEFAULT_SERVER_REGION_SHORTCUT =
GemFireHttpSessionConfiguration.DEFAULT_SERVER_REGION_SHORTCUT;
protected static final String DEFAULT_GEMFIRE_POOL_NAME =
GemFireHttpSessionConfiguration.DEFAULT_GEMFIRE_POOL_NAME;
protected static final String DEFAULT_POOL_NAME =
GemFireHttpSessionConfiguration.DEFAULT_POOL_NAME;
protected static final String DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME =
GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME;
protected static final String DEFAULT_SESSION_REGION_NAME =
GemFireHttpSessionConfiguration.DEFAULT_SESSION_REGION_NAME;
private BeanFactory beanFactory;
@@ -325,7 +325,7 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V>
* @see Pool#getName()
*/
protected String getPoolName() {
return Optional.ofNullable(this.poolName).filter(StringUtils::hasText).orElse(DEFAULT_GEMFIRE_POOL_NAME);
return Optional.ofNullable(this.poolName).filter(StringUtils::hasText).orElse(DEFAULT_POOL_NAME);
}
/**
@@ -370,8 +370,7 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V>
* @see org.apache.geode.cache.Region#getName()
*/
protected String getRegionName() {
return Optional.ofNullable(this.regionName).filter(StringUtils::hasText)
.orElse(DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME);
return Optional.ofNullable(this.regionName).filter(StringUtils::hasText).orElse(DEFAULT_SESSION_REGION_NAME);
}
/**

View File

@@ -0,0 +1,76 @@
/*
* Copyright 2017 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.session.data.gemfire.serialization;
/**
* The SerializationException class is a {@link RuntimeException} indicating an error occurred while attempting to
* serialize a {@link org.springframework.session.Session}.
*
* @author John Blum
* @see java.lang.RuntimeException
* @since 2.0.0
*/
@SuppressWarnings("unused")
public class SerializationException extends RuntimeException {
/**
* Constructs a default instance of {@link SerializationException} with no {@link String message}
* or {@link Throwable cause}.
*
* @see RuntimeException
*/
public SerializationException() {
}
/**
* Constructs a new instance of {@link SerializationException} initialized with the given {@link String message}
* describing the serialization error.
*
* @param message {@link String} describing the serialization error.
* @see RuntimeException(String)
* @see java.lang.String
*/
public SerializationException(String message) {
super(message);
}
/**
* Constructs a new instance of {@link SerializationException} initialized with the given {@link Throwable cause}
* of the serialization error.
*
* @param cause {@link Throwable underlying cause} of the serialization error.
* @see RuntimeException(Throwable)
* @see java.lang.Throwable
*/
public SerializationException(Throwable cause) {
super(cause);
}
/**
* Constructs a new instance of {@link SerializationException} initialized with the given {@link String message}
* describing the serialization error and {@link Throwable cause} of the serialization error.
*
* @param message {@link String} describing the serialization error.
* @param cause {@link Throwable underlying cause} of the serialization error.
* @see RuntimeException(String, Throwable)
* @see java.lang.Throwable
* @see java.lang.String
*/
public SerializationException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright 2017 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.session.data.gemfire.serialization;
import java.util.Optional;
/**
* The {@link SessionSerializer} interface is a Service Provider Interface (SPI) for providers
* needing to provide a custom implementation of their serialization strategy.
*
* @author John Blum
* @since 2.0.0
*/
public interface SessionSerializer<T, IN, OUT> {
/**
* Determines whether the given {@link Object} can be de/serialized by this {@link SessionSerializer}.
*
* @param obj {@link Object} to evaluate for whether de/serialization is supported.
* @return a boolean value indicating whether the specified {@link Object} can be de/serialized
* by this {@link SessionSerializer}.
* @see #canSerialize(Class)
*/
default boolean canSerialize(Object obj) {
return Optional.ofNullable(obj).map(Object::getClass).map(this::canSerialize).orElse(false);
}
/**
* Determines whether the given {@link Class type} can be de/serialized by this {@link SessionSerializer}.
*
* @param type {@link Class} to evaluate for whether de/serialization is supported.
* @return a boolean value indicating whether the specified {@link Class type} can be de/serialized
* by this {@link SessionSerializer}.
* @see #canSerialize(Object)
*/
boolean canSerialize(Class<?> type);
/**
* Serializes the given {@link Object} to the provided {@code out} stream.
*
* @param session {@link Object} to serialize.
* @param out stream in which to write the bytes of the {@link Object}.
*/
void serialize(T session, OUT out);
/**
* Deserializes an {@link Object} from bytes contained in the provided {@code in} stream.
*
* @param in stream from which to read the bytes of the {@link Object}.
* @return the deserialized {@link Object}.
*/
T deserialize(IN in);
}

View File

@@ -0,0 +1,105 @@
/*
* Copyright 2017 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.session.data.gemfire.serialization.data;
import static java.util.Arrays.stream;
import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Optional;
import org.apache.geode.DataSerializer;
import org.springframework.session.data.gemfire.serialization.SerializationException;
import org.springframework.session.data.gemfire.serialization.SessionSerializer;
/**
* The {@link AbstractDataSerializableSessionSerializer} class...
*
* @author John Blum
* @see java.io.DataInput
* @see java.io.DataOutput
* @see org.apache.geode.DataSerializer
* @see org.springframework.session.data.gemfire.serialization.SessionSerializer
* @since 2.0.0
*/
public abstract class AbstractDataSerializableSessionSerializer<T> extends DataSerializer
implements SessionSerializer<T, DataInput, DataOutput> {
@Override
public int getId() {
return 0x0A11ACE5;
}
@Override
public Class<?>[] getSupportedClasses() {
return new Class[0];
}
@Override
@SuppressWarnings("unchecked")
public boolean canSerialize(Class<?> type) {
return stream(nullSafeArray(getSupportedClasses(), Class.class))
.anyMatch(supportedClass -> supportedClass.isAssignableFrom(type));
}
@Override
@SuppressWarnings("unchecked")
public boolean toData(Object session, DataOutput out) throws IOException {
return Optional.ofNullable(session)
.filter(this::canSerialize)
.map(it -> {
serialize((T) session, out);
return true;
})
.orElse(false);
}
@Override
public Object fromData(DataInput in) throws IOException, ClassNotFoundException {
return deserialize(in);
}
protected <T> T safeRead(DataInput in, DataInputReader<T> reader) {
try {
return reader.doRead(in);
}
catch (ClassNotFoundException | IOException cause) {
throw new SerializationException(cause);
}
}
protected void safeWrite(DataOutput out, DataOutputWriter writer) {
try {
writer.doWrite(out);
}
catch (IOException cause) {
throw new SerializationException(cause);
}
}
protected interface DataInputReader<T> {
T doRead(DataInput in) throws ClassNotFoundException, IOException;
}
protected interface DataOutputWriter {
void doWrite(DataOutput out) throws IOException;
}
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright 2017 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.session.data.gemfire.serialization.data.provider;
import static org.springframework.data.gemfire.util.ArrayUtils.asArray;
import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeSet;
import static org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes;
import java.io.DataInput;
import java.io.DataOutput;
import java.util.Set;
import org.apache.geode.DataSerializer;
import org.springframework.session.data.gemfire.serialization.data.AbstractDataSerializableSessionSerializer;
/**
* The {@link DataSerializableSessionAttributesSerializer} class...
*
* @author John Blum
* @since 2.0.0
*/
@SuppressWarnings("unused")
public class DataSerializableSessionAttributesSerializer
extends AbstractDataSerializableSessionSerializer<GemFireSessionAttributes> {
public static void register() {
register(DataSerializableSessionAttributesSerializer.class);
}
@Override
public int getId() {
return 0x8192ACE5;
}
@Override
public Class<?>[] getSupportedClasses() {
return asArray(GemFireSessionAttributes.class);
}
@Override
//@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
public void serialize(GemFireSessionAttributes sessionAttributes, DataOutput out) {
synchronized (sessionAttributes) {
Set<String> attributeNames = nullSafeSet(sessionAttributes.getAttributeNames());
safeWrite(out, output -> output.writeInt(attributeNames.size()));
attributeNames.forEach(attributeName -> {
safeWrite(out, output -> output.writeUTF(attributeName));
safeWrite(out, output -> writeObject(sessionAttributes.getAttribute(attributeName), output));
});
}
}
@Override
public GemFireSessionAttributes deserialize(DataInput in) {
GemFireSessionAttributes sessionAttributes = GemFireSessionAttributes.create();
for (int count = safeRead(in, DataInput::readInt); count > 0; count--) {
sessionAttributes.setAttribute(safeRead(in, DataInput::readUTF), safeRead(in, DataSerializer::readObject));
}
return sessionAttributes;
}
}

View File

@@ -0,0 +1,126 @@
/*
* Copyright 2017 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.session.data.gemfire.serialization.data.provider;
import static org.springframework.data.gemfire.util.ArrayUtils.asArray;
import java.io.DataInput;
import java.io.DataOutput;
import java.time.Duration;
import java.time.Instant;
import java.util.Collections;
import java.util.Set;
import org.apache.geode.DataSerializer;
import org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSession;
import org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes;
import org.springframework.session.data.gemfire.serialization.data.AbstractDataSerializableSessionSerializer;
import org.springframework.session.data.gemfire.support.AbstractSession;
import org.springframework.util.StringUtils;
/**
* The {@link DataSerializableSessionSerializer} class...
*
* @author John Blum
* @since 2.0.0
*/
@SuppressWarnings("unused")
public class DataSerializableSessionSerializer extends AbstractDataSerializableSessionSerializer<GemFireSession> {
public static void register() {
register(DataSerializableSessionSerializer.class);
DataSerializableSessionAttributesSerializer.register();
}
@Override
public int getId() {
return 0x4096ACE5;
}
@Override
public Class<?>[] getSupportedClasses() {
return asArray(GemFireSession.class);
}
@Override
//@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
public void serialize(GemFireSession session, DataOutput out) {
synchronized (session) {
safeWrite(out, output -> output.writeUTF(session.getId()));
safeWrite(out, output -> output.writeLong(session.getCreationTime().toEpochMilli()));
safeWrite(out, output -> output.writeLong(session.getLastAccessedTime().toEpochMilli()));
safeWrite(out, output -> output.writeLong(session.getMaxInactiveInterval().getSeconds()));
String principalName = session.getPrincipalName();
int length = (StringUtils.hasText(principalName) ? principalName.length() : 0);
safeWrite(out, output -> output.writeInt(length));
if (length > 0) {
safeWrite(out, output -> output.writeUTF(principalName));
}
safeWrite(out, output -> writeObject(session.getAttributes(), out));
}
}
@Override
public GemFireSession deserialize(DataInput in) {
GemFireSession session = GemFireSession.from(new AbstractSession() {
@Override
public String getId() {
return safeRead(in, DataInput::readUTF);
}
@Override
public Instant getCreationTime() {
return safeRead(in, in -> Instant.ofEpochMilli(in.readLong()));
}
@Override
public Instant getLastAccessedTime() {
return safeRead(in, in -> Instant.ofEpochMilli(in.readLong()));
}
@Override
public Duration getMaxInactiveInterval() {
return safeRead(in, in -> Duration.ofSeconds(in.readLong()));
}
@Override
public Set<String> getAttributeNames() {
return Collections.emptySet();
}
});
int principalNameLength = safeRead(in, DataInput::readInt);
if (principalNameLength > 0) {
session.setPrincipalName(safeRead(in, DataInput::readUTF));
}
session.getAttributes().from(this.<GemFireSessionAttributes>safeRead(in, DataSerializer::readObject));
return session;
}
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright 2017 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.session.data.gemfire.serialization.data.support;
import static org.springframework.data.gemfire.util.ArrayUtils.asArray;
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException;
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException;
import java.io.DataInput;
import java.io.DataOutput;
import java.util.Optional;
import javax.annotation.Resource;
import org.springframework.session.Session;
import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration;
import org.springframework.session.data.gemfire.serialization.SessionSerializer;
/**
* The DataSerializerSessionSerializerAdapter class...
*
* @author John Blum
* @since 2.0.0
*/
@SuppressWarnings("unused")
public class DataSerializerSessionSerializerAdapter<T extends Session> extends WirableDataSerializer<T> {
static {
register(DataSerializerSessionSerializerAdapter.class);
}
@Resource(name = "${" + GemFireHttpSessionConfiguration.SESSION_SERIALIZER_QUALIFIER_PROPERTY_NAME
+ ":" + GemFireHttpSessionConfiguration.SESSION_DATA_SERIALIZER_BEAN_NAME + "}")
private SessionSerializer<T, DataInput, DataOutput> sessionSerializer;
public DataSerializerSessionSerializerAdapter() {
autowire();
}
public DataSerializerSessionSerializerAdapter(SessionSerializer<T, DataInput, DataOutput> sessionSerializer) {
this.sessionSerializer = Optional.ofNullable(sessionSerializer)
.orElseThrow(() -> newIllegalArgumentException("SessionSerializer is required"));
}
@Override
public int getId() {
return 0x0BAC2BAC;
}
protected SessionSerializer<T, DataInput, DataOutput> getSessionSerializer() {
return Optional.ofNullable(this.sessionSerializer)
.orElseThrow(() -> newIllegalStateException("SessionSerializer was not properly configured"));
}
@Override
public Class<?>[] getSupportedClasses() {
return asArray(Session.class);
}
@Override
public void serialize(T session, DataOutput out) {
getSessionSerializer().serialize(session, out);
}
@Override
public T deserialize(DataInput in) {
return getSessionSerializer().deserialize(in);
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2017 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.session.data.gemfire.serialization.data.support;
import static org.springframework.data.gemfire.support.GemfireBeanFactoryLocator.newBeanFactoryLocator;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.wiring.BeanConfigurerSupport;
import org.springframework.session.data.gemfire.serialization.data.AbstractDataSerializableSessionSerializer;
/**
* The WirableDataSerializer class...
*
* @author John Blum
* @since 2.0.0
*/
public abstract class WirableDataSerializer<T> extends AbstractDataSerializableSessionSerializer<T> {
protected final void autowire() {
BeanConfigurerSupport beanConfigurer = newBeanConfigurer(locateBeanFactory());
beanConfigurer.configureBean(this);
beanConfigurer.destroy();
}
private BeanFactory locateBeanFactory() {
return newBeanFactoryLocator().useBeanFactory();
}
private BeanConfigurerSupport newBeanConfigurer(BeanFactory beanFactory) {
BeanConfigurerSupport beanConfigurer = new BeanConfigurerSupport();
beanConfigurer.setBeanFactory(beanFactory);
beanConfigurer.afterPropertiesSet();
return beanConfigurer;
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright 2017 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.session.data.gemfire.serialization.pdx;
import java.util.Optional;
import org.apache.geode.pdx.PdxReader;
import org.apache.geode.pdx.PdxSerializer;
import org.apache.geode.pdx.PdxWriter;
import org.springframework.session.Session;
import org.springframework.session.data.gemfire.serialization.SessionSerializer;
/**
* The {@link AbstractPdxSerializableSessionSerializer} class...
*
* @author John Blum
* @since 2.0.0
*/
public abstract class AbstractPdxSerializableSessionSerializer<T extends Session>
implements PdxSerializer, SessionSerializer<T, PdxReader, PdxWriter> {
@Override
public boolean canSerialize(Class<?> type) {
return Optional.ofNullable(type).map(Session.class::isAssignableFrom).orElse(false);
}
@Override
@SuppressWarnings("unchecked")
public boolean toData(Object session, PdxWriter writer) {
return Optional.ofNullable(session)
.filter(this::canSerialize)
.map(it -> {
serialize((T) session, writer);
return true;
})
.orElse(false);
}
@Override
public Object fromData(Class<?> type, PdxReader reader) {
return Optional.ofNullable(type)
.filter(this::canSerialize)
.map(it -> deserialize(reader))
.orElse(null);
}
}

View File

@@ -0,0 +1,99 @@
/*
* Copyright 2017 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.session.data.gemfire.serialization.pdx.provider;
import static org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSession;
import static org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes;
import java.time.Duration;
import java.time.Instant;
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
import org.apache.geode.pdx.PdxReader;
import org.apache.geode.pdx.PdxWriter;
import org.springframework.session.data.gemfire.serialization.pdx.AbstractPdxSerializableSessionSerializer;
import org.springframework.session.data.gemfire.support.AbstractSession;
/**
* The PdxSerializableSessionSerializer class...
*
* @author John Blum
* @since 1.0.0
*/
@SuppressWarnings("unused")
public class PdxSerializableSessionSerializer extends AbstractPdxSerializableSessionSerializer<GemFireSession> {
@Override
public boolean canSerialize(Class<?> type) {
return Optional.ofNullable(type).map(GemFireSession.class::isAssignableFrom).orElse(false);
}
@Override
@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
public void serialize(GemFireSession session, PdxWriter writer) {
synchronized (session) {
writer.writeString("id", session.getId());
writer.writeLong("creationTime", session.getCreationTime().toEpochMilli());
writer.writeLong("lastAccessedTime", session.getLastAccessedTime().toEpochMilli());
writer.writeLong("maxInactiveIntervalInSeconds", session.getMaxInactiveInterval().getSeconds());
writer.writeString("principalName", session.getPrincipalName());
writer.writeObject("attributes", session.getAttributes());
}
}
@Override
public GemFireSession deserialize(PdxReader reader) {
GemFireSession session = GemFireSession.from(new AbstractSession() {
@Override
public String getId() {
return reader.readString("id");
}
@Override
public Instant getCreationTime() {
return Instant.ofEpochMilli(reader.readLong("creationTime"));
}
@Override
public Instant getLastAccessedTime() {
return Instant.ofEpochMilli(reader.readLong("lastAccessedTime"));
}
@Override
public Duration getMaxInactiveInterval() {
return Duration.ofSeconds(reader.readLong("maxInactiveIntervalInSeconds"));
}
@Override
public Set<String> getAttributeNames() {
return Collections.emptySet();
}
});
session.setPrincipalName(reader.readString("principalName"));
session.getAttributes().from((GemFireSessionAttributes) reader.readObject("attributes"));
return session;
}
}

View File

@@ -0,0 +1,98 @@
/*
* Copyright 2017 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.session.data.gemfire.serialization.pdx.support;
import static java.util.stream.StreamSupport.stream;
import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray;
import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeIterable;
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.geode.pdx.PdxReader;
import org.apache.geode.pdx.PdxSerializer;
import org.apache.geode.pdx.PdxWriter;
/**
* The ComposablePdxSerializer class...
*
* @author John Blum
* @since 1.0.0
*/
@SuppressWarnings("unused")
public class ComposablePdxSerializer implements Iterable<PdxSerializer>, PdxSerializer {
private final List<PdxSerializer> pdxSerializers;
private ComposablePdxSerializer(List<PdxSerializer> pdxSerializers) {
this.pdxSerializers = Optional.ofNullable(pdxSerializers)
.map(it -> Collections.unmodifiableList(pdxSerializers))
.orElseThrow(() -> newIllegalArgumentException("PdxSerializers [%s] are required", pdxSerializers));
}
public static PdxSerializer compose(PdxSerializer... pdxSerializers) {
return compose(Arrays.asList(nullSafeArray(pdxSerializers, PdxSerializer.class)));
}
public static PdxSerializer compose(Iterable<PdxSerializer> pdxSerializers) {
List<PdxSerializer> pdxSerializerList =
stream(nullSafeIterable(pdxSerializers).spliterator(), false).collect(Collectors.toList());
return (pdxSerializerList.isEmpty() ? null
: (pdxSerializerList.size() == 1 ? pdxSerializerList.get(0)
: new ComposablePdxSerializer(pdxSerializerList)));
}
@Override
public Iterator<PdxSerializer> iterator() {
return this.pdxSerializers.iterator();
}
@Override
public boolean toData(Object obj, PdxWriter out) {
for (PdxSerializer pdxSerializer : this) {
if (pdxSerializer.toData(obj, out)) {
return true;
}
}
return false;
}
@Override
public Object fromData(Class<?> type, PdxReader in) {
for (PdxSerializer pdxSerializer : this) {
Object obj = pdxSerializer.fromData(type, in);
if (obj != null) {
return obj;
}
}
return null;
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2017 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.session.data.gemfire.serialization.pdx.support;
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException;
import java.util.Optional;
import org.apache.geode.pdx.PdxReader;
import org.apache.geode.pdx.PdxWriter;
import org.springframework.session.Session;
import org.springframework.session.data.gemfire.serialization.SessionSerializer;
import org.springframework.session.data.gemfire.serialization.pdx.AbstractPdxSerializableSessionSerializer;
/**
* The {@link PdxSerializerSessionSerializerAdapter} class...
*
* @author John Blum
* @since 2.0.0
*/
@SuppressWarnings("unused")
public class PdxSerializerSessionSerializerAdapter<T extends Session>
extends AbstractPdxSerializableSessionSerializer<T> {
private final SessionSerializer<T, PdxReader, PdxWriter> sessionSerializer;
public PdxSerializerSessionSerializerAdapter(SessionSerializer<T, PdxReader, PdxWriter> sessionSerializer) {
this.sessionSerializer = Optional.ofNullable(sessionSerializer)
.orElseThrow(() -> newIllegalArgumentException("SessionSerializer is required"));
}
protected SessionSerializer<T, PdxReader, PdxWriter> getSessionSerializer() {
return this.sessionSerializer;
}
@Override
public void serialize(T session, PdxWriter writer) {
getSessionSerializer().serialize(session, writer);
}
@Override
public T deserialize(PdxReader reader) {
return getSessionSerializer().deserialize(reader);
}
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright 2017 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.session.data.gemfire.support;
import java.time.Duration;
import java.time.Instant;
import java.util.Set;
import org.springframework.session.Session;
/**
* The AbstractSession class...
*
* @author John Blum
* @since 1.0.0
*/
public class AbstractSession implements Session {
@Override
public String getId() {
throw new UnsupportedOperationException("Not Implemented");
}
@Override
public void setAttribute(String attributeName, Object attributeValue) {
throw new UnsupportedOperationException("Not Implemented");
}
@Override
public <T> T getAttribute(String attributeName) {
throw new UnsupportedOperationException("Not Implemented");
}
@Override
public <T> T getAttributeOrDefault(String name, T defaultValue) {
throw new UnsupportedOperationException("Not Implemented");
}
@Override
public <T> T getRequiredAttribute(String name) {
throw new UnsupportedOperationException("Not Implemented");
}
@Override
public Set<String> getAttributeNames() {
throw new UnsupportedOperationException("Not Implemented");
}
@Override
public boolean isExpired() {
throw new UnsupportedOperationException("Not Implemented");
}
@Override
public Instant getCreationTime() {
throw new UnsupportedOperationException("Not Implemented");
}
@Override
public void setLastAccessedTime(Instant lastAccessedTime) {
throw new UnsupportedOperationException("Not Implemented");
}
@Override
public Instant getLastAccessedTime() {
throw new UnsupportedOperationException("Not Implemented");
}
@Override
public void setMaxInactiveInterval(Duration interval) {
throw new UnsupportedOperationException("Not Implemented");
}
@Override
public Duration getMaxInactiveInterval() {
throw new UnsupportedOperationException("Not Implemented");
}
@Override
public String changeSessionId() {
throw new UnsupportedOperationException("Not Implemented");
}
@Override
public void removeAttribute(String attributeName) {
throw new UnsupportedOperationException("Not Implemented");
}
}

View File

@@ -157,7 +157,7 @@ public class GemFireHttpSessionConfigurationTest {
public void setAndGetPoolName() {
assertThat(this.gemfireConfiguration.getPoolName()).isEqualTo(
GemFireHttpSessionConfiguration.DEFAULT_GEMFIRE_POOL_NAME);
GemFireHttpSessionConfiguration.DEFAULT_POOL_NAME);
this.gemfireConfiguration.setPoolName("TestPoolName");
@@ -166,17 +166,17 @@ public class GemFireHttpSessionConfigurationTest {
this.gemfireConfiguration.setPoolName(" ");
assertThat(this.gemfireConfiguration.getPoolName()).isEqualTo(
GemFireHttpSessionConfiguration.DEFAULT_GEMFIRE_POOL_NAME);
GemFireHttpSessionConfiguration.DEFAULT_POOL_NAME);
this.gemfireConfiguration.setPoolName("");
assertThat(this.gemfireConfiguration.getPoolName()).isEqualTo(
GemFireHttpSessionConfiguration.DEFAULT_GEMFIRE_POOL_NAME);
GemFireHttpSessionConfiguration.DEFAULT_POOL_NAME);
this.gemfireConfiguration.setPoolName(null);
assertThat(this.gemfireConfiguration.getPoolName()).isEqualTo(
GemFireHttpSessionConfiguration.DEFAULT_GEMFIRE_POOL_NAME);
GemFireHttpSessionConfiguration.DEFAULT_POOL_NAME);
}
@Test
@@ -199,27 +199,27 @@ public class GemFireHttpSessionConfigurationTest {
@Test
public void setAndGetSpringSessionGemFireRegionName() {
assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()).isEqualTo(
GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME);
assertThat(this.gemfireConfiguration.getSessionRegionName()).isEqualTo(
GemFireHttpSessionConfiguration.DEFAULT_SESSION_REGION_NAME);
this.gemfireConfiguration.setSpringSessionGemFireRegionName("test");
this.gemfireConfiguration.setSessionRegionName("test");
assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()).isEqualTo("test");
assertThat(this.gemfireConfiguration.getSessionRegionName()).isEqualTo("test");
this.gemfireConfiguration.setSpringSessionGemFireRegionName(" ");
this.gemfireConfiguration.setSessionRegionName(" ");
assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()).isEqualTo(
GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME);
assertThat(this.gemfireConfiguration.getSessionRegionName()).isEqualTo(
GemFireHttpSessionConfiguration.DEFAULT_SESSION_REGION_NAME);
this.gemfireConfiguration.setSpringSessionGemFireRegionName("");
this.gemfireConfiguration.setSessionRegionName("");
assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()).isEqualTo(
GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME);
assertThat(this.gemfireConfiguration.getSessionRegionName()).isEqualTo(
GemFireHttpSessionConfiguration.DEFAULT_SESSION_REGION_NAME);
this.gemfireConfiguration.setSpringSessionGemFireRegionName(null);
this.gemfireConfiguration.setSessionRegionName(null);
assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()).isEqualTo(
GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME);
assertThat(this.gemfireConfiguration.getSessionRegionName()).isEqualTo(
GemFireHttpSessionConfiguration.DEFAULT_SESSION_REGION_NAME);
}
@Test
@@ -246,7 +246,7 @@ public class GemFireHttpSessionConfigurationTest {
assertThat(this.gemfireConfiguration.getMaxInactiveIntervalInSeconds()).isEqualTo(600);
assertThat(this.gemfireConfiguration.getPoolName()).isEqualTo("TestPool");
assertThat(this.gemfireConfiguration.getServerRegionShortcut()).isEqualTo(RegionShortcut.REPLICATE);
assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()).isEqualTo("TEST");
assertThat(this.gemfireConfiguration.getSessionRegionName()).isEqualTo("TEST");
verify(mockAnnotationMetadata, times(1)).getAnnotationAttributes(eq(EnableGemFireHttpSession.class.getName()));
}
@@ -276,11 +276,11 @@ public class GemFireHttpSessionConfigurationTest {
given(mockGemFireCache.getRegion(eq("Example"))).willReturn(mockRegion);
this.gemfireConfiguration.setSpringSessionGemFireRegionName("Example");
this.gemfireConfiguration.setSessionRegionName("Example");
GemfireTemplate template = this.gemfireConfiguration.sessionRegionTemplate(mockGemFireCache);
assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()).isEqualTo("Example");
assertThat(this.gemfireConfiguration.getSessionRegionName()).isEqualTo("Example");
assertThat(template).isNotNull();
assertThat(template.getRegion()).isSameAs(mockRegion);
@@ -298,7 +298,7 @@ public class GemFireHttpSessionConfigurationTest {
this.gemfireConfiguration.setClientRegionShortcut(ClientRegionShortcut.CACHING_PROXY);
this.gemfireConfiguration.setPoolName("TestPool");
this.gemfireConfiguration.setServerRegionShortcut(RegionShortcut.REPLICATE_PERSISTENT);
this.gemfireConfiguration.setSpringSessionGemFireRegionName("TestRegion");
this.gemfireConfiguration.setSessionRegionName("TestRegion");
GemFireCacheTypeAwareRegionFactoryBean<Object, Session> sessionRegionFactoryBean =
this.gemfireConfiguration.sessionRegion(mockGemFireCache, mockRegionAttributes);
@@ -339,9 +339,9 @@ public class GemFireHttpSessionConfigurationTest {
assertThat(sessionRegionAttributes).isNotNull();
assertThat(sessionRegionAttributes.getKeyConstraint()).isEqualTo(
GemFireHttpSessionConfiguration.SPRING_SESSION_GEMFIRE_REGION_KEY_CONSTRAINT);
GemFireHttpSessionConfiguration.SESSION_REGION_KEY_CONSTRAINT);
assertThat(sessionRegionAttributes.getValueConstraint()).isEqualTo(
GemFireHttpSessionConfiguration.SPRING_SESSION_GEMFIRE_REGION_VALUE_CONSTRAINT);
GemFireHttpSessionConfiguration.SESSION_REGION_VALUE_CONSTRAINT);
ExpirationAttributes entryIdleTimeoutExpiration = sessionRegionAttributes.getEntryIdleTimeout();
@@ -369,9 +369,9 @@ public class GemFireHttpSessionConfigurationTest {
assertThat(sessionRegionAttributes).isNotNull();
assertThat(sessionRegionAttributes.getKeyConstraint()).isEqualTo(
GemFireHttpSessionConfiguration.SPRING_SESSION_GEMFIRE_REGION_KEY_CONSTRAINT);
GemFireHttpSessionConfiguration.SESSION_REGION_KEY_CONSTRAINT);
assertThat(sessionRegionAttributes.getValueConstraint()).isEqualTo(
GemFireHttpSessionConfiguration.SPRING_SESSION_GEMFIRE_REGION_VALUE_CONSTRAINT);
GemFireHttpSessionConfiguration.SESSION_REGION_VALUE_CONSTRAINT);
ExpirationAttributes entryIdleTimeoutExpiration = sessionRegionAttributes.getEntryIdleTimeout();

View File

@@ -243,7 +243,7 @@ public class GemFireCacheTypeAwareRegionFactoryBeanTest {
public void setAndGetPoolName() {
assertThat(this.regionFactoryBean.getPoolName()).isEqualTo(
GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_GEMFIRE_POOL_NAME);
GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_POOL_NAME);
this.regionFactoryBean.setPoolName("TestPoolName");
@@ -252,17 +252,17 @@ public class GemFireCacheTypeAwareRegionFactoryBeanTest {
this.regionFactoryBean.setPoolName(" ");
assertThat(this.regionFactoryBean.getPoolName()).isEqualTo(
GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_GEMFIRE_POOL_NAME);
GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_POOL_NAME);
this.regionFactoryBean.setPoolName("");
assertThat(this.regionFactoryBean.getPoolName()).isEqualTo(
GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_GEMFIRE_POOL_NAME);
GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_POOL_NAME);
this.regionFactoryBean.setPoolName(null);
assertThat(this.regionFactoryBean.getPoolName()).isEqualTo(
GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_GEMFIRE_POOL_NAME);
GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_POOL_NAME);
}
@Test
@@ -286,7 +286,7 @@ public class GemFireCacheTypeAwareRegionFactoryBeanTest {
public void setAndGetRegionName() {
assertThat(this.regionFactoryBean.getRegionName()).isEqualTo(
GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME);
GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SESSION_REGION_NAME);
this.regionFactoryBean.setRegionName("Example");
@@ -295,17 +295,17 @@ public class GemFireCacheTypeAwareRegionFactoryBeanTest {
this.regionFactoryBean.setRegionName(" ");
assertThat(this.regionFactoryBean.getRegionName()).isEqualTo(
GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME);
GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SESSION_REGION_NAME);
this.regionFactoryBean.setRegionName("");
assertThat(this.regionFactoryBean.getRegionName()).isEqualTo(
GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME);
GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SESSION_REGION_NAME);
this.regionFactoryBean.setRegionName(null);
assertThat(this.regionFactoryBean.getRegionName()).isEqualTo(
GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME);
GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SESSION_REGION_NAME);
}
@Test

View File

@@ -21,6 +21,6 @@
<bean class="org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration"
p:indexableSessionAttributes="one, two, three" p:maxInactiveIntervalInSeconds="3600"
p:serverRegionShortcut="#{T(org.apache.geode.cache.RegionShortcut).LOCAL}"
p:springSessionGemFireRegionName="XmlExample"/>
p:sessionRegionName="XmlExample"/>
</beans>