diff --git a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/AbstractGemFireIntegrationTests.java b/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/AbstractGemFireIntegrationTests.java index 4a015ae..be06353 100644 --- a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/AbstractGemFireIntegrationTests.java +++ b/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/AbstractGemFireIntegrationTests.java @@ -93,17 +93,15 @@ public abstract class AbstractGemFireIntegrationTests { @Before public void setup() { - System.setProperty("gemfire.Query.VERBOSE", - String.valueOf(isQueryDebuggingEnabled())); + System.setProperty("gemfire.Query.VERBOSE", String.valueOf(isQueryDebuggingEnabled())); } /* (non-Javadoc) */ protected static File createDirectory(String pathname) { File directory = new File(WORKING_DIRECTORY, pathname); - assertThat(directory.isDirectory() || directory.mkdirs()) - .as(String.format("Failed to create directory (%1$s)", directory)) - .isTrue(); + assertThat(directory.isDirectory() || directory.mkdirs()).as( + String.format("Failed to create directory (%1$s)", directory)).isTrue(); directory.deleteOnExit(); @@ -111,8 +109,7 @@ public abstract class AbstractGemFireIntegrationTests { } /* (non-Javadoc) */ - protected static List createJavaProcessCommandLine(Class type, - String... args) { + protected static List createJavaProcessCommandLine(Class type, String... args) { List commandLine = new ArrayList(); String javaHome = System.getProperty("java.home"); @@ -123,8 +120,7 @@ public abstract class AbstractGemFireIntegrationTests { commandLine.add("-ea"); commandLine.add(String.format("-Dgemfire.log-file=%1$s", GEMFIRE_LOG_FILE_NAME)); commandLine.add(String.format("-Dgemfire.log-level=%1$s", GEMFIRE_LOG_LEVEL)); - commandLine - .add(String.format("-Dgemfire.Query.VERBOSE=%1$s", GEMFIRE_QUERY_DEBUG)); + commandLine.add(String.format("-Dgemfire.Query.VERBOSE=%1$s", GEMFIRE_QUERY_DEBUG)); commandLine.addAll(extractJvmArguments(args)); commandLine.add("-classpath"); commandLine.add(System.getProperty("java.class.path")); @@ -163,10 +159,8 @@ public abstract class AbstractGemFireIntegrationTests { } /* (non-Javadoc) */ - protected static Process run(Class type, File directory, String... args) - throws IOException { - return new ProcessBuilder().command(createJavaProcessCommandLine(type, args)) - .directory(directory).start(); + protected static Process run(Class type, File directory, String... args) throws IOException { + return new ProcessBuilder().command(createJavaProcessCommandLine(type, args)).directory(directory).start(); } /* (non-Javadoc) */ @@ -175,10 +169,8 @@ public abstract class AbstractGemFireIntegrationTests { } /* (non-Javadoc) */ - protected static boolean waitForCacheServerToStart(CacheServer cacheServer, - long duration) { - return waitForCacheServerToStart(cacheServer.getBindAddress(), - cacheServer.getPort(), duration); + protected static boolean waitForCacheServerToStart(CacheServer cacheServer, long duration) { + return waitForCacheServerToStart(cacheServer.getBindAddress(), cacheServer.getPort(), duration); } /* (non-Javadoc) */ @@ -187,8 +179,7 @@ public abstract class AbstractGemFireIntegrationTests { } /* (non-Javadoc) */ - protected static boolean waitForCacheServerToStart(final String host, final int port, - long duration) { + protected static boolean waitForCacheServerToStart(final String host, final int port, long duration) { return waitOnCondition(new Condition() { AtomicBoolean connected = new AtomicBoolean(false); @@ -248,8 +239,7 @@ public abstract class AbstractGemFireIntegrationTests { /* (non-Javadoc) */ @SuppressWarnings("all") - protected static boolean waitForProcessToStart(Process process, File directory, - long duration) { + protected static boolean waitForProcessToStart(Process process, File directory, long duration) { final File processControl = new File(directory, DEFAULT_PROCESS_CONTROL_FILENAME); waitOnCondition(new Condition() { @@ -267,8 +257,7 @@ public abstract class AbstractGemFireIntegrationTests { } /* (non-Javadoc) */ - protected static int waitForProcessToStop(Process process, File directory, - long duration) { + protected static int waitForProcessToStop(Process process, File directory, long duration) { final long timeout = (System.currentTimeMillis() + duration); try { @@ -323,30 +312,24 @@ public abstract class AbstractGemFireIntegrationTests { } /* (non-Javadoc) */ - protected void assertRegion(Region actualRegion, String expectedName, - DataPolicy expectedDataPolicy) { + protected void assertRegion(Region actualRegion, String expectedName, DataPolicy expectedDataPolicy) { assertThat(actualRegion).isNotNull(); assertThat(actualRegion.getName()).isEqualTo(expectedName); - assertThat(actualRegion.getFullPath()) - .isEqualTo(GemFireUtils.toRegionPath(expectedName)); + assertThat(actualRegion.getFullPath()).isEqualTo(GemFireUtils.toRegionPath(expectedName)); assertThat(actualRegion.getAttributes()).isNotNull(); - assertThat(actualRegion.getAttributes().getDataPolicy()) - .isEqualTo(expectedDataPolicy); + assertThat(actualRegion.getAttributes().getDataPolicy()).isEqualTo(expectedDataPolicy); } /* (non-Javadoc) */ - protected void assertIndex(Index index, String expectedExpression, - String expectedFromClause) { + protected void assertIndex(Index index, String expectedExpression, String expectedFromClause) { assertThat(index).isNotNull(); assertThat(index.getIndexedExpression()).isEqualTo(expectedExpression); assertThat(index.getFromClause()).isEqualTo(expectedFromClause); } /* (non-Javadoc) */ - protected void assertEntryIdleTimeout(Region region, - ExpirationAction expectedAction, int expectedTimeout) { - assertEntryIdleTimeout(region.getAttributes().getEntryIdleTimeout(), - expectedAction, expectedTimeout); + protected void assertEntryIdleTimeout(Region region, ExpirationAction expectedAction, int expectedTimeout) { + assertEntryIdleTimeout(region.getAttributes().getEntryIdleTimeout(), expectedAction, expectedTimeout); } /* (non-Javadoc) */ @@ -427,8 +410,7 @@ public abstract class AbstractGemFireIntegrationTests { * @see org.springframework.context.ApplicationListener * @see org.springframework.session.events.AbstractSessionEvent */ - public static class SessionEventListener - implements ApplicationListener { + public static class SessionEventListener implements ApplicationListener { private volatile AbstractSessionEvent sessionEvent; diff --git a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/ClientServerGemFireOperationsSessionRepositoryIntegrationTests.java b/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/ClientServerGemFireOperationsSessionRepositoryIntegrationTests.java index ca092a8..9b141d0 100644 --- a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/ClientServerGemFireOperationsSessionRepositoryIntegrationTests.java +++ b/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/ClientServerGemFireOperationsSessionRepositoryIntegrationTests.java @@ -18,7 +18,6 @@ package org.springframework.session.data.gemfire; import java.io.File; import java.io.IOException; -import java.net.InetAddress; import java.net.InetSocketAddress; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -96,8 +95,7 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 1; - private static final DateFormat TIMESTAMP = new SimpleDateFormat( - "yyyy-MM-dd-HH-mm-ss"); + private static final DateFormat TIMESTAMP = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); private static File processWorkingDirectory; @@ -114,25 +112,22 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests final int port = SocketUtils.findAvailableTcpPort(); - System.err.printf( - "Starting GemFire Server running on [%1$s] listening on port [%2$d]%n", - InetAddress.getLocalHost().getHostName(), port); + System.err.printf("Starting a GemFire Server on [%1$s] listening on port [%2$d]%n", + SpringSessionGemFireServerConfiguration.SERVER_HOSTNAME, port); System.setProperty("spring.session.data.gemfire.port", String.valueOf(port)); - String processWorkingDirectoryPathname = String - .format("gemfire-client-server-tests-%1$s", TIMESTAMP.format(new Date())); + String processWorkingDirectoryPathname = String.format("gemfire-client-server-tests-%1$s", + TIMESTAMP.format(new Date())); processWorkingDirectory = createDirectory(processWorkingDirectoryPathname); - gemfireServer = run(SpringSessionGemFireServerConfiguration.class, - processWorkingDirectory, - String.format("-Dspring.session.data.gemfire.port=%1$d", port)); - assertThat(waitForCacheServerToStart( - SpringSessionGemFireServerConfiguration.SERVER_HOSTNAME, port)).isTrue(); + gemfireServer = run(SpringSessionGemFireServerConfiguration.class, processWorkingDirectory, + String.format("-Dspring.session.data.gemfire.port=%1$d", port)); - System.err.printf("GemFire Server [startup time = %1$d ms]%n", - System.currentTimeMillis() - t0); + assertThat(waitForCacheServerToStart(SpringSessionGemFireServerConfiguration.SERVER_HOSTNAME, port)).isTrue(); + + System.err.printf("GemFire Server [startup time = %1$d ms]%n", System.currentTimeMillis() - t0); } @AfterClass @@ -140,11 +135,10 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests if (gemfireServer != null) { gemfireServer.destroyForcibly(); System.err.printf("GemFire Server [exit code = %1$d]%n", - waitForProcessToStop(gemfireServer, processWorkingDirectory)); + waitForProcessToStop(gemfireServer, processWorkingDirectory)); } - if (Boolean.valueOf(System.getProperty("spring.session.data.gemfire.fork.clean", - Boolean.TRUE.toString()))) { + if (Boolean.valueOf(System.getProperty("spring.session.data.gemfire.fork.clean", Boolean.TRUE.toString()))) { FileSystemUtils.deleteRecursively(processWorkingDirectory); } @@ -164,8 +158,7 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests springSessionGemFireRegion.getAttributes(); assertThat(springSessionGemFireRegionAttributes).isNotNull(); - assertThat(springSessionGemFireRegionAttributes.getDataPolicy()) - .isEqualTo(DataPolicy.EMPTY); + assertThat(springSessionGemFireRegionAttributes.getDataPolicy()).isEqualTo(DataPolicy.EMPTY); } @After @@ -179,8 +172,7 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests ExpiringSession expectedSession = save(createSession()); - AbstractSessionEvent sessionEvent = this.sessionEventListener - .waitForSessionEvent(500); + AbstractSessionEvent sessionEvent = this.sessionEventListener.waitForSessionEvent(500); assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class); @@ -188,12 +180,9 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests assertThat(createdSession).isEqualTo(expectedSession); assertThat(createdSession.getId()).isNotNull(); - assertThat(createdSession.getCreationTime()) - .isGreaterThanOrEqualTo(beforeOrAtCreationTime); - assertThat(createdSession.getLastAccessedTime()) - .isEqualTo(createdSession.getCreationTime()); - assertThat(createdSession.getMaxInactiveIntervalInSeconds()) - .isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS); + assertThat(createdSession.getCreationTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime); + assertThat(createdSession.getLastAccessedTime()).isEqualTo(createdSession.getCreationTime()); + assertThat(createdSession.getMaxInactiveIntervalInSeconds()).isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS); this.gemfireSessionRepository.delete(expectedSession.getId()); } @@ -202,15 +191,13 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests public void getExistingNonExpiredSessionBeforeAndAfterExpiration() { ExpiringSession expectedSession = save(touch(createSession())); - AbstractSessionEvent sessionEvent = this.sessionEventListener - .waitForSessionEvent(500); + AbstractSessionEvent sessionEvent = this.sessionEventListener.waitForSessionEvent(500); assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class); assertThat(sessionEvent.getSession()).isEqualTo(expectedSession); assertThat(this.sessionEventListener.getSessionEvent()).isNull(); - ExpiringSession savedSession = this.gemfireSessionRepository - .getSession(expectedSession.getId()); + ExpiringSession savedSession = this.gemfireSessionRepository.getSession(expectedSession.getId()); assertThat(savedSession).isEqualTo(expectedSession); @@ -221,13 +208,12 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests this.sessionEventListener.getSessionEvent(); sessionEvent = this.sessionEventListener.waitForSessionEvent( - TimeUnit.SECONDS.toMillis(MAX_INACTIVE_INTERVAL_IN_SECONDS + 1)); + TimeUnit.SECONDS.toMillis(MAX_INACTIVE_INTERVAL_IN_SECONDS + 1)); assertThat(sessionEvent).isInstanceOf(SessionExpiredEvent.class); assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSession.getId()); - ExpiringSession expiredSession = this.gemfireSessionRepository - .getSession(expectedSession.getId()); + ExpiringSession expiredSession = this.gemfireSessionRepository.getSession(expectedSession.getId()); assertThat(expiredSession).isNull(); } @@ -236,8 +222,7 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests public void deleteExistingNonExpiredSessionFiresSessionDeletedEventAndReturnsNullOnGet() { ExpiringSession expectedSession = save(touch(createSession())); - AbstractSessionEvent sessionEvent = this.sessionEventListener - .waitForSessionEvent(500); + AbstractSessionEvent sessionEvent = this.sessionEventListener.waitForSessionEvent(500); assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class); assertThat(sessionEvent.getSession()).isEqualTo(expectedSession); @@ -249,13 +234,13 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests assertThat(sessionEvent).isInstanceOf(SessionDeletedEvent.class); assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSession.getId()); - ExpiringSession deletedSession = this.gemfireSessionRepository - .getSession(expectedSession.getId()); + ExpiringSession deletedSession = this.gemfireSessionRepository.getSession(expectedSession.getId()); assertThat(deletedSession).isNull(); } - @EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME, maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS) + @EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME, + maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS) static class SpringSessionGemFireClientConfiguration { @Bean @@ -283,6 +268,7 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests @Bean PoolFactoryBean gemfirePool(@Value("${spring.session.data.gemfire.port:" + DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) { + PoolFactoryBean poolFactory = new PoolFactoryBean(); poolFactory.setFreeConnectionTimeout(5000); // 5 seconds @@ -290,7 +276,7 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests poolFactory.setMaxConnections(SpringSessionGemFireServerConfiguration.MAX_CONNECTIONS); poolFactory.setPingInterval(TimeUnit.SECONDS.toMillis(5)); poolFactory.setReadTimeout(2000); // 2 seconds - poolFactory.setRetryAttempts(2); + poolFactory.setRetryAttempts(1); poolFactory.setSubscriptionEnabled(true); poolFactory.setThreadLocalConnections(false); @@ -337,8 +323,7 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests Properties gemfireProperties() { Properties gemfireProperties = new Properties(); - gemfireProperties.setProperty("name", - SpringSessionGemFireServerConfiguration.class.getName()); + gemfireProperties.setProperty("name", name()); gemfireProperties.setProperty("mcast-port", "0"); gemfireProperties.setProperty("log-file", "server.log"); gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL); @@ -346,6 +331,10 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests return gemfireProperties; } + String name() { + return SpringSessionGemFireServerConfiguration.class.getName(); + } + @Bean CacheFactoryBean gemfireCache() { CacheFactoryBean gemfireCache = new CacheFactoryBean(); @@ -358,8 +347,7 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests @Bean CacheServerFactoryBean gemfireCacheServer(Cache gemfireCache, - @Value("${spring.session.data.gemfire.port:" + DEFAULT_GEMFIRE_SERVER_PORT - + "}") int port) { + @Value("${spring.session.data.gemfire.port:" + DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) { CacheServerFactoryBean cacheServerFactory = new CacheServerFactoryBean(); @@ -375,7 +363,7 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests @SuppressWarnings("resource") public static void main(final String[] args) throws IOException { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( - SpringSessionGemFireServerConfiguration.class); + SpringSessionGemFireServerConfiguration.class); context.registerShutdownHook(); writeProcessControlFile(WORKING_DIRECTORY); } diff --git a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/MultiPoolClientServerGemFireOperationsSessionRepositoryIntegrationTests.java b/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/MultiPoolClientServerGemFireOperationsSessionRepositoryIntegrationTests.java new file mode 100644 index 0000000..121f144 --- /dev/null +++ b/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/MultiPoolClientServerGemFireOperationsSessionRepositoryIntegrationTests.java @@ -0,0 +1,346 @@ +/* + * Copyright 2014-2016 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; + +import java.io.File; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Properties; +import java.util.concurrent.TimeUnit; + +import com.gemstone.gemfire.cache.Cache; +import com.gemstone.gemfire.cache.DataPolicy; +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.RegionAttributes; +import com.gemstone.gemfire.cache.client.ClientCache; + +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; +import org.springframework.data.gemfire.CacheFactoryBean; +import org.springframework.data.gemfire.client.ClientCacheFactoryBean; +import org.springframework.data.gemfire.client.PoolFactoryBean; +import org.springframework.data.gemfire.server.CacheServerFactoryBean; +import org.springframework.data.gemfire.support.ConnectionEndpoint; +import org.springframework.session.ExpiringSession; +import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; +import org.springframework.session.data.gemfire.support.GemFireUtils; +import org.springframework.session.events.AbstractSessionEvent; +import org.springframework.session.events.SessionCreatedEvent; +import org.springframework.session.events.SessionExpiredEvent; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.util.FileSystemUtils; +import org.springframework.util.SocketUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * The MultiPoolClientServerGemFireOperationsSessionRepositoryIntegrationTests class is a test suite of test cases + * testing the functionality of a GemFire cache client in a Spring Session application using a specifically named + * GemFire {@link com.gemstone.gemfire.cache.client.Pool} as configured with the 'poolName' attribute on the + * Spring Session Data GemFire {@link EnableGemFireHttpSession} annotation. + * + * @author John Blum + * @see org.junit.Test + * @see org.junit.runner.RunWith + * @see org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests + * @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession + * @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration + * @see org.springframework.test.annotation.DirtiesContext + * @see org.springframework.test.context.ContextConfiguration + * @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner + * @see org.springframework.test.context.web.WebAppConfiguration + * @see com.gemstone.gemfire.cache.Cache + * @see com.gemstone.gemfire.cache.client.ClientCache + * @see com.gemstone.gemfire.cache.client.Pool + * @see com.gemstone.gemfire.cache.server.CacheServer + * @since 1.3.0 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = MultiPoolClientServerGemFireOperationsSessionRepositoryIntegrationTests + .SpringSessionGemFireClientConfiguration.class) +@DirtiesContext +@WebAppConfiguration +public class MultiPoolClientServerGemFireOperationsSessionRepositoryIntegrationTests + extends AbstractGemFireIntegrationTests { + + private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 1; + + private static final DateFormat TIMESTAMP = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); + + private static File processWorkingDirectory; + + private static Process gemfireServer; + + private static final String SPRING_SESSION_GEMFIRE_REGION_NAME = "TestMultiPoolClientServerSessions"; + + @Autowired + private SessionEventListener sessionEventListener; + + @BeforeClass + public static void startGemFireServer() throws IOException { + final long t0 = System.currentTimeMillis(); + + final int port = SocketUtils.findAvailableTcpPort(); + + System.err.printf("Starting a GemFire Server on [%1$s] listening on port [%2$d]%n", + SpringSessionGemFireServerConfiguration.SERVER_HOSTNAME, port); + + System.setProperty("spring.session.data.gemfire.port", String.valueOf(port)); + + String processWorkingDirectoryPathname = String.format("gemfire-multipool-client-server-tests-%1$s", + TIMESTAMP.format(new Date())); + + processWorkingDirectory = createDirectory(processWorkingDirectoryPathname); + + gemfireServer = run(SpringSessionGemFireServerConfiguration.class, processWorkingDirectory, + String.format("-Dspring.session.data.gemfire.port=%1$d", port)); + + assertThat(waitForCacheServerToStart(SpringSessionGemFireServerConfiguration.SERVER_HOSTNAME, port)).isTrue(); + + System.err.printf("GemFire Server [startup time = %1$d ms]%n", System.currentTimeMillis() - t0); + } + + @AfterClass + public static void stopGemFireServerAndDeleteArtifacts() { + if (gemfireServer != null) { + gemfireServer.destroyForcibly(); + System.err.printf("GemFire Server [exit code = %1$d]%n", + waitForProcessToStop(gemfireServer, processWorkingDirectory)); + } + + if (Boolean.valueOf(System.getProperty("spring.session.data.gemfire.fork.clean", Boolean.TRUE.toString()))) { + FileSystemUtils.deleteRecursively(processWorkingDirectory); + } + + assertThat(waitForClientCacheToClose(DEFAULT_WAIT_DURATION)).isTrue(); + } + + @Before + public void setup() { + assertThat(GemFireUtils.isClient(gemfireCache)).isTrue(); + + Region springSessionGemFireRegion = + gemfireCache.getRegion(SPRING_SESSION_GEMFIRE_REGION_NAME); + + assertThat(springSessionGemFireRegion).isNotNull(); + + RegionAttributes springSessionGemFireRegionAttributes = + springSessionGemFireRegion.getAttributes(); + + assertThat(springSessionGemFireRegionAttributes).isNotNull(); + assertThat(springSessionGemFireRegionAttributes.getDataPolicy()).isEqualTo(DataPolicy.EMPTY); + } + + protected static ConnectionEndpoint newConnectionEndpoint(String host, int port) { + return new ConnectionEndpoint(host, port); + } + + @Test + public void getExistingNonExpiredSessionBeforeAndAfterExpiration() { + ExpiringSession expectedSession = save(touch(createSession())); + + AbstractSessionEvent sessionEvent = this.sessionEventListener.waitForSessionEvent(500); + + assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class); + assertThat(sessionEvent.getSession()).isEqualTo(expectedSession); + assertThat(this.sessionEventListener.getSessionEvent()).isNull(); + + ExpiringSession savedSession = this.gemfireSessionRepository.getSession(expectedSession.getId()); + + assertThat(savedSession).isEqualTo(expectedSession); + + this.sessionEventListener.getSessionEvent(); + + sessionEvent = this.sessionEventListener.waitForSessionEvent( + TimeUnit.SECONDS.toMillis(MAX_INACTIVE_INTERVAL_IN_SECONDS + 1)); + + assertThat(sessionEvent).isInstanceOf(SessionExpiredEvent.class); + assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSession.getId()); + + ExpiringSession expiredSession = this.gemfireSessionRepository.getSession(expectedSession.getId()); + + assertThat(expiredSession).isNull(); + } + + @EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME, poolName = "serverPool", + maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS) + static class SpringSessionGemFireClientConfiguration { + + @Bean + PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { + return new PropertySourcesPlaceholderConfigurer(); + } + + @Bean + Properties gemfireProperties() { + Properties gemfireProperties = new Properties(); + gemfireProperties.setProperty("name", name()); + gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL); + return gemfireProperties; + } + + String name() { + return SpringSessionGemFireClientConfiguration.class.getName(); + } + + @Bean + ClientCacheFactoryBean gemfireCache() { + ClientCacheFactoryBean gemfireCache = new ClientCacheFactoryBean(); + + gemfireCache.setClose(true); + gemfireCache.setPoolName("gemfirePool"); + gemfireCache.setProperties(gemfireProperties()); + + return gemfireCache; + } + + @Bean + PoolFactoryBean gemfirePool() { + PoolFactoryBean poolFactory = new PoolFactoryBean(); + + poolFactory.setFreeConnectionTimeout(5000); // 5 seconds + poolFactory.setKeepAlive(false); + poolFactory.setMinConnections(0); + poolFactory.setReadTimeout(500); + + // deliberately set to a non-existing GemFire (Cache) Server + poolFactory.addServers(newConnectionEndpoint("localhost", 53135)); + + return poolFactory; + } + + @Bean + PoolFactoryBean serverPool(@Value("${spring.session.data.gemfire.port:" + + DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) { + + PoolFactoryBean poolFactory = new PoolFactoryBean(); + + poolFactory.setFreeConnectionTimeout(5000); // 5 seconds + poolFactory.setKeepAlive(false); + poolFactory.setMaxConnections(SpringSessionGemFireServerConfiguration.MAX_CONNECTIONS); + poolFactory.setPingInterval(TimeUnit.SECONDS.toMillis(5)); + poolFactory.setReadTimeout(2000); // 2 seconds + poolFactory.setRetryAttempts(1); + poolFactory.setSubscriptionEnabled(true); + poolFactory.setThreadLocalConnections(false); + + poolFactory.addServers(newConnectionEndpoint( + SpringSessionGemFireServerConfiguration.SERVER_HOSTNAME, port)); + + return poolFactory; + } + + @Bean + public AbstractGemFireIntegrationTests.SessionEventListener sessionEventListener() { + return new AbstractGemFireIntegrationTests.SessionEventListener(); + } + + // used for debugging purposes + @SuppressWarnings("resource") + public static void main(final String[] args) { + ConfigurableApplicationContext applicationContext = new AnnotationConfigApplicationContext( + SpringSessionGemFireClientConfiguration.class); + + applicationContext.registerShutdownHook(); + + ClientCache clientCache = applicationContext.getBean(ClientCache.class); + + for (InetSocketAddress server : clientCache.getCurrentServers()) { + System.err.printf("GemFire Server [host: %1$s, port: %2$d]%n", + server.getHostName(), server.getPort()); + } + } + } + + @EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME, maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS) + static class SpringSessionGemFireServerConfiguration { + + static final int MAX_CONNECTIONS = 50; + static final String SERVER_HOSTNAME = "localhost"; + + @Bean + PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { + return new PropertySourcesPlaceholderConfigurer(); + } + + @Bean + Properties gemfireProperties() { + Properties gemfireProperties = new Properties(); + + gemfireProperties.setProperty("name", name()); + gemfireProperties.setProperty("mcast-port", "0"); + gemfireProperties.setProperty("log-file", "server.log"); + gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL); + + return gemfireProperties; + } + + String name() { + return SpringSessionGemFireServerConfiguration.class.getName(); + } + + @Bean + CacheFactoryBean gemfireCache() { + CacheFactoryBean gemfireCache = new CacheFactoryBean(); + + gemfireCache.setClose(true); + gemfireCache.setProperties(gemfireProperties()); + + return gemfireCache; + } + + @Bean + CacheServerFactoryBean gemfireCacheServer(Cache gemfireCache, + @Value("${spring.session.data.gemfire.port:" + DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) { + + CacheServerFactoryBean cacheServerFactory = new CacheServerFactoryBean(); + + cacheServerFactory.setAutoStartup(true); + cacheServerFactory.setBindAddress(SERVER_HOSTNAME); + cacheServerFactory.setCache(gemfireCache); + cacheServerFactory.setMaxConnections(MAX_CONNECTIONS); + cacheServerFactory.setPort(port); + + return cacheServerFactory; + } + + @SuppressWarnings("resource") + public static void main(final String[] args) throws IOException { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + SpringSessionGemFireServerConfiguration.class); + context.registerShutdownHook(); + writeProcessControlFile(WORKING_DIRECTORY); + } + } + +} diff --git a/spring-session/src/main/java/org/springframework/session/data/gemfire/AbstractGemFireOperationsSessionRepository.java b/spring-session/src/main/java/org/springframework/session/data/gemfire/AbstractGemFireOperationsSessionRepository.java index d291450..14a0f18 100644 --- a/spring-session/src/main/java/org/springframework/session/data/gemfire/AbstractGemFireOperationsSessionRepository.java +++ b/spring-session/src/main/java/org/springframework/session/data/gemfire/AbstractGemFireOperationsSessionRepository.java @@ -73,10 +73,8 @@ import org.springframework.util.StringUtils; * @since 1.1.0 * @see EnableGemFireHttpSession */ -public abstract class AbstractGemFireOperationsSessionRepository - extends CacheListenerAdapter - implements InitializingBean, FindByIndexNameSessionRepository, - ApplicationEventPublisherAware { +public abstract class AbstractGemFireOperationsSessionRepository extends CacheListenerAdapter + implements InitializingBean, FindByIndexNameSessionRepository, ApplicationEventPublisherAware { private int maxInactiveIntervalInSeconds = GemFireHttpSessionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL_IN_SECONDS; @@ -125,10 +123,8 @@ public abstract class AbstractGemFireOperationsSessionRepository * publish Session-based events. * @see org.springframework.context.ApplicationEventPublisher */ - public void setApplicationEventPublisher( - ApplicationEventPublisher applicationEventPublisher) { - Assert.notNull(applicationEventPublisher, - "ApplicationEventPublisher must not be null"); + public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { + Assert.notNull(applicationEventPublisher, "ApplicationEventPublisher must not be null"); this.applicationEventPublisher = applicationEventPublisher; } @@ -229,8 +225,7 @@ public abstract class AbstractGemFireOperationsSessionRepository @Override public void afterCreate(EntryEvent event) { if (isExpiringSessionOrNull(event.getNewValue())) { - handleCreated(event.getKey().toString(), - toExpiringSession(event.getNewValue())); + handleCreated(event.getKey().toString(), toExpiringSession(event.getNewValue())); } } @@ -244,8 +239,7 @@ public abstract class AbstractGemFireOperationsSessionRepository */ @Override public void afterDestroy(EntryEvent event) { - handleDestroyed(event.getKey().toString(), - toExpiringSession(event.getOldValue())); + handleDestroyed(event.getKey().toString(), toExpiringSession(event.getOldValue())); } /** @@ -272,7 +266,7 @@ public abstract class AbstractGemFireOperationsSessionRepository */ protected void handleCreated(String sessionId, ExpiringSession session) { publishEvent(session != null ? new SessionCreatedEvent(this, session) - : new SessionCreatedEvent(this, sessionId)); + : new SessionCreatedEvent(this, sessionId)); } /** @@ -286,7 +280,7 @@ public abstract class AbstractGemFireOperationsSessionRepository */ protected void handleDeleted(String sessionId, ExpiringSession session) { publishEvent(session != null ? new SessionDeletedEvent(this, session) - : new SessionDeletedEvent(this, sessionId)); + : new SessionDeletedEvent(this, sessionId)); } /** @@ -300,7 +294,7 @@ public abstract class AbstractGemFireOperationsSessionRepository */ protected void handleDestroyed(String sessionId, ExpiringSession session) { publishEvent(session != null ? new SessionDestroyedEvent(this, session) - : new SessionDestroyedEvent(this, sessionId)); + : new SessionDestroyedEvent(this, sessionId)); } /** @@ -314,7 +308,7 @@ public abstract class AbstractGemFireOperationsSessionRepository */ protected void handleExpired(String sessionId, ExpiringSession session) { publishEvent(session != null ? new SessionExpiredEvent(this, session) - : new SessionExpiredEvent(this, sessionId)); + : new SessionExpiredEvent(this, sessionId)); } /** @@ -329,8 +323,7 @@ public abstract class AbstractGemFireOperationsSessionRepository getApplicationEventPublisher().publishEvent(event); } catch (Throwable t) { - this.logger.error( - String.format("error occurred publishing event (%1$s)", event), t); + this.logger.error(String.format("error occurred publishing event (%1$s)", event), t); } } @@ -464,13 +457,12 @@ public abstract class AbstractGemFireOperationsSessionRepository long maxInactiveIntervalInSeconds = getMaxInactiveIntervalInSeconds(); return (maxInactiveIntervalInSeconds >= 0 - && (idleTimeout(maxInactiveIntervalInSeconds) >= lastAccessedTime)); + && (idleTimeout(maxInactiveIntervalInSeconds) >= lastAccessedTime)); } /* (non-Javadoc) */ private long idleTimeout(long maxInactiveIntervalInSeconds) { - return (System.currentTimeMillis() - - TimeUnit.SECONDS.toMillis(maxInactiveIntervalInSeconds)); + return (System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(maxInactiveIntervalInSeconds)); } /* (non-Javadoc) */ @@ -485,8 +477,7 @@ public abstract class AbstractGemFireOperationsSessionRepository } /* (non-Javadoc) */ - public synchronized void setMaxInactiveIntervalInSeconds( - final int maxInactiveIntervalInSeconds) { + public synchronized void setMaxInactiveIntervalInSeconds(int maxInactiveIntervalInSeconds) { this.delta |= (this.maxInactiveIntervalInSeconds != maxInactiveIntervalInSeconds); this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds; } @@ -509,8 +500,7 @@ public abstract class AbstractGemFireOperationsSessionRepository Object authentication = getAttribute(SPRING_SECURITY_CONTEXT); if (authentication != null) { - Expression expression = this.parser - .parseExpression("authentication?.name"); + Expression expression = this.parser.parseExpression("authentication?.name"); principalName = expression.getValue(authentication, String.class); } } @@ -526,8 +516,8 @@ public abstract class AbstractGemFireOperationsSessionRepository out.writeInt(getMaxInactiveIntervalInSeconds()); String principalName = getPrincipalName(); - int length = (StringUtils.hasText(principalName) ? principalName.length() - : 0); + + int length = (StringUtils.hasText(principalName) ? principalName.length() : 0); out.writeInt(length); @@ -546,8 +536,7 @@ public abstract class AbstractGemFireOperationsSessionRepository } /* (non-Javadoc) */ - public synchronized void fromData(DataInput in) - throws ClassNotFoundException, IOException { + public synchronized void fromData(DataInput in) throws ClassNotFoundException, IOException { this.id = in.readUTF(); this.creationTime = in.readLong(); setLastAccessedTime(in.readLong()); @@ -623,12 +612,10 @@ public abstract class AbstractGemFireOperationsSessionRepository /* (non-Javadoc) */ @Override public synchronized String toString() { - return String.format( - "{ @type = %1$s, id = %2$s, creationTime = %3$s, lastAccessedTime = %4$s" - + ", maxInactiveIntervalInSeconds = %5$s, principalName = %6$s }", - getClass().getName(), getId(), toString(getCreationTime()), - toString(getLastAccessedTime()), getMaxInactiveIntervalInSeconds(), - getPrincipalName()); + return String.format("{ @type = %1$s, id = %2$s, creationTime = %3$s, lastAccessedTime = %4$s" + + ", maxInactiveIntervalInSeconds = %5$s, principalName = %6$s }", + getClass().getName(), getId(), toString(getCreationTime()), toString(getLastAccessedTime()), + getMaxInactiveIntervalInSeconds(), getPrincipalName()); } /* (non-Javadoc) */ @@ -658,12 +645,12 @@ public abstract class AbstractGemFireOperationsSessionRepository static { Instantiator.register( - new Instantiator(GemFireSessionAttributes.class, 800828008) { - @Override - public DataSerializable newInstance() { - return new GemFireSessionAttributes(); - } - }); + new Instantiator(GemFireSessionAttributes.class, 800828008) { + @Override + public DataSerializable newInstance() { + return new GemFireSessionAttributes(); + } + }); } private transient final Map sessionAttributes = new HashMap(); @@ -685,8 +672,7 @@ public abstract class AbstractGemFireOperationsSessionRepository public void setAttribute(String attributeName, Object attributeValue) { synchronized (this.lock) { if (attributeValue != null) { - if (!attributeValue.equals( - this.sessionAttributes.put(attributeName, attributeValue))) { + if (!attributeValue.equals(this.sessionAttributes.put(attributeName, attributeValue))) { this.sessionAttributeDeltas.put(attributeName, attributeValue); } } @@ -716,8 +702,7 @@ public abstract class AbstractGemFireOperationsSessionRepository /* (non-Javadoc) */ public Set getAttributeNames() { synchronized (this.lock) { - return Collections.unmodifiableSet( - new HashSet(this.sessionAttributes.keySet())); + return Collections.unmodifiableSet(new HashSet(this.sessionAttributes.keySet())); } } @@ -733,10 +718,8 @@ public abstract class AbstractGemFireOperationsSessionRepository return new AbstractSet>() { @Override public Iterator> iterator() { - return Collections - .unmodifiableMap( - GemFireSessionAttributes.this.sessionAttributes) - .entrySet().iterator(); + return Collections.unmodifiableMap(GemFireSessionAttributes.this.sessionAttributes) + .entrySet().iterator(); } @Override @@ -759,8 +742,7 @@ public abstract class AbstractGemFireOperationsSessionRepository public void from(GemFireSessionAttributes sessionAttributes) { synchronized (this.lock) { for (String attributeName : sessionAttributes.getAttributeNames()) { - setAttribute(attributeName, - sessionAttributes.getAttribute(attributeName)); + setAttribute(attributeName, sessionAttributes.getAttribute(attributeName)); } } } @@ -812,8 +794,7 @@ public abstract class AbstractGemFireOperationsSessionRepository synchronized (this.lock) { out.writeInt(this.sessionAttributeDeltas.size()); - for (Map.Entry entry : this.sessionAttributeDeltas - .entrySet()) { + for (Map.Entry entry : this.sessionAttributeDeltas.entrySet()) { out.writeUTF(entry.getKey()); writeObject(entry.getValue(), out); } diff --git a/spring-session/src/main/java/org/springframework/session/data/gemfire/GemFireOperationsSessionRepository.java b/spring-session/src/main/java/org/springframework/session/data/gemfire/GemFireOperationsSessionRepository.java index 313869d..179ec88 100644 --- a/spring-session/src/main/java/org/springframework/session/data/gemfire/GemFireOperationsSessionRepository.java +++ b/spring-session/src/main/java/org/springframework/session/data/gemfire/GemFireOperationsSessionRepository.java @@ -32,8 +32,7 @@ import org.springframework.session.ExpiringSession; * @since 1.1.0 * @see AbstractGemFireOperationsSessionRepository */ -public class GemFireOperationsSessionRepository - extends AbstractGemFireOperationsSessionRepository { +public class GemFireOperationsSessionRepository extends AbstractGemFireOperationsSessionRepository { // GemFire OQL query used to lookup Sessions by arbitrary attributes. protected static final String FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY = "SELECT s FROM %1$s s WHERE s.attributes['%2$s'] = $1"; @@ -68,13 +67,10 @@ public class GemFireOperationsSessionRepository * @see java.util.Map * @see #prepareQuery(String) */ - public Map findByIndexNameAndIndexValue(String indexName, - String indexValue) { - SelectResults results = getTemplate() - .find(prepareQuery(indexName), indexValue); + public Map findByIndexNameAndIndexValue(String indexName, String indexValue) { + SelectResults results = getTemplate().find(prepareQuery(indexName), indexValue); - Map sessions = new HashMap( - results.size()); + Map sessions = new HashMap(results.size()); for (ExpiringSession session : results.asList()) { sessions.put(session.getId(), session); @@ -93,10 +89,8 @@ public class GemFireOperationsSessionRepository */ protected String prepareQuery(String indexName) { return (PRINCIPAL_NAME_INDEX_NAME.equals(indexName) - ? String.format(FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY, - getFullyQualifiedRegionName()) - : String.format(FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY, - getFullyQualifiedRegionName(), indexName)); + ? String.format(FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY, getFullyQualifiedRegionName()) + : String.format(FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY, getFullyQualifiedRegionName(), indexName)); } /** @@ -156,8 +150,7 @@ public class GemFireOperationsSessionRepository * @see #handleDeleted(String, ExpiringSession) */ public void delete(String sessionId) { - handleDeleted(sessionId, - getTemplate().remove(sessionId)); + handleDeleted(sessionId, getTemplate().remove(sessionId)); } } diff --git a/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.java b/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.java index bc7872d..d290449 100644 --- a/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.java +++ b/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.java @@ -27,16 +27,14 @@ import com.gemstone.gemfire.cache.client.ClientRegionShortcut; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession; /** - * Add this annotation to an {@code @Configuration} class to expose the - * SessionRepositoryFilter as a bean named "springSessionRepositoryFilter" and backed by - * Pivotal GemFire or Apache Geode. + * Add this annotation to a Spring {@code @Configuration} class to expose the SessionRepositoryFilter + * as a bean named "springSessionRepositoryFilter" and backed by Pivotal GemFire or Apache Geode. * * In order to leverage the annotation, a single Pivotal GemFire/Apache Geode - * {@link com.gemstone.gemfire.cache.Cache} or - * {@link com.gemstone.gemfire.cache.client.ClientCache} instance must be provided. + * {@link com.gemstone.gemfire.cache.Cache} + * or {@link com.gemstone.gemfire.cache.client.ClientCache} instance must be provided. * * For example: * @@ -57,18 +55,17 @@ import org.springframework.session.config.annotation.web.http.EnableSpringHttpSe * * {@literal @Bean} * public CacheFactoryBean gemfireCache() throws Exception { - * CacheFactoryBean clientCacheFactoryBean = new CacheFactoryBean(); - * clientCacheFactoryBean.setLazyInitialize(false); - * clientCacheFactoryBean.setProperties(gemfireProperties()); - * clientCacheFactoryBean.setUseBeanFactoryLocator(false); - * return clientCacheFactoryBean; + * CacheFactoryBean cache = new CacheFactoryBean(); + * cache.setProperties(gemfireProperties()); + * return cache; * } * } * * - * Alternatively, a Spring Session can be configured to use Pivotal GemFire (Apache Geode) - * as a client using a dedicated GemFire Server cluster and a - * {@link com.gemstone.gemfire.cache.client.ClientCache}. For example: + * Alternatively, Spring Session can be configured to use Pivotal GemFire (Apache Geode) as a client + * using a dedicated GemFire Server cluster and a {@link com.gemstone.gemfire.cache.client.ClientCache}. + * + * For example: * * * {@literal @Configuration} @@ -85,21 +82,26 @@ import org.springframework.session.config.annotation.web.http.EnableSpringHttpSe * * {@literal @Bean} * public ClientCacheFactoryBean gemfireCache() throws Exception { - * ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean(); - * clientCacheFactoryBean.setLazyInitialize(false); - * clientCacheFactoryBean.setProperties(gemfireProperties()); - * clientCacheFactoryBean.setUseBeanFactoryLocator(false); - * return clientCacheFactoryBean; + * 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("serverHost", 40404); + * return pool; * } * } * * - * More advanced configurations can extend {@link GemFireHttpSessionConfiguration} - * instead. + * More advanced configurations can extend {@link GemFireHttpSessionConfiguration} instead. * * @author John Blum + * @see org.springframework.session.config.annotation.web.http.EnableSpringHttpSession * @see GemFireHttpSessionConfiguration - * @see EnableSpringHttpSession * @since 1.1.0 */ @Documented @@ -125,7 +127,7 @@ public @interface EnableGemFireHttpSession { * * @return an array of Strings identifying the names of Session attributes to index. */ - String[]indexableSessionAttributes() default {}; + String[] indexableSessionAttributes() default {}; /** * Defines the maximum interval in seconds that a Session can remain inactive before @@ -136,6 +138,17 @@ public @interface EnableGemFireHttpSession { */ int maxInactiveIntervalInSeconds() default 1800; + /** + * Specifies the name of the specific GemFire {@link com.gemstone.gemfire.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. + * + * @return the name of the GemFire {@link com.gemstone.gemfire.cache.client.Pool} to be used + * by the client Region used to manage (HTTP) Sessions. + * @see org.springframework.data.gemfire.config.GemfireConstants#DEFAULT_GEMFIRE_POOL_NAME + */ + String poolName() default GemFireHttpSessionConfiguration.DEFAULT_GEMFIRE_POOL_NAME; + /** * Defines the name of the GemFire (Client)Cache Region used to store Sessions. * diff --git a/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfiguration.java b/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfiguration.java index a9fd0b7..c770f77 100644 --- a/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfiguration.java +++ b/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfiguration.java @@ -25,6 +25,7 @@ import com.gemstone.gemfire.cache.Region; import com.gemstone.gemfire.cache.RegionAttributes; import com.gemstone.gemfire.cache.RegionShortcut; import com.gemstone.gemfire.cache.client.ClientRegionShortcut; +import com.gemstone.gemfire.cache.client.Pool; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.annotation.Qualifier; @@ -39,6 +40,7 @@ import org.springframework.data.gemfire.GemfireTemplate; import org.springframework.data.gemfire.IndexFactoryBean; import org.springframework.data.gemfire.IndexType; import org.springframework.data.gemfire.RegionAttributesFactoryBean; +import org.springframework.data.gemfire.config.GemfireConstants; import org.springframework.session.ExpiringSession; import org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration; import org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSession; @@ -54,8 +56,8 @@ import org.springframework.util.StringUtils; * HttpSession provider implementation in Spring Session. * * @author John Blum - * @since 1.1.0 * @see EnableGemFireHttpSession + * @since 1.1.0 */ @Configuration public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfiguration @@ -65,8 +67,7 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat * The default maximum interval in seconds in which a Session can remain inactive * before it is considered expired. */ - public static final int DEFAULT_MAX_INACTIVE_INTERVAL_IN_SECONDS = - (int) TimeUnit.MINUTES.toSeconds(30); + public static final int DEFAULT_MAX_INACTIVE_INTERVAL_IN_SECONDS = (int) TimeUnit.MINUTES.toSeconds(30); protected static final Class SPRING_SESSION_GEMFIRE_REGION_KEY_CONSTRAINT = Object.class; protected static final Class SPRING_SESSION_GEMFIRE_REGION_VALUE_CONSTRAINT = GemFireSession.class; @@ -83,6 +84,11 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat */ 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. + */ + public static final String DEFAULT_GEMFIRE_POOL_NAME = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME; + /** * The default name of the Gemfire (Client)Cache Region used to store Sessions. */ @@ -101,6 +107,8 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat private RegionShortcut serverRegionShortcut = DEFAULT_SERVER_REGION_SHORTCUT; + private String poolName = DEFAULT_GEMFIRE_POOL_NAME; + private String springSessionGemFireRegionName = DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME; private String[] indexableSessionAttributes = DEFAULT_INDEXABLE_SESSION_ATTRIBUTES; @@ -151,8 +159,7 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat * @see EnableGemFireHttpSession#clientRegionShortcut() */ protected ClientRegionShortcut getClientRegionShortcut() { - return (this.clientRegionShortcut != null ? this.clientRegionShortcut - : DEFAULT_CLIENT_REGION_SHORTCUT); + return (this.clientRegionShortcut != null ? this.clientRegionShortcut : DEFAULT_CLIENT_REGION_SHORTCUT); } /** @@ -224,6 +231,28 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat 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. + * + * @param poolName the name of a GemFire {@link Pool}. + * @see Pool#getName() + */ + 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. + * + * @return the name of a GemFire {@link Pool}. + * @see Pool#getName() + */ + protected String getPoolName() { + return (StringUtils.hasText(this.poolName) ? this.poolName : DEFAULT_GEMFIRE_POOL_NAME); + } + /** * Sets the {@link RegionShortcut} used to configure the GemFire Cache Region that * will store Spring Sessions. @@ -244,8 +273,7 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat * @see EnableGemFireHttpSession#serverRegionShortcut() */ protected RegionShortcut getServerRegionShortcut() { - return (this.serverRegionShortcut != null ? this.serverRegionShortcut - : DEFAULT_SERVER_REGION_SHORTCUT); + return (this.serverRegionShortcut != null ? this.serverRegionShortcut : DEFAULT_SERVER_REGION_SHORTCUT); } /** @@ -268,8 +296,7 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat * @see EnableGemFireHttpSession#regionName() */ protected String getSpringSessionGemFireRegionName() { - return (StringUtils.hasText(this.springSessionGemFireRegionName) - ? this.springSessionGemFireRegionName + return (StringUtils.hasText(this.springSessionGemFireRegionName) ? this.springSessionGemFireRegionName : DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); } @@ -288,17 +315,19 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat setClientRegionShortcut(ClientRegionShortcut.class.cast( enableGemFireHttpSessionAnnotationAttributes.getEnum("clientRegionShortcut"))); - setIndexableSessionAttributes(enableGemFireHttpSessionAnnotationAttributes - .getStringArray("indexableSessionAttributes")); + setIndexableSessionAttributes(enableGemFireHttpSessionAnnotationAttributes.getStringArray( + "indexableSessionAttributes")); - setMaxInactiveIntervalInSeconds(enableGemFireHttpSessionAnnotationAttributes - .getNumber("maxInactiveIntervalInSeconds").intValue()); + setMaxInactiveIntervalInSeconds(enableGemFireHttpSessionAnnotationAttributes.getNumber( + "maxInactiveIntervalInSeconds").intValue()); - setServerRegionShortcut(RegionShortcut.class.cast( - enableGemFireHttpSessionAnnotationAttributes.getEnum("serverRegionShortcut"))); + setPoolName(enableGemFireHttpSessionAnnotationAttributes.getString("poolName")); - setSpringSessionGemFireRegionName( - enableGemFireHttpSessionAnnotationAttributes.getString("regionName")); + setServerRegionShortcut(RegionShortcut.class.cast(enableGemFireHttpSessionAnnotationAttributes.getEnum( + "serverRegionShortcut"))); + + setSpringSessionGemFireRegionName(enableGemFireHttpSessionAnnotationAttributes.getString( + "regionName")); } /** @@ -317,8 +346,7 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat GemFireOperationsSessionRepository sessionRepository = new GemFireOperationsSessionRepository(gemfireOperations); - sessionRepository.setMaxInactiveIntervalInSeconds( - getMaxInactiveIntervalInSeconds()); + sessionRepository.setMaxInactiveIntervalInSeconds(getMaxInactiveIntervalInSeconds()); return sessionRepository; } @@ -337,8 +365,7 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat @Bean @DependsOn(DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME) public GemfireTemplate sessionRegionTemplate(GemFireCache gemFireCache) { - return new GemfireTemplate(gemFireCache.getRegion( - getSpringSessionGemFireRegionName())); + return new GemfireTemplate(gemFireCache.getRegion(getSpringSessionGemFireRegionName())); } /** @@ -357,20 +384,20 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat * @see #getServerRegionShortcut() */ @Bean(name = DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME) - public GemFireCacheTypeAwareRegionFactoryBean sessionRegion( - GemFireCache gemfireCache, + public GemFireCacheTypeAwareRegionFactoryBean sessionRegion(GemFireCache gemfireCache, RegionAttributes sessionRegionAttributes) { - GemFireCacheTypeAwareRegionFactoryBean serverRegion = + GemFireCacheTypeAwareRegionFactoryBean sessionRegion = new GemFireCacheTypeAwareRegionFactoryBean(); - serverRegion.setGemfireCache(gemfireCache); - serverRegion.setClientRegionShortcut(getClientRegionShortcut()); - serverRegion.setRegionAttributes(sessionRegionAttributes); - serverRegion.setRegionName(getSpringSessionGemFireRegionName()); - serverRegion.setServerRegionShortcut(getServerRegionShortcut()); + sessionRegion.setClientRegionShortcut(getClientRegionShortcut()); + sessionRegion.setGemfireCache(gemfireCache); + sessionRegion.setPoolName(getPoolName()); + sessionRegion.setRegionAttributes(sessionRegionAttributes); + sessionRegion.setRegionName(getSpringSessionGemFireRegionName()); + sessionRegion.setServerRegionShortcut(getServerRegionShortcut()); - return serverRegion; + return sessionRegion; } /** @@ -390,7 +417,6 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat @Bean @SuppressWarnings({ "unchecked", "deprecation" }) public RegionAttributesFactoryBean sessionRegionAttributes(GemFireCache gemfireCache) { - RegionAttributesFactoryBean regionAttributes = new RegionAttributesFactoryBean(); regionAttributes.setKeyConstraint(SPRING_SESSION_GEMFIRE_REGION_KEY_CONSTRAINT); @@ -399,8 +425,7 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat if (isExpirationAllowed(gemfireCache)) { regionAttributes.setStatisticsEnabled(true); regionAttributes.setEntryIdleTimeout(new ExpirationAttributes( - Math.max(getMaxInactiveIntervalInSeconds(), 0), - ExpirationAction.INVALIDATE)); + Math.max(getMaxInactiveIntervalInSeconds(), 0), ExpirationAction.INVALIDATE)); } return regionAttributes; @@ -418,8 +443,7 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat * @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())); } @@ -474,8 +498,7 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat IndexFactoryBean index = new IndexFactoryBean() { @Override public void afterPropertiesSet() throws Exception { - if (GemFireUtils.isPeer(gemfireCache) - && !ObjectUtils.isEmpty(getIndexableSessionAttributes())) { + if (GemFireUtils.isPeer(gemfireCache) && !ObjectUtils.isEmpty(getIndexableSessionAttributes())) { super.afterPropertiesSet(); } } @@ -485,8 +508,7 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat index.setName("sessionAttributesIndex"); index.setExpression(String.format("s.attributes[%1$s]", getIndexableSessionAttributesAsGemFireIndexExpression())); - index.setFrom(String.format("%1$s s", - GemFireUtils.toRegionPath(getSpringSessionGemFireRegionName()))); + index.setFrom(String.format("%1$s s", GemFireUtils.toRegionPath(getSpringSessionGemFireRegionName()))); index.setOverride(true); return index; diff --git a/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/GemFireCacheTypeAwareRegionFactoryBean.java b/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/GemFireCacheTypeAwareRegionFactoryBean.java index 4cb967b..9ae5ab1 100644 --- a/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/GemFireCacheTypeAwareRegionFactoryBean.java +++ b/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/GemFireCacheTypeAwareRegionFactoryBean.java @@ -22,6 +22,7 @@ import com.gemstone.gemfire.cache.Region; import com.gemstone.gemfire.cache.RegionAttributes; import com.gemstone.gemfire.cache.RegionShortcut; import com.gemstone.gemfire.cache.client.ClientRegionShortcut; +import com.gemstone.gemfire.cache.client.Pool; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; @@ -52,11 +53,17 @@ import org.springframework.util.StringUtils; public class GemFireCacheTypeAwareRegionFactoryBean implements BeanFactoryAware, FactoryBean>, InitializingBean { - protected static final ClientRegionShortcut DEFAULT_CLIENT_REGION_SHORTCUT = GemFireHttpSessionConfiguration.DEFAULT_CLIENT_REGION_SHORTCUT; + protected static final ClientRegionShortcut DEFAULT_CLIENT_REGION_SHORTCUT = + GemFireHttpSessionConfiguration.DEFAULT_CLIENT_REGION_SHORTCUT; - protected static final RegionShortcut DEFAULT_SERVER_REGION_SHORTCUT = GemFireHttpSessionConfiguration.DEFAULT_SERVER_REGION_SHORTCUT; + protected static final RegionShortcut DEFAULT_SERVER_REGION_SHORTCUT = + GemFireHttpSessionConfiguration.DEFAULT_SERVER_REGION_SHORTCUT; - protected static final String DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME = GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME; + protected static final String DEFAULT_GEMFIRE_POOL_NAME = + GemFireHttpSessionConfiguration.DEFAULT_GEMFIRE_POOL_NAME; + + protected static final String DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME = + GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME; private BeanFactory beanFactory; @@ -70,6 +77,7 @@ public class GemFireCacheTypeAwareRegionFactoryBean private RegionShortcut serverRegionShortcut; + private String poolName; private String regionName; /** @@ -112,8 +120,8 @@ public class GemFireCacheTypeAwareRegionFactoryBean protected Region newServerRegion(GemFireCache gemfireCache) throws Exception { GenericRegionFactoryBean serverRegion = new GenericRegionFactoryBean(); - serverRegion.setCache(gemfireCache); serverRegion.setAttributes(getRegionAttributes()); + serverRegion.setCache(gemfireCache); serverRegion.setRegionName(getRegionName()); serverRegion.setShortcut(getServerRegionShortcut()); serverRegion.afterPropertiesSet(); @@ -145,10 +153,11 @@ public class GemFireCacheTypeAwareRegionFactoryBean ClientRegionShortcut shortcut = getClientRegionShortcut(); + clientRegion.setAttributes(getRegionAttributes()); clientRegion.setBeanFactory(getBeanFactory()); clientRegion.setCache(gemfireCache); - clientRegion.setAttributes(getRegionAttributes()); clientRegion.setInterests(registerInterests(!GemFireUtils.isLocal(shortcut))); + clientRegion.setPoolName(getPoolName()); clientRegion.setRegionName(getRegionName()); clientRegion.setShortcut(shortcut); clientRegion.afterPropertiesSet(); @@ -157,16 +166,8 @@ public class GemFireCacheTypeAwareRegionFactoryBean } /** - * Registers interests in all keys when the client {@link Region} is non-local. - * - * @return an array of Interests specifying the server notifications of interests to - * the client. - * @see org.springframework.data.gemfire.client.Interest - */ - /** - * Decides whether interests will be registered for all keys. Interests is only - * registered on a client and typically only when the client is a (CACHING) PROXY to - * the server (i.e. non-LOCAL only). + * Decides whether interests will be registered for all keys. Interests is only registered on + * a client and typically only when the client is a (CACHING) PROXY to the server (i.e. non-LOCAL only). * * @param register a boolean value indicating whether interests should be registered. * @return an array of Interests KEY/VALUE registrations. @@ -174,9 +175,9 @@ public class GemFireCacheTypeAwareRegionFactoryBean */ @SuppressWarnings("unchecked") protected Interest[] registerInterests(boolean register) { - return (!register ? new Interest[0] - : new Interest[] { - new Interest("ALL_KEYS", InterestResultPolicy.KEYS) }); + return (!register ? new Interest[0] : new Interest[] { + new Interest("ALL_KEYS", InterestResultPolicy.KEYS) + }); } /** @@ -237,8 +238,7 @@ public class GemFireCacheTypeAwareRegionFactoryBean * @see org.springframework.beans.factory.BeanFactory */ protected BeanFactory getBeanFactory() { - Assert.state(this.beanFactory != null, - "A reference to the BeanFactory was not properly configured"); + Assert.state(this.beanFactory != null, "A reference to the BeanFactory was not properly configured"); return this.beanFactory; } @@ -264,8 +264,7 @@ public class GemFireCacheTypeAwareRegionFactoryBean * @see com.gemstone.gemfire.cache.client.ClientRegionShortcut */ protected ClientRegionShortcut getClientRegionShortcut() { - return (this.clientRegionShortcut != null ? this.clientRegionShortcut - : DEFAULT_CLIENT_REGION_SHORTCUT); + return (this.clientRegionShortcut != null ? this.clientRegionShortcut : DEFAULT_CLIENT_REGION_SHORTCUT); } /** @@ -288,11 +287,32 @@ public class GemFireCacheTypeAwareRegionFactoryBean * @throws IllegalStateException if the {@link GemFireCache} reference is null. */ protected GemFireCache getGemfireCache() { - Assert.state(this.gemfireCache != null, - "A reference to the GemFireCache was not properly configured"); + Assert.state(this.gemfireCache != null, "A reference to the GemFireCache was not properly configured"); return this.gemfireCache; } + /** + * Sets the name of the GemFire {@link Pool} used by the client Region for managing Sessions + * during cache operations involving the server. + * + * @param poolName the name of a GemFire {@link Pool}. + * @see Pool#getName() + */ + public void setPoolName(final 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. + * + * @return the name of a GemFire {@link Pool}. + * @see Pool#getName() + */ + protected String getPoolName() { + return (StringUtils.hasText(this.poolName) ? this.poolName : DEFAULT_GEMFIRE_POOL_NAME); + } + /** * Sets the GemFire {@link RegionAttributes} used to configure the GemFire cache * {@link Region} used to store and manage Session state. @@ -335,8 +355,7 @@ public class GemFireCacheTypeAwareRegionFactoryBean * @see com.gemstone.gemfire.cache.Region#getName() */ protected String getRegionName() { - return (StringUtils.hasText(this.regionName) ? this.regionName - : DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); + return (StringUtils.hasText(this.regionName) ? this.regionName : DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); } /** @@ -360,8 +379,7 @@ public class GemFireCacheTypeAwareRegionFactoryBean * @see com.gemstone.gemfire.cache.RegionShortcut */ protected RegionShortcut getServerRegionShortcut() { - return (this.serverRegionShortcut != null ? this.serverRegionShortcut - : DEFAULT_SERVER_REGION_SHORTCUT); + return (this.serverRegionShortcut != null ? this.serverRegionShortcut : DEFAULT_SERVER_REGION_SHORTCUT); } } diff --git a/spring-session/src/main/java/org/springframework/session/data/gemfire/support/GemFireUtils.java b/spring-session/src/main/java/org/springframework/session/data/gemfire/support/GemFireUtils.java index 3756dcb..f1a0e8e 100644 --- a/spring-session/src/main/java/org/springframework/session/data/gemfire/support/GemFireUtils.java +++ b/spring-session/src/main/java/org/springframework/session/data/gemfire/support/GemFireUtils.java @@ -67,8 +67,7 @@ public abstract class GemFireUtils { */ public static boolean isClient(GemFireCache gemFireCache) { boolean client = (gemFireCache instanceof ClientCache); - client &= (!(gemFireCache instanceof GemFireCacheImpl) - || ((GemFireCacheImpl) gemFireCache).isClient()); + client &= (!(gemFireCache instanceof GemFireCacheImpl) || ((GemFireCacheImpl) gemFireCache).isClient()); return client; } diff --git a/spring-session/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfigurationTest.java b/spring-session/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfigurationTest.java index 86996e5..cd5ffea 100644 --- a/spring-session/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfigurationTest.java +++ b/spring-session/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfigurationTest.java @@ -16,22 +16,30 @@ package org.springframework.session.data.gemfire.config.annotation.web.http; +import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; import com.gemstone.gemfire.cache.Cache; +import com.gemstone.gemfire.cache.ExpirationAction; +import com.gemstone.gemfire.cache.ExpirationAttributes; import com.gemstone.gemfire.cache.GemFireCache; import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.RegionAttributes; import com.gemstone.gemfire.cache.RegionShortcut; import com.gemstone.gemfire.cache.client.ClientCache; import com.gemstone.gemfire.cache.client.ClientRegionShortcut; + import org.junit.Before; import org.junit.Test; import org.springframework.core.type.AnnotationMetadata; import org.springframework.data.gemfire.GemfireOperations; import org.springframework.data.gemfire.GemfireTemplate; +import org.springframework.data.gemfire.RegionAttributesFactoryBean; +import org.springframework.session.ExpiringSession; import org.springframework.session.data.gemfire.GemFireOperationsSessionRepository; +import org.springframework.session.data.gemfire.config.annotation.web.http.support.GemFireCacheTypeAwareRegionFactoryBean; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; @@ -39,6 +47,7 @@ import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; /** * The GemFireHttpSessionConfigurationTest class is a test suite of test cases testing the @@ -62,6 +71,23 @@ public class GemFireHttpSessionConfigurationTest { private GemFireHttpSessionConfiguration gemfireConfiguration; + @SuppressWarnings("unchecked") + protected T getField(Object obj, String fieldName) { + try { + Field field = obj.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + return (T) field.get(obj); + } + catch (NoSuchFieldException e) { + throw new IllegalArgumentException(String.format( + "field with name [%1$s] was not found in class [%2$s]", fieldName, obj), e); + } + catch (IllegalAccessException e) { + throw new Error(String.format("unable to access field [%1$s] on object of type [%2$s]", + fieldName, obj.getClass().getName()), e); + } + } + protected T[] toArray(T... array) { return array; } @@ -75,11 +101,10 @@ public class GemFireHttpSessionConfigurationTest { public void setAndGetBeanClassLoader() { assertThat(this.gemfireConfiguration.getBeanClassLoader()).isNull(); - this.gemfireConfiguration - .setBeanClassLoader(Thread.currentThread().getContextClassLoader()); + this.gemfireConfiguration.setBeanClassLoader(Thread.currentThread().getContextClassLoader()); - assertThat(this.gemfireConfiguration.getBeanClassLoader()) - .isEqualTo(Thread.currentThread().getContextClassLoader()); + assertThat(this.gemfireConfiguration.getBeanClassLoader()).isEqualTo( + Thread.currentThread().getContextClassLoader()); this.gemfireConfiguration.setBeanClassLoader(null); @@ -89,48 +114,45 @@ public class GemFireHttpSessionConfigurationTest { @Test public void setAndGetClientRegionShortcut() { assertThat(this.gemfireConfiguration.getClientRegionShortcut()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_CLIENT_REGION_SHORTCUT); + GemFireHttpSessionConfiguration.DEFAULT_CLIENT_REGION_SHORTCUT); - this.gemfireConfiguration - .setClientRegionShortcut(ClientRegionShortcut.CACHING_PROXY); + this.gemfireConfiguration.setClientRegionShortcut(ClientRegionShortcut.CACHING_PROXY); - assertThat(this.gemfireConfiguration.getClientRegionShortcut()) - .isEqualTo(ClientRegionShortcut.CACHING_PROXY); + assertThat(this.gemfireConfiguration.getClientRegionShortcut()).isEqualTo( + ClientRegionShortcut.CACHING_PROXY); this.gemfireConfiguration.setClientRegionShortcut(null); assertThat(this.gemfireConfiguration.getClientRegionShortcut()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_CLIENT_REGION_SHORTCUT); + GemFireHttpSessionConfiguration.DEFAULT_CLIENT_REGION_SHORTCUT); } @Test public void setAndGetIndexableSessionAttributes() { assertThat(this.gemfireConfiguration.getIndexableSessionAttributes()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_INDEXABLE_SESSION_ATTRIBUTES); + GemFireHttpSessionConfiguration.DEFAULT_INDEXABLE_SESSION_ATTRIBUTES); - this.gemfireConfiguration - .setIndexableSessionAttributes(toArray("one", "two", "three")); + assertThat(this.gemfireConfiguration.getIndexableSessionAttributesAsGemFireIndexExpression()).isEqualTo("*"); - assertThat(this.gemfireConfiguration.getIndexableSessionAttributes()) - .isEqualTo(toArray("one", "two", "three")); - assertThat(this.gemfireConfiguration - .getIndexableSessionAttributesAsGemFireIndexExpression()) - .isEqualTo("'one', 'two', 'three'"); + this.gemfireConfiguration.setIndexableSessionAttributes(toArray("one", "two", "three")); + + assertThat(this.gemfireConfiguration.getIndexableSessionAttributes()).isEqualTo( + toArray("one", "two", "three")); + + assertThat(this.gemfireConfiguration.getIndexableSessionAttributesAsGemFireIndexExpression()).isEqualTo( + "'one', 'two', 'three'"); this.gemfireConfiguration.setIndexableSessionAttributes(toArray("one")); - assertThat(this.gemfireConfiguration.getIndexableSessionAttributes()) - .isEqualTo(toArray("one")); - assertThat(this.gemfireConfiguration - .getIndexableSessionAttributesAsGemFireIndexExpression()) - .isEqualTo("'one'"); + assertThat(this.gemfireConfiguration.getIndexableSessionAttributes()).isEqualTo(toArray("one")); + assertThat(this.gemfireConfiguration.getIndexableSessionAttributesAsGemFireIndexExpression()).isEqualTo("'one'"); this.gemfireConfiguration.setIndexableSessionAttributes(null); assertThat(this.gemfireConfiguration.getIndexableSessionAttributes()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_INDEXABLE_SESSION_ATTRIBUTES); - assertThat(this.gemfireConfiguration - .getIndexableSessionAttributesAsGemFireIndexExpression()).isEqualTo("*"); + GemFireHttpSessionConfiguration.DEFAULT_INDEXABLE_SESSION_ATTRIBUTES); + + assertThat(this.gemfireConfiguration.getIndexableSessionAttributesAsGemFireIndexExpression()).isEqualTo("*"); } @Test @@ -140,117 +162,123 @@ public class GemFireHttpSessionConfigurationTest { this.gemfireConfiguration.setMaxInactiveIntervalInSeconds(300); - assertThat(this.gemfireConfiguration.getMaxInactiveIntervalInSeconds()) - .isEqualTo(300); + assertThat(this.gemfireConfiguration.getMaxInactiveIntervalInSeconds()).isEqualTo(300); this.gemfireConfiguration.setMaxInactiveIntervalInSeconds(Integer.MAX_VALUE); - assertThat(this.gemfireConfiguration.getMaxInactiveIntervalInSeconds()) - .isEqualTo(Integer.MAX_VALUE); + assertThat(this.gemfireConfiguration.getMaxInactiveIntervalInSeconds()).isEqualTo(Integer.MAX_VALUE); this.gemfireConfiguration.setMaxInactiveIntervalInSeconds(-1); - assertThat(this.gemfireConfiguration.getMaxInactiveIntervalInSeconds()) - .isEqualTo(-1); + assertThat(this.gemfireConfiguration.getMaxInactiveIntervalInSeconds()).isEqualTo(-1); this.gemfireConfiguration.setMaxInactiveIntervalInSeconds(Integer.MIN_VALUE); - assertThat(this.gemfireConfiguration.getMaxInactiveIntervalInSeconds()) - .isEqualTo(Integer.MIN_VALUE); + assertThat(this.gemfireConfiguration.getMaxInactiveIntervalInSeconds()).isEqualTo(Integer.MIN_VALUE); + } + + @Test + public void setAndGetPoolName() { + assertThat(this.gemfireConfiguration.getPoolName()).isEqualTo( + GemFireHttpSessionConfiguration.DEFAULT_GEMFIRE_POOL_NAME); + + this.gemfireConfiguration.setPoolName("TestPoolName"); + + assertThat(this.gemfireConfiguration.getPoolName()).isEqualTo("TestPoolName"); + + this.gemfireConfiguration.setPoolName(" "); + + assertThat(this.gemfireConfiguration.getPoolName()).isEqualTo( + GemFireHttpSessionConfiguration.DEFAULT_GEMFIRE_POOL_NAME); + + this.gemfireConfiguration.setPoolName(""); + + assertThat(this.gemfireConfiguration.getPoolName()).isEqualTo( + GemFireHttpSessionConfiguration.DEFAULT_GEMFIRE_POOL_NAME); + + this.gemfireConfiguration.setPoolName(null); + + assertThat(this.gemfireConfiguration.getPoolName()).isEqualTo( + GemFireHttpSessionConfiguration.DEFAULT_GEMFIRE_POOL_NAME); } @Test public void setAndGetServerRegionShortcut() { assertThat(this.gemfireConfiguration.getServerRegionShortcut()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_SERVER_REGION_SHORTCUT); + GemFireHttpSessionConfiguration.DEFAULT_SERVER_REGION_SHORTCUT); - this.gemfireConfiguration - .setServerRegionShortcut(RegionShortcut.REPLICATE_PERSISTENT); + this.gemfireConfiguration.setServerRegionShortcut(RegionShortcut.REPLICATE_PERSISTENT); - assertThat(this.gemfireConfiguration.getServerRegionShortcut()) - .isEqualTo(RegionShortcut.REPLICATE_PERSISTENT); + assertThat(this.gemfireConfiguration.getServerRegionShortcut()).isEqualTo( + RegionShortcut.REPLICATE_PERSISTENT); this.gemfireConfiguration.setServerRegionShortcut(null); assertThat(this.gemfireConfiguration.getServerRegionShortcut()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_SERVER_REGION_SHORTCUT); + GemFireHttpSessionConfiguration.DEFAULT_SERVER_REGION_SHORTCUT); } @Test public void setAndGetSpringSessionGemFireRegionName() { - assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()) - .isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); + assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()).isEqualTo( + GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); this.gemfireConfiguration.setSpringSessionGemFireRegionName("test"); - assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()) - .isEqualTo("test"); + assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()).isEqualTo("test"); this.gemfireConfiguration.setSpringSessionGemFireRegionName(" "); - assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()) - .isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); + assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()).isEqualTo( + GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); this.gemfireConfiguration.setSpringSessionGemFireRegionName(""); - assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()) - .isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); + assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()).isEqualTo( + GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); this.gemfireConfiguration.setSpringSessionGemFireRegionName(null); - assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()) - .isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); + assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()).isEqualTo( + GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); } @Test - public void setImportMetadata() { - AnnotationMetadata mockAnnotationMetadata = mock(AnnotationMetadata.class, - "testSetImportMetadata"); + public void setsImportMetadata() { + AnnotationMetadata mockAnnotationMetadata = mock(AnnotationMetadata.class); Map annotationAttributes = new HashMap(4); - annotationAttributes.put("clientRegionShortcut", - ClientRegionShortcut.CACHING_PROXY); - annotationAttributes.put("indexableSessionAttributes", - toArray("one", "two", "three")); + annotationAttributes.put("clientRegionShortcut", ClientRegionShortcut.CACHING_PROXY); + annotationAttributes.put("indexableSessionAttributes", toArray("one", "two", "three")); annotationAttributes.put("maxInactiveIntervalInSeconds", 600); + annotationAttributes.put("poolName", "TestPool"); annotationAttributes.put("serverRegionShortcut", RegionShortcut.REPLICATE); annotationAttributes.put("regionName", "TEST"); - given(mockAnnotationMetadata - .getAnnotationAttributes(eq(EnableGemFireHttpSession.class.getName()))) - .willReturn(annotationAttributes); + given(mockAnnotationMetadata.getAnnotationAttributes(eq(EnableGemFireHttpSession.class.getName()))) + .willReturn(annotationAttributes); this.gemfireConfiguration.setImportMetadata(mockAnnotationMetadata); - assertThat(this.gemfireConfiguration.getClientRegionShortcut()) - .isEqualTo(ClientRegionShortcut.CACHING_PROXY); - assertThat(this.gemfireConfiguration.getIndexableSessionAttributes()) - .isEqualTo(toArray("one", "two", "three")); - assertThat(this.gemfireConfiguration.getMaxInactiveIntervalInSeconds()) - .isEqualTo(600); - assertThat(this.gemfireConfiguration.getServerRegionShortcut()) - .isEqualTo(RegionShortcut.REPLICATE); - assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()) - .isEqualTo("TEST"); + assertThat(this.gemfireConfiguration.getClientRegionShortcut()).isEqualTo(ClientRegionShortcut.CACHING_PROXY); + assertThat(this.gemfireConfiguration.getIndexableSessionAttributes()).isEqualTo(toArray("one", "two", "three")); + 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"); - verify(mockAnnotationMetadata, times(1)) - .getAnnotationAttributes(eq(EnableGemFireHttpSession.class.getName())); + verify(mockAnnotationMetadata, times(1)).getAnnotationAttributes(eq(EnableGemFireHttpSession.class.getName())); } @Test - public void createAndInitializeSpringSessionRepositoryBean() { - GemfireOperations mockGemfireOperations = mock(GemfireOperations.class, - "testCreateAndInitializeSpringSessionRepositoryBean"); + public void createsAndInitializesSessionRepositoryBean() { + GemfireOperations mockGemfireOperations = mock(GemfireOperations.class); this.gemfireConfiguration.setMaxInactiveIntervalInSeconds(120); - GemFireOperationsSessionRepository sessionRepository = this.gemfireConfiguration - .sessionRepository(mockGemfireOperations); + GemFireOperationsSessionRepository sessionRepository = this.gemfireConfiguration.sessionRepository( + mockGemfireOperations); assertThat(sessionRepository).isNotNull(); assertThat(sessionRepository.getTemplate()).isSameAs(mockGemfireOperations); @@ -259,7 +287,7 @@ public class GemFireHttpSessionConfigurationTest { @Test @SuppressWarnings("unchecked") - public void createAndInitializeSpringSessionGemFireRegionTemplate() { + public void createsAndInitializesSessionRegionTemplateBean() { GemFireCache mockGemFireCache = mock(GemFireCache.class); Region mockRegion = mock(Region.class); @@ -267,59 +295,136 @@ public class GemFireHttpSessionConfigurationTest { this.gemfireConfiguration.setSpringSessionGemFireRegionName("Example"); - GemfireTemplate template = this.gemfireConfiguration - .sessionRegionTemplate(mockGemFireCache); + GemfireTemplate template = this.gemfireConfiguration.sessionRegionTemplate(mockGemFireCache); - assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()) - .isEqualTo("Example"); + assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()).isEqualTo("Example"); assertThat(template).isNotNull(); assertThat(template.getRegion()).isSameAs(mockRegion); verify(mockGemFireCache, times(1)).getRegion(eq("Example")); } + @Test + @SuppressWarnings("unchecked") + public void createsAndInitializesSessionRegionBean() { + GemFireCache mockGemFireCache = mock(GemFireCache.class); + RegionAttributes mockRegionAttributes = mock(RegionAttributes.class); + + this.gemfireConfiguration.setClientRegionShortcut(ClientRegionShortcut.CACHING_PROXY); + this.gemfireConfiguration.setPoolName("TestPool"); + this.gemfireConfiguration.setServerRegionShortcut(RegionShortcut.REPLICATE_PERSISTENT); + this.gemfireConfiguration.setSpringSessionGemFireRegionName("TestRegion"); + + GemFireCacheTypeAwareRegionFactoryBean sessionRegionFactoryBean = + this.gemfireConfiguration.sessionRegion(mockGemFireCache, mockRegionAttributes); + + assertThat(sessionRegionFactoryBean).isNotNull(); + assertThat(getField(sessionRegionFactoryBean, "clientRegionShortcut")).isEqualTo( + ClientRegionShortcut.CACHING_PROXY); + assertThat(getField(sessionRegionFactoryBean, "gemfireCache")).isEqualTo(mockGemFireCache); + assertThat(getField(sessionRegionFactoryBean, "poolName")).isEqualTo("TestPool"); + assertThat(getField(sessionRegionFactoryBean, "regionAttributes")).isEqualTo(mockRegionAttributes); + assertThat(getField(sessionRegionFactoryBean, "regionName")).isEqualTo("TestRegion"); + assertThat(getField(sessionRegionFactoryBean, "serverRegionShortcut")).isEqualTo( + RegionShortcut.REPLICATE_PERSISTENT); + + verifyZeroInteractions(mockGemFireCache); + verifyZeroInteractions(mockRegionAttributes); + } + + @Test + @SuppressWarnings("unchecked") + public void createsAndInitializesSessionRegionAttributesWithExpiration() throws Exception { + Cache mockCache = mock(Cache.class); + + this.gemfireConfiguration.setMaxInactiveIntervalInSeconds(300); + this.gemfireConfiguration.setServerRegionShortcut(RegionShortcut.LOCAL); + + RegionAttributesFactoryBean regionAttributesFactory = + this.gemfireConfiguration.sessionRegionAttributes(mockCache); + + assertThat(regionAttributesFactory).isNotNull(); + + regionAttributesFactory.afterPropertiesSet(); + + RegionAttributes sessionRegionAttributes = regionAttributesFactory.getObject(); + + assertThat(sessionRegionAttributes).isNotNull(); + assertThat(sessionRegionAttributes.getKeyConstraint()).isEqualTo( + GemFireHttpSessionConfiguration.SPRING_SESSION_GEMFIRE_REGION_KEY_CONSTRAINT); + assertThat(sessionRegionAttributes.getValueConstraint()).isEqualTo( + GemFireHttpSessionConfiguration.SPRING_SESSION_GEMFIRE_REGION_VALUE_CONSTRAINT); + + ExpirationAttributes entryIdleTimeoutExpiration = sessionRegionAttributes.getEntryIdleTimeout(); + + assertThat(entryIdleTimeoutExpiration).isNotNull(); + assertThat(entryIdleTimeoutExpiration.getAction()).isEqualTo(ExpirationAction.INVALIDATE); + assertThat(entryIdleTimeoutExpiration.getTimeout()).isEqualTo(300); + } + + @Test + public void createsAndInitializesSessionRegionAttributesWithoutExpiration() throws Exception { + ClientCache mockClientCache = mock(ClientCache.class); + + this.gemfireConfiguration.setMaxInactiveIntervalInSeconds(300); + + RegionAttributesFactoryBean regionAttributesFactory = + this.gemfireConfiguration.sessionRegionAttributes(mockClientCache); + + assertThat(regionAttributesFactory).isNotNull(); + + regionAttributesFactory.afterPropertiesSet(); + + RegionAttributes sessionRegionAttributes = regionAttributesFactory.getObject(); + + assertThat(sessionRegionAttributes).isNotNull(); + assertThat(sessionRegionAttributes.getKeyConstraint()).isEqualTo( + GemFireHttpSessionConfiguration.SPRING_SESSION_GEMFIRE_REGION_KEY_CONSTRAINT); + assertThat(sessionRegionAttributes.getValueConstraint()).isEqualTo( + GemFireHttpSessionConfiguration.SPRING_SESSION_GEMFIRE_REGION_VALUE_CONSTRAINT); + + ExpirationAttributes entryIdleTimeoutExpiration = sessionRegionAttributes.getEntryIdleTimeout(); + + assertThat(entryIdleTimeoutExpiration).isNotNull(); + assertThat(entryIdleTimeoutExpiration.getAction()).isEqualTo(ExpirationAction.INVALIDATE); + assertThat(entryIdleTimeoutExpiration.getTimeout()).isEqualTo(0); + } + @Test public void expirationIsAllowed() { - Cache mockCache = mock(Cache.class, "testExpirationIsAllowed.MockCache"); - ClientCache mockClientCache = mock(ClientCache.class, - "testExpirationIsAllowed.MockClientCache"); + Cache mockCache = mock(Cache.class); + + ClientCache mockClientCache = mock(ClientCache.class); this.gemfireConfiguration.setClientRegionShortcut(ClientRegionShortcut.PROXY); this.gemfireConfiguration.setServerRegionShortcut(RegionShortcut.REPLICATE); assertThat(this.gemfireConfiguration.isExpirationAllowed(mockCache)).isTrue(); - this.gemfireConfiguration.setServerRegionShortcut( - RegionShortcut.PARTITION_REDUNDANT_PERSISTENT_OVERFLOW); + this.gemfireConfiguration.setServerRegionShortcut(RegionShortcut.PARTITION_REDUNDANT_PERSISTENT_OVERFLOW); assertThat(this.gemfireConfiguration.isExpirationAllowed(mockCache)).isTrue(); - this.gemfireConfiguration - .setClientRegionShortcut(ClientRegionShortcut.CACHING_PROXY); + this.gemfireConfiguration.setClientRegionShortcut(ClientRegionShortcut.CACHING_PROXY); this.gemfireConfiguration.setServerRegionShortcut(RegionShortcut.PARTITION_PROXY); - assertThat(this.gemfireConfiguration.isExpirationAllowed(mockClientCache)) - .isTrue(); + assertThat(this.gemfireConfiguration.isExpirationAllowed(mockClientCache)).isTrue(); - this.gemfireConfiguration - .setClientRegionShortcut(ClientRegionShortcut.LOCAL_PERSISTENT_OVERFLOW); + this.gemfireConfiguration.setClientRegionShortcut(ClientRegionShortcut.LOCAL_PERSISTENT_OVERFLOW); this.gemfireConfiguration.setServerRegionShortcut(RegionShortcut.REPLICATE_PROXY); - assertThat(this.gemfireConfiguration.isExpirationAllowed(mockClientCache)) - .isTrue(); + assertThat(this.gemfireConfiguration.isExpirationAllowed(mockClientCache)).isTrue(); } @Test public void expirationIsNotAllowed() { - Cache mockCache = mock(Cache.class, "testExpirationIsAllowed.MockCache"); - ClientCache mockClientCache = mock(ClientCache.class, - "testExpirationIsAllowed.MockClientCache"); + Cache mockCache = mock(Cache.class); + ClientCache mockClientCache = mock(ClientCache.class); this.gemfireConfiguration.setClientRegionShortcut(ClientRegionShortcut.PROXY); this.gemfireConfiguration.setServerRegionShortcut(RegionShortcut.PARTITION); - assertThat(this.gemfireConfiguration.isExpirationAllowed(mockClientCache)) - .isFalse(); + assertThat(this.gemfireConfiguration.isExpirationAllowed(mockClientCache)).isFalse(); this.gemfireConfiguration.setClientRegionShortcut(ClientRegionShortcut.LOCAL); this.gemfireConfiguration.setServerRegionShortcut(RegionShortcut.PARTITION_PROXY); diff --git a/spring-session/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/GemFireCacheTypeAwareRegionFactoryBeanTest.java b/spring-session/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/GemFireCacheTypeAwareRegionFactoryBeanTest.java index 67796f2..0e959c2 100644 --- a/spring-session/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/GemFireCacheTypeAwareRegionFactoryBeanTest.java +++ b/spring-session/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/GemFireCacheTypeAwareRegionFactoryBeanTest.java @@ -67,6 +67,9 @@ public class GemFireCacheTypeAwareRegionFactoryBeanTest { @Rule public ExpectedException exception = ExpectedException.none(); + @Mock + Cache mockCache; + @Mock ClientCache mockClientCache; @@ -83,63 +86,43 @@ public class GemFireCacheTypeAwareRegionFactoryBeanTest { this.regionFactoryBean = new GemFireCacheTypeAwareRegionFactoryBean(); } - @Test - public void afterPropertiesSetCreatesClientRegionForClientCache() throws Exception { + protected void afterPropertiesSetCreatesCorrectRegionForGemFireCacheType(final GemFireCache expectedCache, + Region expectedRegion) throws Exception { + this.regionFactoryBean = new GemFireCacheTypeAwareRegionFactoryBean() { @Override - protected Region newClientRegion( - GemFireCache gemfireCache) throws Exception { - assertThat(gemfireCache).isSameAs( - GemFireCacheTypeAwareRegionFactoryBeanTest.this.mockClientCache); + protected Region newClientRegion(GemFireCache gemfireCache) throws Exception { + assertThat(gemfireCache).isSameAs(expectedCache); return GemFireCacheTypeAwareRegionFactoryBeanTest.this.mockClientRegion; } @Override - protected Region newServerRegion( - final GemFireCache gemfireCache) throws Exception { - assertThat(gemfireCache).isSameAs( - GemFireCacheTypeAwareRegionFactoryBeanTest.this.mockClientCache); + protected Region newServerRegion(GemFireCache gemfireCache) throws Exception { + assertThat(gemfireCache).isSameAs(expectedCache); return GemFireCacheTypeAwareRegionFactoryBeanTest.this.mockServerRegion; } }; - this.regionFactoryBean.setGemfireCache(this.mockClientCache); + this.regionFactoryBean.setGemfireCache(expectedCache); this.regionFactoryBean.afterPropertiesSet(); - assertThat(this.regionFactoryBean.getGemfireCache()) - .isSameAs(this.mockClientCache); - assertThat(this.regionFactoryBean.getObject()).isEqualTo(this.mockClientRegion); + assertThat(this.regionFactoryBean.getGemfireCache()).isSameAs(expectedCache); + assertThat(this.regionFactoryBean.getObject()).isEqualTo(expectedRegion); + assertThat(this.regionFactoryBean.getObjectType()).isEqualTo(expectedRegion.getClass()); + } + + @Test + public void afterPropertiesSetCreatesClientRegionForClientCache() throws Exception { + afterPropertiesSetCreatesCorrectRegionForGemFireCacheType(this.mockClientCache, this.mockClientRegion); } @Test public void afterPropertiesSetCreatesServerRegionForPeerCache() throws Exception { - final Cache mockCache = mock(Cache.class); - - this.regionFactoryBean = new GemFireCacheTypeAwareRegionFactoryBean() { - @Override - protected Region newClientRegion( - GemFireCache gemfireCache) throws Exception { - assertThat(gemfireCache).isSameAs(mockCache); - return GemFireCacheTypeAwareRegionFactoryBeanTest.this.mockClientRegion; - } - - @Override - protected Region newServerRegion( - final GemFireCache gemfireCache) throws Exception { - assertThat(gemfireCache).isSameAs(mockCache); - return GemFireCacheTypeAwareRegionFactoryBeanTest.this.mockServerRegion; - } - }; - - this.regionFactoryBean.setGemfireCache(mockCache); - this.regionFactoryBean.afterPropertiesSet(); - - assertThat(this.regionFactoryBean.getGemfireCache()).isSameAs(mockCache); - assertThat(this.regionFactoryBean.getObject()).isEqualTo(this.mockServerRegion); + afterPropertiesSetCreatesCorrectRegionForGemFireCacheType(this.mockCache, this.mockServerRegion); } @Test - public void allKeysInterestRegistration() { + public void allKeysInterestsRegistration() { Interest[] interests = this.regionFactoryBean.registerInterests(true); assertThat(interests).isNotNull(); @@ -187,26 +170,24 @@ public class GemFireCacheTypeAwareRegionFactoryBeanTest { @Test public void getBeanFactoryWhenNullThrowsIllegalStateException() { this.exception.expect(IllegalStateException.class); - this.exception.expectMessage( - "A reference to the BeanFactory was not properly configured"); + this.exception.expectMessage("A reference to the BeanFactory was not properly configured"); this.regionFactoryBean.getBeanFactory(); } @Test public void setAndGetClientRegionShortcut() { assertThat(this.regionFactoryBean.getClientRegionShortcut()).isEqualTo( - GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_CLIENT_REGION_SHORTCUT); + GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_CLIENT_REGION_SHORTCUT); - this.regionFactoryBean.setClientRegionShortcut( + this.regionFactoryBean.setClientRegionShortcut(ClientRegionShortcut.LOCAL_PERSISTENT); + + assertThat(this.regionFactoryBean.getClientRegionShortcut()).isEqualTo( ClientRegionShortcut.LOCAL_PERSISTENT); - assertThat(this.regionFactoryBean.getClientRegionShortcut()) - .isEqualTo(ClientRegionShortcut.LOCAL_PERSISTENT); - this.regionFactoryBean.setClientRegionShortcut(null); assertThat(this.regionFactoryBean.getClientRegionShortcut()).isEqualTo( - GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_CLIENT_REGION_SHORTCUT); + GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_CLIENT_REGION_SHORTCUT); } @Test @@ -228,23 +209,45 @@ public class GemFireCacheTypeAwareRegionFactoryBeanTest { @Test public void getGemfireCacheWhenNullThrowsIllegalStateException() { this.exception.expect(IllegalStateException.class); - this.exception.expectMessage( - "A reference to the GemFireCache was not properly configured"); + this.exception.expectMessage("A reference to the GemFireCache was not properly configured"); this.regionFactoryBean.getGemfireCache(); } + @Test + public void setAndGetPoolName() { + assertThat(this.regionFactoryBean.getPoolName()).isEqualTo( + GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_GEMFIRE_POOL_NAME); + + this.regionFactoryBean.setPoolName("TestPoolName"); + + assertThat(this.regionFactoryBean.getPoolName()).isEqualTo("TestPoolName"); + + this.regionFactoryBean.setPoolName(" "); + + assertThat(this.regionFactoryBean.getPoolName()).isEqualTo( + GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_GEMFIRE_POOL_NAME); + + this.regionFactoryBean.setPoolName(""); + + assertThat(this.regionFactoryBean.getPoolName()).isEqualTo( + GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_GEMFIRE_POOL_NAME); + + this.regionFactoryBean.setPoolName(null); + + assertThat(this.regionFactoryBean.getPoolName()).isEqualTo( + GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_GEMFIRE_POOL_NAME); + } + @Test @SuppressWarnings("unchecked") public void setAndGetRegionAttributes() { - RegionAttributes mockRegionAttributes = mock( - RegionAttributes.class); + RegionAttributes mockRegionAttributes = mock(RegionAttributes.class); assertThat(this.regionFactoryBean.getRegionAttributes()).isNull(); this.regionFactoryBean.setRegionAttributes(mockRegionAttributes); - assertThat(this.regionFactoryBean.getRegionAttributes()) - .isSameAs(mockRegionAttributes); + assertThat(this.regionFactoryBean.getRegionAttributes()).isSameAs(mockRegionAttributes); this.regionFactoryBean.setRegionAttributes(null); @@ -254,7 +257,7 @@ public class GemFireCacheTypeAwareRegionFactoryBeanTest { @Test public void setAndGetRegionName() { assertThat(this.regionFactoryBean.getRegionName()).isEqualTo( - GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); + GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); this.regionFactoryBean.setRegionName("Example"); @@ -263,33 +266,32 @@ public class GemFireCacheTypeAwareRegionFactoryBeanTest { this.regionFactoryBean.setRegionName(" "); assertThat(this.regionFactoryBean.getRegionName()).isEqualTo( - GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); + GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); this.regionFactoryBean.setRegionName(""); assertThat(this.regionFactoryBean.getRegionName()).isEqualTo( - GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); + GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); this.regionFactoryBean.setRegionName(null); assertThat(this.regionFactoryBean.getRegionName()).isEqualTo( - GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); + GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); } @Test public void setAndGetServerRegionShortcut() { assertThat(this.regionFactoryBean.getServerRegionShortcut()).isEqualTo( - GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SERVER_REGION_SHORTCUT); + GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SERVER_REGION_SHORTCUT); this.regionFactoryBean.setServerRegionShortcut(RegionShortcut.LOCAL_PERSISTENT); - assertThat(this.regionFactoryBean.getServerRegionShortcut()) - .isEqualTo(RegionShortcut.LOCAL_PERSISTENT); + assertThat(this.regionFactoryBean.getServerRegionShortcut()).isEqualTo(RegionShortcut.LOCAL_PERSISTENT); this.regionFactoryBean.setServerRegionShortcut(null); assertThat(this.regionFactoryBean.getServerRegionShortcut()).isEqualTo( - GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SERVER_REGION_SHORTCUT); + GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SERVER_REGION_SHORTCUT); } }