Introduce usingDataSerialization boolean flag fixing bug when DataSerializer is not the DataSerializableSessionSerializer provided by SSDG.

Rename exposeSpringSessionGemFireConfigurationAsProperties() to exposeSpringSessionGemFireConfiguration().
This commit is contained in:
John Blum
2018-12-06 01:04:55 -08:00
parent 50827c21cb
commit 308bf0e6b7
3 changed files with 226 additions and 8 deletions

View File

@@ -0,0 +1,192 @@
/*
* Copyright 2018 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.config.annotation.web.http;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray;
import java.io.DataInput;
import java.io.DataOutput;
import java.util.Arrays;
import org.junit.Test;
import org.apache.geode.DataSerializer;
import org.apache.geode.cache.GemFireCache;
import org.apache.geode.internal.InternalDataSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.data.gemfire.config.annotation.ClientCacheApplication;
import org.springframework.data.gemfire.tests.integration.SpringApplicationContextIntegrationTestsSupport;
import org.springframework.data.gemfire.tests.mock.annotation.EnableGemFireMockObjects;
import org.springframework.session.data.gemfire.serialization.SessionSerializer;
import org.springframework.session.data.gemfire.serialization.data.AbstractDataSerializableSessionSerializer;
import org.springframework.session.data.gemfire.serialization.data.provider.DataSerializableSessionSerializer;
import org.springframework.session.data.gemfire.serialization.pdx.support.PdxSerializerSessionSerializerAdapter;
/**
* The GemFireHttpSessionConfigurationIntegrationTests class...
*
* @author John Blum
* @since 1.0.0
*/
@SuppressWarnings("unused")
public class GemFireHttpSessionConfigurationIntegrationTests extends SpringApplicationContextIntegrationTestsSupport {
private void assertDataSerializerRegistered(DataSerializer dataSerializer) {
assertDataSerializerRegistered(dataSerializer.getClass());
}
private void assertDataSerializerRegistered(Class<? extends DataSerializer> dataSerializerType) {
assertThat(Arrays.stream(nullSafeArray(InternalDataSerializer.getSerializers(), DataSerializer.class))
.map(Object::getClass)
.filter(dataSerializerType::isAssignableFrom)
.findFirst()
.orElse(null)).isNotNull();
}
private void testUsesDataSerialization(Class<? extends DataSerializer> expectedDataSerializerType) {
GemFireHttpSessionConfiguration configuration =
getApplicationContext().getBean(GemFireHttpSessionConfiguration.class);
assertThat(configuration).isNotNull();
assertThat(configuration.isUsingDataSerialization()).isTrue();
GemFireCache gemfireCache = getApplicationContext().getBean(GemFireCache.class);
assertThat(gemfireCache).isNotNull();
assertThat(gemfireCache.getPdxSerializer()).isNull();
DataSerializer dataSerializer =
getApplicationContext().getBean(configuration.getSessionSerializerBeanName(), expectedDataSerializerType);
assertThat(dataSerializer).isInstanceOf(expectedDataSerializerType);
assertDataSerializerRegistered(dataSerializer);
}
@Test
public void usesDataSerializationWhenDataSerializableSessionSerializerConfigured() {
newApplicationContext(DataSerializableSessionSerializerConfiguration.class);
testUsesDataSerialization(DataSerializableSessionSerializer.class);
}
@Test
public void usesDataSerializationWhenTestDataSerializerConfigured() {
newApplicationContext(TestDataSerializerConfiguration.class);
testUsesDataSerialization(TestDataSerializer.class);
}
@Test
public void notUsingDataSerializationWhenPdxConfigured() {
newApplicationContext(TestSessionSerializerConfiguration.class);
GemFireHttpSessionConfiguration configuration =
getApplicationContext().getBean(GemFireHttpSessionConfiguration.class);
assertThat(configuration).isNotNull();
assertThat(configuration.isUsingDataSerialization()).isFalse();
GemFireCache gemfireCache = getApplicationContext().getBean(GemFireCache.class);
SessionSerializer testSessionSerializer =
getApplicationContext().getBean("TestSessionSerializer", SessionSerializer.class);
assertThat(gemfireCache).isNotNull();
assertThat(gemfireCache.getPdxSerializer()).isInstanceOf(PdxSerializerSessionSerializerAdapter.class);
assertThat(((PdxSerializerSessionSerializerAdapter<?>) gemfireCache.getPdxSerializer()).getSessionSerializer())
.isEqualTo(testSessionSerializer);
assertThat(Arrays.stream(nullSafeArray(InternalDataSerializer.getSerializers(), DataSerializer.class))
.filter(testSessionSerializer::equals)
.findAny()
.orElse(null)).isNull();
}
@ClientCacheApplication
@EnableGemFireMockObjects
@EnableGemFireHttpSession(
poolName = "DEFAULT",
sessionSerializerBeanName = GemFireHttpSessionConfiguration.SESSION_DATA_SERIALIZER_BEAN_NAME
)
static class DataSerializableSessionSerializerConfiguration { }
@ClientCacheApplication
@EnableGemFireMockObjects
@EnableGemFireHttpSession(poolName = "DEFAULT", sessionSerializerBeanName = "TestDataSerializer")
static class TestDataSerializerConfiguration {
@Bean("TestDataSerializer")
DataSerializer testDataSerializer() {
return new TestDataSerializer();
}
}
@ClientCacheApplication
@EnableGemFireMockObjects
@EnableGemFireHttpSession(poolName = "DEFAULT", sessionSerializerBeanName = "TestSessionSerializer")
static class TestSessionSerializerConfiguration {
@Bean("TestSessionSerializer")
SessionSerializer testSessionSerializer() {
return mock(SessionSerializer.class);
}
}
static class TestDataSerializer extends AbstractDataSerializableSessionSerializer<Object> {
@Override
public Class<?>[] getSupportedClasses() {
return new Class[] { Object.class };
}
@Override
public void serialize(Object session, DataOutput dataOutput) {
throw new UnsupportedOperationException("Not Implemented");
}
@Override
public Object deserialize(DataInput dataInput) {
throw new UnsupportedOperationException("Not Implemented");
}
}
static class TestSessionSerializer implements SessionSerializer<Object, DataInput, DataOutput> {
@Override
public void serialize(Object session, DataOutput dataOutput) {
throw new UnsupportedOperationException("Not Implemented");
}
@Override
public Object deserialize(DataInput dataInput) {
throw new UnsupportedOperationException("Not Implemented");
}
@Override
public boolean canSerialize(Class<?> type) {
return false;
}
}
}

