Refactor GemFireHttpSessionConfiguration to always set a Region Entry Idle Timeout (TTI) Expiration Policy regardless if the user provided her own custom, Region Entry Idle Timeout (TTI) Expiration Policy.

Resolves gh-5.
This commit is contained in:
John Blum
2018-10-23 14:14:56 -07:00
parent 7c5a7da9ea
commit bff54fa08a
2 changed files with 88 additions and 49 deletions

View File

@@ -26,6 +26,8 @@ import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.apache.geode.cache.ExpirationAction;
import org.apache.geode.cache.ExpirationAttributes;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionAttributes;
@@ -47,6 +49,8 @@ import org.springframework.util.ReflectionUtils;
*
* @author John Blum
* @see org.junit.Test
* @see org.apache.geode.cache.ExpirationAction
* @see org.apache.geode.cache.ExpirationAttributes
* @see org.apache.geode.cache.Region
* @see org.apache.geode.cache.RegionAttributes
* @see org.springframework.context.annotation.Bean
@@ -90,7 +94,7 @@ public class CustomSessionExpirationConfigurationIntegrationTests {
}
@Test
public void regionIdleTimeoutExpirationConfigurationIsCorrect() throws Exception {
public void regionCustomEntryIdleTimeoutExpirationConfigurationIsCorrect() throws Exception {
assertThat(this.sessions).isNotNull();
@@ -100,11 +104,30 @@ public class CustomSessionExpirationConfigurationIntegrationTests {
assertThat(sessionRegionAttributes.getCustomEntryIdleTimeout())
.isInstanceOf(SessionExpirationPolicyCustomExpiryAdapter.class);
SessionExpirationPolicyCustomExpiryAdapter adapter =
SessionExpirationPolicyCustomExpiryAdapter customEntryIdleTimeout =
(SessionExpirationPolicyCustomExpiryAdapter) sessionRegionAttributes.getCustomEntryIdleTimeout();
assertThat(this.<SessionExpirationPolicy>invokeMethod(adapter, "getSessionExpirationPolicy"))
.isEqualTo(this.sessionExpirationPolicy);
SessionExpirationPolicy actualSessionExpirationPolicy =
invokeMethod(customEntryIdleTimeout, "getSessionExpirationPolicy");
assertThat(actualSessionExpirationPolicy).isEqualTo(this.sessionExpirationPolicy);
}
@Test
public void regionEntryIdleTimeoutExpirationConfigurationIsCorrect() {
assertThat(this.sessions).isNotNull();
RegionAttributes<String, Object> sessionRegionAttributes = this.sessions.getAttributes();
assertThat(sessionRegionAttributes).isNotNull();
ExpirationAttributes entryIdleTimeout = sessionRegionAttributes.getEntryIdleTimeout();
assertThat(entryIdleTimeout).isNotNull();
assertThat(entryIdleTimeout.getTimeout()).isEqualTo(600);
assertThat(entryIdleTimeout.getAction()).isEqualTo(ExpirationAction.INVALIDATE);
}
@PeerCacheApplication

View File

@@ -81,8 +81,11 @@ import org.springframework.util.StringUtils;
* {@link javax.servlet.http.HttpSession} provider implementation in Spring {@link Session}.
*
* @author John Blum
* @see java.time.Duration
* @see org.apache.geode.DataSerializer
* @see org.apache.geode.cache.Cache
* @see org.apache.geode.cache.ExpirationAttributes
* @see org.apache.geode.cache.GemFireCache
* @see org.apache.geode.cache.Region
* @see org.apache.geode.cache.RegionAttributes
* @see org.apache.geode.cache.RegionShortcut
@@ -411,6 +414,8 @@ public class GemFireHttpSessionConfiguration extends AbstractGemFireHttpSessionC
* Callback with the {@link AnnotationMetadata} of the class containing {@link Import @Import} annotation
* that imported this {@link Configuration @Configuration} class.
*
* The {@link Configuration @Configuration} class should have been annotated with {@link EnableGemFireHttpSession}.
*
* @param importMetadata {@link AnnotationMetadata} of the application class importing
* this {@link Configuration} class.
* @see org.springframework.core.type.AnnotationMetadata
@@ -461,6 +466,7 @@ public class GemFireHttpSessionConfiguration extends AbstractGemFireHttpSessionC
}
private void configurePoolName(AnnotationAttributes enableGemFireHttpSessionAttributes) {
String defaultPoolName = enableGemFireHttpSessionAttributes.getString("poolName");
setPoolName(resolveProperty(poolNamePropertyName(), defaultPoolName));
@@ -471,8 +477,8 @@ public class GemFireHttpSessionConfiguration extends AbstractGemFireHttpSessionC
RegionShortcut defaultServerRegionShortcut =
enableGemFireHttpSessionAttributes.getEnum("serverRegionShortcut");
setServerRegionShortcut(resolveProperty(serverRegionShortcutPropertyName(),
RegionShortcut.class, defaultServerRegionShortcut));
setServerRegionShortcut(resolveProperty(serverRegionShortcutPropertyName(), RegionShortcut.class,
defaultServerRegionShortcut));
}
private void configureSessionExpirationPolicyBeanName(AnnotationAttributes enableGemFireHttpSessionAttributes) {
@@ -500,6 +506,20 @@ public class GemFireHttpSessionConfiguration extends AbstractGemFireHttpSessionC
defaultSessionSerializerBeanName));
}
private void applySpringSessionGemFireConfigurer() {
resolveSpringSessionGemFireConfigurer().ifPresent(configurer -> {
setClientRegionShortcut(configurer.getClientRegionShortcut());
setIndexableSessionAttributes(configurer.getIndexableSessionAttributes());
setMaxInactiveIntervalInSeconds(configurer.getMaxInactiveIntervalInSeconds());
setPoolName(configurer.getPoolName());
setServerRegionShortcut(configurer.getServerRegionShortcut());
setSessionRegionName(configurer.getRegionName());
setSessionExpirationPolicyBeanName(configurer.getSessionExpirationPolicyBeanName());
setSessionSerializerBeanName(configurer.getSessionSerializerBeanName());
});
}
private Optional<SpringSessionGemFireConfigurer> resolveSpringSessionGemFireConfigurer() {
try {
@@ -519,20 +539,6 @@ public class GemFireHttpSessionConfiguration extends AbstractGemFireHttpSessionC
return (!(cause instanceof NoUniqueBeanDefinitionException) && cause instanceof NoSuchBeanDefinitionException);
}
private void applySpringSessionGemFireConfigurer() {
resolveSpringSessionGemFireConfigurer().ifPresent(configurer -> {
setClientRegionShortcut(configurer.getClientRegionShortcut());
setIndexableSessionAttributes(configurer.getIndexableSessionAttributes());
setMaxInactiveIntervalInSeconds(configurer.getMaxInactiveIntervalInSeconds());
setPoolName(configurer.getPoolName());
setServerRegionShortcut(configurer.getServerRegionShortcut());
setSessionRegionName(configurer.getRegionName());
setSessionExpirationPolicyBeanName(configurer.getSessionExpirationPolicyBeanName());
setSessionSerializerBeanName(configurer.getSessionSerializerBeanName());
});
}
@PostConstruct
public void init() {
getBeanFactory().registerAlias(getSessionSerializerBeanName(), SESSION_SERIALIZER_BEAN_ALIAS);
@@ -546,6 +552,26 @@ public class GemFireHttpSessionConfiguration extends AbstractGemFireHttpSessionC
return new SessionExpirationTimeoutAwareBeanPostProcessor(expirationTimeout);
}
@Bean
BeanPostProcessor sessionSerializerConfigurationBeanPostProcessor() {
return new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof CacheFactoryBean) {
SessionSerializer sessionSerializer = resolveSessionSerializer();
configureSerialization((CacheFactoryBean) bean, sessionSerializer);
}
return bean;
}
};
}
private Optional<SessionExpirationPolicy> resolveSessionExpirationPolicy() {
Optional<String> sessionExpirationPolicyBeanName = getSessionExpirationPolicyBeanName();
@@ -568,26 +594,6 @@ public class GemFireHttpSessionConfiguration extends AbstractGemFireHttpSessionC
return Optional.empty();
}
@Bean
BeanPostProcessor sessionSerializerConfigurationBeanPostProcessor() {
return new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof CacheFactoryBean) {
SessionSerializer sessionSerializer = resolveSessionSerializer();
configureSerialization((CacheFactoryBean) bean, sessionSerializer);
}
return bean;
}
};
}
private SessionSerializer resolveSessionSerializer() {
return getApplicationContext().getBean(SESSION_SERIALIZER_BEAN_ALIAS, SessionSerializer.class);
}
@@ -623,11 +629,25 @@ public class GemFireHttpSessionConfiguration extends AbstractGemFireHttpSessionC
}
}
/**
* {@link SessionSerializer} bean implemented with Apache Geode/Pivotal GemFire DataSerialization framework.
*
* @return a DataSerialization {@link SessionSerializer} implementation.
* @see org.springframework.session.data.gemfire.serialization.data.provider.DataSerializableSessionSerializer
* @see org.springframework.session.data.gemfire.serialization.SessionSerializer
*/
@Bean(SESSION_DATA_SERIALIZER_BEAN_NAME)
public Object sessionDataSerializer() {
return new DataSerializableSessionSerializer();
}
/**
* {@link SessionSerializer} bean implemented with Apache Geode/Pivotal GemFire PDX serialization framework.
*
* @return a PDX serialization {@link SessionSerializer} implementation.
* @see org.springframework.session.data.gemfire.serialization.pdx.provider.PdxSerializableSessionSerializer
* @see org.springframework.session.data.gemfire.serialization.SessionSerializer
*/
@Bean(SESSION_PDX_SERIALIZER_BEAN_NAME)
public Object sessionPdxSerializer() {
return new PdxSerializableSessionSerializer();
@@ -693,16 +713,12 @@ public class GemFireHttpSessionConfiguration extends AbstractGemFireHttpSessionC
regionAttributes.setStatisticsEnabled(true);
Optional<SessionExpirationPolicy> sessionExpirationPolicy = resolveSessionExpirationPolicy();
regionAttributes.setEntryIdleTimeout(new ExpirationAttributes(
Math.max(getMaxInactiveIntervalInSeconds(), 0), ExpirationAction.INVALIDATE));
if (sessionExpirationPolicy.isPresent()) {
regionAttributes.setCustomEntryIdleTimeout(new SessionExpirationPolicyCustomExpiryAdapter(
sessionExpirationPolicy.get()));
}
else {
regionAttributes.setEntryIdleTimeout(new ExpirationAttributes(
Math.max(getMaxInactiveIntervalInSeconds(), 0), ExpirationAction.INVALIDATE));
}
resolveSessionExpirationPolicy()
.map(SessionExpirationPolicyCustomExpiryAdapter::new)
.ifPresent(regionAttributes::setCustomEntryIdleTimeout);
}
else {
getLogger().info("Expiration is not allowed on Regions with a data management policy of {}",