Improve GemFire SessionRepository, Session copy logic to avoid issues with delta propagation on updates
Fixes #gh-755
(cherry picked from commit dcc0c07981)
Signed-off-by: John Blum <jblum@pivotal.io>
This commit is contained in:
@@ -80,7 +80,7 @@ public abstract class AbstractGemFireIntegrationTests {
|
||||
System.getProperty("spring.session.data.gemfire.log-file", "server.log");
|
||||
|
||||
protected static final String GEMFIRE_LOG_LEVEL =
|
||||
System.getProperty("spring.session.data.gemfire.log-level", "warning");
|
||||
System.getProperty("spring.session.data.gemfire.log-level", "error");
|
||||
|
||||
@Autowired
|
||||
protected Cache gemfireCache;
|
||||
@@ -255,7 +255,7 @@ public abstract class AbstractGemFireIntegrationTests {
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected static int waitForProcessToStop(Process process, File directory, long duration) {
|
||||
final long timeout = (System.currentTimeMillis() + duration);
|
||||
long timeout = (System.currentTimeMillis() + duration);
|
||||
|
||||
try {
|
||||
while (process.isAlive() && System.currentTimeMillis() < timeout) {
|
||||
@@ -279,7 +279,7 @@ public abstract class AbstractGemFireIntegrationTests {
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("all")
|
||||
protected static boolean waitOnCondition(Condition condition, long duration) {
|
||||
final long timeout = (System.currentTimeMillis() + duration);
|
||||
long timeout = (System.currentTimeMillis() + duration);
|
||||
|
||||
try {
|
||||
while (!condition.evaluate() && System.currentTimeMillis() < timeout) {
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.apache.geode.cache.DataPolicy;
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.RegionAttributes;
|
||||
import org.apache.geode.cache.client.ClientCache;
|
||||
import org.apache.geode.cache.client.ClientRegionShortcut;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
@@ -59,7 +60,7 @@ import org.springframework.session.events.SessionDeletedEvent;
|
||||
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.junit4.SpringRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.util.FileSystemUtils;
|
||||
import org.springframework.util.SocketUtils;
|
||||
@@ -67,28 +68,30 @@ import org.springframework.util.SocketUtils;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* The ClientServerGemFireOperationsSessionRepositoryIntegrationTests class is a test
|
||||
* suite of test cases testing the functionality of GemFire-backed Spring Sessions using a
|
||||
* GemFire client-server topology.
|
||||
* Integration tests to test the functionality of GemFire-backed Spring Sessions using
|
||||
* the GemFire client-server topology.
|
||||
*
|
||||
* @author John Blum
|
||||
* @since 1.1.0
|
||||
* @see org.junit.Test
|
||||
* @see org.junit.runner.RunWith
|
||||
* @see org.springframework.context.ConfigurableApplicationContext
|
||||
* @see org.springframework.session.ExpiringSession
|
||||
* @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.junit4.SpringRunner
|
||||
* @see org.springframework.test.context.web.WebAppConfiguration
|
||||
* @see org.apache.geode.cache.Cache
|
||||
* @see org.apache.geode.cache.client.ClientCache
|
||||
* @see org.apache.geode.cache.client.Pool
|
||||
* @see org.apache.geode.cache.server.CacheServer
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = ClientServerGemFireOperationsSessionRepositoryIntegrationTests.SpringSessionGemFireClientConfiguration.class)
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration(classes =
|
||||
ClientServerGemFireOperationsSessionRepositoryIntegrationTests.SpringSessionDataGemFireClientConfiguration.class)
|
||||
@DirtiesContext
|
||||
@WebAppConfiguration
|
||||
public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
@@ -109,24 +112,25 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
|
||||
@BeforeClass
|
||||
public static void startGemFireServer() throws IOException {
|
||||
final long t0 = System.currentTimeMillis();
|
||||
long t0 = System.currentTimeMillis();
|
||||
|
||||
final int port = SocketUtils.findAvailableTcpPort();
|
||||
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.err.printf("Starting a GemFire Server running on host [%1$s] listening on port [%2$d]%n",
|
||||
SpringSessionDataGemFireServerConfiguration.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,
|
||||
gemfireServer = run(SpringSessionDataGemFireServerConfiguration.class, processWorkingDirectory,
|
||||
String.format("-Dspring.session.data.gemfire.port=%1$d", port));
|
||||
|
||||
assertThat(waitForCacheServerToStart(SpringSessionGemFireServerConfiguration.SERVER_HOSTNAME, port)).isTrue();
|
||||
assertThat(waitForCacheServerToStart(SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port))
|
||||
.isTrue();
|
||||
|
||||
System.err.printf("GemFire Server [startup time = %1$d ms]%n", System.currentTimeMillis() - t0);
|
||||
}
|
||||
@@ -134,7 +138,7 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
@AfterClass
|
||||
public static void stopGemFireServerAndDeleteArtifacts() {
|
||||
if (gemfireServer != null) {
|
||||
gemfireServer.destroyForcibly();
|
||||
gemfireServer.destroy();
|
||||
System.err.printf("GemFire Server [exit code = %1$d]%n",
|
||||
waitForProcessToStop(gemfireServer, processWorkingDirectory));
|
||||
}
|
||||
@@ -159,7 +163,7 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
springSessionGemFireRegion.getAttributes();
|
||||
|
||||
assertThat(springSessionGemFireRegionAttributes).isNotNull();
|
||||
assertThat(springSessionGemFireRegionAttributes.getDataPolicy()).isEqualTo(DataPolicy.EMPTY);
|
||||
assertThat(springSessionGemFireRegionAttributes.getDataPolicy()).isEqualTo(DataPolicy.NORMAL);
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -169,7 +173,7 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
|
||||
@Test
|
||||
public void createSessionFiresSessionCreatedEvent() {
|
||||
final long beforeOrAtCreationTime = System.currentTimeMillis();
|
||||
long beforeOrAtCreationTime = System.currentTimeMillis();
|
||||
|
||||
ExpiringSession expectedSession = save(createSession());
|
||||
|
||||
@@ -179,12 +183,19 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
|
||||
ExpiringSession createdSession = sessionEvent.getSession();
|
||||
|
||||
assertThat(createdSession).isEqualTo(expectedSession);
|
||||
assertThat(createdSession.getId()).isNotNull();
|
||||
assertThat(createdSession.getId()).isEqualTo(expectedSession.getId());
|
||||
assertThat(createdSession.getCreationTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime);
|
||||
assertThat(createdSession.getLastAccessedTime()).isEqualTo(createdSession.getCreationTime());
|
||||
assertThat(createdSession.getMaxInactiveIntervalInSeconds()).isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
||||
|
||||
createdSession.setAttribute("attrOne", 1);
|
||||
|
||||
assertThat(save(touch(createdSession)).getAttribute("attrOne")).isEqualTo(1);
|
||||
|
||||
sessionEvent = this.sessionEventListener.waitForSessionEvent(500);
|
||||
|
||||
assertThat(sessionEvent).isNull();
|
||||
|
||||
this.gemfireSessionRepository.delete(expectedSession.getId());
|
||||
}
|
||||
|
||||
@@ -195,19 +206,13 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
AbstractSessionEvent sessionEvent = this.sessionEventListener.waitForSessionEvent(500);
|
||||
|
||||
assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class);
|
||||
assertThat(sessionEvent.<ExpiringSession>getSession()).isEqualTo(expectedSession);
|
||||
assertThat(sessionEvent.getSession()).isEqualTo(expectedSession);
|
||||
assertThat(this.sessionEventListener.getSessionEvent()).isNull();
|
||||
|
||||
ExpiringSession savedSession = this.gemfireSessionRepository.getSession(expectedSession.getId());
|
||||
|
||||
assertThat(savedSession).isEqualTo(expectedSession);
|
||||
|
||||
// NOTE for some reason or another, performing a GemFire (Client)Cache
|
||||
// Region.get(key)
|
||||
// causes a Region CREATE event... o.O
|
||||
// calling sessionEventListener.getSessionEvent() here to clear the event
|
||||
this.sessionEventListener.getSessionEvent();
|
||||
|
||||
sessionEvent = this.sessionEventListener.waitForSessionEvent(
|
||||
TimeUnit.SECONDS.toMillis(MAX_INACTIVE_INTERVAL_IN_SECONDS + 1));
|
||||
|
||||
@@ -241,11 +246,12 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
}
|
||||
|
||||
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME,
|
||||
maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
|
||||
static class SpringSessionGemFireClientConfiguration {
|
||||
clientRegionShortcut = ClientRegionShortcut.CACHING_PROXY,
|
||||
maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
|
||||
static class SpringSessionDataGemFireClientConfiguration {
|
||||
|
||||
@Bean
|
||||
static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
|
||||
static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
|
||||
return new PropertySourcesPlaceholderConfigurer();
|
||||
}
|
||||
|
||||
@@ -271,17 +277,14 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
|
||||
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.setServers(Collections.singletonList(new ConnectionEndpoint(
|
||||
SpringSessionGemFireServerConfiguration.SERVER_HOSTNAME, port)));
|
||||
SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port)));
|
||||
|
||||
return poolFactory;
|
||||
}
|
||||
@@ -293,9 +296,9 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
|
||||
// used for debugging purposes
|
||||
@SuppressWarnings("resource")
|
||||
public static void main(final String[] args) {
|
||||
ConfigurableApplicationContext applicationContext =
|
||||
new AnnotationConfigApplicationContext(SpringSessionGemFireClientConfiguration.class);
|
||||
public static void main(String[] args) {
|
||||
ConfigurableApplicationContext applicationContext = new AnnotationConfigApplicationContext(
|
||||
SpringSessionDataGemFireClientConfiguration.class);
|
||||
|
||||
applicationContext.registerShutdownHook();
|
||||
|
||||
@@ -310,30 +313,27 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
|
||||
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME,
|
||||
maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
|
||||
static class SpringSessionGemFireServerConfiguration {
|
||||
static class SpringSessionDataGemFireServerConfiguration {
|
||||
|
||||
static final int MAX_CONNECTIONS = 50;
|
||||
static final String SERVER_HOSTNAME = "localhost";
|
||||
|
||||
@Bean
|
||||
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
|
||||
static 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();
|
||||
return SpringSessionDataGemFireServerConfiguration.class.getName();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -352,20 +352,21 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||
|
||||
CacheServerFactoryBean cacheServerFactory = new CacheServerFactoryBean();
|
||||
|
||||
cacheServerFactory.setCache(gemfireCache);
|
||||
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 {
|
||||
public static void main(String[] args) throws IOException {
|
||||
AnnotationConfigApplicationContext context =
|
||||
new AnnotationConfigApplicationContext(SpringSessionGemFireServerConfiguration.class);
|
||||
new AnnotationConfigApplicationContext(SpringSessionDataGemFireServerConfiguration.class);
|
||||
|
||||
context.registerShutdownHook();
|
||||
|
||||
writeProcessControlFile(WORKING_DIRECTORY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
* 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.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.geode.cache.Cache;
|
||||
import org.apache.geode.cache.client.ClientCache;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
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.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.util.FileSystemUtils;
|
||||
import org.springframework.util.SocketUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests testing the addition/removal of HTTP Session Attributes
|
||||
* and the proper persistence of the HTTP Session state in a GemFire cache
|
||||
* across a client/server topology.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.junit.runner.RunWith
|
||||
* @see org.springframework.context.ConfigurableApplicationContext
|
||||
* @see org.springframework.session.ExpiringSession
|
||||
* @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.context.ContextConfiguration
|
||||
* @see org.springframework.test.context.junit4.SpringRunner
|
||||
* @see org.apache.geode.cache.Cache
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.apache.geode.cache.client.ClientCache
|
||||
* @since 1.3.1
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration(classes =
|
||||
ClientServerHttpSessionAttributesDeltaIntegrationTests.SpringSessionDataGemFireClientConfiguration.class)
|
||||
public class ClientServerHttpSessionAttributesDeltaIntegrationTests 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;
|
||||
|
||||
@BeforeClass
|
||||
public static void startGemFireServer() throws IOException {
|
||||
long t0 = System.currentTimeMillis();
|
||||
|
||||
int port = SocketUtils.findAvailableTcpPort();
|
||||
|
||||
System.err.printf("Starting a GemFire Server running on host [%1$s] listening on port [%2$d]%n",
|
||||
SpringSessionDataGemFireServerConfiguration.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()));
|
||||
|
||||
processWorkingDirectory = createDirectory(processWorkingDirectoryPathname);
|
||||
|
||||
gemfireServer = run(SpringSessionDataGemFireServerConfiguration.class, processWorkingDirectory,
|
||||
String.format("-Dspring.session.data.gemfire.port=%1$d", port));
|
||||
|
||||
assertThat(waitForCacheServerToStart(SpringSessionDataGemFireServerConfiguration.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.destroy();
|
||||
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();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sessionCreationAndAccessIsSuccessful() {
|
||||
ExpiringSession session = save(touch(createSession()));
|
||||
|
||||
assertThat(session).isNotNull();
|
||||
assertThat(session.isExpired()).isFalse();
|
||||
|
||||
session.setAttribute("attrOne", 1);
|
||||
session.setAttribute("attrTwo", 2);
|
||||
|
||||
save(touch(session));
|
||||
|
||||
ExpiringSession loadedSession = get(session.getId());
|
||||
|
||||
assertThat(loadedSession).isNotNull();
|
||||
assertThat(loadedSession.isExpired()).isFalse();
|
||||
assertThat(loadedSession).isNotSameAs(session);
|
||||
assertThat(loadedSession.getId()).isEqualTo(session.getId());
|
||||
assertThat(loadedSession.<Integer>getAttribute("attrOne")).isEqualTo(1);
|
||||
assertThat(loadedSession.<Integer>getAttribute("attrTwo")).isEqualTo(2);
|
||||
|
||||
loadedSession.removeAttribute("attrTwo");
|
||||
|
||||
assertThat(loadedSession.getAttributeNames()).doesNotContain("attrTwo");
|
||||
assertThat(loadedSession.getAttributeNames()).hasSize(1);
|
||||
|
||||
save(touch(loadedSession));
|
||||
|
||||
ExpiringSession reloadedSession = get(loadedSession.getId());
|
||||
|
||||
assertThat(reloadedSession).isNotNull();
|
||||
assertThat(reloadedSession.isExpired()).isFalse();
|
||||
assertThat(reloadedSession).isNotSameAs(loadedSession);
|
||||
assertThat(reloadedSession.getId()).isEqualTo(loadedSession.getId());
|
||||
assertThat(reloadedSession.getAttributeNames()).hasSize(1);
|
||||
assertThat(reloadedSession.getAttributeNames()).doesNotContain("attrTwo");
|
||||
assertThat(reloadedSession.<Integer>getAttribute("attrOne")).isEqualTo(1);
|
||||
}
|
||||
|
||||
@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
|
||||
static class SpringSessionDataGemFireClientConfiguration {
|
||||
|
||||
@Bean
|
||||
static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
|
||||
return new PropertySourcesPlaceholderConfigurer();
|
||||
}
|
||||
|
||||
Properties gemfireProperties() {
|
||||
Properties gemfireProperties = new Properties();
|
||||
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
|
||||
return gemfireProperties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
ClientCacheFactoryBean gemfireCache() {
|
||||
ClientCacheFactoryBean clientCacheFactory = new ClientCacheFactoryBean();
|
||||
|
||||
clientCacheFactory.setClose(true);
|
||||
clientCacheFactory.setProperties(gemfireProperties());
|
||||
|
||||
return clientCacheFactory;
|
||||
}
|
||||
|
||||
@Bean
|
||||
PoolFactoryBean gemfirePool(@Value("${spring.session.data.gemfire.port:"
|
||||
+ DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) {
|
||||
|
||||
PoolFactoryBean poolFactory = new PoolFactoryBean();
|
||||
|
||||
poolFactory.setKeepAlive(false);
|
||||
poolFactory.setPingInterval(TimeUnit.SECONDS.toMillis(5));
|
||||
poolFactory.setReadTimeout(2000); // 2 seconds
|
||||
poolFactory.setRetryAttempts(1);
|
||||
poolFactory.setSubscriptionEnabled(true);
|
||||
|
||||
poolFactory.setServers(Collections.singletonList(new ConnectionEndpoint(
|
||||
SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port)));
|
||||
|
||||
return poolFactory;
|
||||
}
|
||||
|
||||
// used for debugging purposes
|
||||
@SuppressWarnings("resource")
|
||||
public static void main(String[] args) {
|
||||
ConfigurableApplicationContext applicationContext =
|
||||
new AnnotationConfigApplicationContext(SpringSessionDataGemFireClientConfiguration.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(maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
|
||||
static class SpringSessionDataGemFireServerConfiguration {
|
||||
|
||||
static final String SERVER_HOSTNAME = "localhost";
|
||||
|
||||
@Bean
|
||||
static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
|
||||
return new PropertySourcesPlaceholderConfigurer();
|
||||
}
|
||||
|
||||
Properties gemfireProperties() {
|
||||
Properties gemfireProperties = new Properties();
|
||||
|
||||
gemfireProperties.setProperty("name", name());
|
||||
gemfireProperties.setProperty("mcast-port", "0");
|
||||
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
|
||||
|
||||
return gemfireProperties;
|
||||
}
|
||||
|
||||
String name() {
|
||||
return SpringSessionDataGemFireServerConfiguration.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.setCache(gemfireCache);
|
||||
cacheServerFactory.setAutoStartup(true);
|
||||
cacheServerFactory.setBindAddress(SERVER_HOSTNAME);
|
||||
cacheServerFactory.setPort(port);
|
||||
|
||||
return cacheServerFactory;
|
||||
}
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
public static void main(String[] args) throws IOException {
|
||||
AnnotationConfigApplicationContext context =
|
||||
new AnnotationConfigApplicationContext(SpringSessionDataGemFireServerConfiguration.class);
|
||||
|
||||
context.registerShutdownHook();
|
||||
|
||||
writeProcessControlFile(WORKING_DIRECTORY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -276,6 +276,19 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
handleExpired(event.getKey().toString(), toExpiringSession(event.getOldValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the given {@link Session} from GemFire.
|
||||
*
|
||||
* @param session {@link Session} to delete.
|
||||
* @return {@literal null}.
|
||||
* @see org.springframework.session.Session
|
||||
* @see #delete(String)
|
||||
*/
|
||||
protected ExpiringSession delete(Session session) {
|
||||
delete(session.getId());
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Causes Session created events to be published to the Spring application context.
|
||||
*
|
||||
@@ -344,10 +357,23 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
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 [%s]", event), t);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the {@link ExpiringSession#setLastAccessedTime(long)} property of the {@link ExpiringSession}.
|
||||
*
|
||||
* @param <T> {@link Class} sub-type of the {@link ExpiringSession}.
|
||||
* @param expiringSession {@link ExpiringSession} to touch.
|
||||
* @return the {@link ExpiringSession}.
|
||||
* @see org.springframework.session.ExpiringSession#setLastAccessedTime(long)
|
||||
*/
|
||||
protected <T extends ExpiringSession> T touch(T expiringSession) {
|
||||
expiringSession.setLastAccessedTime(System.currentTimeMillis());
|
||||
return expiringSession;
|
||||
}
|
||||
|
||||
/**
|
||||
* GemFireSession is a GemFire representation model of a Spring {@link ExpiringSession}
|
||||
* that stores and manages Session state information in GemFire. This class implements
|
||||
@@ -407,11 +433,13 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
||||
return session;
|
||||
}
|
||||
|
||||
public static GemFireSession copy(ExpiringSession session) {
|
||||
return new GemFireSession(session);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public static GemFireSession from(ExpiringSession expiringSession) {
|
||||
GemFireSession session = new GemFireSession(expiringSession);
|
||||
session.setLastAccessedTime(System.currentTimeMillis());
|
||||
return session;
|
||||
public static GemFireSession from(ExpiringSession session) {
|
||||
return (session instanceof GemFireSession ? (GemFireSession) session : copy(session));
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
|
||||
@@ -122,15 +122,12 @@ public class GemFireOperationsSessionRepository extends AbstractGemFireOperation
|
||||
ExpiringSession storedSession = getTemplate().get(sessionId);
|
||||
|
||||
if (storedSession != null) {
|
||||
if (storedSession.isExpired()) {
|
||||
delete(storedSession.getId());
|
||||
}
|
||||
else {
|
||||
return GemFireSession.from(storedSession);
|
||||
}
|
||||
storedSession = storedSession.isExpired()
|
||||
? delete(storedSession)
|
||||
: touch(GemFireSession.from(storedSession));
|
||||
}
|
||||
|
||||
return null;
|
||||
return storedSession;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,7 +138,7 @@ public class GemFireOperationsSessionRepository extends AbstractGemFireOperation
|
||||
* @see org.springframework.session.ExpiringSession
|
||||
*/
|
||||
public void save(ExpiringSession session) {
|
||||
getTemplate().put(session.getId(), new GemFireSession(session));
|
||||
getTemplate().put(session.getId(), GemFireSession.from(session));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -101,7 +101,7 @@ import org.springframework.context.annotation.Import;
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.session.config.annotation.web.http.EnableSpringHttpSession
|
||||
* @see GemFireHttpSessionConfiguration
|
||||
* @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@Documented
|
||||
|
||||
@@ -32,14 +32,13 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
import edu.umd.cs.mtc.MultithreadedTestCase;
|
||||
import edu.umd.cs.mtc.TestFramework;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.geode.cache.AttributesMutator;
|
||||
import org.apache.geode.cache.EntryEvent;
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
@@ -70,14 +69,17 @@ import static org.mockito.ArgumentMatchers.same;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.BDDMockito.willAnswer;
|
||||
import static org.mockito.BDDMockito.willThrow;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AbstractGemFireOperationsSessionRepository} class.
|
||||
* Unit tests for {@link AbstractGemFireOperationsSessionRepository}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @since 1.1.0
|
||||
@@ -88,6 +90,7 @@ import static org.mockito.Mockito.verify;
|
||||
* @see org.mockito.Mock
|
||||
* @see org.mockito.Mockito
|
||||
* @see org.mockito.junit.MockitoJUnitRunner
|
||||
* @see org.mockito.Spy
|
||||
* @see org.springframework.data.gemfire.GemfireOperations
|
||||
* @see org.springframework.data.gemfire.GemfireTemplate
|
||||
* @see org.springframework.session.ExpiringSession
|
||||
@@ -103,8 +106,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
protected static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 600;
|
||||
|
||||
@Rule
|
||||
public ExpectedException expectedException = ExpectedException.none();
|
||||
private AbstractGemFireOperationsSessionRepository sessionRepository;
|
||||
|
||||
@Mock
|
||||
private GemfireOperations mockGemfireOperations;
|
||||
@@ -112,16 +114,14 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
@Mock
|
||||
private Log mockLog;
|
||||
|
||||
private AbstractGemFireOperationsSessionRepository sessionRepository;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.sessionRepository = new TestGemFireOperationsSessionRepository(this.mockGemfireOperations) {
|
||||
this.sessionRepository = spy(new TestGemFireOperationsSessionRepository(this.mockGemfireOperations) {
|
||||
@Override
|
||||
Log newLogger() {
|
||||
return AbstractGemFireOperationsSessionRepositoryTest.this.mockLog;
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
protected static <E> Set<E> asSet(E... elements) {
|
||||
@@ -133,12 +133,12 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
protected ExpiringSession mockSession(String sessionId, long creationAndLastAccessedTime,
|
||||
int maxInactiveIntervalInSeconds) {
|
||||
|
||||
return mockSession(sessionId, creationAndLastAccessedTime,
|
||||
creationAndLastAccessedTime, maxInactiveIntervalInSeconds);
|
||||
return mockSession(sessionId, creationAndLastAccessedTime, creationAndLastAccessedTime,
|
||||
maxInactiveIntervalInSeconds);
|
||||
}
|
||||
|
||||
protected ExpiringSession mockSession(String sessionId, long creationTime,
|
||||
long lastAccessedTime, int maxInactiveIntervalInSeconds) {
|
||||
protected ExpiringSession mockSession(String sessionId, long creationTime, long lastAccessedTime,
|
||||
int maxInactiveIntervalInSeconds) {
|
||||
|
||||
ExpiringSession mockSession = mock(ExpiringSession.class, sessionId);
|
||||
|
||||
@@ -150,12 +150,17 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
return mockSession;
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructGemFireOperationsSessionRepositoryWithNullTemplate() {
|
||||
this.expectedException.expect(IllegalArgumentException.class);
|
||||
this.expectedException.expectMessage("GemfireOperations must not be null");
|
||||
try {
|
||||
new TestGemFireOperationsSessionRepository(null);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertThat(expected).hasMessage("GemfireOperations must not be null");
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
new TestGemFireOperationsSessionRepository(null);
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -208,9 +213,9 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
assertThat(this.sessionRepository.getMaxInactiveIntervalInSeconds()).isEqualTo(Integer.MIN_VALUE);
|
||||
|
||||
this.sessionRepository.setMaxInactiveIntervalInSeconds(3600);
|
||||
this.sessionRepository.setMaxInactiveIntervalInSeconds(1024000);
|
||||
|
||||
assertThat(this.sessionRepository.getMaxInactiveIntervalInSeconds()).isEqualTo(3600);
|
||||
assertThat(this.sessionRepository.getMaxInactiveIntervalInSeconds()).isEqualTo(1024000);
|
||||
|
||||
this.sessionRepository.setMaxInactiveIntervalInSeconds(Integer.MAX_VALUE);
|
||||
|
||||
@@ -258,7 +263,8 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
verify(mockEntryEvent, times(2)).getNewValue();
|
||||
verify(mockEntryEvent, never()).getOldValue();
|
||||
verify(mockSession, times(1)).getId();
|
||||
verify(mockApplicationEventPublisher, times(1)).publishEvent(isA(SessionCreatedEvent.class));
|
||||
verify(mockApplicationEventPublisher, times(1))
|
||||
.publishEvent(isA(SessionCreatedEvent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -298,7 +304,8 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
verify(mockEntryEvent, times(1)).getKey();
|
||||
verify(mockEntryEvent, times(2)).getNewValue();
|
||||
verify(mockEntryEvent, never()).getOldValue();
|
||||
verify(mockApplicationEventPublisher, times(1)).publishEvent(isA(SessionCreatedEvent.class));
|
||||
verify(mockApplicationEventPublisher, times(1))
|
||||
.publishEvent(isA(SessionCreatedEvent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -364,7 +371,8 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
verify(mockEntryEvent, never()).getNewValue();
|
||||
verify(mockEntryEvent, times(1)).getOldValue();
|
||||
verify(mockSession, times(1)).getId();
|
||||
verify(mockApplicationEventPublisher, times(1)).publishEvent(isA(SessionDestroyedEvent.class));
|
||||
verify(mockApplicationEventPublisher, times(1))
|
||||
.publishEvent(isA(SessionDestroyedEvent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -404,7 +412,8 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
verify(mockEntryEvent, times(1)).getKey();
|
||||
verify(mockEntryEvent, never()).getNewValue();
|
||||
verify(mockEntryEvent, times(1)).getOldValue();
|
||||
verify(mockApplicationEventPublisher, times(1)).publishEvent(isA(SessionDestroyedEvent.class));
|
||||
verify(mockApplicationEventPublisher, times(1))
|
||||
.publishEvent(isA(SessionDestroyedEvent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -444,7 +453,8 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
verify(mockEntryEvent, times(1)).getKey();
|
||||
verify(mockEntryEvent, never()).getNewValue();
|
||||
verify(mockEntryEvent, times(1)).getOldValue();
|
||||
verify(mockApplicationEventPublisher, times(1)).publishEvent(isA(SessionDestroyedEvent.class));
|
||||
verify(mockApplicationEventPublisher, times(1))
|
||||
.publishEvent(isA(SessionDestroyedEvent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -528,7 +538,8 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
verify(mockEntryEvent, times(1)).getKey();
|
||||
verify(mockEntryEvent, never()).getNewValue();
|
||||
verify(mockEntryEvent, times(1)).getOldValue();
|
||||
verify(mockApplicationEventPublisher, times(1)).publishEvent(isA(SessionExpiredEvent.class));
|
||||
verify(mockApplicationEventPublisher, times(1))
|
||||
.publishEvent(isA(SessionExpiredEvent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -568,7 +579,20 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
verify(mockEntryEvent, times(1)).getKey();
|
||||
verify(mockEntryEvent, never()).getNewValue();
|
||||
verify(mockEntryEvent, times(1)).getOldValue();
|
||||
verify(mockApplicationEventPublisher, times(1)).publishEvent(isA(SessionExpiredEvent.class));
|
||||
verify(mockApplicationEventPublisher, times(1))
|
||||
.publishEvent(isA(SessionExpiredEvent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteSessionCallsDeleteSessionId() {
|
||||
Session mockSession = mock(Session.class);
|
||||
|
||||
doNothing().when(this.sessionRepository).delete(anyString());
|
||||
given(mockSession.getId()).willReturn("2");
|
||||
|
||||
assertThat(this.sessionRepository.delete(mockSession)).isNull();
|
||||
|
||||
verify(this.sessionRepository, times(1)).delete(eq("2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -603,7 +627,8 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
assertThat(this.sessionRepository.getApplicationEventPublisher()).isSameAs(mockApplicationEventPublisher);
|
||||
|
||||
verify(mockSession, times(1)).getId();
|
||||
verify(mockApplicationEventPublisher, times(1)).publishEvent(isA(SessionDeletedEvent.class));
|
||||
verify(mockApplicationEventPublisher, times(1))
|
||||
.publishEvent(isA(SessionDeletedEvent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -634,7 +659,8 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
assertThat(this.sessionRepository.getApplicationEventPublisher()).isSameAs(mockApplicationEventPublisher);
|
||||
|
||||
verify(mockApplicationEventPublisher, times(1)).publishEvent(isA(SessionDeletedEvent.class));
|
||||
verify(mockApplicationEventPublisher, times(1))
|
||||
.publishEvent(isA(SessionDeletedEvent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -652,13 +678,23 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
assertThat(this.sessionRepository.getApplicationEventPublisher()).isSameAs(mockApplicationEventPublisher);
|
||||
|
||||
verify(mockApplicationEventPublisher, times(1)).publishEvent(eq(mockApplicationEvent));
|
||||
verify(this.mockLog, times(1)).error(eq(String.format("error occurred publishing event (%s)",
|
||||
mockApplicationEvent)), isA(IllegalStateException.class));
|
||||
verify(this.mockLog, times(1))
|
||||
.error(eq(String.format("Error occurred publishing event [%s]", mockApplicationEvent)),
|
||||
isA(IllegalStateException.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void touchSetsLastAccessedTime() {
|
||||
ExpiringSession mockSession = mock(ExpiringSession.class);
|
||||
|
||||
assertThat(this.sessionRepository.touch(mockSession)).isSameAs(mockSession);
|
||||
|
||||
verify(mockSession, times(1)).setLastAccessedTime(anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructGemFireSessionWithDefaultInitialization() {
|
||||
final long beforeOrAtCreationTime = System.currentTimeMillis();
|
||||
long beforeOrAtCreationTime = System.currentTimeMillis();
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession();
|
||||
@@ -668,12 +704,12 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
assertThat(session.getLastAccessedTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime);
|
||||
assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(0);
|
||||
assertThat(session.getAttributeNames()).isNotNull();
|
||||
assertThat(session.getAttributeNames().isEmpty()).isTrue();
|
||||
assertThat(session.getAttributeNames()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructGemFireSessionWithId() {
|
||||
final long beforeOrAtCreationTime = System.currentTimeMillis();
|
||||
long beforeOrAtCreationTime = System.currentTimeMillis();
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession("1");
|
||||
@@ -683,16 +719,29 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
assertThat(session.getLastAccessedTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime);
|
||||
assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(0);
|
||||
assertThat(session.getAttributeNames()).isNotNull();
|
||||
assertThat(session.getAttributeNames().isEmpty()).isTrue();
|
||||
assertThat(session.getAttributeNames()).isEmpty();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructGemFireSessionWithUnspecifiedId() {
|
||||
try {
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession(" ");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertThat(expected).hasMessage("ID must be specified");
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructGemFireSessionWithSession() {
|
||||
final long expectedCreationTime = 1L;
|
||||
final long expectedLastAccessTime = 2L;
|
||||
long expectedCreationTime = 1L;
|
||||
long expectedLastAccessTime = 2L;
|
||||
|
||||
ExpiringSession mockSession = mockSession("2", expectedCreationTime, expectedLastAccessTime,
|
||||
MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
||||
ExpiringSession mockSession =
|
||||
mockSession("2", expectedCreationTime, expectedLastAccessTime, MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
||||
|
||||
Set<String> expectedAttributedNames = asSet("attrOne", "attrTwo");
|
||||
|
||||
@@ -720,25 +769,22 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
verify(mockSession, times(1)).getAttribute(eq("attrTwo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructGemFireSessionWithNullSession() {
|
||||
this.expectedException.expect(IllegalArgumentException.class);
|
||||
this.expectedException.expectMessage("The ExpiringSession to copy cannot be null");
|
||||
try {
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession((ExpiringSession) null);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertThat(expected).hasMessage("The ExpiringSession to copy cannot be null");
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession((ExpiringSession) null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructGemFireSessionWithUnspecifiedId() {
|
||||
this.expectedException.expect(IllegalArgumentException.class);
|
||||
this.expectedException.expectMessage("ID must be specified");
|
||||
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession(" ");
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createNewGemFireSession() {
|
||||
final long beforeOrAtCreationTime = System.currentTimeMillis();
|
||||
long beforeOrAtCreationTime = System.currentTimeMillis();
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession.create(120);
|
||||
@@ -754,8 +800,8 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
@Test
|
||||
public void fromExistingSession() {
|
||||
final long expectedCreationTime = 1L;
|
||||
final long expectedLastAccessedTime = 2L;
|
||||
long expectedCreationTime = 1L;
|
||||
long expectedLastAccessedTime = 2L;
|
||||
|
||||
ExpiringSession mockSession = mockSession("4", expectedCreationTime, expectedLastAccessedTime,
|
||||
MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
||||
@@ -768,9 +814,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
assertThat(gemfireSession).isNotNull();
|
||||
assertThat(gemfireSession.getId()).isEqualTo("4");
|
||||
assertThat(gemfireSession.getCreationTime()).isEqualTo(expectedCreationTime);
|
||||
assertThat(gemfireSession.getLastAccessedTime()).isNotEqualTo(expectedLastAccessedTime);
|
||||
assertThat(gemfireSession.getLastAccessedTime()).isGreaterThanOrEqualTo(expectedCreationTime);
|
||||
assertThat(gemfireSession.getLastAccessedTime()).isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(gemfireSession.getLastAccessedTime()).isEqualTo(expectedLastAccessedTime);
|
||||
assertThat(gemfireSession.getMaxInactiveIntervalInSeconds()).isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
||||
assertThat(gemfireSession.getAttributeNames()).isNotNull();
|
||||
assertThat(gemfireSession.getAttributeNames().isEmpty()).isTrue();
|
||||
@@ -783,6 +827,17 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
verify(mockSession, never()).getAttribute(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromExistingGemFireSessionIsGemFireSession() {
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession gemfireSession =
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession.create(300);
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession fromGemFireSession =
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession.from(gemfireSession);
|
||||
|
||||
assertThat(fromGemFireSession).isSameAs(gemfireSession);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setGetAndRemoveAttribute() {
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
@@ -918,17 +973,18 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
verify(mockDataOutput, times(1)).writeUTF(eq("1"));
|
||||
verify(mockDataOutput, times(1)).writeLong(eq(session.getCreationTime()));
|
||||
verify(mockDataOutput, times(1)).writeLong(eq(session.getLastAccessedTime()));
|
||||
verify(mockDataOutput, times(1)).writeInt(eq(session.getMaxInactiveIntervalInSeconds()));
|
||||
verify(mockDataOutput, times(1))
|
||||
.writeInt(eq(session.getMaxInactiveIntervalInSeconds()));
|
||||
verify(mockDataOutput, times(1)).writeInt(eq("jblum".length()));
|
||||
verify(mockDataOutput, times(1)).writeUTF(eq(session.getPrincipalName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sessionFromData() throws Exception {
|
||||
final long expectedCreationTime = 1L;
|
||||
final long expectedLastAccessedTime = 2L;
|
||||
long expectedCreationTime = 1L;
|
||||
long expectedLastAccessedTime = 2L;
|
||||
|
||||
final int expectedMaxInactiveIntervalInSeconds = (int) TimeUnit.HOURS.toSeconds(6);
|
||||
int expectedMaxInactiveIntervalInSeconds = (int) TimeUnit.HOURS.toSeconds(6);
|
||||
|
||||
final String expectedPrincipalName = "jblum";
|
||||
|
||||
@@ -958,8 +1014,8 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
session.fromData(mockDataInput);
|
||||
|
||||
Set<String> expectedAttributeNames = asSet("attrOne", "attrTwo",
|
||||
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME);
|
||||
Set<String> expectedAttributeNames =
|
||||
asSet("attrOne", "attrTwo", FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME);
|
||||
|
||||
assertThat(session.getId()).isEqualTo("2");
|
||||
assertThat(session.getCreationTime()).isEqualTo(expectedCreationTime);
|
||||
@@ -1044,7 +1100,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
@Test
|
||||
public void hasDeltaWhenSessionLastAccessedTimeIsUpdatedIsTrue() {
|
||||
final long expectedLastAccessTime = 1L;
|
||||
long expectedLastAccessTime = 1L;
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession();
|
||||
@@ -1065,7 +1121,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
@Test
|
||||
public void hasDeltaWhenSessionMaxInactiveIntervalInSecondsIsUpdatedIsTrue() {
|
||||
final int expectedMaxInactiveIntervalInSeconds = 300;
|
||||
int expectedMaxInactiveIntervalInSeconds = 300;
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession session =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession();
|
||||
@@ -1146,7 +1202,7 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
|
||||
@Test
|
||||
public void sessionComparisons() {
|
||||
final long twoHoursAgo = (System.currentTimeMillis() - TimeUnit.HOURS.toMillis(2));
|
||||
long twoHoursAgo = (System.currentTimeMillis() - TimeUnit.HOURS.toMillis(2));
|
||||
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession sessionOne =
|
||||
new AbstractGemFireOperationsSessionRepository.GemFireSession(
|
||||
@@ -1528,8 +1584,9 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
assertThat(this.session.getMaxInactiveIntervalInSeconds()).isEqualTo(60);
|
||||
assertThat(this.session.getPrincipalName()).isEqualTo("jblum");
|
||||
assertThat(this.session.getAttributeNames().size()).isEqualTo(1);
|
||||
assertThat(String.valueOf(this.session.getAttribute(
|
||||
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME))).isEqualTo("jblum");
|
||||
assertThat(String.valueOf(
|
||||
this.session.getAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME)))
|
||||
.isEqualTo("jblum");
|
||||
|
||||
this.session.setAttribute("tennis", "ping");
|
||||
this.session.setAttribute("junk", "test");
|
||||
@@ -1595,24 +1652,24 @@ public class AbstractGemFireOperationsSessionRepositoryTest {
|
||||
super(gemfireOperations);
|
||||
}
|
||||
|
||||
public Map<String, ExpiringSession> findByIndexNameAndIndexValue(String indexName, String indexValue) {
|
||||
throw new UnsupportedOperationException("not implemented");
|
||||
public ExpiringSession createSession() {
|
||||
throw new UnsupportedOperationException("Not Implemented");
|
||||
}
|
||||
|
||||
public ExpiringSession createSession() {
|
||||
throw new UnsupportedOperationException("not implemented");
|
||||
public Map<String, ExpiringSession> findByIndexNameAndIndexValue(String indexName, String indexValue) {
|
||||
throw new UnsupportedOperationException("Not Implemented");
|
||||
}
|
||||
|
||||
public ExpiringSession getSession(String id) {
|
||||
throw new UnsupportedOperationException("not implemented");
|
||||
throw new UnsupportedOperationException("Not Implemented");
|
||||
}
|
||||
|
||||
public void save(ExpiringSession session) {
|
||||
throw new UnsupportedOperationException("not implemented");
|
||||
throw new UnsupportedOperationException("Not Implemented");
|
||||
}
|
||||
|
||||
public void delete(String id) {
|
||||
throw new UnsupportedOperationException("not implemented");
|
||||
throw new UnsupportedOperationException("Not Implemented");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import org.apache.geode.cache.AttributesMutator;
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.query.SelectResults;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -65,6 +66,7 @@ import static org.mockito.Mockito.verify;
|
||||
* @see org.mockito.Mock
|
||||
* @see org.mockito.Mockito
|
||||
* @see org.mockito.junit.MockitoJUnitRunner
|
||||
* @see org.springframework.data.gemfire.GemfireOperations
|
||||
* @see org.springframework.session.data.gemfire.GemFireOperationsSessionRepository
|
||||
* @see org.apache.geode.cache.Region
|
||||
*/
|
||||
@@ -79,34 +81,28 @@ public class GemFireOperationsSessionRepositoryTest {
|
||||
@Mock
|
||||
private AttributesMutator<Object, ExpiringSession> mockAttributesMutator;
|
||||
|
||||
@Mock
|
||||
private Region<Object, ExpiringSession> mockRegion;
|
||||
|
||||
@Mock
|
||||
private GemfireOperationsAccessor mockTemplate;
|
||||
|
||||
private GemFireOperationsSessionRepository sessionRepository;
|
||||
|
||||
@Mock
|
||||
private Region<Object, ExpiringSession> mockRegion;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
given(this.mockRegion.getAttributesMutator()).willReturn(this.mockAttributesMutator);
|
||||
given(this.mockRegion.getFullPath()).willReturn("/Example");
|
||||
given(this.mockTemplate.<Object, ExpiringSession>getRegion()).willReturn(this.mockRegion);
|
||||
|
||||
this.sessionRepository = new GemFireOperationsSessionRepository(
|
||||
this.mockTemplate);
|
||||
this.sessionRepository
|
||||
.setApplicationEventPublisher(this.mockApplicationEventPublisher);
|
||||
this.sessionRepository
|
||||
.setMaxInactiveIntervalInSeconds(MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
||||
this.sessionRepository = new GemFireOperationsSessionRepository(this.mockTemplate);
|
||||
this.sessionRepository.setApplicationEventPublisher(this.mockApplicationEventPublisher);
|
||||
this.sessionRepository.setMaxInactiveIntervalInSeconds(MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
||||
this.sessionRepository.afterPropertiesSet();
|
||||
|
||||
assertThat(this.sessionRepository.getApplicationEventPublisher())
|
||||
.isSameAs(this.mockApplicationEventPublisher);
|
||||
assertThat(this.sessionRepository.getFullyQualifiedRegionName())
|
||||
.isEqualTo("/Example");
|
||||
assertThat(this.sessionRepository.getMaxInactiveIntervalInSeconds())
|
||||
.isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
||||
assertThat(this.sessionRepository.getApplicationEventPublisher()).isSameAs(this.mockApplicationEventPublisher);
|
||||
assertThat(this.sessionRepository.getFullyQualifiedRegionName()).isEqualTo("/Example");
|
||||
assertThat(this.sessionRepository.getMaxInactiveIntervalInSeconds()).isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -130,14 +126,13 @@ public class GemFireOperationsSessionRepositoryTest {
|
||||
String indexName = "vip";
|
||||
String indexValue = "rwinch";
|
||||
|
||||
String expectedQql = String.format(
|
||||
GemFireOperationsSessionRepository.FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY,
|
||||
this.sessionRepository.getFullyQualifiedRegionName(), indexName);
|
||||
String expectedQql = String.format(GemFireOperationsSessionRepository.FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY,
|
||||
this.sessionRepository.getFullyQualifiedRegionName(), indexName);
|
||||
|
||||
given(this.mockTemplate.find(eq(expectedQql), eq(indexValue))).willReturn(mockSelectResults);
|
||||
|
||||
Map<String, ExpiringSession> sessions =
|
||||
this.sessionRepository.findByIndexNameAndIndexValue(indexName, indexValue);
|
||||
this.sessionRepository.findByIndexNameAndIndexValue(indexName, indexValue);
|
||||
|
||||
assertThat(sessions).isNotNull();
|
||||
assertThat(sessions.size()).isEqualTo(1);
|
||||
@@ -161,22 +156,18 @@ public class GemFireOperationsSessionRepositoryTest {
|
||||
|
||||
SelectResults<Object> mockSelectResults = mock(SelectResults.class);
|
||||
|
||||
given(mockSelectResults.asList()).willReturn(
|
||||
Arrays.<Object>asList(mockSessionOne, mockSessionTwo, mockSessionThree));
|
||||
given(mockSelectResults.asList())
|
||||
.willReturn(Arrays.<Object>asList(mockSessionOne, mockSessionTwo, mockSessionThree));
|
||||
|
||||
String principalName = "jblum";
|
||||
|
||||
String expectedOql = String.format(
|
||||
GemFireOperationsSessionRepository.FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY,
|
||||
this.sessionRepository.getFullyQualifiedRegionName());
|
||||
String expectedOql = String.format(GemFireOperationsSessionRepository.FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY,
|
||||
this.sessionRepository.getFullyQualifiedRegionName());
|
||||
|
||||
given(this.mockTemplate.find(eq(expectedOql), eq(principalName)))
|
||||
.willReturn(mockSelectResults);
|
||||
given(this.mockTemplate.find(eq(expectedOql), eq(principalName))).willReturn(mockSelectResults);
|
||||
|
||||
Map<String, ExpiringSession> sessions = this.sessionRepository
|
||||
.findByIndexNameAndIndexValue(
|
||||
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
|
||||
principalName);
|
||||
Map<String, ExpiringSession> sessions = this.sessionRepository.findByIndexNameAndIndexValue(
|
||||
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, principalName);
|
||||
|
||||
assertThat(sessions).isNotNull();
|
||||
assertThat(sessions.size()).isEqualTo(3);
|
||||
@@ -200,15 +191,13 @@ public class GemFireOperationsSessionRepositoryTest {
|
||||
|
||||
String principalName = "jblum";
|
||||
|
||||
String expectedOql = String.format(
|
||||
GemFireOperationsSessionRepository.FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY,
|
||||
this.sessionRepository.getFullyQualifiedRegionName());
|
||||
String expectedOql = String.format(GemFireOperationsSessionRepository.FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY,
|
||||
this.sessionRepository.getFullyQualifiedRegionName());
|
||||
|
||||
given(this.mockTemplate.find(eq(expectedOql), eq(principalName)))
|
||||
.willReturn(mockSelectResults);
|
||||
given(this.mockTemplate.find(eq(expectedOql), eq(principalName))).willReturn(mockSelectResults);
|
||||
|
||||
Map<String, ExpiringSession> sessions = this.sessionRepository.findByIndexNameAndIndexValue(
|
||||
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, principalName);
|
||||
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, principalName);
|
||||
|
||||
assertThat(sessions).isNotNull();
|
||||
assertThat(sessions.isEmpty()).isTrue();
|
||||
@@ -219,12 +208,11 @@ public class GemFireOperationsSessionRepositoryTest {
|
||||
|
||||
@Test
|
||||
public void prepareQueryReturnsPrincipalNameOql() {
|
||||
String actualQql = this.sessionRepository.prepareQuery(
|
||||
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME);
|
||||
String actualQql =
|
||||
this.sessionRepository.prepareQuery(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME);
|
||||
|
||||
String expectedOql = String.format(
|
||||
GemFireOperationsSessionRepository.FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY,
|
||||
this.sessionRepository.getFullyQualifiedRegionName());
|
||||
String expectedOql = String.format(GemFireOperationsSessionRepository.FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY,
|
||||
this.sessionRepository.getFullyQualifiedRegionName());
|
||||
|
||||
assertThat(actualQql).isEqualTo(expectedOql);
|
||||
}
|
||||
@@ -233,21 +221,19 @@ public class GemFireOperationsSessionRepositoryTest {
|
||||
public void prepareQueryReturnsIndexNameValueOql() {
|
||||
String attributeName = "testAttributeName";
|
||||
String actualOql = this.sessionRepository.prepareQuery(attributeName);
|
||||
String expectedOql = String.format(
|
||||
GemFireOperationsSessionRepository.FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY,
|
||||
this.sessionRepository.getFullyQualifiedRegionName(), attributeName);
|
||||
String expectedOql = String.format(GemFireOperationsSessionRepository.FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY,
|
||||
this.sessionRepository.getFullyQualifiedRegionName(), attributeName);
|
||||
|
||||
assertThat(actualOql).isEqualTo(expectedOql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createProperlyInitializedSession() {
|
||||
final long beforeOrAtCreationTime = System.currentTimeMillis();
|
||||
long beforeOrAtCreationTime = System.currentTimeMillis();
|
||||
|
||||
ExpiringSession session = this.sessionRepository.createSession();
|
||||
|
||||
assertThat(session).isInstanceOf(
|
||||
AbstractGemFireOperationsSessionRepository.GemFireSession.class);
|
||||
assertThat(session).isInstanceOf(AbstractGemFireOperationsSessionRepository.GemFireSession.class);
|
||||
assertThat(session.getId()).isNotNull();
|
||||
assertThat(session.getAttributeNames().isEmpty()).isTrue();
|
||||
assertThat(session.getCreationTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime);
|
||||
@@ -274,8 +260,8 @@ public class GemFireOperationsSessionRepositoryTest {
|
||||
|
||||
AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent;
|
||||
|
||||
assertThat(sessionEvent.getSource()).isSameAs(
|
||||
GemFireOperationsSessionRepositoryTest.this.sessionRepository);
|
||||
assertThat(sessionEvent.getSource())
|
||||
.isSameAs(GemFireOperationsSessionRepositoryTest.this.sessionRepository);
|
||||
assertThat(sessionEvent.getSession()).isSameAs(mockSession);
|
||||
assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSessionId);
|
||||
|
||||
@@ -289,16 +275,16 @@ public class GemFireOperationsSessionRepositoryTest {
|
||||
verify(this.mockTemplate, times(1)).remove(eq(expectedSessionId));
|
||||
verify(mockSession, times(1)).isExpired();
|
||||
verify(mockSession, times(2)).getId();
|
||||
verify(this.mockApplicationEventPublisher, times(1)).publishEvent(isA(SessionDeletedEvent.class));
|
||||
verify(this.mockApplicationEventPublisher, times(1))
|
||||
.publishEvent(isA(SessionDeletedEvent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSessionFindsMatchingNonExpiredSessionById() {
|
||||
final String expectedId = "1";
|
||||
String expectedId = "1";
|
||||
|
||||
final long expectedCreationTime = System.currentTimeMillis();
|
||||
final long currentLastAccessedTime = (expectedCreationTime
|
||||
+ TimeUnit.MINUTES.toMillis(5));
|
||||
long expectedCreationTime = System.currentTimeMillis();
|
||||
long currentLastAccessedTime = (expectedCreationTime + TimeUnit.MINUTES.toMillis(5));
|
||||
|
||||
ExpiringSession mockSession = mock(ExpiringSession.class);
|
||||
|
||||
@@ -340,8 +326,7 @@ public class GemFireOperationsSessionRepositoryTest {
|
||||
final String expectedSessionId = "1";
|
||||
|
||||
final long expectedCreationTime = System.currentTimeMillis();
|
||||
final long expectedLastAccessTime = (expectedCreationTime
|
||||
+ TimeUnit.MINUTES.toMillis(5));
|
||||
final long expectedLastAccessTime = (expectedCreationTime + TimeUnit.MINUTES.toMillis(5));
|
||||
|
||||
ExpiringSession mockSession = mock(ExpiringSession.class);
|
||||
|
||||
@@ -353,22 +338,22 @@ public class GemFireOperationsSessionRepositoryTest {
|
||||
given(mockSession.getAttributeNames()).willReturn(Collections.<String>emptySet());
|
||||
|
||||
given(this.mockTemplate.put(eq(expectedSessionId),
|
||||
isA(AbstractGemFireOperationsSessionRepository.GemFireSession.class)))
|
||||
.willAnswer(new Answer<ExpiringSession>() {
|
||||
public ExpiringSession answer(InvocationOnMock invocation) throws Throwable {
|
||||
ExpiringSession session = invocation.getArgument(1);
|
||||
isA(AbstractGemFireOperationsSessionRepository.GemFireSession.class)))
|
||||
.willAnswer(new Answer<ExpiringSession>() {
|
||||
public ExpiringSession answer(InvocationOnMock invocation) throws Throwable {
|
||||
ExpiringSession session = invocation.getArgument(1);
|
||||
|
||||
assertThat(session).isNotNull();
|
||||
assertThat(session.getId()).isEqualTo(expectedSessionId);
|
||||
assertThat(session.getCreationTime()).isEqualTo(expectedCreationTime);
|
||||
assertThat(session.getLastAccessedTime()).isEqualTo(expectedLastAccessTime);
|
||||
assertThat(session.getMaxInactiveIntervalInSeconds())
|
||||
.isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
||||
assertThat(session.getAttributeNames().isEmpty()).isTrue();
|
||||
assertThat(session).isNotNull();
|
||||
assertThat(session.getId()).isEqualTo(expectedSessionId);
|
||||
assertThat(session.getCreationTime()).isEqualTo(expectedCreationTime);
|
||||
assertThat(session.getLastAccessedTime()).isEqualTo(expectedLastAccessTime);
|
||||
assertThat(session.getMaxInactiveIntervalInSeconds())
|
||||
.isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
||||
assertThat(session.getAttributeNames().isEmpty()).isTrue();
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
this.sessionRepository.save(mockSession);
|
||||
|
||||
@@ -378,7 +363,7 @@ public class GemFireOperationsSessionRepositoryTest {
|
||||
verify(mockSession, times(1)).getMaxInactiveIntervalInSeconds();
|
||||
verify(mockSession, times(1)).getAttributeNames();
|
||||
verify(this.mockTemplate, times(1)).put(eq(expectedSessionId),
|
||||
isA(AbstractGemFireOperationsSessionRepository.GemFireSession.class));
|
||||
isA(AbstractGemFireOperationsSessionRepository.GemFireSession.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -398,8 +383,8 @@ public class GemFireOperationsSessionRepositoryTest {
|
||||
|
||||
AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent;
|
||||
|
||||
assertThat(sessionEvent.getSource()).isSameAs(
|
||||
GemFireOperationsSessionRepositoryTest.this.sessionRepository);
|
||||
assertThat(sessionEvent.getSource())
|
||||
.isSameAs(GemFireOperationsSessionRepositoryTest.this.sessionRepository);
|
||||
assertThat(sessionEvent.getSession()).isSameAs(mockSession);
|
||||
assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSessionId);
|
||||
|
||||
@@ -411,7 +396,8 @@ public class GemFireOperationsSessionRepositoryTest {
|
||||
|
||||
verify(mockSession, times(1)).getId();
|
||||
verify(this.mockTemplate, times(1)).remove(eq(expectedSessionId));
|
||||
verify(this.mockApplicationEventPublisher, times(1)).publishEvent(isA(SessionDeletedEvent.class));
|
||||
verify(this.mockApplicationEventPublisher, times(1))
|
||||
.publishEvent(isA(SessionDeletedEvent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -428,20 +414,20 @@ public class GemFireOperationsSessionRepositoryTest {
|
||||
|
||||
AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent;
|
||||
|
||||
assertThat(sessionEvent.getSource()).isSameAs(
|
||||
GemFireOperationsSessionRepositoryTest.this.sessionRepository);
|
||||
assertThat(sessionEvent.getSource()).
|
||||
isSameAs(GemFireOperationsSessionRepositoryTest.this.sessionRepository);
|
||||
assertThat(sessionEvent.getSession()).isNull();
|
||||
assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSessionId);
|
||||
|
||||
return null;
|
||||
}
|
||||
}).given(this.mockApplicationEventPublisher)
|
||||
.publishEvent(isA(SessionDeletedEvent.class));
|
||||
}).given(this.mockApplicationEventPublisher).publishEvent(isA(SessionDeletedEvent.class));
|
||||
|
||||
this.sessionRepository.delete(expectedSessionId);
|
||||
|
||||
verify(this.mockTemplate, times(1)).remove(eq(expectedSessionId));
|
||||
verify(this.mockApplicationEventPublisher, times(1)).publishEvent(isA(SessionDeletedEvent.class));
|
||||
verify(this.mockApplicationEventPublisher, times(1))
|
||||
.publishEvent(isA(SessionDeletedEvent.class));
|
||||
}
|
||||
|
||||
protected abstract class GemfireOperationsAccessor extends GemfireAccessor
|
||||
|
||||
Reference in New Issue
Block a user