View File

@@ -146,6 +146,12 @@ public class GemFireHttpSessionConfiguration extends AbstractGemFireHttpSessionC
*/
public static final boolean DEFAULT_EXPOSE_CONFIGURATION_AS_PROPERTIES = false;
/**
* Indicates whether to employ Apache Geode/Pivotal's DataSerialization framework
* for {@link Session} de/serialization.
*/
public static final boolean DEFAULT_USE_DATA_SERIALIZATION = false;
/**
* Default maximum interval in seconds in which a {@link Session} can remain inactive before it expires.
*/
@@ -233,6 +239,7 @@ public class GemFireHttpSessionConfiguration extends AbstractGemFireHttpSessionC
public static final String[] DEFAULT_INDEXABLE_SESSION_ATTRIBUTES = {};
private boolean exposeConfigurationAsProperties = DEFAULT_EXPOSE_CONFIGURATION_AS_PROPERTIES;
private boolean usingDataSerialization = DEFAULT_USE_DATA_SERIALIZATION;
private int maxInactiveIntervalInSeconds = DEFAULT_MAX_INACTIVE_INTERVAL_IN_SECONDS;
@@ -538,6 +545,17 @@ public class GemFireHttpSessionConfiguration extends AbstractGemFireHttpSessionC
.orElse(DEFAULT_SESSION_SERIALIZER_BEAN_NAME);
}
/**
* Set whether to use Apache Geode / Pivotal GemFire's DataSerialization framework
* for {@link Session} de/serialization.
*
* @param useDataSerialization boolean value indicating whether to use Apache Geode
* / Pivotal GemFire's DataSerialization framework for {@link Session} de/serialization.
*/
private void setUseDataSerialization(boolean useDataSerialization) {
this.usingDataSerialization = useDataSerialization;
}
/**
* Determine whether the configured serialization strategy is using Apache Geode / Pivotal GemFire's
* DataSerialization framework.
@@ -547,7 +565,9 @@ public class GemFireHttpSessionConfiguration extends AbstractGemFireHttpSessionC
* @see #getSessionSerializerBeanName()
*/
protected boolean isUsingDataSerialization() {
return SESSION_DATA_SERIALIZER_BEAN_NAME.equals(getSessionSerializerBeanName());
return this.usingDataSerialization
|| SESSION_DATA_SERIALIZER_BEAN_NAME.equals(getSessionSerializerBeanName());
}
/**
@@ -560,7 +580,7 @@ public class GemFireHttpSessionConfiguration extends AbstractGemFireHttpSessionC
* this {@link Configuration} class.
* @see org.springframework.core.type.AnnotationMetadata
* @see #applySpringSessionGemFireConfigurer()
* @see #exposeSpringSessionGemFireConfigurationAsProperties()
* @see #exposeSpringSessionGemFireConfiguration()
*/
public void setImportMetadata(AnnotationMetadata importMetadata) {
@@ -585,7 +605,7 @@ public class GemFireHttpSessionConfiguration extends AbstractGemFireHttpSessionC
// Expose configuration as {@link Properties} in the Spring {@link Environment}
// if {@link EnableGemFireHttpSession#exposeConfigurationAsProperties} is set to {@literal true}.
exposeSpringSessionGemFireConfigurationAsProperties();
exposeSpringSessionGemFireConfiguration();
}
private void configureClientRegionShortcut(AnnotationAttributes enableGemFireHttpSessionAttributes) {
@@ -786,7 +806,7 @@ public class GemFireHttpSessionConfiguration extends AbstractGemFireHttpSessionC
*
* @see #isExposeConfigurationAsProperties()
*/
void exposeSpringSessionGemFireConfigurationAsProperties() {
void exposeSpringSessionGemFireConfiguration() {
if (isExposeConfigurationAsProperties()) {
@@ -907,12 +927,15 @@ public class GemFireHttpSessionConfiguration extends AbstractGemFireHttpSessionC
private void configureSerialization(CacheFactoryBean cacheFactoryBean, SessionSerializer sessionSerializer) {
if (sessionSerializer instanceof DataSerializer) {
if (sessionSerializer instanceof DataSerializableSessionSerializer) {
DataSerializableSessionSerializer.register();
}
else {
DataSerializer.register(sessionSerializer.getClass());
}
setUseDataSerialization(true);
}
else if (sessionSerializer instanceof PdxSerializer) {
cacheFactoryBean.setPdxSerializer(ComposablePdxSerializer.compose(

View File

@@ -99,8 +99,11 @@ public class GemFireHttpSessionConfigurationTests {
private <T> T getField(Object obj, String fieldName) {
try {
Field field = resolveField(obj, fieldName);
field.setAccessible(true);
return (T) field.get(obj);
}
catch (NoSuchFieldException cause) {
@@ -538,7 +541,7 @@ public class GemFireHttpSessionConfigurationTests {
this.gemfireConfiguration.setSessionRegionName("Sessions");
this.gemfireConfiguration.setSessionSerializerBeanName("TestSessionSerializer");
this.gemfireConfiguration.setExposeConfigurationAsProperties(true);
this.gemfireConfiguration.exposeSpringSessionGemFireConfigurationAsProperties();
this.gemfireConfiguration.exposeSpringSessionGemFireConfiguration();
PropertySource springSessionGemFirePropertySource = environment.getPropertySources()
.get(GemFireHttpSessionConfiguration.SPRING_SESSION_GEMFIRE_PROPERTY_SOURCE);
@@ -593,7 +596,7 @@ public class GemFireHttpSessionConfigurationTests {
this.gemfireConfiguration.setEnvironment(null);
this.gemfireConfiguration.setExposeConfigurationAsProperties(true);
this.gemfireConfiguration.exposeSpringSessionGemFireConfigurationAsProperties();
this.gemfireConfiguration.exposeSpringSessionGemFireConfiguration();
verify(this.gemfireConfiguration, never()).getClientRegionShortcut();
verify(this.gemfireConfiguration, times(1)).getEnvironment();
@@ -614,7 +617,7 @@ public class GemFireHttpSessionConfigurationTests {
this.gemfireConfiguration.setEnvironment(mockEnvironment);
this.gemfireConfiguration.setExposeConfigurationAsProperties(false);
this.gemfireConfiguration.exposeSpringSessionGemFireConfigurationAsProperties();
this.gemfireConfiguration.exposeSpringSessionGemFireConfiguration();
verify(this.gemfireConfiguration, never()).getClientRegionShortcut();
verify(this.gemfireConfiguration, never()).getEnvironment();
@@ -636,7 +639,7 @@ public class GemFireHttpSessionConfigurationTests {
this.gemfireConfiguration.setEnvironment(mockEnvironment);
this.gemfireConfiguration.setExposeConfigurationAsProperties(true);
this.gemfireConfiguration.exposeSpringSessionGemFireConfigurationAsProperties();
this.gemfireConfiguration.exposeSpringSessionGemFireConfiguration();
verify(this.gemfireConfiguration, never()).getClientRegionShortcut();
verify(this.gemfireConfiguration, times(1)).getEnvironment();