From d2af4563c4181b1915a83198bbc9526987f06ef9 Mon Sep 17 00:00:00 2001 From: John Blum Date: Fri, 2 Nov 2018 15:06:45 -0700 Subject: [PATCH] Change the default behavior of SpringSessionGemFireConfigurer to only override configuration for configuration callback methods specifically implemented by users. Resolves gh-10. --- ...pSessionConfigurationIntegrationTests.java | 48 ++-- .../http/GemFireHttpSessionConfiguration.java | 147 ++++++++++-- ...ringSessionGemFireConfigurerUnitTests.java | 209 ++++++++++++++++++ 3 files changed, 375 insertions(+), 29 deletions(-) create mode 100644 spring-session-data-geode/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/SpringSessionGemFireConfigurerUnitTests.java diff --git a/spring-session-data-geode/src/integration-test/java/org/springframework/session/data/gemfire/config/annotation/web/http/ConfigurerBasedGemFireHttpSessionConfigurationIntegrationTests.java b/spring-session-data-geode/src/integration-test/java/org/springframework/session/data/gemfire/config/annotation/web/http/ConfigurerBasedGemFireHttpSessionConfigurationIntegrationTests.java index 650c9ca..346113b 100644 --- a/spring-session-data-geode/src/integration-test/java/org/springframework/session/data/gemfire/config/annotation/web/http/ConfigurerBasedGemFireHttpSessionConfigurationIntegrationTests.java +++ b/spring-session-data-geode/src/integration-test/java/org/springframework/session/data/gemfire/config/annotation/web/http/ConfigurerBasedGemFireHttpSessionConfigurationIntegrationTests.java @@ -26,6 +26,7 @@ import org.junit.Test; import org.apache.geode.cache.RegionShortcut; import org.apache.geode.cache.client.ClientRegionShortcut; +import org.apache.geode.cache.client.Pool; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ConfigurableApplicationContext; @@ -44,17 +45,24 @@ import org.springframework.session.data.gemfire.serialization.SessionSerializer; /** * Integration tests testing {@link SpringSessionGemFireConfigurer} based configuration of either Apache Geode - * or Pivotal GemFire * as the (HTTP) {@link Session} state management provider in Spring Session. + * or Pivotal GemFire as the (HTTP) {@link Session} state management provider in Spring Session. * * @author John Blum * @see org.junit.Test + * @see org.mockito.Mockito * @see org.springframework.context.ConfigurableApplicationContext * @see org.springframework.context.annotation.AnnotationConfigApplicationContext + * @see org.springframework.context.annotation.Bean + * @see org.springframework.context.annotation.Configuration + * @see org.springframework.context.support.PropertySourcesPlaceholderConfigurer * @see org.springframework.core.env.PropertySource * @see org.springframework.data.gemfire.config.annotation.ClientCacheApplication * @see org.springframework.data.gemfire.tests.mock.annotation.EnableGemFireMockObjects * @see org.springframework.mock.env.MockPropertySource + * @see org.springframework.session.Session + * @see org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests * @see org.springframework.session.data.gemfire.config.annotation.web.http.support.SpringSessionGemFireConfigurer + * @see org.springframework.session.data.gemfire.serialization.SessionSerializer * @since 2.0.4 */ @SuppressWarnings("unused") @@ -85,7 +93,7 @@ public class ConfigurerBasedGemFireHttpSessionConfigurationIntegrationTests { } @Test - public void springSessionGemFireConfigurerOverridesAnnotationAttributeAndPropertyConfiguration() { + public void onlySpringSessionGemFireConfigurerImplementedCallbacksOverrideAnnotationAttributesAndPropertyConfiguration() { MockPropertySource testPropertySource = new MockPropertySource("TestProperties") .withProperty("spring.session.data.gemfire.cache.client.pool.name", "Car") @@ -103,10 +111,10 @@ public class ConfigurerBasedGemFireHttpSessionConfigurationIntegrationTests { assertThat(sessionConfiguration).isNotNull(); assertThat(sessionConfiguration.getClientRegionShortcut()).isEqualTo(ClientRegionShortcut.CACHING_PROXY); - assertThat(sessionConfiguration.getIndexableSessionAttributes()).containsExactly("two", "four"); + assertThat(sessionConfiguration.getIndexableSessionAttributes()).containsExactly("firstName", "lastName"); assertThat(sessionConfiguration.getMaxInactiveIntervalInSeconds()).isEqualTo(3600); assertThat(sessionConfiguration.getPoolName()).isEqualTo("Dead"); - assertThat(sessionConfiguration.getServerRegionShortcut()).isEqualTo(RegionShortcut.PARTITION); + assertThat(sessionConfiguration.getServerRegionShortcut()).isEqualTo(RegionShortcut.REPLICATE_PERSISTENT_OVERFLOW); assertThat(sessionConfiguration.getSessionRegionName()).isEqualTo("ConfigurerRegionName"); assertThat(sessionConfiguration.getSessionSerializerBeanName()).isEqualTo("SessionPdxSerializer"); } @@ -115,16 +123,14 @@ public class ConfigurerBasedGemFireHttpSessionConfigurationIntegrationTests { public void usesPrimarySpringSessionGemFireConfigurerWhenPresent() { MockPropertySource testPropertySource = new MockPropertySource("TestProperties") - .withProperty("test.cache.client.region.shortcut", ClientRegionShortcut.CACHING_PROXY.name()) .withProperty("test.cache.client.pool.name", "Car") + .withProperty("test.cache.client.region.shortcut", ClientRegionShortcut.CACHING_PROXY.name()) .withProperty("test.session.expiration.max-inactive-interval-seconds", "300") .withProperty("test.session.region.name", "TestSessionRegionName") .withProperty("spring.session.data.gemfire.cache.client.region.shortcut", ClientRegionShortcut.LOCAL_PERSISTENT.name()) .withProperty("spring.session.data.gemfire.cache.server.region.shortcut", RegionShortcut.REPLICATE_PERSISTENT_OVERFLOW.name()) - .withProperty("spring.session.data.gemfire.session.attributes.indexable", "firstName, lastName") .withProperty("spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds", "120") .withProperty("spring.session.data.gemfire.session.region.name", "PropertyRegionName"); - //.withProperty("spring.session.data.gemfire.session.serializer.bean-name", "MockSessionSerializer"); this.applicationContext = newApplicationContext(testPropertySource, TestConfiguration.class, TestSpringSessionGemFireConfigurerConfiguration.class); @@ -134,7 +140,7 @@ public class ConfigurerBasedGemFireHttpSessionConfigurationIntegrationTests { assertThat(sessionConfiguration).isNotNull(); assertThat(sessionConfiguration.getClientRegionShortcut()).isEqualTo(ClientRegionShortcut.CACHING_PROXY); - assertThat(sessionConfiguration.getIndexableSessionAttributes()).isEmpty(); + assertThat(sessionConfiguration.getIndexableSessionAttributes()).containsExactly("one", "two"); assertThat(sessionConfiguration.getMaxInactiveIntervalInSeconds()).isEqualTo(300); assertThat(sessionConfiguration.getPoolName()).isEqualTo("Car"); assertThat(sessionConfiguration.getServerRegionShortcut()).isEqualTo(RegionShortcut.PARTITION_PERSISTENT); @@ -152,10 +158,10 @@ public class ConfigurerBasedGemFireHttpSessionConfigurationIntegrationTests { assertThat(sessionConfiguration).isNotNull(); assertThat(sessionConfiguration.getClientRegionShortcut()).isEqualTo(ClientRegionShortcut.CACHING_PROXY); - assertThat(sessionConfiguration.getIndexableSessionAttributes()).containsExactly("two", "four"); + assertThat(sessionConfiguration.getIndexableSessionAttributes()).containsExactly("one", "two"); assertThat(sessionConfiguration.getMaxInactiveIntervalInSeconds()).isEqualTo(3600); assertThat(sessionConfiguration.getPoolName()).isEqualTo("Dead"); - assertThat(sessionConfiguration.getServerRegionShortcut()).isEqualTo(RegionShortcut.PARTITION); + assertThat(sessionConfiguration.getServerRegionShortcut()).isEqualTo(RegionShortcut.REPLICATE); assertThat(sessionConfiguration.getSessionRegionName()).isEqualTo("ConfigurerRegionName"); assertThat(sessionConfiguration.getSessionSerializerBeanName()).isEqualTo("SessionPdxSerializer"); } @@ -173,6 +179,21 @@ public class ConfigurerBasedGemFireHttpSessionConfigurationIntegrationTests { ) static class TestConfiguration { + @Bean("Car") + Pool mockCarPool() { + return mock(Pool.class, "Car"); + } + + @Bean("Dead") + Pool mockDeadPool() { + return mock(Pool.class, "Dead"); + } + + @Bean("Swimming") + Pool mockSwimmingPool() { + return mock(Pool.class, "Swimming"); + } + @Bean("TestSessionSerializer") Object testSessionSerializer() { return mock(SessionSerializer.class); @@ -188,11 +209,6 @@ public class ConfigurerBasedGemFireHttpSessionConfigurationIntegrationTests { return ClientRegionShortcut.CACHING_PROXY; } - @Override - public String[] getIndexableSessionAttributes() { - return new String[] { "two", "four" }; - } - @Override public int getMaxInactiveIntervalInSeconds() { return 3600; @@ -229,7 +245,7 @@ public class ConfigurerBasedGemFireHttpSessionConfigurationIntegrationTests { @Primary SpringSessionGemFireConfigurer primarySpringSessionGemFireConfigurer( @Value("${test.cache.client.pool.name:geodePool}") String poolName, - @Value("${test.cache.client.region.shortcut:PROXY}") ClientRegionShortcut clientRegionShortcut, + @Value("${test.cache.client.region.shortcut:LOCAL}") ClientRegionShortcut clientRegionShortcut, @Value("${test.cache.server.region.shortcut:PARTITION_PERSISTENT}") RegionShortcut serverRegionShortcut, @Value("${test.session.expiration.max-inactive-interval-seconds:600}") int maxInactiveIntervalInSeconds, @Value("${test.session.region.name:MockSessionRegionName}") String regionName) { diff --git a/spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfiguration.java b/spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfiguration.java index d809c64..f48d7c2 100644 --- a/spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfiguration.java +++ b/spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfiguration.java @@ -16,8 +16,14 @@ package org.springframework.session.data.gemfire.config.annotation.web.http; +import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException; + +import java.lang.reflect.Method; +import java.util.Arrays; import java.util.Optional; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; +import java.util.function.Function; import javax.annotation.PostConstruct; @@ -130,6 +136,33 @@ public class GemFireHttpSessionConfiguration extends AbstractGemFireHttpSessionC */ public static final RegionShortcut DEFAULT_SERVER_REGION_SHORTCUT = RegionShortcut.PARTITION; + /** + * {@link SpringSessionGemFireConfigurer} {@link Class} {@link Method} {@link String Names} + */ + public static final String CONFIGURER_GET_CLIENT_REGION_SHORTCUT_METHOD_NAME = + findByMethodName(SpringSessionGemFireConfigurer.class, "getClientRegionShortcut"); + + public static final String CONFIGURER_GET_INDEXABLE_SESSION_ATTRIBUTES_METHOD_NAME = + findByMethodName(SpringSessionGemFireConfigurer.class, "getIndexableSessionAttributes"); + + public static final String CONFIGURER_GET_MAX_INACTIVE_INTERVAL_IN_SECONDS_METHOD_NAME = + findByMethodName(SpringSessionGemFireConfigurer.class, "getMaxInactiveIntervalInSeconds"); + + public static final String CONFIGURER_GET_POOL_NAME_METHOD_NAME = + findByMethodName(SpringSessionGemFireConfigurer.class, "getPoolName"); + + public static final String CONFIGURER_GET_REGION_NAME_METHOD_NAME = + findByMethodName(SpringSessionGemFireConfigurer.class, "getRegionName"); + + public static final String CONFIGURER_GET_SERVER_REGION_SHORTCUT_METHOD_NAME = + findByMethodName(SpringSessionGemFireConfigurer.class, "getServerRegionShortcut"); + + public static final String CONFIGURER_GET_SESSION_EXPIRATION_POLICY_BEAN_NAME_METHOD_NAME = + findByMethodName(SpringSessionGemFireConfigurer.class, "getSessionExpirationPolicyBeanName"); + + public static final String CONFIGURER_GET_SESSION_SERIALIZER_BEAN_NAME_METHOD_NAME = + findByMethodName(SpringSessionGemFireConfigurer.class, "getSessionSerializerBeanName"); + /** * Name of the connection {@link Pool} used by the client {@link Region} to send {@link Session} state * to the cluster of Apache Geode servers. @@ -169,6 +202,34 @@ public class GemFireHttpSessionConfiguration extends AbstractGemFireHttpSessionC private String[] indexableSessionAttributes = DEFAULT_INDEXABLE_SESSION_ATTRIBUTES; + private static String findByMethodName(Class type, String methodName) { + + return Arrays.stream(type.getDeclaredMethods()) + .map(Method::getName) + .filter(declaredMethodName -> declaredMethodName.startsWith(methodName)) + .findFirst() + .orElseThrow(() -> newIllegalArgumentException("No method with name [%1$s] was found on class [%2$s]", + methodName, type.getName())); + } + + private static Optional safeFindByMethodName(Class type, String methodName) { + + try { + return Optional.of(findByMethodName(type, methodName)); + } + catch (Throwable ignore) { + return Optional.empty(); + } + } + + private static boolean isOverriddenMethodPresent(Object target, String methodName) { + + return Optional.ofNullable(target) + .map(Object::getClass) + .flatMap(targetType -> safeFindByMethodName(targetType, methodName)) + .isPresent(); + } + /** * Gets the {@link ClientRegionShortcut} used to configure the data management policy of the {@link ClientCache} * {@link Region} that will store {@link Session} state. @@ -417,6 +478,79 @@ public class GemFireHttpSessionConfiguration extends AbstractGemFireHttpSessionC applySpringSessionGemFireConfigurer(); } + private void applySpringSessionGemFireConfigurer() { + + resolveSpringSessionGemFireConfigurer() + .map(this::applyClientRegionShortcut) + .map(this::applyIndexableSessionAttributes) + .map(this::applyMaxInactiveIntervalInSeconds) + .map(this::applyPoolName) + .map(this::applyServerRegionShortcut) + .map(this::applySessionRegionName) + .map(this::applySessionSerializerBeanName); + } + + private SpringSessionGemFireConfigurer applySpringSessionGemFireConfigurerConfiguration( + SpringSessionGemFireConfigurer configurer, String methodName, + Function getter, Consumer setter) { + + Optional.ofNullable(configurer) + .filter(it -> isOverriddenMethodPresent(configurer, methodName)) + .map(getter) + .ifPresent(setter); + + return configurer; + } + + private SpringSessionGemFireConfigurer applyClientRegionShortcut(SpringSessionGemFireConfigurer configurer) { + + return applySpringSessionGemFireConfigurerConfiguration(configurer, + CONFIGURER_GET_CLIENT_REGION_SHORTCUT_METHOD_NAME, + SpringSessionGemFireConfigurer::getClientRegionShortcut, this::setClientRegionShortcut); + } + + private SpringSessionGemFireConfigurer applyIndexableSessionAttributes(SpringSessionGemFireConfigurer configurer) { + + return applySpringSessionGemFireConfigurerConfiguration(configurer, + CONFIGURER_GET_INDEXABLE_SESSION_ATTRIBUTES_METHOD_NAME, + SpringSessionGemFireConfigurer::getIndexableSessionAttributes, this::setIndexableSessionAttributes); + } + + private SpringSessionGemFireConfigurer applyMaxInactiveIntervalInSeconds(SpringSessionGemFireConfigurer configurer) { + + return applySpringSessionGemFireConfigurerConfiguration(configurer, + CONFIGURER_GET_MAX_INACTIVE_INTERVAL_IN_SECONDS_METHOD_NAME, + SpringSessionGemFireConfigurer::getMaxInactiveIntervalInSeconds, this::setMaxInactiveIntervalInSeconds); + } + + private SpringSessionGemFireConfigurer applyPoolName(SpringSessionGemFireConfigurer configurer) { + + return applySpringSessionGemFireConfigurerConfiguration(configurer, + CONFIGURER_GET_POOL_NAME_METHOD_NAME, + SpringSessionGemFireConfigurer::getPoolName, this::setPoolName); + } + + private SpringSessionGemFireConfigurer applyServerRegionShortcut(SpringSessionGemFireConfigurer configurer) { + + return applySpringSessionGemFireConfigurerConfiguration(configurer, + CONFIGURER_GET_SERVER_REGION_SHORTCUT_METHOD_NAME, + SpringSessionGemFireConfigurer::getServerRegionShortcut, this::setServerRegionShortcut); + } + + private SpringSessionGemFireConfigurer applySessionRegionName(SpringSessionGemFireConfigurer configurer) { + + return applySpringSessionGemFireConfigurerConfiguration(configurer, + CONFIGURER_GET_REGION_NAME_METHOD_NAME, + SpringSessionGemFireConfigurer::getRegionName, this::setSessionRegionName); + } + + private SpringSessionGemFireConfigurer applySessionSerializerBeanName(SpringSessionGemFireConfigurer configurer) { + + return applySpringSessionGemFireConfigurerConfiguration(configurer, + CONFIGURER_GET_SESSION_SERIALIZER_BEAN_NAME_METHOD_NAME, + SpringSessionGemFireConfigurer::getSessionSerializerBeanName, this::setSessionSerializerBeanName); + } + private Optional resolveSpringSessionGemFireConfigurer() { try { @@ -436,19 +570,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()); - setSessionSerializerBeanName(configurer.getSessionSerializerBeanName()); - }); - } - @PostConstruct public void init() { getBeanFactory().registerAlias(getSessionSerializerBeanName(), SESSION_SERIALIZER_BEAN_ALIAS); diff --git a/spring-session-data-geode/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/SpringSessionGemFireConfigurerUnitTests.java b/spring-session-data-geode/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/SpringSessionGemFireConfigurerUnitTests.java new file mode 100644 index 0000000..e7ef8aa --- /dev/null +++ b/spring-session-data-geode/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/SpringSessionGemFireConfigurerUnitTests.java @@ -0,0 +1,209 @@ +/* + * 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.config.annotation.web.http.support; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.Test; + +import org.apache.geode.cache.RegionShortcut; +import org.apache.geode.cache.client.ClientRegionShortcut; + +import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration; + +/** + * Unit tests for {@link SpringSessionGemFireConfigurer}. + * + * @author John Blum + * @see org.junit.Test + * @see org.springframework.session.data.gemfire.config.annotation.web.http.support.SpringSessionGemFireConfigurer + * @since 2.1.1 + */ +public class SpringSessionGemFireConfigurerUnitTests { + + private SpringSessionGemFireConfigurer newTestConfigurerWithAllOverrides() { + + return new SpringSessionGemFireConfigurer() { + + @Override + public ClientRegionShortcut getClientRegionShortcut() { + return ClientRegionShortcut.LOCAL; + } + + @Override + public String[] getIndexableSessionAttributes() { + return new String[] { "fieldOne", "fieldTwo" }; + } + + @Override + public int getMaxInactiveIntervalInSeconds() { + return 300; + } + + @Override + public String getPoolName() { + return "MockPool"; + } + + @Override + public String getRegionName() { + return "MockRegion"; + } + + @Override + public RegionShortcut getServerRegionShortcut() { + return RegionShortcut.REPLICATE; + } + + @Override + public String getSessionExpirationPolicyBeanName() { + return "MockExpirationPolicy"; + } + + @Override + public String getSessionSerializerBeanName() { + return "MockSerializer"; + } + }; + } + + private SpringSessionGemFireConfigurer newTestConfigurerWithNoOverrides() { + return new SpringSessionGemFireConfigurer() { }; + } + + private SpringSessionGemFireConfigurer newTestConfigurerWithOverrides() { + + return new SpringSessionGemFireConfigurer() { + + @Override + public ClientRegionShortcut getClientRegionShortcut() { + return ClientRegionShortcut.CACHING_PROXY; + } + + @Override + public int getMaxInactiveIntervalInSeconds() { + return 600; + } + + @Override + public String getPoolName() { + return "TestPool"; + } + + @Override + public String getRegionName() { + return "TestRegion"; + } + }; + } + + @Test + public void classGetDeclaredMethodsOnCustomConfigurerObjectHasAllMethods() { + + SpringSessionGemFireConfigurer testConfigurer = newTestConfigurerWithAllOverrides(); + + assertThat(testConfigurer).isNotNull(); + assertThat(testConfigurer.getClientRegionShortcut()).isEqualTo(ClientRegionShortcut.LOCAL); + assertThat(testConfigurer.getIndexableSessionAttributes()).containsExactly("fieldOne", "fieldTwo"); + assertThat(testConfigurer.getMaxInactiveIntervalInSeconds()).isEqualTo(300); + assertThat(testConfigurer.getPoolName()).isEqualTo("MockPool"); + assertThat(testConfigurer.getRegionName()).isEqualTo("MockRegion"); + assertThat(testConfigurer.getServerRegionShortcut()).isEqualTo(RegionShortcut.REPLICATE); + assertThat(testConfigurer.getSessionExpirationPolicyBeanName()).isEqualTo("MockExpirationPolicy"); + assertThat(testConfigurer.getSessionSerializerBeanName()).isEqualTo("MockSerializer"); + + Method[] declaredMethods = testConfigurer.getClass().getDeclaredMethods(); + + List declaredMethodNames = + Arrays.stream(declaredMethods).map(Method::getName).sorted().collect(Collectors.toList()); + + assertThat(declaredMethods).isNotNull(); + assertThat(declaredMethods).hasSize(8); + + assertThat(declaredMethodNames) + .containsExactly("getClientRegionShortcut", "getIndexableSessionAttributes", + "getMaxInactiveIntervalInSeconds", "getPoolName", "getRegionName", "getServerRegionShortcut", + "getSessionExpirationPolicyBeanName", "getSessionSerializerBeanName"); + } + + @Test + public void classGetDeclaredMethodsOnCustomConfigurerObjectHasNoMethods() { + + SpringSessionGemFireConfigurer testConfigurer = newTestConfigurerWithNoOverrides(); + + assertThat(testConfigurer).isNotNull(); + assertThat(testConfigurer.getClientRegionShortcut()) + .isEqualTo(GemFireHttpSessionConfiguration.DEFAULT_CLIENT_REGION_SHORTCUT); + assertThat(testConfigurer.getIndexableSessionAttributes()) + .isEqualTo(GemFireHttpSessionConfiguration.DEFAULT_INDEXABLE_SESSION_ATTRIBUTES); + assertThat(testConfigurer.getMaxInactiveIntervalInSeconds()) + .isEqualTo(GemFireHttpSessionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL_IN_SECONDS); + assertThat(testConfigurer.getPoolName()) + .isEqualTo(GemFireHttpSessionConfiguration.DEFAULT_POOL_NAME); + assertThat(testConfigurer.getRegionName()) + .isEqualTo(GemFireHttpSessionConfiguration.DEFAULT_SESSION_REGION_NAME); + assertThat(testConfigurer.getServerRegionShortcut()) + .isEqualTo(GemFireHttpSessionConfiguration.DEFAULT_SERVER_REGION_SHORTCUT); + assertThat(testConfigurer.getSessionExpirationPolicyBeanName()) + .isEqualTo(GemFireHttpSessionConfiguration.DEFAULT_SESSION_EXPIRATION_POLICY_BEAN_NAME); + assertThat(testConfigurer.getSessionSerializerBeanName()) + .isEqualTo(GemFireHttpSessionConfiguration.DEFAULT_SESSION_SERIALIZER_BEAN_NAME); + + Method[] declaredMethods = testConfigurer.getClass().getDeclaredMethods(); + + assertThat(declaredMethods).isNotNull(); + assertThat(declaredMethods).isEmpty(); + } + + @Test + public void classGetDeclaredMethodsOnCustomConfigurerObjectOnlyHasOverriddenMethods() { + + SpringSessionGemFireConfigurer testConfigurer = newTestConfigurerWithOverrides(); + + assertThat(testConfigurer).isNotNull(); + assertThat(testConfigurer.getClientRegionShortcut()).isEqualTo(ClientRegionShortcut.CACHING_PROXY); + assertThat(testConfigurer.getIndexableSessionAttributes()).isEmpty(); + assertThat(testConfigurer.getMaxInactiveIntervalInSeconds()).isEqualTo(600); + assertThat(testConfigurer.getPoolName()).isEqualTo("TestPool"); + assertThat(testConfigurer.getRegionName()).isEqualTo("TestRegion"); + assertThat(testConfigurer.getServerRegionShortcut()).isEqualTo(RegionShortcut.PARTITION); + assertThat(testConfigurer.getSessionExpirationPolicyBeanName()).isEmpty(); + assertThat(testConfigurer.getSessionSerializerBeanName()) + .isEqualTo(GemFireHttpSessionConfiguration.DEFAULT_SESSION_SERIALIZER_BEAN_NAME); + + Method[] declaredMethods = testConfigurer.getClass().getDeclaredMethods(); + + List declaredMethodNames = + Arrays.stream(declaredMethods).map(Method::getName).sorted().collect(Collectors.toList()); + + assertThat(declaredMethods).isNotNull(); + assertThat(declaredMethods).hasSize(4); + + assertThat(declaredMethodNames) + .containsExactly("getClientRegionShortcut", "getMaxInactiveIntervalInSeconds", + "getPoolName", "getRegionName"); + + assertThat(declaredMethodNames) + .doesNotContain("getIndexableSessionAttributes", "getServerRegionShortcut", + "getSessionExpirationPolicyBeanName", "getSessionSerializerBeanName"); + } +}