Additional Checkstyle Fixes
Issue gh-393
This commit is contained in:
@@ -48,8 +48,8 @@ import org.springframework.session.events.AbstractSessionEvent;
|
|||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AbstractGemFireIntegrationTests is an abstract base class encapsulating common operations for writing
|
* AbstractGemFireIntegrationTests is an abstract base class encapsulating common
|
||||||
* Spring Session GemFire integration tests.
|
* operations for writing Spring Session GemFire integration tests.
|
||||||
*
|
*
|
||||||
* @author John Blum
|
* @author John Blum
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
@@ -64,24 +64,25 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
* @see com.gemstone.gemfire.cache.server.CacheServer
|
* @see com.gemstone.gemfire.cache.server.CacheServer
|
||||||
*/
|
*/
|
||||||
public class AbstractGemFireIntegrationTests {
|
public class AbstractGemFireIntegrationTests {
|
||||||
public static final String GEMFIRE_LOG_LEVEL = System.getProperty(
|
public static final String GEMFIRE_LOG_LEVEL = System
|
||||||
"spring.session.data.gemfire.log-level", "warning");
|
.getProperty("spring.session.data.gemfire.log-level", "warning");
|
||||||
|
|
||||||
protected static final boolean DEFAULT_ENABLE_QUERY_DEBUGGING = false;
|
protected static final boolean DEFAULT_ENABLE_QUERY_DEBUGGING = false;
|
||||||
protected static final boolean GEMFIRE_QUERY_DEBUG = Boolean.getBoolean("spring.session.data.gemfire.query.debug");
|
protected static final boolean GEMFIRE_QUERY_DEBUG = Boolean
|
||||||
|
.getBoolean("spring.session.data.gemfire.query.debug");
|
||||||
|
|
||||||
protected static final int DEFAULT_GEMFIRE_SERVER_PORT = CacheServer.DEFAULT_PORT;
|
protected static final int DEFAULT_GEMFIRE_SERVER_PORT = CacheServer.DEFAULT_PORT;
|
||||||
|
|
||||||
protected static final long DEFAULT_WAIT_DURATION = TimeUnit.SECONDS.toMillis(20);
|
protected static final long DEFAULT_WAIT_DURATION = TimeUnit.SECONDS.toMillis(20);
|
||||||
protected static final long DEFAULT_WAIT_INTERVAL = 500L;
|
protected static final long DEFAULT_WAIT_INTERVAL = 500L;
|
||||||
|
|
||||||
protected static final File WORKING_DIRECTORY = new File(System.getProperty("user.dir"));
|
protected static final File WORKING_DIRECTORY = new File(
|
||||||
|
System.getProperty("user.dir"));
|
||||||
|
|
||||||
protected static final String DEFAULT_PROCESS_CONTROL_FILENAME = "process.ctl";
|
protected static final String DEFAULT_PROCESS_CONTROL_FILENAME = "process.ctl";
|
||||||
|
|
||||||
protected static final String GEMFIRE_LOG_FILE_NAME = System.getProperty(
|
protected static final String GEMFIRE_LOG_FILE_NAME = System
|
||||||
"spring.session.data.gemfire.log-file", "server.log");
|
.getProperty("spring.session.data.gemfire.log-file", "server.log");
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
protected Cache gemfireCache;
|
protected Cache gemfireCache;
|
||||||
@@ -91,15 +92,17 @@ public class AbstractGemFireIntegrationTests {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
System.setProperty("gemfire.Query.VERBOSE", String.valueOf(isQueryDebuggingEnabled()));
|
System.setProperty("gemfire.Query.VERBOSE",
|
||||||
|
String.valueOf(isQueryDebuggingEnabled()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
protected static File createDirectory(String pathname) {
|
protected static File createDirectory(String pathname) {
|
||||||
File directory = new File(WORKING_DIRECTORY, pathname);
|
File directory = new File(WORKING_DIRECTORY, pathname);
|
||||||
|
|
||||||
assertThat(directory.isDirectory() || directory.mkdirs()).as(
|
assertThat(directory.isDirectory() || directory.mkdirs())
|
||||||
String.format("Failed to create directory (%1$s)", directory)).isTrue();
|
.as(String.format("Failed to create directory (%1$s)", directory))
|
||||||
|
.isTrue();
|
||||||
|
|
||||||
directory.deleteOnExit();
|
directory.deleteOnExit();
|
||||||
|
|
||||||
@@ -107,7 +110,8 @@ public class AbstractGemFireIntegrationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
protected static List<String> createJavaProcessCommandLine(Class<?> type, String... args) {
|
protected static List<String> createJavaProcessCommandLine(Class<?> type,
|
||||||
|
String... args) {
|
||||||
List<String> commandLine = new ArrayList<String>();
|
List<String> commandLine = new ArrayList<String>();
|
||||||
|
|
||||||
String javaHome = System.getProperty("java.home");
|
String javaHome = System.getProperty("java.home");
|
||||||
@@ -118,7 +122,8 @@ public class AbstractGemFireIntegrationTests {
|
|||||||
commandLine.add("-ea");
|
commandLine.add("-ea");
|
||||||
commandLine.add(String.format("-Dgemfire.log-file=%1$s", GEMFIRE_LOG_FILE_NAME));
|
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.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.addAll(extractJvmArguments(args));
|
||||||
commandLine.add("-classpath");
|
commandLine.add("-classpath");
|
||||||
commandLine.add(System.getProperty("java.class.path"));
|
commandLine.add(System.getProperty("java.class.path"));
|
||||||
@@ -157,11 +162,10 @@ public class AbstractGemFireIntegrationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
protected static Process run(Class<?> type, File directory, String... args) throws IOException {
|
protected static Process run(Class<?> type, File directory, String... args)
|
||||||
return new ProcessBuilder()
|
throws IOException {
|
||||||
.command(createJavaProcessCommandLine(type, args))
|
return new ProcessBuilder().command(createJavaProcessCommandLine(type, args))
|
||||||
.directory(directory)
|
.directory(directory).start();
|
||||||
.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
@@ -170,8 +174,10 @@ public class AbstractGemFireIntegrationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
protected static boolean waitForCacheServerToStart(CacheServer cacheServer, long duration) {
|
protected static boolean waitForCacheServerToStart(CacheServer cacheServer,
|
||||||
return waitForCacheServerToStart(cacheServer.getBindAddress(), cacheServer.getPort(), duration);
|
long duration) {
|
||||||
|
return waitForCacheServerToStart(cacheServer.getBindAddress(),
|
||||||
|
cacheServer.getPort(), duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
@@ -180,7 +186,8 @@ public class AbstractGemFireIntegrationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (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() {
|
return waitOnCondition(new Condition() {
|
||||||
AtomicBoolean connected = new AtomicBoolean(false);
|
AtomicBoolean connected = new AtomicBoolean(false);
|
||||||
|
|
||||||
@@ -204,7 +211,8 @@ public class AbstractGemFireIntegrationTests {
|
|||||||
}, duration);
|
}, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE this method would not be necessary except Spring Sessions' build does not fork the test JVM
|
// NOTE this method would not be necessary except Spring Sessions' build does not fork
|
||||||
|
// the test JVM
|
||||||
// for every test class.
|
// for every test class.
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
protected static boolean waitForClientCacheToClose() {
|
protected static boolean waitForClientCacheToClose() {
|
||||||
@@ -239,7 +247,8 @@ public class AbstractGemFireIntegrationTests {
|
|||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
@SuppressWarnings("all")
|
@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);
|
final File processControl = new File(directory, DEFAULT_PROCESS_CONTROL_FILENAME);
|
||||||
|
|
||||||
waitOnCondition(new Condition() {
|
waitOnCondition(new Condition() {
|
||||||
@@ -257,7 +266,8 @@ public class AbstractGemFireIntegrationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (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);
|
final long timeout = (System.currentTimeMillis() + duration);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -312,24 +322,30 @@ public class AbstractGemFireIntegrationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (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).isNotNull();
|
||||||
assertThat(actualRegion.getName()).isEqualTo(expectedName);
|
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()).isNotNull();
|
||||||
assertThat(actualRegion.getAttributes().getDataPolicy()).isEqualTo(expectedDataPolicy);
|
assertThat(actualRegion.getAttributes().getDataPolicy())
|
||||||
|
.isEqualTo(expectedDataPolicy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (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).isNotNull();
|
||||||
assertThat(index.getIndexedExpression()).isEqualTo(expectedExpression);
|
assertThat(index.getIndexedExpression()).isEqualTo(expectedExpression);
|
||||||
assertThat(index.getFromClause()).isEqualTo(expectedFromClause);
|
assertThat(index.getFromClause()).isEqualTo(expectedFromClause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
protected void assertEntryIdleTimeout(Region<?, ?> region, ExpirationAction expectedAction, int expectedTimeout) {
|
protected void assertEntryIdleTimeout(Region<?, ?> region,
|
||||||
assertEntryIdleTimeout(region.getAttributes().getEntryIdleTimeout(), expectedAction, expectedTimeout);
|
ExpirationAction expectedAction, int expectedTimeout) {
|
||||||
|
assertEntryIdleTimeout(region.getAttributes().getEntryIdleTimeout(),
|
||||||
|
expectedAction, expectedTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
@@ -404,13 +420,14 @@ public class AbstractGemFireIntegrationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The SessionEventListener class is a Spring {@link ApplicationListener} listening for Spring HTTP Session
|
* The SessionEventListener class is a Spring {@link ApplicationListener} listening
|
||||||
* application events.
|
* for Spring HTTP Session application events.
|
||||||
*
|
*
|
||||||
* @see org.springframework.context.ApplicationListener
|
* @see org.springframework.context.ApplicationListener
|
||||||
* @see org.springframework.session.events.AbstractSessionEvent
|
* @see org.springframework.session.events.AbstractSessionEvent
|
||||||
*/
|
*/
|
||||||
public static class SessionEventListener implements ApplicationListener<AbstractSessionEvent> {
|
public static class SessionEventListener
|
||||||
|
implements ApplicationListener<AbstractSessionEvent> {
|
||||||
|
|
||||||
private volatile AbstractSessionEvent sessionEvent;
|
private volatile AbstractSessionEvent sessionEvent;
|
||||||
|
|
||||||
@@ -440,7 +457,8 @@ public class AbstractGemFireIntegrationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Condition interface defines a logical condition that must be satisfied before it is safe to proceed.
|
* The Condition interface defines a logical condition that must be satisfied before
|
||||||
|
* it is safe to proceed.
|
||||||
*/
|
*/
|
||||||
protected interface Condition {
|
protected interface Condition {
|
||||||
boolean evaluate();
|
boolean evaluate();
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ public class HttpSessionGemFireIndexingITests extends AbstractGemFireIntegration
|
|||||||
sessionRepository.save(session);
|
sessionRepository.save(session);
|
||||||
|
|
||||||
// tag::findbyindexname-get[]
|
// tag::findbyindexname-get[]
|
||||||
Map<String, ExpiringSession> idToSessions = sessionRepository.findByIndexNameAndIndexValue(indexName, username);
|
Map<String, ExpiringSession> idToSessions = sessionRepository
|
||||||
|
.findByIndexNameAndIndexValue(indexName, username);
|
||||||
// end::findbyindexname-get[]
|
// end::findbyindexname-get[]
|
||||||
|
|
||||||
assertThat(idToSessions.keySet()).containsOnly(session.getId());
|
assertThat(idToSessions.keySet()).containsOnly(session.getId());
|
||||||
@@ -78,12 +79,15 @@ public class HttpSessionGemFireIndexingITests extends AbstractGemFireIntegration
|
|||||||
Authentication authentication = context.getAuthentication();
|
Authentication authentication = context.getAuthentication();
|
||||||
// end::findbyspringsecurityindexname-context[]
|
// end::findbyspringsecurityindexname-context[]
|
||||||
|
|
||||||
session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context);
|
session.setAttribute(
|
||||||
|
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY,
|
||||||
|
context);
|
||||||
sessionRepository.save(session);
|
sessionRepository.save(session);
|
||||||
|
|
||||||
// tag::findbyspringsecurityindexname-get[]
|
// tag::findbyspringsecurityindexname-get[]
|
||||||
String indexName = FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME;
|
String indexName = FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME;
|
||||||
Map<String, ExpiringSession> idToSessions = sessionRepository.findByIndexNameAndIndexValue(indexName, authentication.getName());
|
Map<String, ExpiringSession> idToSessions = sessionRepository
|
||||||
|
.findByIndexNameAndIndexValue(indexName, authentication.getName());
|
||||||
// end::findbyspringsecurityindexname-get[]
|
// end::findbyspringsecurityindexname-get[]
|
||||||
|
|
||||||
assertThat(idToSessions.keySet()).containsOnly(session.getId());
|
assertThat(idToSessions.keySet()).containsOnly(session.getId());
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ public class GemFireHttpSessionConfig {
|
|||||||
|
|
||||||
gemfireProperties.setProperty("name", GemFireHttpSessionConfig.class.getName());
|
gemfireProperties.setProperty("name", GemFireHttpSessionConfig.class.getName());
|
||||||
gemfireProperties.setProperty("mcast-port", "0");
|
gemfireProperties.setProperty("mcast-port", "0");
|
||||||
gemfireProperties.setProperty("log-level", AbstractGemFireIntegrationTests.GEMFIRE_LOG_LEVEL);
|
gemfireProperties.setProperty("log-level",
|
||||||
|
AbstractGemFireIntegrationTests.GEMFIRE_LOG_LEVEL);
|
||||||
|
|
||||||
return gemfireProperties;
|
return gemfireProperties;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,8 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
*/
|
*/
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@ContextConfiguration(classes = GemFireHttpSessionConfig.class)
|
@ContextConfiguration(classes = GemFireHttpSessionConfig.class)
|
||||||
public class HttpSessionGemFireIndexingCustomITests extends AbstractGemFireIntegrationTests {
|
public class HttpSessionGemFireIndexingCustomITests
|
||||||
|
extends AbstractGemFireIntegrationTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByIndexName() {
|
public void findByIndexName() {
|
||||||
@@ -49,7 +50,8 @@ public class HttpSessionGemFireIndexingCustomITests extends AbstractGemFireInteg
|
|||||||
sessionRepository.save(session);
|
sessionRepository.save(session);
|
||||||
|
|
||||||
// tag::findbyindexname-get[]
|
// tag::findbyindexname-get[]
|
||||||
Map<String, ExpiringSession> idToSessions = sessionRepository.findByIndexNameAndIndexValue(indexName, attrValue);
|
Map<String, ExpiringSession> idToSessions = sessionRepository
|
||||||
|
.findByIndexNameAndIndexValue(indexName, attrValue);
|
||||||
// end::findbyindexname-get[]
|
// end::findbyindexname-get[]
|
||||||
|
|
||||||
assertThat(idToSessions.keySet()).containsOnly(session.getId());
|
assertThat(idToSessions.keySet()).containsOnly(session.getId());
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ public class FindByIndexNameSessionRepositoryTests {
|
|||||||
public void setUsername() {
|
public void setUsername() {
|
||||||
// tag::set-username[]
|
// tag::set-username[]
|
||||||
String username = "username";
|
String username = "username";
|
||||||
this.session.setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, username);
|
this.session.setAttribute(
|
||||||
|
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, username);
|
||||||
// end::set-username[]
|
// end::set-username[]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,8 +51,10 @@ public class FindByIndexNameSessionRepositoryTests {
|
|||||||
public void findByUsername() {
|
public void findByUsername() {
|
||||||
// tag::findby-username[]
|
// tag::findby-username[]
|
||||||
String username = "username";
|
String username = "username";
|
||||||
Map<String, Session> sessionIdToSession =
|
Map<String, Session> sessionIdToSession = this.sessionRepository
|
||||||
this.sessionRepository.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, username);
|
.findByIndexNameAndIndexValue(
|
||||||
|
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
|
||||||
|
username);
|
||||||
// end::findby-username[]
|
// end::findby-username[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ public class HttpSessionConfigurationNoOpConfigureRedisActionXmlTests {
|
|||||||
assertThat(this.filter).isNotNull();
|
assertThat(this.filter).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static RedisConnectionFactory connectionFactory() {
|
static RedisConnectionFactory connectionFactory() {
|
||||||
return mock(RedisConnectionFactory.class);
|
return mock(RedisConnectionFactory.class);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ public class IndexDocTests {
|
|||||||
}
|
}
|
||||||
// end::repository-demo[]
|
// end::repository-demo[]
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void expireRepositoryDemo() {
|
public void expireRepositoryDemo() {
|
||||||
ExpiringRepositoryDemo<ExpiringSession> demo = new ExpiringRepositoryDemo<ExpiringSession>();
|
ExpiringRepositoryDemo<ExpiringSession> demo = new ExpiringRepositoryDemo<ExpiringSession>();
|
||||||
@@ -102,8 +101,8 @@ public class IndexDocTests {
|
|||||||
public void newRedisOperationsSessionRepository() {
|
public void newRedisOperationsSessionRepository() {
|
||||||
// tag::new-redisoperationssessionrepository[]
|
// tag::new-redisoperationssessionrepository[]
|
||||||
JedisConnectionFactory factory = new JedisConnectionFactory();
|
JedisConnectionFactory factory = new JedisConnectionFactory();
|
||||||
SessionRepository<? extends ExpiringSession> repository =
|
SessionRepository<? extends ExpiringSession> repository = new RedisOperationsSessionRepository(
|
||||||
new RedisOperationsSessionRepository(factory);
|
factory);
|
||||||
// end::new-redisoperationssessionrepository[]
|
// end::new-redisoperationssessionrepository[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,9 @@ public abstract class AbstractHttpSessionListenerTests {
|
|||||||
public void springSessionDestroyedTranslatedToSpringSecurityDestroyed() {
|
public void springSessionDestroyedTranslatedToSpringSecurityDestroyed() {
|
||||||
Session session = new MapSession();
|
Session session = new MapSession();
|
||||||
|
|
||||||
this.publisher.publishEvent(new org.springframework.session.events.SessionDestroyedEvent(this, session));
|
this.publisher.publishEvent(
|
||||||
|
new org.springframework.session.events.SessionDestroyedEvent(this,
|
||||||
|
session));
|
||||||
|
|
||||||
assertThat(this.listener.getEvent().getId()).isEqualTo(session.getId());
|
assertThat(this.listener.getEvent().getId()).isEqualTo(session.getId());
|
||||||
}
|
}
|
||||||
@@ -64,12 +66,16 @@ public abstract class AbstractHttpSessionListenerTests {
|
|||||||
return factory;
|
return factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class SecuritySessionDestroyedListener implements ApplicationListener<SessionDestroyedEvent> {
|
static class SecuritySessionDestroyedListener
|
||||||
|
implements ApplicationListener<SessionDestroyedEvent> {
|
||||||
|
|
||||||
private SessionDestroyedEvent event;
|
private SessionDestroyedEvent event;
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/*
|
||||||
* @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see org.springframework.context.ApplicationListener#onApplicationEvent(org.
|
||||||
|
* springframework.context.ApplicationEvent)
|
||||||
*/
|
*/
|
||||||
public void onApplicationEvent(SessionDestroyedEvent event) {
|
public void onApplicationEvent(SessionDestroyedEvent event) {
|
||||||
this.event = event;
|
this.event = event;
|
||||||
|
|||||||
@@ -30,12 +30,10 @@ import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
|
|||||||
@Configuration
|
@Configuration
|
||||||
@EnableScheduling
|
@EnableScheduling
|
||||||
@EnableWebSocketMessageBroker
|
@EnableWebSocketMessageBroker
|
||||||
public class WebSocketConfig
|
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
|
||||||
extends AbstractWebSocketMessageBrokerConfigurer {
|
|
||||||
|
|
||||||
public void registerStompEndpoints(StompEndpointRegistry registry) {
|
public void registerStompEndpoints(StompEndpointRegistry registry) {
|
||||||
registry.addEndpoint("/messages")
|
registry.addEndpoint("/messages").withSockJS();
|
||||||
.withSockJS();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ package sample.config;
|
|||||||
|
|
||||||
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
|
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
|
||||||
|
|
||||||
|
|
||||||
// tag::class[]
|
// tag::class[]
|
||||||
@EnableRedisHttpSession // <1>
|
@EnableRedisHttpSession // <1>
|
||||||
public class HttpSessionConfig { }
|
public class HttpSessionConfig {
|
||||||
|
}
|
||||||
// end::class[]
|
// end::class[]
|
||||||
|
|||||||
@@ -29,8 +29,6 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
auth
|
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
|
||||||
.inMemoryAuthentication()
|
|
||||||
.withUser("user").password("password").roles("USER");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import org.springframework.session.data.redis.config.annotation.web.http.EnableR
|
|||||||
import org.springframework.session.web.http.CookieSerializer;
|
import org.springframework.session.web.http.CookieSerializer;
|
||||||
import org.springframework.session.web.http.DefaultCookieSerializer;
|
import org.springframework.session.web.http.DefaultCookieSerializer;
|
||||||
|
|
||||||
|
|
||||||
@EnableRedisHttpSession
|
@EnableRedisHttpSession
|
||||||
public class Config {
|
public class Config {
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ package sample;
|
|||||||
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
|
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
|
||||||
|
|
||||||
// tag::class[]
|
// tag::class[]
|
||||||
public class Initializer
|
public class Initializer extends AbstractHttpSessionApplicationInitializer { // <1>
|
||||||
extends AbstractHttpSessionApplicationInitializer { // <1>
|
|
||||||
|
|
||||||
public Initializer() {
|
public Initializer() {
|
||||||
super(Config.class); // <2>
|
super(Config.class); // <2>
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
public class SessionServlet extends HttpServlet {
|
public class SessionServlet extends HttpServlet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
||||||
|
throws ServletException, IOException {
|
||||||
String attributeName = req.getParameter("attributeName");
|
String attributeName = req.getParameter("attributeName");
|
||||||
String attributeValue = req.getParameter("attributeValue");
|
String attributeValue = req.getParameter("attributeValue");
|
||||||
req.getSession().setAttribute(attributeName, attributeValue);
|
req.getSession().setAttribute(attributeName, attributeValue);
|
||||||
|
|||||||
@@ -33,7 +33,9 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
public class GeoConfig {
|
public class GeoConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public DatabaseReader geoDatabaseReader(@Value("classpath:GeoLite2-City.mmdb") InputStream geoInputStream) throws Exception {
|
public DatabaseReader geoDatabaseReader(
|
||||||
|
@Value("classpath:GeoLite2-City.mmdb") InputStream geoInputStream)
|
||||||
|
throws Exception {
|
||||||
return new DatabaseReader.Builder(geoInputStream).build();
|
return new DatabaseReader.Builder(geoInputStream).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,5 +25,6 @@ import org.springframework.session.data.redis.config.annotation.web.http.EnableR
|
|||||||
*/
|
*/
|
||||||
// tag::class[]
|
// tag::class[]
|
||||||
@EnableRedisHttpSession // <1>
|
@EnableRedisHttpSession // <1>
|
||||||
public class HttpSessionConfig { }
|
public class HttpSessionConfig {
|
||||||
|
}
|
||||||
// end::class[]
|
// end::class[]
|
||||||
|
|||||||
@@ -31,24 +31,14 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||||||
// tag::config[]
|
// tag::config[]
|
||||||
@Override
|
@Override
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http.formLogin().loginPage("/login").permitAll().and().authorizeRequests()
|
||||||
.formLogin()
|
.antMatchers("/resources/**").permitAll().anyRequest().authenticated()
|
||||||
.loginPage("/login")
|
.and().logout().permitAll();
|
||||||
.permitAll()
|
|
||||||
.and()
|
|
||||||
.authorizeRequests()
|
|
||||||
.antMatchers("/resources/**").permitAll()
|
|
||||||
.anyRequest().authenticated()
|
|
||||||
.and()
|
|
||||||
.logout()
|
|
||||||
.permitAll();
|
|
||||||
}
|
}
|
||||||
// end::config[]
|
// end::config[]
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
auth
|
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
|
||||||
.inMemoryAuthentication()
|
|
||||||
.withUser("user").password("password").roles("USER");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,17 +43,21 @@ public class IndexController {
|
|||||||
|
|
||||||
@RequestMapping("/")
|
@RequestMapping("/")
|
||||||
public String index(Principal principal, Model model) {
|
public String index(Principal principal, Model model) {
|
||||||
Collection<? extends ExpiringSession> usersSessions =
|
Collection<? extends ExpiringSession> usersSessions = this.sessions
|
||||||
this.sessions.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
|
.findByIndexNameAndIndexValue(
|
||||||
principal.getName()).values();
|
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
|
||||||
|
principal.getName())
|
||||||
|
.values();
|
||||||
model.addAttribute("sessions", usersSessions);
|
model.addAttribute("sessions", usersSessions);
|
||||||
return "index";
|
return "index";
|
||||||
}
|
}
|
||||||
// end::findbyusername[]
|
// end::findbyusername[]
|
||||||
|
|
||||||
@RequestMapping(value = "/sessions/{sessionIdToDelete}", method = RequestMethod.DELETE)
|
@RequestMapping(value = "/sessions/{sessionIdToDelete}", method = RequestMethod.DELETE)
|
||||||
public String removeSession(Principal principal, @PathVariable String sessionIdToDelete) {
|
public String removeSession(Principal principal,
|
||||||
Set<String> usersSessionIds = this.sessions.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
|
@PathVariable String sessionIdToDelete) {
|
||||||
|
Set<String> usersSessionIds = this.sessions.findByIndexNameAndIndexValue(
|
||||||
|
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
|
||||||
principal.getName()).keySet();
|
principal.getName()).keySet();
|
||||||
if (usersSessionIds.contains(sessionIdToDelete)) {
|
if (usersSessionIds.contains(sessionIdToDelete)) {
|
||||||
this.sessions.delete(sessionIdToDelete);
|
this.sessions.delete(sessionIdToDelete);
|
||||||
|
|||||||
@@ -35,10 +35,10 @@ import org.springframework.stereotype.Component;
|
|||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserts the session details into the session for every request. Some users
|
* Inserts the session details into the session for every request. Some users may prefer
|
||||||
* may prefer to insert session details only after authentication. This is fine,
|
* to insert session details only after authentication. This is fine, but it may be
|
||||||
* but it may be valuable to the most up to date information so that if someone
|
* valuable to the most up to date information so that if someone stole the user's session
|
||||||
* stole the user's session id it can be observed.
|
* id it can be observed.
|
||||||
*
|
*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*
|
*
|
||||||
@@ -57,8 +57,8 @@ public class SessionDetailsFilter extends OncePerRequestFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// tag::dofilterinternal[]
|
// tag::dofilterinternal[]
|
||||||
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
|
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
|
||||||
throws IOException, ServletException {
|
FilterChain chain) throws IOException, ServletException {
|
||||||
chain.doFilter(request, response);
|
chain.doFilter(request, response);
|
||||||
|
|
||||||
HttpSession session = request.getSession(false);
|
HttpSession session = request.getSession(false);
|
||||||
@@ -109,4 +109,3 @@ public class SessionDetailsFilter extends OncePerRequestFilter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// end::class[]
|
// end::class[]
|
||||||
|
|
||||||
|
|||||||
@@ -48,16 +48,19 @@ public class SessionDetailsFilterTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getGeoLocationHanldesInvalidIp() {
|
public void getGeoLocationHanldesInvalidIp() {
|
||||||
assertThat(this.filter.getGeoLocation("a")).isEqualTo(SessionDetailsFilter.UNKNOWN);
|
assertThat(this.filter.getGeoLocation("a"))
|
||||||
|
.isEqualTo(SessionDetailsFilter.UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getGeoLocationNullCity() {
|
public void getGeoLocationNullCity() {
|
||||||
assertThat(this.filter.getGeoLocation("22.231.113.64")).isEqualTo("United States");
|
assertThat(this.filter.getGeoLocation("22.231.113.64"))
|
||||||
|
.isEqualTo("United States");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getGeoLocationBoth() {
|
public void getGeoLocationBoth() {
|
||||||
assertThat(this.filter.getGeoLocation("184.154.83.119")).isEqualTo("Chicago, United States");
|
assertThat(this.filter.getGeoLocation("184.154.83.119"))
|
||||||
|
.isEqualTo("Chicago, United States");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ public class Config {
|
|||||||
netConfig.setPort(SocketUtils.findAvailableTcpPort());
|
netConfig.setPort(SocketUtils.findAvailableTcpPort());
|
||||||
System.out.println("Hazelcast port #: " + netConfig.getPort());
|
System.out.println("Hazelcast port #: " + netConfig.getPort());
|
||||||
cfg.setNetworkConfig(netConfig);
|
cfg.setNetworkConfig(netConfig);
|
||||||
SerializerConfig serializer = new SerializerConfig().setTypeClass(
|
SerializerConfig serializer = new SerializerConfig().setTypeClass(Object.class)
|
||||||
Object.class).setImplementation(new ObjectStreamSerializer());
|
.setImplementation(new ObjectStreamSerializer());
|
||||||
cfg.getSerializationConfig().addSerializerConfig(serializer);
|
cfg.getSerializationConfig().addSerializerConfig(serializer);
|
||||||
|
|
||||||
return Hazelcast.newHazelcastInstance(cfg);
|
return Hazelcast.newHazelcastInstance(cfg);
|
||||||
|
|||||||
@@ -27,11 +27,10 @@ import com.hazelcast.nio.ObjectDataOutput;
|
|||||||
import com.hazelcast.nio.serialization.StreamSerializer;
|
import com.hazelcast.nio.serialization.StreamSerializer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link StreamSerializer} that uses Java serialization to persist the
|
* A {@link StreamSerializer} that uses Java serialization to persist the session. This is
|
||||||
* session. This is certainly not the most efficient way to persist sessions,
|
* certainly not the most efficient way to persist sessions, but the example is intended
|
||||||
* but the example is intended to demonstrate using minimal dependencies. For
|
* to demonstrate using minimal dependencies. For better serialization methods try using
|
||||||
* better serialization methods try using <a
|
* <a href="https://github.com/EsotericSoftware/kryo">Kryo</a>.
|
||||||
* href="https://github.com/EsotericSoftware/kryo">Kryo</a>.
|
|
||||||
*
|
*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*
|
*
|
||||||
@@ -48,8 +47,7 @@ public class ObjectStreamSerializer implements StreamSerializer<Object> {
|
|||||||
out.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object read(ObjectDataInput objectDataInput)
|
public Object read(ObjectDataInput objectDataInput) throws IOException {
|
||||||
throws IOException {
|
|
||||||
ObjectInputStream in = new ObjectInputStream((InputStream) objectDataInput);
|
ObjectInputStream in = new ObjectInputStream((InputStream) objectDataInput);
|
||||||
try {
|
try {
|
||||||
return in.readObject();
|
return in.readObject();
|
||||||
|
|||||||
@@ -28,8 +28,6 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
|
|||||||
public class SecurityConfig {
|
public class SecurityConfig {
|
||||||
@Autowired
|
@Autowired
|
||||||
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
auth
|
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
|
||||||
.inMemoryAuthentication()
|
|
||||||
.withUser("user").password("password").roles("USER");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ package sample;
|
|||||||
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
|
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
|
||||||
|
|
||||||
// tag::class[]
|
// tag::class[]
|
||||||
public class SecurityInitializer extends
|
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
|
||||||
AbstractSecurityWebApplicationInitializer {
|
|
||||||
|
|
||||||
public SecurityInitializer() {
|
public SecurityInitializer() {
|
||||||
super(SecurityConfig.class, Config.class);
|
super(SecurityConfig.class, Config.class);
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
public class SessionServlet extends HttpServlet {
|
public class SessionServlet extends HttpServlet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
||||||
|
throws ServletException, IOException {
|
||||||
String attributeName = req.getParameter("attributeName");
|
String attributeName = req.getParameter("attributeName");
|
||||||
String attributeValue = req.getParameter("attributeValue");
|
String attributeValue = req.getParameter("attributeValue");
|
||||||
req.getSession().setAttribute(attributeName, attributeValue);
|
req.getSession().setAttribute(attributeName, attributeValue);
|
||||||
|
|||||||
@@ -53,8 +53,7 @@ public class Initializer implements ServletContextListener {
|
|||||||
NetworkConfig netConfig = new NetworkConfig();
|
NetworkConfig netConfig = new NetworkConfig();
|
||||||
netConfig.setPort(getAvailablePort());
|
netConfig.setPort(getAvailablePort());
|
||||||
cfg.setNetworkConfig(netConfig);
|
cfg.setNetworkConfig(netConfig);
|
||||||
SerializerConfig serializer = new SerializerConfig()
|
SerializerConfig serializer = new SerializerConfig().setTypeClass(Object.class)
|
||||||
.setTypeClass(Object.class)
|
|
||||||
.setImplementation(new ObjectStreamSerializer());
|
.setImplementation(new ObjectStreamSerializer());
|
||||||
cfg.getSerializationConfig().addSerializerConfig(serializer);
|
cfg.getSerializationConfig().addSerializerConfig(serializer);
|
||||||
MapConfig mc = new MapConfig();
|
MapConfig mc = new MapConfig();
|
||||||
@@ -65,10 +64,10 @@ public class Initializer implements ServletContextListener {
|
|||||||
this.instance = Hazelcast.newHazelcastInstance(cfg);
|
this.instance = Hazelcast.newHazelcastInstance(cfg);
|
||||||
Map<String, ExpiringSession> sessions = this.instance.getMap(sessionMapName);
|
Map<String, ExpiringSession> sessions = this.instance.getMap(sessionMapName);
|
||||||
|
|
||||||
SessionRepository<ExpiringSession> sessionRepository =
|
SessionRepository<ExpiringSession> sessionRepository = new MapSessionRepository(
|
||||||
new MapSessionRepository(sessions);
|
sessions);
|
||||||
SessionRepositoryFilter<ExpiringSession> filter =
|
SessionRepositoryFilter<ExpiringSession> filter = new SessionRepositoryFilter<ExpiringSession>(
|
||||||
new SessionRepositoryFilter<ExpiringSession>(sessionRepository);
|
sessionRepository);
|
||||||
Dynamic fr = sc.addFilter("springSessionFilter", filter);
|
Dynamic fr = sc.addFilter("springSessionFilter", filter);
|
||||||
fr.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
|
fr.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,11 +27,10 @@ import com.hazelcast.nio.ObjectDataOutput;
|
|||||||
import com.hazelcast.nio.serialization.StreamSerializer;
|
import com.hazelcast.nio.serialization.StreamSerializer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link StreamSerializer} that uses Java serialization to persist the
|
* A {@link StreamSerializer} that uses Java serialization to persist the session. This is
|
||||||
* session. This is certainly not the most efficient way to persist sessions,
|
* certainly not the most efficient way to persist sessions, but the example is intended
|
||||||
* but the example is intended to demonstrate using minimal dependencies. For
|
* to demonstrate using minimal dependencies. For better serialization methods try using
|
||||||
* better serialization methods try using <a
|
* <a href="https://github.com/EsotericSoftware/kryo">Kryo</a>.
|
||||||
* href="https://github.com/EsotericSoftware/kryo">Kryo</a>.
|
|
||||||
*
|
*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*
|
*
|
||||||
@@ -48,8 +47,7 @@ public class ObjectStreamSerializer implements StreamSerializer<Object> {
|
|||||||
out.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object read(ObjectDataInput objectDataInput)
|
public Object read(ObjectDataInput objectDataInput) throws IOException {
|
||||||
throws IOException {
|
|
||||||
ObjectInputStream in = new ObjectInputStream((InputStream) objectDataInput);
|
ObjectInputStream in = new ObjectInputStream((InputStream) objectDataInput);
|
||||||
try {
|
try {
|
||||||
return in.readObject();
|
return in.readObject();
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
public class SessionServlet extends HttpServlet {
|
public class SessionServlet extends HttpServlet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
||||||
|
throws ServletException, IOException {
|
||||||
String attributeName = req.getParameter("attributeName");
|
String attributeName = req.getParameter("attributeName");
|
||||||
String attributeValue = req.getParameter("attributeValue");
|
String attributeValue = req.getParameter("attributeValue");
|
||||||
req.getSession().setAttribute(attributeName, attributeValue);
|
req.getSession().setAttribute(attributeName, attributeValue);
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ import org.springframework.context.annotation.ImportResource;
|
|||||||
public class Application {
|
public class Application {
|
||||||
|
|
||||||
public static void main(final String[] args) {
|
public static void main(final String[] args) {
|
||||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Application.class);
|
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||||
|
Application.class);
|
||||||
context.registerShutdownHook();
|
context.registerShutdownHook();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ public class GemFireCacheServerReadyBeanPostProcessor implements BeanPostProcess
|
|||||||
|
|
||||||
// tag::class[]
|
// tag::class[]
|
||||||
static {
|
static {
|
||||||
ClientMembership.registerClientMembershipListener(new ClientMembershipListenerAdapter() {
|
ClientMembership
|
||||||
|
.registerClientMembershipListener(new ClientMembershipListenerAdapter() {
|
||||||
public void memberJoined(final ClientMembershipEvent event) {
|
public void memberJoined(final ClientMembershipEvent event) {
|
||||||
if (!event.isClient()) {
|
if (!event.isClient()) {
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
@@ -64,17 +65,21 @@ public class GemFireCacheServerReadyBeanPostProcessor implements BeanPostProcess
|
|||||||
@Resource(name = "applicationProperties")
|
@Resource(name = "applicationProperties")
|
||||||
private Properties applicationProperties;
|
private Properties applicationProperties;
|
||||||
|
|
||||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||||
|
throws BeansException {
|
||||||
if (bean instanceof PoolFactoryBean || bean instanceof Pool) {
|
if (bean instanceof PoolFactoryBean || bean instanceof Pool) {
|
||||||
String host = getServerHost(DEFAULT_SERVER_HOST);
|
String host = getServerHost(DEFAULT_SERVER_HOST);
|
||||||
Assert.isTrue(waitForCacheServerToStart(host, this.port), String.format(
|
Assert.isTrue(waitForCacheServerToStart(host, this.port),
|
||||||
"GemFire Server failed to start [host: '%1$s', port: %2$d]%n", host, this.port));
|
String.format(
|
||||||
|
"GemFire Server failed to start [host: '%1$s', port: %2$d]%n",
|
||||||
|
host, this.port));
|
||||||
}
|
}
|
||||||
|
|
||||||
return bean;
|
return bean;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||||
|
throws BeansException {
|
||||||
if (bean instanceof PoolFactoryBean || bean instanceof Pool) {
|
if (bean instanceof PoolFactoryBean || bean instanceof Pool) {
|
||||||
try {
|
try {
|
||||||
latch.await(DEFAULT_WAIT_DURATION, TimeUnit.MILLISECONDS);
|
latch.await(DEFAULT_WAIT_DURATION, TimeUnit.MILLISECONDS);
|
||||||
@@ -93,7 +98,8 @@ public class GemFireCacheServerReadyBeanPostProcessor implements BeanPostProcess
|
|||||||
}
|
}
|
||||||
|
|
||||||
String getServerHost(String defaultServerHost) {
|
String getServerHost(String defaultServerHost) {
|
||||||
return this.applicationProperties.getProperty("application.gemfire.client-server.host", defaultServerHost);
|
return this.applicationProperties
|
||||||
|
.getProperty("application.gemfire.client-server.host", defaultServerHost);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean waitForCacheServerToStart(String host, int port) {
|
boolean waitForCacheServerToStart(String host, int port) {
|
||||||
@@ -109,8 +115,10 @@ public class GemFireCacheServerReadyBeanPostProcessor implements BeanPostProcess
|
|||||||
Socket socket = null;
|
Socket socket = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// NOTE: this code is not intended to be an atomic, compound action (a possible race condition);
|
// NOTE: this code is not intended to be an atomic, compound action (a
|
||||||
// opening another connection (at the expense of using system resources) after connectivity
|
// possible race condition);
|
||||||
|
// opening another connection (at the expense of using system
|
||||||
|
// resources) after connectivity
|
||||||
// has already been established is not detrimental in this use case
|
// has already been established is not detrimental in this use case
|
||||||
if (!connected.get()) {
|
if (!connected.get()) {
|
||||||
socket = new Socket(host, port);
|
socket = new Socket(host, port);
|
||||||
|
|||||||
@@ -55,8 +55,8 @@ public class ClientConfig {
|
|||||||
System.setProperty("gemfire.log-level",
|
System.setProperty("gemfire.log-level",
|
||||||
System.getProperty("sample.httpsession.gemfire.log-level", "warning"));
|
System.getProperty("sample.httpsession.gemfire.log-level", "warning"));
|
||||||
|
|
||||||
ClientMembership.registerClientMembershipListener(
|
ClientMembership
|
||||||
new ClientMembershipListenerAdapter() {
|
.registerClientMembershipListener(new ClientMembershipListenerAdapter() {
|
||||||
public void memberJoined(ClientMembershipEvent event) {
|
public void memberJoined(ClientMembershipEvent event) {
|
||||||
if (!event.isClient()) {
|
if (!event.isClient()) {
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
@@ -77,7 +77,8 @@ public class ClientConfig {
|
|||||||
|
|
||||||
@Bean(name = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME)
|
@Bean(name = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME)
|
||||||
PoolFactoryBean gemfirePool(// <3>
|
PoolFactoryBean gemfirePool(// <3>
|
||||||
@Value("${spring.session.data.gemfire.port:" + ServerConfig.SERVER_PORT + "}") int port) {
|
@Value("${spring.session.data.gemfire.port:" + ServerConfig.SERVER_PORT
|
||||||
|
+ "}") int port) {
|
||||||
|
|
||||||
PoolFactoryBean poolFactory = new PoolFactoryBean();
|
PoolFactoryBean poolFactory = new PoolFactoryBean();
|
||||||
|
|
||||||
@@ -91,8 +92,8 @@ public class ClientConfig {
|
|||||||
poolFactory.setSubscriptionEnabled(true);
|
poolFactory.setSubscriptionEnabled(true);
|
||||||
poolFactory.setThreadLocalConnections(false);
|
poolFactory.setThreadLocalConnections(false);
|
||||||
|
|
||||||
poolFactory.setServerEndpoints(Collections.singletonList(new ConnectionEndpoint(
|
poolFactory.setServerEndpoints(Collections.singletonList(
|
||||||
ServerConfig.SERVER_HOSTNAME, port)));
|
new ConnectionEndpoint(ServerConfig.SERVER_HOSTNAME, port)));
|
||||||
|
|
||||||
return poolFactory;
|
return poolFactory;
|
||||||
}
|
}
|
||||||
@@ -111,27 +112,29 @@ public class ClientConfig {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
BeanPostProcessor gemfireCacheServerReadyBeanPostProcessor(// <5>
|
BeanPostProcessor gemfireCacheServerReadyBeanPostProcessor(// <5>
|
||||||
@Value("${spring.session.data.gemfire.port:" + ServerConfig.SERVER_PORT + "}") final int port) {
|
@Value("${spring.session.data.gemfire.port:" + ServerConfig.SERVER_PORT
|
||||||
|
+ "}") final int port) {
|
||||||
|
|
||||||
return new BeanPostProcessor() {
|
return new BeanPostProcessor() {
|
||||||
|
|
||||||
public Object postProcessBeforeInitialization(
|
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||||
Object bean, String beanName) throws BeansException {
|
throws BeansException {
|
||||||
if (bean instanceof PoolFactoryBean || bean instanceof Pool) {
|
if (bean instanceof PoolFactoryBean || bean instanceof Pool) {
|
||||||
Assert.isTrue(waitForCacheServerToStart(ServerConfig.SERVER_HOSTNAME, port),
|
Assert.isTrue(
|
||||||
String.format("GemFire Server failed to start [hostname: %1$s, port: %2$d]",
|
waitForCacheServerToStart(ServerConfig.SERVER_HOSTNAME, port),
|
||||||
|
String.format(
|
||||||
|
"GemFire Server failed to start [hostname: %1$s, port: %2$d]",
|
||||||
ServerConfig.SERVER_HOSTNAME, port));
|
ServerConfig.SERVER_HOSTNAME, port));
|
||||||
}
|
}
|
||||||
|
|
||||||
return bean;
|
return bean;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object postProcessAfterInitialization(
|
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||||
Object bean, String beanName) throws BeansException {
|
throws BeansException {
|
||||||
if (bean instanceof PoolFactoryBean || bean instanceof Pool) {
|
if (bean instanceof PoolFactoryBean || bean instanceof Pool) {
|
||||||
try {
|
try {
|
||||||
latch.await(DEFAULT_WAIT_DURATION,
|
latch.await(DEFAULT_WAIT_DURATION, TimeUnit.MILLISECONDS);
|
||||||
TimeUnit.MILLISECONDS);
|
|
||||||
}
|
}
|
||||||
catch (InterruptedException e) {
|
catch (InterruptedException e) {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
@@ -161,8 +164,10 @@ public class ClientConfig {
|
|||||||
Socket socket = null;
|
Socket socket = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// NOTE: this code is not intended to be an atomic, compound action (a possible race condition);
|
// NOTE: this code is not intended to be an atomic, compound action (a
|
||||||
// opening another connection (at the expense of using system resources) after connectivity
|
// possible race condition);
|
||||||
|
// opening another connection (at the expense of using system
|
||||||
|
// resources) after connectivity
|
||||||
// has already been established is not detrimental in this use case
|
// has already been established is not detrimental in this use case
|
||||||
if (!connected.get()) {
|
if (!connected.get()) {
|
||||||
socket = new Socket(host, port);
|
socket = new Socket(host, port);
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ package sample;
|
|||||||
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
|
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
|
||||||
|
|
||||||
// tag::class[]
|
// tag::class[]
|
||||||
public class Initializer
|
public class Initializer extends AbstractHttpSessionApplicationInitializer { // <1>
|
||||||
extends AbstractHttpSessionApplicationInitializer { // <1>
|
|
||||||
|
|
||||||
public Initializer() {
|
public Initializer() {
|
||||||
super(ClientConfig.class); // <2>
|
super(ClientConfig.class); // <2>
|
||||||
|
|||||||
@@ -84,8 +84,7 @@ public class ServerConfig {
|
|||||||
|
|
||||||
@SuppressWarnings("resource")
|
@SuppressWarnings("resource")
|
||||||
public static void main(final String[] args) throws IOException { // <5>
|
public static void main(final String[] args) throws IOException { // <5>
|
||||||
new AnnotationConfigApplicationContext(ServerConfig.class)
|
new AnnotationConfigApplicationContext(ServerConfig.class).registerShutdownHook();
|
||||||
.registerShutdownHook();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// end::class[]
|
// end::class[]
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ package sample;
|
|||||||
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
|
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
|
||||||
|
|
||||||
// tag::class[]
|
// tag::class[]
|
||||||
public class Initializer
|
public class Initializer extends AbstractHttpSessionApplicationInitializer { // <1>
|
||||||
extends AbstractHttpSessionApplicationInitializer { // <1>
|
|
||||||
|
|
||||||
public Initializer() {
|
public Initializer() {
|
||||||
super(Config.class); // <2>
|
super(Config.class); // <2>
|
||||||
|
|||||||
@@ -15,15 +15,19 @@
|
|||||||
*/
|
*/
|
||||||
package sample;
|
package sample;
|
||||||
|
|
||||||
import javax.servlet.*;
|
|
||||||
import javax.servlet.http.*;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
// tag::class[]
|
// tag::class[]
|
||||||
public class SessionServlet extends HttpServlet {
|
public class SessionServlet extends HttpServlet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
||||||
|
throws ServletException, IOException {
|
||||||
String attributeName = req.getParameter("attributeName");
|
String attributeName = req.getParameter("attributeName");
|
||||||
String attributeValue = req.getParameter("attributeValue");
|
String attributeValue = req.getParameter("attributeValue");
|
||||||
req.getSession().setAttribute(attributeName, attributeValue);
|
req.getSession().setAttribute(attributeName, attributeValue);
|
||||||
|
|||||||
@@ -34,8 +34,7 @@ public class Config {
|
|||||||
public EmbeddedDatabase dataSource() {
|
public EmbeddedDatabase dataSource() {
|
||||||
return new EmbeddedDatabaseBuilder() // <2>
|
return new EmbeddedDatabaseBuilder() // <2>
|
||||||
.setType(EmbeddedDatabaseType.H2)
|
.setType(EmbeddedDatabaseType.H2)
|
||||||
.addScript("org/springframework/session/jdbc/schema-h2.sql")
|
.addScript("org/springframework/session/jdbc/schema-h2.sql").build();
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|||||||
@@ -18,8 +18,7 @@ package sample;
|
|||||||
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
|
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
|
||||||
|
|
||||||
// tag::class[]
|
// tag::class[]
|
||||||
public class Initializer
|
public class Initializer extends AbstractHttpSessionApplicationInitializer { // <1>
|
||||||
extends AbstractHttpSessionApplicationInitializer { // <1>
|
|
||||||
|
|
||||||
public Initializer() {
|
public Initializer() {
|
||||||
super(Config.class); // <2>
|
super(Config.class); // <2>
|
||||||
|
|||||||
@@ -15,17 +15,21 @@
|
|||||||
*/
|
*/
|
||||||
package sample;
|
package sample;
|
||||||
|
|
||||||
import javax.servlet.*;
|
|
||||||
import javax.servlet.annotation.*;
|
|
||||||
import javax.servlet.http.*;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.annotation.WebServlet;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
// tag::class[]
|
// tag::class[]
|
||||||
@WebServlet("/session")
|
@WebServlet("/session")
|
||||||
public class SessionServlet extends HttpServlet {
|
public class SessionServlet extends HttpServlet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
||||||
|
throws ServletException, IOException {
|
||||||
String attributeName = req.getParameter("attributeName");
|
String attributeName = req.getParameter("attributeName");
|
||||||
String attributeValue = req.getParameter("attributeValue");
|
String attributeValue = req.getParameter("attributeValue");
|
||||||
req.getSession().setAttribute(attributeName, attributeValue);
|
req.getSession().setAttribute(attributeName, attributeValue);
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
public class SessionServlet extends HttpServlet {
|
public class SessionServlet extends HttpServlet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
||||||
|
throws ServletException, IOException {
|
||||||
String attributeName = req.getParameter("attributeName");
|
String attributeName = req.getParameter("attributeName");
|
||||||
String attributeValue = req.getParameter("attributeValue");
|
String attributeValue = req.getParameter("attributeValue");
|
||||||
req.getSession().setAttribute(attributeName, attributeValue);
|
req.getSession().setAttribute(attributeName, attributeValue);
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ package sample;
|
|||||||
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
|
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
|
||||||
|
|
||||||
// tag::class[]
|
// tag::class[]
|
||||||
public class Initializer
|
public class Initializer extends AbstractHttpSessionApplicationInitializer { // <1>
|
||||||
extends AbstractHttpSessionApplicationInitializer { // <1>
|
|
||||||
|
|
||||||
public Initializer() {
|
public Initializer() {
|
||||||
super(Config.class); // <2>
|
super(Config.class); // <2>
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
public class SessionServlet extends HttpServlet {
|
public class SessionServlet extends HttpServlet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
||||||
|
throws ServletException, IOException {
|
||||||
String attributeName = req.getParameter("attributeName");
|
String attributeName = req.getParameter("attributeName");
|
||||||
String attributeValue = req.getParameter("attributeValue");
|
String attributeValue = req.getParameter("attributeValue");
|
||||||
req.getSession().setAttribute(attributeName, attributeValue);
|
req.getSession().setAttribute(attributeName, attributeValue);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 the original author or authors.
|
* Copyright 2014-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,16 +16,15 @@
|
|||||||
package sample
|
package sample
|
||||||
|
|
||||||
import geb.spock.*
|
import geb.spock.*
|
||||||
import org.springframework.beans.factory.annotation.Value
|
import pages.*
|
||||||
import org.springframework.boot.test.IntegrationTest
|
|
||||||
import org.springframework.boot.test.SpringApplicationConfiguration
|
|
||||||
import org.springframework.boot.test.SpringApplicationContextLoader
|
|
||||||
import org.springframework.test.context.ContextConfiguration
|
|
||||||
import org.springframework.test.context.web.WebAppConfiguration
|
|
||||||
import sample.pages.HomePage
|
import sample.pages.HomePage
|
||||||
import sample.pages.LoginPage
|
import sample.pages.LoginPage
|
||||||
import spock.lang.Stepwise
|
import spock.lang.Stepwise
|
||||||
import pages.*
|
|
||||||
|
import org.springframework.boot.test.IntegrationTest
|
||||||
|
import org.springframework.boot.test.SpringApplicationContextLoader
|
||||||
|
import org.springframework.test.context.ContextConfiguration
|
||||||
|
import org.springframework.test.context.web.WebAppConfiguration
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the demo that supports multiple sessions
|
* Tests the demo that supports multiple sessions
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 the original author or authors.
|
* Copyright 2014-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* use this file except in compliance with the License. You may obtain a copy of
|
* you may not use this file except in compliance with the License.
|
||||||
* the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* License for the specific language governing permissions and limitations under
|
* See the License for the specific language governing permissions and
|
||||||
* the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package sample;
|
package sample;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 the original author or authors.
|
* Copyright 2014-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -17,8 +17,8 @@ package sample.config;
|
|||||||
|
|
||||||
import org.springframework.session.data.mongo.config.annotation.web.http.EnableMongoHttpSession;
|
import org.springframework.session.data.mongo.config.annotation.web.http.EnableMongoHttpSession;
|
||||||
|
|
||||||
|
|
||||||
// tag::class[]
|
// tag::class[]
|
||||||
@EnableMongoHttpSession // <1>
|
@EnableMongoHttpSession // <1>
|
||||||
public class HttpSessionConfig { }
|
public class HttpSessionConfig {
|
||||||
|
}
|
||||||
// end::class[]
|
// end::class[]
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 the original author or authors.
|
* Copyright 2014-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* use this file except in compliance with the License. You may obtain a copy of
|
* you may not use this file except in compliance with the License.
|
||||||
* the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* License for the specific language governing permissions and limitations under
|
* See the License for the specific language governing permissions and
|
||||||
* the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package sample.config;
|
package sample.config;
|
||||||
|
|
||||||
@@ -28,8 +28,6 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
auth
|
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
|
||||||
.inMemoryAuthentication()
|
|
||||||
.withUser("user").password("password").roles("USER");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 the original author or authors.
|
* Copyright 2014-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* use this file except in compliance with the License. You may obtain a copy of
|
* you may not use this file except in compliance with the License.
|
||||||
* the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* License for the specific language governing permissions and limitations under
|
* See the License for the specific language governing permissions and
|
||||||
* the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package sample.mvc;
|
package sample.mvc;
|
||||||
|
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@ContextConfiguration(classes = {HttpSessionConfig.class, SecurityConfig.class, MvcConfig.class})
|
@ContextConfiguration(classes = { HttpSessionConfig.class, SecurityConfig.class,
|
||||||
|
MvcConfig.class })
|
||||||
@WebAppConfiguration
|
@WebAppConfiguration
|
||||||
public class RestMockMvcTests {
|
public class RestMockMvcTests {
|
||||||
|
|
||||||
@@ -59,25 +59,20 @@ public class RestMockMvcTests {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
this.mvc = MockMvcBuilders.webAppContextSetup(this.context)
|
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).alwaysDo(print())
|
||||||
.alwaysDo(print())
|
.addFilters(this.sessionRepositoryFilter).apply(springSecurity()).build();
|
||||||
.addFilters(this.sessionRepositoryFilter)
|
|
||||||
.apply(springSecurity())
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void noSessionOnNoCredentials() throws Exception {
|
public void noSessionOnNoCredentials() throws Exception {
|
||||||
this.mvc.perform(get("/"))
|
this.mvc.perform(get("/")).andExpect(header().doesNotExist("x-auth-token"))
|
||||||
.andExpect(header().doesNotExist("x-auth-token"))
|
|
||||||
.andExpect(status().isUnauthorized());
|
.andExpect(status().isUnauthorized());
|
||||||
}
|
}
|
||||||
|
|
||||||
@WithMockUser
|
@WithMockUser
|
||||||
@Test
|
@Test
|
||||||
public void autheticatedAnnotation() throws Exception {
|
public void autheticatedAnnotation() throws Exception {
|
||||||
this.mvc.perform(get("/"))
|
this.mvc.perform(get("/")).andExpect(content().string("{\"username\":\"user\"}"));
|
||||||
.andExpect(content().string("{\"username\":\"user\"}"));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import org.springframework.security.web.context.AbstractSecurityWebApplicationIn
|
|||||||
/**
|
/**
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
public class SecurityInitializer extends
|
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
|
||||||
AbstractSecurityWebApplicationInitializer {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,8 +28,6 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
|
|||||||
public class SecurityConfig {
|
public class SecurityConfig {
|
||||||
@Autowired
|
@Autowired
|
||||||
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
auth
|
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
|
||||||
.inMemoryAuthentication()
|
|
||||||
.withUser("user").password("password").roles("USER");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ package sample;
|
|||||||
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
|
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
|
||||||
|
|
||||||
// tag::class[]
|
// tag::class[]
|
||||||
public class SecurityInitializer extends
|
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
|
||||||
AbstractSecurityWebApplicationInitializer {
|
|
||||||
|
|
||||||
public SecurityInitializer() {
|
public SecurityInitializer() {
|
||||||
super(SecurityConfig.class, Config.class);
|
super(SecurityConfig.class, Config.class);
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
public class SessionServlet extends HttpServlet {
|
public class SessionServlet extends HttpServlet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
||||||
|
throws ServletException, IOException {
|
||||||
String attributeName = req.getParameter("attributeName");
|
String attributeName = req.getParameter("attributeName");
|
||||||
String attributeValue = req.getParameter("attributeValue");
|
String attributeValue = req.getParameter("attributeValue");
|
||||||
req.getSession().setAttribute(attributeName, attributeValue);
|
req.getSession().setAttribute(attributeName, attributeValue);
|
||||||
|
|||||||
@@ -44,11 +44,11 @@ public class UserAccountsFilter implements Filter {
|
|||||||
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||||
|
|
||||||
// tag::HttpSessionManager[]
|
// tag::HttpSessionManager[]
|
||||||
HttpSessionManager sessionManager =
|
HttpSessionManager sessionManager = (HttpSessionManager) httpRequest
|
||||||
(HttpSessionManager) httpRequest.getAttribute(HttpSessionManager.class.getName());
|
.getAttribute(HttpSessionManager.class.getName());
|
||||||
// end::HttpSessionManager[]
|
// end::HttpSessionManager[]
|
||||||
SessionRepository<Session> repo =
|
SessionRepository<Session> repo = (SessionRepository<Session>) httpRequest
|
||||||
(SessionRepository<Session>) httpRequest.getAttribute(SessionRepository.class.getName());
|
.getAttribute(SessionRepository.class.getName());
|
||||||
|
|
||||||
String currentSessionAlias = sessionManager.getCurrentSessionAlias(httpRequest);
|
String currentSessionAlias = sessionManager.getCurrentSessionAlias(httpRequest);
|
||||||
Map<String, String> sessionIds = sessionManager.getSessionIds(httpRequest);
|
Map<String, String> sessionIds = sessionManager.getSessionIds(httpRequest);
|
||||||
@@ -85,7 +85,8 @@ public class UserAccountsFilter implements Filter {
|
|||||||
|
|
||||||
// tag::addAccountUrl[]
|
// tag::addAccountUrl[]
|
||||||
String addAlias = unauthenticatedAlias == null ? // <1>
|
String addAlias = unauthenticatedAlias == null ? // <1>
|
||||||
sessionManager.getNewSessionAlias(httpRequest) : // <2>
|
sessionManager.getNewSessionAlias(httpRequest)
|
||||||
|
: // <2>
|
||||||
unauthenticatedAlias; // <3>
|
unauthenticatedAlias; // <3>
|
||||||
String addAccountUrl = sessionManager.encodeURL(contextPath, addAlias); // <4>
|
String addAccountUrl = sessionManager.encodeURL(contextPath, addAlias); // <4>
|
||||||
// end::addAccountUrl[]
|
// end::addAccountUrl[]
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ import org.springframework.context.annotation.Bean;
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the H2 {@link WebServlet} so we can access our in memory database
|
* Initializes the H2 {@link WebServlet} so we can access our in memory database from the
|
||||||
* from the URL "/h2".
|
* URL "/h2".
|
||||||
*
|
*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -34,8 +34,7 @@ import org.springframework.session.data.redis.config.annotation.web.http.EnableR
|
|||||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||||
// tag::enable-redis-httpsession[]
|
// tag::enable-redis-httpsession[]
|
||||||
@EnableRedisHttpSession // (maxInactiveIntervalInSeconds = 60)
|
@EnableRedisHttpSession // (maxInactiveIntervalInSeconds = 60)
|
||||||
public class WebSecurityConfig
|
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
extends WebSecurityConfigurerAdapter {
|
|
||||||
// end::enable-redis-httpsession[]
|
// end::enable-redis-httpsession[]
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
|
|||||||
@@ -32,8 +32,7 @@ public class WebSocketConfig
|
|||||||
extends AbstractSessionWebSocketMessageBrokerConfigurer<ExpiringSession> { // <1>
|
extends AbstractSessionWebSocketMessageBrokerConfigurer<ExpiringSession> { // <1>
|
||||||
|
|
||||||
protected void configureStompEndpoints(StompEndpointRegistry registry) { // <2>
|
protected void configureStompEndpoints(StompEndpointRegistry registry) { // <2>
|
||||||
registry.addEndpoint("/messages")
|
registry.addEndpoint("/messages").withSockJS();
|
||||||
.withSockJS();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void configureMessageBroker(MessageBrokerRegistry registry) {
|
public void configureMessageBroker(MessageBrokerRegistry registry) {
|
||||||
|
|||||||
@@ -24,8 +24,10 @@ import org.springframework.context.annotation.Bean;
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.messaging.simp.SimpMessageSendingOperations;
|
import org.springframework.messaging.simp.SimpMessageSendingOperations;
|
||||||
import org.springframework.session.ExpiringSession;
|
import org.springframework.session.ExpiringSession;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These handlers are separated from WebSocketConfig because they are specific to this application and do not demonstrate a typical Spring Session setup.
|
* These handlers are separated from WebSocketConfig because they are specific to this
|
||||||
|
* application and do not demonstrate a typical Spring Session setup.
|
||||||
*
|
*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
@@ -33,12 +35,16 @@ import org.springframework.session.ExpiringSession;
|
|||||||
public class WebSocketHandlersConfig<S extends ExpiringSession> {
|
public class WebSocketHandlersConfig<S extends ExpiringSession> {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public WebSocketConnectHandler<S> webSocketConnectHandler(SimpMessageSendingOperations messagingTemplate, ActiveWebSocketUserRepository repository) {
|
public WebSocketConnectHandler<S> webSocketConnectHandler(
|
||||||
|
SimpMessageSendingOperations messagingTemplate,
|
||||||
|
ActiveWebSocketUserRepository repository) {
|
||||||
return new WebSocketConnectHandler<S>(messagingTemplate, repository);
|
return new WebSocketConnectHandler<S>(messagingTemplate, repository);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public WebSocketDisconnectHandler<S> webSocketDisconnectHandler(SimpMessageSendingOperations messagingTemplate, ActiveWebSocketUserRepository repository) {
|
public WebSocketDisconnectHandler<S> webSocketDisconnectHandler(
|
||||||
|
SimpMessageSendingOperations messagingTemplate,
|
||||||
|
ActiveWebSocketUserRepository repository) {
|
||||||
return new WebSocketDisconnectHandler<S>(messagingTemplate, repository);
|
return new WebSocketDisconnectHandler<S>(messagingTemplate, repository);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ import org.springframework.security.config.annotation.web.socket.AbstractSecurit
|
|||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
|
public class WebSocketSecurityConfig
|
||||||
|
extends AbstractSecurityWebSocketMessageBrokerConfigurer {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -56,5 +56,4 @@ public class ActiveWebSocketUser {
|
|||||||
this.connectionTime = connectionTime;
|
this.connectionTime = connectionTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ import java.util.List;
|
|||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
|
||||||
public interface ActiveWebSocketUserRepository extends CrudRepository<ActiveWebSocketUser, String> {
|
public interface ActiveWebSocketUserRepository
|
||||||
|
extends CrudRepository<ActiveWebSocketUser, String> {
|
||||||
|
|
||||||
@Query("select DISTINCT(u.username) from ActiveWebSocketUser u where u.username != ?#{principal?.username}")
|
@Query("select DISTINCT(u.username) from ActiveWebSocketUser u where u.username != ?#{principal?.username}")
|
||||||
List<String> findAllActiveUsers();
|
List<String> findAllActiveUsers();
|
||||||
|
|||||||
@@ -59,6 +59,4 @@ public class InstantMessage {
|
|||||||
this.created = created;
|
this.created = created;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,8 @@ public class MessageController {
|
|||||||
private ActiveWebSocketUserRepository activeUserRepository;
|
private ActiveWebSocketUserRepository activeUserRepository;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public MessageController(ActiveWebSocketUserRepository activeUserRepository, SimpMessageSendingOperations messagingTemplate) {
|
public MessageController(ActiveWebSocketUserRepository activeUserRepository,
|
||||||
|
SimpMessageSendingOperations messagingTemplate) {
|
||||||
this.activeUserRepository = activeUserRepository;
|
this.activeUserRepository = activeUserRepository;
|
||||||
this.messagingTemplate = messagingTemplate;
|
this.messagingTemplate = messagingTemplate;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,16 +27,14 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
|||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Annotate Spring MVC method arguments with this annotation to indicate you
|
* Annotate Spring MVC method arguments with this annotation to indicate you wish to
|
||||||
* wish to specify the argument with the value of the current
|
* specify the argument with the value of the current
|
||||||
* {@link Authentication#getPrincipal()} found on the
|
* {@link Authentication#getPrincipal()} found on the {@link SecurityContextHolder}.
|
||||||
* {@link SecurityContextHolder}.
|
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Creating your own annotation that uses {@link AuthenticationPrincipal} as a
|
* Creating your own annotation that uses {@link AuthenticationPrincipal} as a meta
|
||||||
* meta annotation creates a layer of indirection between your code and Spring
|
* annotation creates a layer of indirection between your code and Spring Security's. For
|
||||||
* Security's. For simplicity, you could instead use the
|
* simplicity, you could instead use the {@link AuthenticationPrincipal} directly.
|
||||||
* {@link AuthenticationPrincipal} directly.
|
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
|
|||||||
@@ -42,8 +42,12 @@ public class UserRepositoryUserDetailsService implements UserDetailsService {
|
|||||||
this.userRepository = userRepository;
|
this.userRepository = userRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/*
|
||||||
* @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see
|
||||||
|
* org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername
|
||||||
|
* (java.lang.String)
|
||||||
*/
|
*/
|
||||||
public UserDetails loadUserByUsername(String username)
|
public UserDetails loadUserByUsername(String username)
|
||||||
throws UsernameNotFoundException {
|
throws UsernameNotFoundException {
|
||||||
|
|||||||
@@ -29,11 +29,13 @@ import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
|
|||||||
import org.springframework.messaging.simp.SimpMessageSendingOperations;
|
import org.springframework.messaging.simp.SimpMessageSendingOperations;
|
||||||
import org.springframework.web.socket.messaging.SessionConnectEvent;
|
import org.springframework.web.socket.messaging.SessionConnectEvent;
|
||||||
|
|
||||||
public class WebSocketConnectHandler<S> implements ApplicationListener<SessionConnectEvent> {
|
public class WebSocketConnectHandler<S>
|
||||||
|
implements ApplicationListener<SessionConnectEvent> {
|
||||||
private ActiveWebSocketUserRepository repository;
|
private ActiveWebSocketUserRepository repository;
|
||||||
private SimpMessageSendingOperations messagingTemplate;
|
private SimpMessageSendingOperations messagingTemplate;
|
||||||
|
|
||||||
public WebSocketConnectHandler(SimpMessageSendingOperations messagingTemplate, ActiveWebSocketUserRepository repository) {
|
public WebSocketConnectHandler(SimpMessageSendingOperations messagingTemplate,
|
||||||
|
ActiveWebSocketUserRepository repository) {
|
||||||
super();
|
super();
|
||||||
this.messagingTemplate = messagingTemplate;
|
this.messagingTemplate = messagingTemplate;
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
@@ -46,7 +48,9 @@ public class WebSocketConnectHandler<S> implements ApplicationListener<SessionCo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String id = SimpMessageHeaderAccessor.getSessionId(headers);
|
String id = SimpMessageHeaderAccessor.getSessionId(headers);
|
||||||
this.repository.save(new ActiveWebSocketUser(id, user.getName(), Calendar.getInstance()));
|
this.repository.save(
|
||||||
this.messagingTemplate.convertAndSend("/topic/friends/signin", Arrays.asList(user.getName()));
|
new ActiveWebSocketUser(id, user.getName(), Calendar.getInstance()));
|
||||||
|
this.messagingTemplate.convertAndSend("/topic/friends/signin",
|
||||||
|
Arrays.asList(user.getName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,11 +25,13 @@ import org.springframework.context.ApplicationListener;
|
|||||||
import org.springframework.messaging.simp.SimpMessageSendingOperations;
|
import org.springframework.messaging.simp.SimpMessageSendingOperations;
|
||||||
import org.springframework.web.socket.messaging.SessionDisconnectEvent;
|
import org.springframework.web.socket.messaging.SessionDisconnectEvent;
|
||||||
|
|
||||||
public class WebSocketDisconnectHandler<S> implements ApplicationListener<SessionDisconnectEvent> {
|
public class WebSocketDisconnectHandler<S>
|
||||||
|
implements ApplicationListener<SessionDisconnectEvent> {
|
||||||
private ActiveWebSocketUserRepository repository;
|
private ActiveWebSocketUserRepository repository;
|
||||||
private SimpMessageSendingOperations messagingTemplate;
|
private SimpMessageSendingOperations messagingTemplate;
|
||||||
|
|
||||||
public WebSocketDisconnectHandler(SimpMessageSendingOperations messagingTemplate, ActiveWebSocketUserRepository repository) {
|
public WebSocketDisconnectHandler(SimpMessageSendingOperations messagingTemplate,
|
||||||
|
ActiveWebSocketUserRepository repository) {
|
||||||
super();
|
super();
|
||||||
this.messagingTemplate = messagingTemplate;
|
this.messagingTemplate = messagingTemplate;
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
@@ -46,7 +48,8 @@ public class WebSocketDisconnectHandler<S> implements ApplicationListener<Sessio
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.repository.delete(id);
|
this.repository.delete(id);
|
||||||
this.messagingTemplate.convertAndSend("/topic/friends/signout", Arrays.asList(user.getUsername()));
|
this.messagingTemplate.convertAndSend("/topic/friends/signout",
|
||||||
|
Arrays.asList(user.getUsername()));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
package org.springframework.session.data;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.core.authority.AuthorityUtils;
|
import org.springframework.security.core.authority.AuthorityUtils;
|
||||||
@@ -10,8 +28,6 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
|||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.test.context.web.WebAppConfiguration;
|
import org.springframework.test.context.web.WebAppConfiguration;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for repositories integration tests
|
* Base class for repositories integration tests
|
||||||
*
|
*
|
||||||
@@ -30,14 +46,18 @@ public abstract class AbstractITests {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
if (registry != null) {
|
if (this.registry != null) {
|
||||||
registry.clear();
|
this.registry.clear();
|
||||||
}
|
}
|
||||||
context = SecurityContextHolder.createEmptyContext();
|
this.context = SecurityContextHolder.createEmptyContext();
|
||||||
context.setAuthentication(new UsernamePasswordAuthenticationToken("username-" + UUID.randomUUID(), "na", AuthorityUtils.createAuthorityList("ROLE_USER")));
|
this.context.setAuthentication(
|
||||||
|
new UsernamePasswordAuthenticationToken("username-" + UUID.randomUUID(),
|
||||||
|
"na", AuthorityUtils.createAuthorityList("ROLE_USER")));
|
||||||
|
|
||||||
changedContext = SecurityContextHolder.createEmptyContext();
|
this.changedContext = SecurityContextHolder.createEmptyContext();
|
||||||
changedContext.setAuthentication(new UsernamePasswordAuthenticationToken("changedContext-" + UUID.randomUUID(), "na", AuthorityUtils.createAuthorityList("ROLE_USER")));
|
this.changedContext.setAuthentication(new UsernamePasswordAuthenticationToken(
|
||||||
|
"changedContext-" + UUID.randomUUID(), "na",
|
||||||
|
AuthorityUtils.createAuthorityList("ROLE_USER")));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,12 +45,14 @@ public class SessionEventRegistry implements ApplicationListener<AbstractSession
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <E extends AbstractSessionEvent> E getEvent(String sessionId) throws InterruptedException {
|
public <E extends AbstractSessionEvent> E getEvent(String sessionId)
|
||||||
|
throws InterruptedException {
|
||||||
return (E) waitForEvent(sessionId);
|
return (E) waitForEvent(sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private <E extends AbstractSessionEvent> E waitForEvent(String sessionId) throws InterruptedException {
|
private <E extends AbstractSessionEvent> E waitForEvent(String sessionId)
|
||||||
|
throws InterruptedException {
|
||||||
Object lock = getLock(sessionId);
|
Object lock = getLock(sessionId);
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
if (!this.events.containsKey(sessionId)) {
|
if (!this.events.containsKey(sessionId)) {
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ import org.springframework.session.events.AbstractSessionEvent;
|
|||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AbstractGemFireIntegrationTests is an abstract base class encapsulating common operations for writing
|
* AbstractGemFireIntegrationTests is an abstract base class encapsulating common
|
||||||
* Spring Session GemFire integration tests.
|
* operations for writing Spring Session GemFire integration tests.
|
||||||
*
|
*
|
||||||
* @author John Blum
|
* @author John Blum
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
@@ -65,22 +65,24 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
public abstract class AbstractGemFireIntegrationTests {
|
public abstract class AbstractGemFireIntegrationTests {
|
||||||
|
|
||||||
protected static final boolean DEFAULT_ENABLE_QUERY_DEBUGGING = false;
|
protected static final boolean DEFAULT_ENABLE_QUERY_DEBUGGING = false;
|
||||||
protected static final boolean GEMFIRE_QUERY_DEBUG = Boolean.getBoolean("spring.session.data.gemfire.query.debug");
|
protected static final boolean GEMFIRE_QUERY_DEBUG = Boolean
|
||||||
|
.getBoolean("spring.session.data.gemfire.query.debug");
|
||||||
|
|
||||||
protected static final int DEFAULT_GEMFIRE_SERVER_PORT = CacheServer.DEFAULT_PORT;
|
protected static final int DEFAULT_GEMFIRE_SERVER_PORT = CacheServer.DEFAULT_PORT;
|
||||||
|
|
||||||
protected static final long DEFAULT_WAIT_DURATION = TimeUnit.SECONDS.toMillis(20);
|
protected static final long DEFAULT_WAIT_DURATION = TimeUnit.SECONDS.toMillis(20);
|
||||||
protected static final long DEFAULT_WAIT_INTERVAL = 500L;
|
protected static final long DEFAULT_WAIT_INTERVAL = 500L;
|
||||||
|
|
||||||
protected static final File WORKING_DIRECTORY = new File(System.getProperty("user.dir"));
|
protected static final File WORKING_DIRECTORY = new File(
|
||||||
|
System.getProperty("user.dir"));
|
||||||
|
|
||||||
protected static final String DEFAULT_PROCESS_CONTROL_FILENAME = "process.ctl";
|
protected static final String DEFAULT_PROCESS_CONTROL_FILENAME = "process.ctl";
|
||||||
|
|
||||||
protected static final String GEMFIRE_LOG_FILE_NAME = System.getProperty(
|
protected static final String GEMFIRE_LOG_FILE_NAME = System
|
||||||
"spring.session.data.gemfire.log-file", "server.log");
|
.getProperty("spring.session.data.gemfire.log-file", "server.log");
|
||||||
|
|
||||||
protected static final String GEMFIRE_LOG_LEVEL = System.getProperty(
|
protected static final String GEMFIRE_LOG_LEVEL = System
|
||||||
"spring.session.data.gemfire.log-level", "warning");
|
.getProperty("spring.session.data.gemfire.log-level", "warning");
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
protected Cache gemfireCache;
|
protected Cache gemfireCache;
|
||||||
@@ -90,15 +92,17 @@ public abstract class AbstractGemFireIntegrationTests {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
System.setProperty("gemfire.Query.VERBOSE", String.valueOf(isQueryDebuggingEnabled()));
|
System.setProperty("gemfire.Query.VERBOSE",
|
||||||
|
String.valueOf(isQueryDebuggingEnabled()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
protected static File createDirectory(String pathname) {
|
protected static File createDirectory(String pathname) {
|
||||||
File directory = new File(WORKING_DIRECTORY, pathname);
|
File directory = new File(WORKING_DIRECTORY, pathname);
|
||||||
|
|
||||||
assertThat(directory.isDirectory() || directory.mkdirs()).as(
|
assertThat(directory.isDirectory() || directory.mkdirs())
|
||||||
String.format("Failed to create directory (%1$s)", directory)).isTrue();
|
.as(String.format("Failed to create directory (%1$s)", directory))
|
||||||
|
.isTrue();
|
||||||
|
|
||||||
directory.deleteOnExit();
|
directory.deleteOnExit();
|
||||||
|
|
||||||
@@ -106,7 +110,8 @@ public abstract class AbstractGemFireIntegrationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
protected static List<String> createJavaProcessCommandLine(Class<?> type, String... args) {
|
protected static List<String> createJavaProcessCommandLine(Class<?> type,
|
||||||
|
String... args) {
|
||||||
List<String> commandLine = new ArrayList<String>();
|
List<String> commandLine = new ArrayList<String>();
|
||||||
|
|
||||||
String javaHome = System.getProperty("java.home");
|
String javaHome = System.getProperty("java.home");
|
||||||
@@ -117,7 +122,8 @@ public abstract class AbstractGemFireIntegrationTests {
|
|||||||
commandLine.add("-ea");
|
commandLine.add("-ea");
|
||||||
commandLine.add(String.format("-Dgemfire.log-file=%1$s", GEMFIRE_LOG_FILE_NAME));
|
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.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.addAll(extractJvmArguments(args));
|
||||||
commandLine.add("-classpath");
|
commandLine.add("-classpath");
|
||||||
commandLine.add(System.getProperty("java.class.path"));
|
commandLine.add(System.getProperty("java.class.path"));
|
||||||
@@ -156,11 +162,10 @@ public abstract class AbstractGemFireIntegrationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
protected static Process run(Class<?> type, File directory, String... args) throws IOException {
|
protected static Process run(Class<?> type, File directory, String... args)
|
||||||
return new ProcessBuilder()
|
throws IOException {
|
||||||
.command(createJavaProcessCommandLine(type, args))
|
return new ProcessBuilder().command(createJavaProcessCommandLine(type, args))
|
||||||
.directory(directory)
|
.directory(directory).start();
|
||||||
.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
@@ -169,8 +174,10 @@ public abstract class AbstractGemFireIntegrationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
protected static boolean waitForCacheServerToStart(CacheServer cacheServer, long duration) {
|
protected static boolean waitForCacheServerToStart(CacheServer cacheServer,
|
||||||
return waitForCacheServerToStart(cacheServer.getBindAddress(), cacheServer.getPort(), duration);
|
long duration) {
|
||||||
|
return waitForCacheServerToStart(cacheServer.getBindAddress(),
|
||||||
|
cacheServer.getPort(), duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
@@ -179,7 +186,8 @@ public abstract class AbstractGemFireIntegrationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (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() {
|
return waitOnCondition(new Condition() {
|
||||||
AtomicBoolean connected = new AtomicBoolean(false);
|
AtomicBoolean connected = new AtomicBoolean(false);
|
||||||
|
|
||||||
@@ -203,7 +211,8 @@ public abstract class AbstractGemFireIntegrationTests {
|
|||||||
}, duration);
|
}, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE this method would not be necessary except Spring Sessions' build does not fork the test JVM
|
// NOTE this method would not be necessary except Spring Sessions' build does not fork
|
||||||
|
// the test JVM
|
||||||
// for every test class.
|
// for every test class.
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
protected static boolean waitForClientCacheToClose() {
|
protected static boolean waitForClientCacheToClose() {
|
||||||
@@ -238,7 +247,8 @@ public abstract class AbstractGemFireIntegrationTests {
|
|||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
@SuppressWarnings("all")
|
@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);
|
final File processControl = new File(directory, DEFAULT_PROCESS_CONTROL_FILENAME);
|
||||||
|
|
||||||
waitOnCondition(new Condition() {
|
waitOnCondition(new Condition() {
|
||||||
@@ -256,7 +266,8 @@ public abstract class AbstractGemFireIntegrationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (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);
|
final long timeout = (System.currentTimeMillis() + duration);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -311,24 +322,30 @@ public abstract class AbstractGemFireIntegrationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (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).isNotNull();
|
||||||
assertThat(actualRegion.getName()).isEqualTo(expectedName);
|
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()).isNotNull();
|
||||||
assertThat(actualRegion.getAttributes().getDataPolicy()).isEqualTo(expectedDataPolicy);
|
assertThat(actualRegion.getAttributes().getDataPolicy())
|
||||||
|
.isEqualTo(expectedDataPolicy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (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).isNotNull();
|
||||||
assertThat(index.getIndexedExpression()).isEqualTo(expectedExpression);
|
assertThat(index.getIndexedExpression()).isEqualTo(expectedExpression);
|
||||||
assertThat(index.getFromClause()).isEqualTo(expectedFromClause);
|
assertThat(index.getFromClause()).isEqualTo(expectedFromClause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
protected void assertEntryIdleTimeout(Region<?, ?> region, ExpirationAction expectedAction, int expectedTimeout) {
|
protected void assertEntryIdleTimeout(Region<?, ?> region,
|
||||||
assertEntryIdleTimeout(region.getAttributes().getEntryIdleTimeout(), expectedAction, expectedTimeout);
|
ExpirationAction expectedAction, int expectedTimeout) {
|
||||||
|
assertEntryIdleTimeout(region.getAttributes().getEntryIdleTimeout(),
|
||||||
|
expectedAction, expectedTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
@@ -403,13 +420,14 @@ public abstract class AbstractGemFireIntegrationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The SessionEventListener class is a Spring {@link ApplicationListener} listening for Spring HTTP Session
|
* The SessionEventListener class is a Spring {@link ApplicationListener} listening
|
||||||
* application events.
|
* for Spring HTTP Session application events.
|
||||||
*
|
*
|
||||||
* @see org.springframework.context.ApplicationListener
|
* @see org.springframework.context.ApplicationListener
|
||||||
* @see org.springframework.session.events.AbstractSessionEvent
|
* @see org.springframework.session.events.AbstractSessionEvent
|
||||||
*/
|
*/
|
||||||
public static class SessionEventListener implements ApplicationListener<AbstractSessionEvent> {
|
public static class SessionEventListener
|
||||||
|
implements ApplicationListener<AbstractSessionEvent> {
|
||||||
|
|
||||||
private volatile AbstractSessionEvent sessionEvent;
|
private volatile AbstractSessionEvent sessionEvent;
|
||||||
|
|
||||||
@@ -439,7 +457,8 @@ public abstract class AbstractGemFireIntegrationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Condition interface defines a logical condition that must be satisfied before it is safe to proceed.
|
* The Condition interface defines a logical condition that must be satisfied before
|
||||||
|
* it is safe to proceed.
|
||||||
*/
|
*/
|
||||||
protected interface Condition {
|
protected interface Condition {
|
||||||
boolean evaluate();
|
boolean evaluate();
|
||||||
|
|||||||
@@ -69,16 +69,19 @@ import org.springframework.util.SocketUtils;
|
|||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The ClientServerGemFireOperationsSessionRepositoryIntegrationTests class is a test suite of test cases testing
|
* The ClientServerGemFireOperationsSessionRepositoryIntegrationTests class is a test
|
||||||
* the functionality of GemFire-backed Spring Sessions using a GemFire client-server topology.
|
* suite of test cases testing the functionality of GemFire-backed Spring Sessions using a
|
||||||
|
* GemFire client-server topology.
|
||||||
*
|
*
|
||||||
* @author John Blum
|
* @author John Blum
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
* @see org.junit.Test
|
* @see org.junit.Test
|
||||||
* @see org.junit.runner.RunWith
|
* @see org.junit.runner.RunWith
|
||||||
* @see org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests
|
* @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.
|
||||||
* @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration
|
* EnableGemFireHttpSession
|
||||||
|
* @see org.springframework.session.data.gemfire.config.annotation.web.http.
|
||||||
|
* GemFireHttpSessionConfiguration
|
||||||
* @see org.springframework.test.annotation.DirtiesContext
|
* @see org.springframework.test.annotation.DirtiesContext
|
||||||
* @see org.springframework.test.context.ContextConfiguration
|
* @see org.springframework.test.context.ContextConfiguration
|
||||||
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
|
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
|
||||||
@@ -89,15 +92,16 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
* @see com.gemstone.gemfire.cache.server.CacheServer
|
* @see com.gemstone.gemfire.cache.server.CacheServer
|
||||||
*/
|
*/
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@ContextConfiguration(classes =
|
@ContextConfiguration(classes = ClientServerGemFireOperationsSessionRepositoryIntegrationTests.SpringSessionGemFireClientConfiguration.class)
|
||||||
ClientServerGemFireOperationsSessionRepositoryIntegrationTests.SpringSessionGemFireClientConfiguration.class)
|
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
@WebAppConfiguration
|
@WebAppConfiguration
|
||||||
public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests extends AbstractGemFireIntegrationTests {
|
public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
|
||||||
|
extends AbstractGemFireIntegrationTests {
|
||||||
|
|
||||||
private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 1;
|
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;
|
private static File processWorkingDirectory;
|
||||||
|
|
||||||
@@ -114,21 +118,25 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
|
|||||||
|
|
||||||
final int port = SocketUtils.findAvailableTcpPort();
|
final int port = SocketUtils.findAvailableTcpPort();
|
||||||
|
|
||||||
System.err.printf("Starting GemFire Server running on [%1$s] listening on port [%2$d]%n",
|
System.err.printf(
|
||||||
|
"Starting GemFire Server running on [%1$s] listening on port [%2$d]%n",
|
||||||
InetAddress.getLocalHost().getHostName(), port);
|
InetAddress.getLocalHost().getHostName(), port);
|
||||||
|
|
||||||
System.setProperty("spring.session.data.gemfire.port", String.valueOf(port));
|
System.setProperty("spring.session.data.gemfire.port", String.valueOf(port));
|
||||||
|
|
||||||
String processWorkingDirectoryPathname = String.format("gemfire-client-server-tests-%1$s",
|
String processWorkingDirectoryPathname = String
|
||||||
TIMESTAMP.format(new Date()));
|
.format("gemfire-client-server-tests-%1$s", TIMESTAMP.format(new Date()));
|
||||||
|
|
||||||
processWorkingDirectory = createDirectory(processWorkingDirectoryPathname);
|
processWorkingDirectory = createDirectory(processWorkingDirectoryPathname);
|
||||||
gemfireServer = run(SpringSessionGemFireServerConfiguration.class, processWorkingDirectory,
|
gemfireServer = run(SpringSessionGemFireServerConfiguration.class,
|
||||||
|
processWorkingDirectory,
|
||||||
String.format("-Dspring.session.data.gemfire.port=%1$d", port));
|
String.format("-Dspring.session.data.gemfire.port=%1$d", port));
|
||||||
|
|
||||||
assertThat(waitForCacheServerToStart(SpringSessionGemFireServerConfiguration.SERVER_HOSTNAME, port)).isTrue();
|
assertThat(waitForCacheServerToStart(
|
||||||
|
SpringSessionGemFireServerConfiguration.SERVER_HOSTNAME, port)).isTrue();
|
||||||
|
|
||||||
System.err.printf("GemFire Server [startup time = %1$d ms]%n", System.currentTimeMillis() - t0);
|
System.err.printf("GemFire Server [startup time = %1$d ms]%n",
|
||||||
|
System.currentTimeMillis() - t0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
@@ -139,7 +147,8 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
|
|||||||
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);
|
FileSystemUtils.deleteRecursively(processWorkingDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,16 +159,17 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
|
|||||||
public void setup() {
|
public void setup() {
|
||||||
assertThat(GemFireUtils.isClient(gemfireCache)).isTrue();
|
assertThat(GemFireUtils.isClient(gemfireCache)).isTrue();
|
||||||
|
|
||||||
Region<Object, ExpiringSession> springSessionGemFireRegion = gemfireCache.getRegion(
|
Region<Object, ExpiringSession> springSessionGemFireRegion = gemfireCache
|
||||||
SPRING_SESSION_GEMFIRE_REGION_NAME);
|
.getRegion(SPRING_SESSION_GEMFIRE_REGION_NAME);
|
||||||
|
|
||||||
assertThat(springSessionGemFireRegion).isNotNull();
|
assertThat(springSessionGemFireRegion).isNotNull();
|
||||||
|
|
||||||
RegionAttributes<Object, ExpiringSession> springSessionGemFireRegionAttributes =
|
RegionAttributes<Object, ExpiringSession> springSessionGemFireRegionAttributes = springSessionGemFireRegion
|
||||||
springSessionGemFireRegion.getAttributes();
|
.getAttributes();
|
||||||
|
|
||||||
assertThat(springSessionGemFireRegionAttributes).isNotNull();
|
assertThat(springSessionGemFireRegionAttributes).isNotNull();
|
||||||
assertThat(springSessionGemFireRegionAttributes.getDataPolicy()).isEqualTo(DataPolicy.EMPTY);
|
assertThat(springSessionGemFireRegionAttributes.getDataPolicy())
|
||||||
|
.isEqualTo(DataPolicy.EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
@@ -173,7 +183,8 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
|
|||||||
|
|
||||||
ExpiringSession expectedSession = save(createSession());
|
ExpiringSession expectedSession = save(createSession());
|
||||||
|
|
||||||
AbstractSessionEvent sessionEvent = this.sessionEventListener.waitForSessionEvent(500);
|
AbstractSessionEvent sessionEvent = this.sessionEventListener
|
||||||
|
.waitForSessionEvent(500);
|
||||||
|
|
||||||
assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class);
|
assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class);
|
||||||
|
|
||||||
@@ -181,9 +192,12 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
|
|||||||
|
|
||||||
assertThat(createdSession).isEqualTo(expectedSession);
|
assertThat(createdSession).isEqualTo(expectedSession);
|
||||||
assertThat(createdSession.getId()).isNotNull();
|
assertThat(createdSession.getId()).isNotNull();
|
||||||
assertThat(createdSession.getCreationTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime);
|
assertThat(createdSession.getCreationTime())
|
||||||
assertThat(createdSession.getLastAccessedTime()).isEqualTo(createdSession.getCreationTime());
|
.isGreaterThanOrEqualTo(beforeOrAtCreationTime);
|
||||||
assertThat(createdSession.getMaxInactiveIntervalInSeconds()).isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
assertThat(createdSession.getLastAccessedTime())
|
||||||
|
.isEqualTo(createdSession.getCreationTime());
|
||||||
|
assertThat(createdSession.getMaxInactiveIntervalInSeconds())
|
||||||
|
.isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
||||||
|
|
||||||
this.gemfireSessionRepository.delete(expectedSession.getId());
|
this.gemfireSessionRepository.delete(expectedSession.getId());
|
||||||
}
|
}
|
||||||
@@ -192,28 +206,32 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
|
|||||||
public void getExistingNonExpiredSessionBeforeAndAfterExpiration() {
|
public void getExistingNonExpiredSessionBeforeAndAfterExpiration() {
|
||||||
ExpiringSession expectedSession = save(touch(createSession()));
|
ExpiringSession expectedSession = save(touch(createSession()));
|
||||||
|
|
||||||
AbstractSessionEvent sessionEvent = this.sessionEventListener.waitForSessionEvent(500);
|
AbstractSessionEvent sessionEvent = this.sessionEventListener
|
||||||
|
.waitForSessionEvent(500);
|
||||||
|
|
||||||
assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class);
|
assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class);
|
||||||
assertThat(sessionEvent.<ExpiringSession>getSession()).isEqualTo(expectedSession);
|
assertThat(sessionEvent.<ExpiringSession>getSession()).isEqualTo(expectedSession);
|
||||||
assertThat(this.sessionEventListener.getSessionEvent()).isNull();
|
assertThat(this.sessionEventListener.getSessionEvent()).isNull();
|
||||||
|
|
||||||
ExpiringSession savedSession = this.gemfireSessionRepository.getSession(expectedSession.getId());
|
ExpiringSession savedSession = this.gemfireSessionRepository
|
||||||
|
.getSession(expectedSession.getId());
|
||||||
|
|
||||||
assertThat(savedSession).isEqualTo(expectedSession);
|
assertThat(savedSession).isEqualTo(expectedSession);
|
||||||
|
|
||||||
// NOTE for some reason or another, performing a GemFire (Client)Cache Region.get(key)
|
// NOTE for some reason or another, performing a GemFire (Client)Cache
|
||||||
|
// Region.get(key)
|
||||||
// causes a Region CREATE event... o.O
|
// causes a Region CREATE event... o.O
|
||||||
// calling sessionEventListener.getSessionEvent() here to clear the event
|
// calling sessionEventListener.getSessionEvent() here to clear the event
|
||||||
this.sessionEventListener.getSessionEvent();
|
this.sessionEventListener.getSessionEvent();
|
||||||
|
|
||||||
sessionEvent = this.sessionEventListener.waitForSessionEvent(TimeUnit.SECONDS.toMillis(
|
sessionEvent = this.sessionEventListener.waitForSessionEvent(
|
||||||
MAX_INACTIVE_INTERVAL_IN_SECONDS + 1));
|
TimeUnit.SECONDS.toMillis(MAX_INACTIVE_INTERVAL_IN_SECONDS + 1));
|
||||||
|
|
||||||
assertThat(sessionEvent).isInstanceOf(SessionExpiredEvent.class);
|
assertThat(sessionEvent).isInstanceOf(SessionExpiredEvent.class);
|
||||||
assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSession.getId());
|
assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSession.getId());
|
||||||
|
|
||||||
ExpiringSession expiredSession = this.gemfireSessionRepository.getSession(expectedSession.getId());
|
ExpiringSession expiredSession = this.gemfireSessionRepository
|
||||||
|
.getSession(expectedSession.getId());
|
||||||
|
|
||||||
assertThat(expiredSession).isNull();
|
assertThat(expiredSession).isNull();
|
||||||
}
|
}
|
||||||
@@ -222,7 +240,8 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
|
|||||||
public void deleteExistingNonExpiredSessionFiresSessionDeletedEventAndReturnsNullOnGet() {
|
public void deleteExistingNonExpiredSessionFiresSessionDeletedEventAndReturnsNullOnGet() {
|
||||||
ExpiringSession expectedSession = save(touch(createSession()));
|
ExpiringSession expectedSession = save(touch(createSession()));
|
||||||
|
|
||||||
AbstractSessionEvent sessionEvent = this.sessionEventListener.waitForSessionEvent(500);
|
AbstractSessionEvent sessionEvent = this.sessionEventListener
|
||||||
|
.waitForSessionEvent(500);
|
||||||
|
|
||||||
assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class);
|
assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class);
|
||||||
assertThat(sessionEvent.<ExpiringSession>getSession()).isEqualTo(expectedSession);
|
assertThat(sessionEvent.<ExpiringSession>getSession()).isEqualTo(expectedSession);
|
||||||
@@ -234,13 +253,13 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
|
|||||||
assertThat(sessionEvent).isInstanceOf(SessionDeletedEvent.class);
|
assertThat(sessionEvent).isInstanceOf(SessionDeletedEvent.class);
|
||||||
assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSession.getId());
|
assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSession.getId());
|
||||||
|
|
||||||
ExpiringSession deletedSession = this.gemfireSessionRepository.getSession(expectedSession.getId());
|
ExpiringSession deletedSession = this.gemfireSessionRepository
|
||||||
|
.getSession(expectedSession.getId());
|
||||||
|
|
||||||
assertThat(deletedSession).isNull();
|
assertThat(deletedSession).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME,
|
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME, maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
|
||||||
maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
|
|
||||||
static class SpringSessionGemFireClientConfiguration {
|
static class SpringSessionGemFireClientConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@@ -251,13 +270,16 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
|
|||||||
@Bean
|
@Bean
|
||||||
Properties gemfireProperties() {
|
Properties gemfireProperties() {
|
||||||
Properties gemfireProperties = new Properties();
|
Properties gemfireProperties = new Properties();
|
||||||
gemfireProperties.setProperty("name", ClientServerGemFireOperationsSessionRepositoryIntegrationTests.class.getName());
|
gemfireProperties.setProperty("name",
|
||||||
|
ClientServerGemFireOperationsSessionRepositoryIntegrationTests.class
|
||||||
|
.getName());
|
||||||
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
|
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
|
||||||
return gemfireProperties;
|
return gemfireProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean(name = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME)
|
@Bean(name = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME)
|
||||||
PoolFactoryBean gemfirePool(@Value("${spring.session.data.gemfire.port:" + DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) {
|
PoolFactoryBean gemfirePool(@Value("${spring.session.data.gemfire.port:"
|
||||||
|
+ DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) {
|
||||||
PoolFactoryBean poolFactory = new PoolFactoryBean() {
|
PoolFactoryBean poolFactory = new PoolFactoryBean() {
|
||||||
@Override
|
@Override
|
||||||
protected Properties resolveGemfireProperties() {
|
protected Properties resolveGemfireProperties() {
|
||||||
@@ -268,15 +290,18 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
|
|||||||
poolFactory.setName(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME);
|
poolFactory.setName(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME);
|
||||||
poolFactory.setFreeConnectionTimeout(5000); // 5 seconds
|
poolFactory.setFreeConnectionTimeout(5000); // 5 seconds
|
||||||
poolFactory.setKeepAlive(false);
|
poolFactory.setKeepAlive(false);
|
||||||
poolFactory.setMaxConnections(SpringSessionGemFireServerConfiguration.MAX_CONNECTIONS);
|
poolFactory.setMaxConnections(
|
||||||
|
SpringSessionGemFireServerConfiguration.MAX_CONNECTIONS);
|
||||||
poolFactory.setPingInterval(TimeUnit.SECONDS.toMillis(5));
|
poolFactory.setPingInterval(TimeUnit.SECONDS.toMillis(5));
|
||||||
poolFactory.setReadTimeout(2000); // 2 seconds
|
poolFactory.setReadTimeout(2000); // 2 seconds
|
||||||
poolFactory.setRetryAttempts(2);
|
poolFactory.setRetryAttempts(2);
|
||||||
poolFactory.setSubscriptionEnabled(true);
|
poolFactory.setSubscriptionEnabled(true);
|
||||||
poolFactory.setThreadLocalConnections(false);
|
poolFactory.setThreadLocalConnections(false);
|
||||||
|
|
||||||
poolFactory.setServerEndpoints(Collections.singletonList(new ConnectionEndpoint(
|
poolFactory
|
||||||
SpringSessionGemFireServerConfiguration.SERVER_HOSTNAME, port)));
|
.setServerEndpoints(Collections.singletonList(new ConnectionEndpoint(
|
||||||
|
SpringSessionGemFireServerConfiguration.SERVER_HOSTNAME,
|
||||||
|
port)));
|
||||||
|
|
||||||
return poolFactory;
|
return poolFactory;
|
||||||
}
|
}
|
||||||
@@ -315,8 +340,7 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME,
|
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME, maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
|
||||||
maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
|
|
||||||
static class SpringSessionGemFireServerConfiguration {
|
static class SpringSessionGemFireServerConfiguration {
|
||||||
|
|
||||||
static final int MAX_CONNECTIONS = 50;
|
static final int MAX_CONNECTIONS = 50;
|
||||||
@@ -331,7 +355,8 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
|
|||||||
Properties gemfireProperties() {
|
Properties gemfireProperties() {
|
||||||
Properties gemfireProperties = new Properties();
|
Properties gemfireProperties = new Properties();
|
||||||
|
|
||||||
gemfireProperties.setProperty("name", SpringSessionGemFireServerConfiguration.class.getName());
|
gemfireProperties.setProperty("name",
|
||||||
|
SpringSessionGemFireServerConfiguration.class.getName());
|
||||||
gemfireProperties.setProperty("mcast-port", "0");
|
gemfireProperties.setProperty("mcast-port", "0");
|
||||||
gemfireProperties.setProperty("log-file", "server.log");
|
gemfireProperties.setProperty("log-file", "server.log");
|
||||||
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
|
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
|
||||||
@@ -351,7 +376,8 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
CacheServerFactoryBean gemfireCacheServer(Cache gemfireCache,
|
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();
|
CacheServerFactoryBean cacheServerFactory = new CacheServerFactoryBean();
|
||||||
|
|
||||||
@@ -366,7 +392,8 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
|
|||||||
|
|
||||||
@SuppressWarnings("resource")
|
@SuppressWarnings("resource")
|
||||||
public static void main(final String[] args) throws IOException {
|
public static void main(final String[] args) throws IOException {
|
||||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringSessionGemFireServerConfiguration.class);
|
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||||
|
SpringSessionGemFireServerConfiguration.class);
|
||||||
context.registerShutdownHook();
|
context.registerShutdownHook();
|
||||||
writeProcessControlFile(WORKING_DIRECTORY);
|
writeProcessControlFile(WORKING_DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,8 +55,9 @@ import org.springframework.util.ObjectUtils;
|
|||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The GemFireOperationsSessionRepositoryIntegrationTests class is a test suite of test cases testing
|
* The GemFireOperationsSessionRepositoryIntegrationTests class is a test suite of test
|
||||||
* the findByPrincipalName query method on the GemFireOpeationsSessionRepository class.
|
* cases testing the findByPrincipalName query method on the
|
||||||
|
* GemFireOpeationsSessionRepository class.
|
||||||
*
|
*
|
||||||
* @author John Blum
|
* @author John Blum
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
@@ -75,7 +76,8 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
@ContextConfiguration
|
@ContextConfiguration
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
@WebAppConfiguration
|
@WebAppConfiguration
|
||||||
public class GemFireOperationsSessionRepositoryIntegrationTests extends AbstractGemFireIntegrationTests {
|
public class GemFireOperationsSessionRepositoryIntegrationTests
|
||||||
|
extends AbstractGemFireIntegrationTests {
|
||||||
|
|
||||||
private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 300;
|
private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 300;
|
||||||
|
|
||||||
@@ -90,48 +92,63 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
|
|||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
this.context = SecurityContextHolder.createEmptyContext();
|
this.context = SecurityContextHolder.createEmptyContext();
|
||||||
this.context.setAuthentication(new UsernamePasswordAuthenticationToken("username-" + UUID.randomUUID(), "na", AuthorityUtils.createAuthorityList("ROLE_USER")));
|
this.context.setAuthentication(
|
||||||
|
new UsernamePasswordAuthenticationToken("username-" + UUID.randomUUID(),
|
||||||
|
"na", AuthorityUtils.createAuthorityList("ROLE_USER")));
|
||||||
|
|
||||||
this.changedContext = SecurityContextHolder.createEmptyContext();
|
this.changedContext = SecurityContextHolder.createEmptyContext();
|
||||||
this.changedContext.setAuthentication(new UsernamePasswordAuthenticationToken("changedContext-" + UUID.randomUUID(), "na", AuthorityUtils.createAuthorityList("ROLE_USER")));
|
this.changedContext.setAuthentication(new UsernamePasswordAuthenticationToken(
|
||||||
|
"changedContext-" + UUID.randomUUID(), "na",
|
||||||
|
AuthorityUtils.createAuthorityList("ROLE_USER")));
|
||||||
|
|
||||||
assertThat(this.gemfireCache).isNotNull();
|
assertThat(this.gemfireCache).isNotNull();
|
||||||
assertThat(this.gemfireSessionRepository).isNotNull();
|
assertThat(this.gemfireSessionRepository).isNotNull();
|
||||||
assertThat(this.gemfireSessionRepository.getMaxInactiveIntervalInSeconds()).isEqualTo(
|
assertThat(this.gemfireSessionRepository.getMaxInactiveIntervalInSeconds())
|
||||||
|
.isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
||||||
|
|
||||||
|
Region<Object, ExpiringSession> sessionRegion = this.gemfireCache
|
||||||
|
.getRegion(SPRING_SESSION_GEMFIRE_REGION_NAME);
|
||||||
|
|
||||||
|
assertRegion(sessionRegion, SPRING_SESSION_GEMFIRE_REGION_NAME,
|
||||||
|
DataPolicy.PARTITION);
|
||||||
|
assertEntryIdleTimeout(sessionRegion, ExpirationAction.INVALIDATE,
|
||||||
MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
||||||
|
|
||||||
Region<Object, ExpiringSession> sessionRegion = this.gemfireCache.getRegion(SPRING_SESSION_GEMFIRE_REGION_NAME);
|
|
||||||
|
|
||||||
assertRegion(sessionRegion, SPRING_SESSION_GEMFIRE_REGION_NAME, DataPolicy.PARTITION);
|
|
||||||
assertEntryIdleTimeout(sessionRegion, ExpirationAction.INVALIDATE, MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Map<String, ExpiringSession> doFindByIndexNameAndIndexValue(String indexName, String indexValue) {
|
protected Map<String, ExpiringSession> doFindByIndexNameAndIndexValue(
|
||||||
return this.gemfireSessionRepository.findByIndexNameAndIndexValue(indexName, indexValue);
|
String indexName, String indexValue) {
|
||||||
|
return this.gemfireSessionRepository.findByIndexNameAndIndexValue(indexName,
|
||||||
|
indexValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Map<String, ExpiringSession> doFindByPrincipalName(String principalName) {
|
protected Map<String, ExpiringSession> doFindByPrincipalName(String principalName) {
|
||||||
return doFindByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, principalName);
|
return doFindByIndexNameAndIndexValue(
|
||||||
|
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
|
||||||
|
principalName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({ "unchecked" })
|
@SuppressWarnings({ "unchecked" })
|
||||||
protected Map<String, ExpiringSession> doFindByPrincipalName(String regionName, String principalName) {
|
protected Map<String, ExpiringSession> doFindByPrincipalName(String regionName,
|
||||||
|
String principalName) {
|
||||||
try {
|
try {
|
||||||
Region<String, ExpiringSession> region = this.gemfireCache.getRegion(regionName);
|
Region<String, ExpiringSession> region = this.gemfireCache
|
||||||
|
.getRegion(regionName);
|
||||||
|
|
||||||
assertThat(region).isNotNull();
|
assertThat(region).isNotNull();
|
||||||
|
|
||||||
QueryService queryService = region.getRegionService().getQueryService();
|
QueryService queryService = region.getRegionService().getQueryService();
|
||||||
|
|
||||||
String queryString = String.format(GemFireOperationsSessionRepository.FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY,
|
String queryString = String.format(
|
||||||
|
GemFireOperationsSessionRepository.FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY,
|
||||||
region.getFullPath());
|
region.getFullPath());
|
||||||
|
|
||||||
Query query = queryService.newQuery(queryString);
|
Query query = queryService.newQuery(queryString);
|
||||||
|
|
||||||
SelectResults<ExpiringSession> results = (SelectResults<ExpiringSession>) query.execute(
|
SelectResults<ExpiringSession> results = (SelectResults<ExpiringSession>) query
|
||||||
new Object[] { principalName });
|
.execute(new Object[] { principalName });
|
||||||
|
|
||||||
Map<String, ExpiringSession> sessions = new HashMap<String, ExpiringSession>(results.size());
|
Map<String, ExpiringSession> sessions = new HashMap<String, ExpiringSession>(
|
||||||
|
results.size());
|
||||||
|
|
||||||
for (ExpiringSession session : results.asList()) {
|
for (ExpiringSession session : results.asList()) {
|
||||||
sessions.put(session.getId(), session);
|
sessions.put(session.getId(), session);
|
||||||
@@ -149,17 +166,22 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ExpiringSession setAttribute(ExpiringSession session, String attributeName, Object attributeValue) {
|
protected ExpiringSession setAttribute(ExpiringSession session, String attributeName,
|
||||||
|
Object attributeValue) {
|
||||||
session.setAttribute(attributeName, attributeValue);
|
session.setAttribute(attributeName, attributeValue);
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findSessionsByIndexedSessionAttributeNameValues() {
|
public void findSessionsByIndexedSessionAttributeNameValues() {
|
||||||
ExpiringSession johnBlumSession = save(touch(setAttribute(createSession("johnBlum"), "vip", "yes")));
|
ExpiringSession johnBlumSession = save(
|
||||||
ExpiringSession robWinchSession = save(touch(setAttribute(createSession("robWinch"), "vip", "yes")));
|
touch(setAttribute(createSession("johnBlum"), "vip", "yes")));
|
||||||
ExpiringSession jonDoeSession = save(touch(setAttribute(createSession("jonDoe"), "vip", "no")));
|
ExpiringSession robWinchSession = save(
|
||||||
ExpiringSession pieDoeSession = save(touch(setAttribute(createSession("pieDoe"), "viper", "true")));
|
touch(setAttribute(createSession("robWinch"), "vip", "yes")));
|
||||||
|
ExpiringSession jonDoeSession = save(
|
||||||
|
touch(setAttribute(createSession("jonDoe"), "vip", "no")));
|
||||||
|
ExpiringSession pieDoeSession = save(
|
||||||
|
touch(setAttribute(createSession("pieDoe"), "viper", "true")));
|
||||||
ExpiringSession sourDoeSession = save(touch(createSession("sourDoe")));
|
ExpiringSession sourDoeSession = save(touch(createSession("sourDoe")));
|
||||||
|
|
||||||
assertThat(get(johnBlumSession.getId())).isEqualTo(johnBlumSession);
|
assertThat(get(johnBlumSession.getId())).isEqualTo(johnBlumSession);
|
||||||
@@ -173,7 +195,8 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
|
|||||||
assertThat(get(sourDoeSession.getId())).isEqualTo(sourDoeSession);
|
assertThat(get(sourDoeSession.getId())).isEqualTo(sourDoeSession);
|
||||||
assertThat(sourDoeSession.getAttributeNames().contains("vip")).isFalse();
|
assertThat(sourDoeSession.getAttributeNames().contains("vip")).isFalse();
|
||||||
|
|
||||||
Map<String, ExpiringSession> vipSessions = doFindByIndexNameAndIndexValue("vip", "yes");
|
Map<String, ExpiringSession> vipSessions = doFindByIndexNameAndIndexValue("vip",
|
||||||
|
"yes");
|
||||||
|
|
||||||
assertThat(vipSessions).isNotNull();
|
assertThat(vipSessions).isNotNull();
|
||||||
assertThat(vipSessions.size()).isEqualTo(2);
|
assertThat(vipSessions.size()).isEqualTo(2);
|
||||||
@@ -183,7 +206,8 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
|
|||||||
assertThat(vipSessions.containsKey(pieDoeSession.getId()));
|
assertThat(vipSessions.containsKey(pieDoeSession.getId()));
|
||||||
assertThat(vipSessions.containsKey(sourDoeSession.getId()));
|
assertThat(vipSessions.containsKey(sourDoeSession.getId()));
|
||||||
|
|
||||||
Map<String, ExpiringSession> nonVipSessions = doFindByIndexNameAndIndexValue("vip", "no");
|
Map<String, ExpiringSession> nonVipSessions = doFindByIndexNameAndIndexValue(
|
||||||
|
"vip", "no");
|
||||||
|
|
||||||
assertThat(nonVipSessions).isNotNull();
|
assertThat(nonVipSessions).isNotNull();
|
||||||
assertThat(nonVipSessions.size()).isEqualTo(1);
|
assertThat(nonVipSessions.size()).isEqualTo(1);
|
||||||
@@ -193,7 +217,8 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
|
|||||||
assertThat(nonVipSessions.containsKey(pieDoeSession.getId()));
|
assertThat(nonVipSessions.containsKey(pieDoeSession.getId()));
|
||||||
assertThat(nonVipSessions.containsKey(sourDoeSession.getId()));
|
assertThat(nonVipSessions.containsKey(sourDoeSession.getId()));
|
||||||
|
|
||||||
Map<String, ExpiringSession> noSessions = doFindByIndexNameAndIndexValue("nonExistingAttribute", "test");
|
Map<String, ExpiringSession> noSessions = doFindByIndexNameAndIndexValue(
|
||||||
|
"nonExistingAttribute", "test");
|
||||||
|
|
||||||
assertThat(noSessions).isNotNull();
|
assertThat(noSessions).isNotNull();
|
||||||
assertThat(noSessions.isEmpty()).isTrue();
|
assertThat(noSessions.isEmpty()).isTrue();
|
||||||
@@ -241,7 +266,8 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
|
|||||||
|
|
||||||
save(toSave);
|
save(toSave);
|
||||||
|
|
||||||
Map<String, ExpiringSession> findByPrincipalName = doFindByPrincipalName(getSecurityName());
|
Map<String, ExpiringSession> findByPrincipalName = doFindByPrincipalName(
|
||||||
|
getSecurityName());
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
}
|
}
|
||||||
@@ -255,7 +281,8 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
|
|||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext);
|
||||||
save(toSave);
|
save(toSave);
|
||||||
|
|
||||||
Map<String, ExpiringSession> findByPrincipalName = doFindByPrincipalName(getSecurityName());
|
Map<String, ExpiringSession> findByPrincipalName = doFindByPrincipalName(
|
||||||
|
getSecurityName());
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
|
|
||||||
findByPrincipalName = doFindByPrincipalName(getChangedSecurityName());
|
findByPrincipalName = doFindByPrincipalName(getChangedSecurityName());
|
||||||
@@ -264,7 +291,8 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findsNoSessionsByNonExistingPrincipal() {
|
public void findsNoSessionsByNonExistingPrincipal() {
|
||||||
Map<String, ExpiringSession> nonExistingPrincipalSessions = doFindByPrincipalName("nonExistingPrincipalName");
|
Map<String, ExpiringSession> nonExistingPrincipalSessions = doFindByPrincipalName(
|
||||||
|
"nonExistingPrincipalName");
|
||||||
|
|
||||||
assertThat(nonExistingPrincipalSessions).isNotNull();
|
assertThat(nonExistingPrincipalSessions).isNotNull();
|
||||||
assertThat(nonExistingPrincipalSessions.isEmpty()).isTrue();
|
assertThat(nonExistingPrincipalSessions.isEmpty()).isTrue();
|
||||||
@@ -274,10 +302,12 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
|
|||||||
public void findsNoSessionsAfterPrincipalIsRemoved() {
|
public void findsNoSessionsAfterPrincipalIsRemoved() {
|
||||||
String username = "doesNotFindAfterPrincipalRemoved";
|
String username = "doesNotFindAfterPrincipalRemoved";
|
||||||
ExpiringSession session = save(touch(createSession(username)));
|
ExpiringSession session = save(touch(createSession(username)));
|
||||||
session.setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, null);
|
session.setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
|
||||||
|
null);
|
||||||
save(session);
|
save(session);
|
||||||
|
|
||||||
Map<String, ExpiringSession> nonExistingPrincipalSessions = doFindByPrincipalName(username);
|
Map<String, ExpiringSession> nonExistingPrincipalSessions = doFindByPrincipalName(
|
||||||
|
username);
|
||||||
|
|
||||||
assertThat(nonExistingPrincipalSessions).isNotNull();
|
assertThat(nonExistingPrincipalSessions).isNotNull();
|
||||||
assertThat(nonExistingPrincipalSessions.isEmpty()).isTrue();
|
assertThat(nonExistingPrincipalSessions.isEmpty()).isTrue();
|
||||||
@@ -287,12 +317,14 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
|
|||||||
public void saveAndReadSessionWithAttributes() {
|
public void saveAndReadSessionWithAttributes() {
|
||||||
ExpiringSession expectedSession = this.gemfireSessionRepository.createSession();
|
ExpiringSession expectedSession = this.gemfireSessionRepository.createSession();
|
||||||
|
|
||||||
assertThat(expectedSession).isInstanceOf(AbstractGemFireOperationsSessionRepository.GemFireSession.class);
|
assertThat(expectedSession).isInstanceOf(
|
||||||
|
AbstractGemFireOperationsSessionRepository.GemFireSession.class);
|
||||||
|
|
||||||
((AbstractGemFireOperationsSessionRepository.GemFireSession) expectedSession).setPrincipalName("jblum");
|
((AbstractGemFireOperationsSessionRepository.GemFireSession) expectedSession)
|
||||||
|
.setPrincipalName("jblum");
|
||||||
|
|
||||||
List<String> expectedAttributeNames = Arrays.asList(
|
List<String> expectedAttributeNames = Arrays.asList("booleanAttribute",
|
||||||
"booleanAttribute", "numericAttribute", "stringAttribute", "personAttribute");
|
"numericAttribute", "stringAttribute", "personAttribute");
|
||||||
|
|
||||||
Person jonDoe = new Person("Jon", "Doe");
|
Person jonDoe = new Person("Jon", "Doe");
|
||||||
|
|
||||||
@@ -303,21 +335,32 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
|
|||||||
|
|
||||||
this.gemfireSessionRepository.save(touch(expectedSession));
|
this.gemfireSessionRepository.save(touch(expectedSession));
|
||||||
|
|
||||||
ExpiringSession savedSession = this.gemfireSessionRepository.getSession(expectedSession.getId());
|
ExpiringSession savedSession = this.gemfireSessionRepository
|
||||||
|
.getSession(expectedSession.getId());
|
||||||
|
|
||||||
assertThat(savedSession).isEqualTo(expectedSession);
|
assertThat(savedSession).isEqualTo(expectedSession);
|
||||||
assertThat(savedSession).isInstanceOf(AbstractGemFireOperationsSessionRepository.GemFireSession.class);
|
assertThat(savedSession).isInstanceOf(
|
||||||
assertThat(((AbstractGemFireOperationsSessionRepository.GemFireSession) savedSession).getPrincipalName()).isEqualTo("jblum");
|
AbstractGemFireOperationsSessionRepository.GemFireSession.class);
|
||||||
|
assertThat(
|
||||||
|
((AbstractGemFireOperationsSessionRepository.GemFireSession) savedSession)
|
||||||
|
.getPrincipalName()).isEqualTo("jblum");
|
||||||
|
|
||||||
assertThat(savedSession.getAttributeNames().containsAll(expectedAttributeNames)).as(
|
assertThat(savedSession.getAttributeNames().containsAll(expectedAttributeNames))
|
||||||
String.format("Expected (%1$s); but was (%2$s)", expectedAttributeNames, savedSession.getAttributeNames()))
|
.as(String.format("Expected (%1$s); but was (%2$s)",
|
||||||
|
expectedAttributeNames, savedSession.getAttributeNames()))
|
||||||
.isTrue();
|
.isTrue();
|
||||||
|
|
||||||
assertThat(Boolean.valueOf(String.valueOf(savedSession.getAttribute(expectedAttributeNames.get(0))))).isTrue();
|
assertThat(Boolean.valueOf(
|
||||||
assertThat(Double.valueOf(String.valueOf(savedSession.getAttribute(expectedAttributeNames.get(1)))))
|
String.valueOf(savedSession.getAttribute(expectedAttributeNames.get(0)))))
|
||||||
|
.isTrue();
|
||||||
|
assertThat(Double.valueOf(
|
||||||
|
String.valueOf(savedSession.getAttribute(expectedAttributeNames.get(1)))))
|
||||||
.isEqualTo(Math.PI);
|
.isEqualTo(Math.PI);
|
||||||
assertThat(String.valueOf(savedSession.getAttribute(expectedAttributeNames.get(2)))).isEqualTo("test");
|
assertThat(
|
||||||
assertThat(savedSession.getAttribute(expectedAttributeNames.get(3))).isEqualTo(jonDoe);
|
String.valueOf(savedSession.getAttribute(expectedAttributeNames.get(2))))
|
||||||
|
.isEqualTo("test");
|
||||||
|
assertThat(savedSession.getAttribute(expectedAttributeNames.get(3)))
|
||||||
|
.isEqualTo(jonDoe);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getSecurityName() {
|
private String getSecurityName() {
|
||||||
@@ -328,15 +371,15 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
|
|||||||
return this.changedContext.getAuthentication().getName();
|
return this.changedContext.getAuthentication().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME,
|
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME, maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
|
||||||
maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
|
|
||||||
static class SpringSessionGemFireConfiguration {
|
static class SpringSessionGemFireConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
Properties gemfireProperties() {
|
Properties gemfireProperties() {
|
||||||
Properties gemfireProperties = new Properties();
|
Properties gemfireProperties = new Properties();
|
||||||
|
|
||||||
gemfireProperties.setProperty("name", GemFireOperationsSessionRepositoryIntegrationTests.class.getName());
|
gemfireProperties.setProperty("name",
|
||||||
|
GemFireOperationsSessionRepositoryIntegrationTests.class.getName());
|
||||||
gemfireProperties.setProperty("mcast-port", "0");
|
gemfireProperties.setProperty("mcast-port", "0");
|
||||||
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
|
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
|
||||||
|
|
||||||
@@ -370,7 +413,8 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String validate(String value) {
|
private String validate(String value) {
|
||||||
Assert.hasText(value, String.format("The String value (%1$s) must be specified!", value));
|
Assert.hasText(value,
|
||||||
|
String.format("The String value (%1$s) must be specified!", value));
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,7 +443,8 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
|
|||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public int compareTo(final Person person) {
|
public int compareTo(final Person person) {
|
||||||
int compareValue = getLastName().compareTo(person.getLastName());
|
int compareValue = getLastName().compareTo(person.getLastName());
|
||||||
return (compareValue != 0 ? compareValue : getFirstName().compareTo(person.getFirstName()));
|
return (compareValue != 0 ? compareValue
|
||||||
|
: getFirstName().compareTo(person.getFirstName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -47,8 +47,9 @@ import org.springframework.test.context.web.WebAppConfiguration;
|
|||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The EnableGemFireHttpSessionEventsIntegrationTests class is a test suite of test cases testing the Session Event
|
* The EnableGemFireHttpSessionEventsIntegrationTests class is a test suite of test cases
|
||||||
* functionality and behavior of the GemFireOperationsSessionRepository and GemFire's configuration.
|
* testing the Session Event functionality and behavior of the
|
||||||
|
* GemFireOperationsSessionRepository and GemFire's configuration.
|
||||||
*
|
*
|
||||||
* @author John Blum
|
* @author John Blum
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
@@ -70,7 +71,8 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
@ContextConfiguration
|
@ContextConfiguration
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
@WebAppConfiguration
|
@WebAppConfiguration
|
||||||
public class EnableGemFireHttpSessionEventsIntegrationTests extends AbstractGemFireIntegrationTests {
|
public class EnableGemFireHttpSessionEventsIntegrationTests
|
||||||
|
extends AbstractGemFireIntegrationTests {
|
||||||
|
|
||||||
private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 1;
|
private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 1;
|
||||||
|
|
||||||
@@ -84,14 +86,17 @@ public class EnableGemFireHttpSessionEventsIntegrationTests extends AbstractGemF
|
|||||||
public void setup() {
|
public void setup() {
|
||||||
assertThat(GemFireUtils.isPeer(this.gemfireCache)).isTrue();
|
assertThat(GemFireUtils.isPeer(this.gemfireCache)).isTrue();
|
||||||
assertThat(this.gemfireSessionRepository).isNotNull();
|
assertThat(this.gemfireSessionRepository).isNotNull();
|
||||||
assertThat(this.gemfireSessionRepository.getMaxInactiveIntervalInSeconds()).isEqualTo(
|
assertThat(this.gemfireSessionRepository.getMaxInactiveIntervalInSeconds())
|
||||||
MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
.isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
||||||
assertThat(this.sessionEventListener).isNotNull();
|
assertThat(this.sessionEventListener).isNotNull();
|
||||||
|
|
||||||
Region<Object, ExpiringSession> sessionRegion = this.gemfireCache.getRegion(SPRING_SESSION_GEMFIRE_REGION_NAME);
|
Region<Object, ExpiringSession> sessionRegion = this.gemfireCache
|
||||||
|
.getRegion(SPRING_SESSION_GEMFIRE_REGION_NAME);
|
||||||
|
|
||||||
assertRegion(sessionRegion, SPRING_SESSION_GEMFIRE_REGION_NAME, DataPolicy.REPLICATE);
|
assertRegion(sessionRegion, SPRING_SESSION_GEMFIRE_REGION_NAME,
|
||||||
assertEntryIdleTimeout(sessionRegion, ExpirationAction.INVALIDATE, MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
DataPolicy.REPLICATE);
|
||||||
|
assertEntryIdleTimeout(sessionRegion, ExpirationAction.INVALIDATE,
|
||||||
|
MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
@@ -113,9 +118,12 @@ public class EnableGemFireHttpSessionEventsIntegrationTests extends AbstractGemF
|
|||||||
|
|
||||||
assertThat(createdSession).isEqualTo(expectedSession);
|
assertThat(createdSession).isEqualTo(expectedSession);
|
||||||
assertThat(createdSession.getId()).isNotNull();
|
assertThat(createdSession.getId()).isNotNull();
|
||||||
assertThat(createdSession.getCreationTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime);
|
assertThat(createdSession.getCreationTime())
|
||||||
assertThat(createdSession.getLastAccessedTime()).isEqualTo(createdSession.getCreationTime());
|
.isGreaterThanOrEqualTo(beforeOrAtCreationTime);
|
||||||
assertThat(createdSession.getMaxInactiveIntervalInSeconds()).isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
assertThat(createdSession.getLastAccessedTime())
|
||||||
|
.isEqualTo(createdSession.getCreationTime());
|
||||||
|
assertThat(createdSession.getMaxInactiveIntervalInSeconds())
|
||||||
|
.isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
||||||
assertThat(createdSession.isExpired()).isFalse();
|
assertThat(createdSession.isExpired()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +134,8 @@ public class EnableGemFireHttpSessionEventsIntegrationTests extends AbstractGemF
|
|||||||
assertThat(expectedSession.isExpired()).isFalse();
|
assertThat(expectedSession.isExpired()).isFalse();
|
||||||
|
|
||||||
// NOTE though unlikely, a possible race condition exists between save and get...
|
// NOTE though unlikely, a possible race condition exists between save and get...
|
||||||
ExpiringSession savedSession = this.gemfireSessionRepository.getSession(expectedSession.getId());
|
ExpiringSession savedSession = this.gemfireSessionRepository
|
||||||
|
.getSession(expectedSession.getId());
|
||||||
|
|
||||||
assertThat(savedSession).isEqualTo(expectedSession);
|
assertThat(savedSession).isEqualTo(expectedSession);
|
||||||
}
|
}
|
||||||
@@ -143,18 +152,21 @@ public class EnableGemFireHttpSessionEventsIntegrationTests extends AbstractGemF
|
|||||||
|
|
||||||
assertThat(createdSession).isEqualTo(expectedSession);
|
assertThat(createdSession).isEqualTo(expectedSession);
|
||||||
assertThat(createdSession.isExpired()).isTrue();
|
assertThat(createdSession.isExpired()).isTrue();
|
||||||
assertThat(this.gemfireSessionRepository.getSession(createdSession.getId())).isNull();
|
assertThat(this.gemfireSessionRepository.getSession(createdSession.getId()))
|
||||||
|
.isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getNonExistingSession() {
|
public void getNonExistingSession() {
|
||||||
assertThat(this.gemfireSessionRepository.getSession(UUID.randomUUID().toString())).isNull();
|
assertThat(this.gemfireSessionRepository.getSession(UUID.randomUUID().toString()))
|
||||||
|
.isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deleteExistingNonExpiredSession() {
|
public void deleteExistingNonExpiredSession() {
|
||||||
ExpiringSession expectedSession = save(touch(createSession()));
|
ExpiringSession expectedSession = save(touch(createSession()));
|
||||||
ExpiringSession savedSession = this.gemfireSessionRepository.getSession(expectedSession.getId());
|
ExpiringSession savedSession = this.gemfireSessionRepository
|
||||||
|
.getSession(expectedSession.getId());
|
||||||
|
|
||||||
assertThat(savedSession).isEqualTo(expectedSession);
|
assertThat(savedSession).isEqualTo(expectedSession);
|
||||||
assertThat(savedSession.isExpired()).isFalse();
|
assertThat(savedSession.isExpired()).isFalse();
|
||||||
@@ -169,7 +181,8 @@ public class EnableGemFireHttpSessionEventsIntegrationTests extends AbstractGemF
|
|||||||
ExpiringSession deletedSession = sessionEvent.getSession();
|
ExpiringSession deletedSession = sessionEvent.getSession();
|
||||||
|
|
||||||
assertThat(deletedSession).isEqualTo(savedSession);
|
assertThat(deletedSession).isEqualTo(savedSession);
|
||||||
assertThat(this.gemfireSessionRepository.getSession(deletedSession.getId())).isNull();
|
assertThat(this.gemfireSessionRepository.getSession(deletedSession.getId()))
|
||||||
|
.isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -184,8 +197,9 @@ public class EnableGemFireHttpSessionEventsIntegrationTests extends AbstractGemF
|
|||||||
|
|
||||||
assertThat(createdSession).isEqualTo(expectedSession);
|
assertThat(createdSession).isEqualTo(expectedSession);
|
||||||
|
|
||||||
sessionEvent = this.sessionEventListener.waitForSessionEvent(TimeUnit.SECONDS.toMillis(
|
sessionEvent = this.sessionEventListener.waitForSessionEvent(TimeUnit.SECONDS
|
||||||
this.gemfireSessionRepository.getMaxInactiveIntervalInSeconds() + 1));
|
.toMillis(this.gemfireSessionRepository.getMaxInactiveIntervalInSeconds()
|
||||||
|
+ 1));
|
||||||
|
|
||||||
assertThat(sessionEvent).isInstanceOf(SessionExpiredEvent.class);
|
assertThat(sessionEvent).isInstanceOf(SessionExpiredEvent.class);
|
||||||
|
|
||||||
@@ -201,7 +215,8 @@ public class EnableGemFireHttpSessionEventsIntegrationTests extends AbstractGemF
|
|||||||
assertThat(sessionEvent).isInstanceOf(SessionDeletedEvent.class);
|
assertThat(sessionEvent).isInstanceOf(SessionDeletedEvent.class);
|
||||||
assertThat(sessionEvent.getSession()).isNull();
|
assertThat(sessionEvent.getSession()).isNull();
|
||||||
assertThat(sessionEvent.getSessionId()).isEqualTo(expiredSession.getId());
|
assertThat(sessionEvent.getSessionId()).isEqualTo(expiredSession.getId());
|
||||||
assertThat(this.gemfireSessionRepository.getSession(sessionEvent.getSessionId())).isNull();
|
assertThat(this.gemfireSessionRepository.getSession(sessionEvent.getSessionId()))
|
||||||
|
.isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -219,16 +234,15 @@ public class EnableGemFireHttpSessionEventsIntegrationTests extends AbstractGemF
|
|||||||
assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSessionId);
|
assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME,
|
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME, maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS, serverRegionShortcut = RegionShortcut.REPLICATE)
|
||||||
maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS,
|
|
||||||
serverRegionShortcut = RegionShortcut.REPLICATE)
|
|
||||||
static class SpringSessionGemFireConfiguration {
|
static class SpringSessionGemFireConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
Properties gemfireProperties() {
|
Properties gemfireProperties() {
|
||||||
Properties gemfireProperties = new Properties();
|
Properties gemfireProperties = new Properties();
|
||||||
|
|
||||||
gemfireProperties.setProperty("name", EnableGemFireHttpSessionEventsIntegrationTests.class.getName());
|
gemfireProperties.setProperty("name",
|
||||||
|
EnableGemFireHttpSessionEventsIntegrationTests.class.getName());
|
||||||
gemfireProperties.setProperty("mcast-port", "0");
|
gemfireProperties.setProperty("mcast-port", "0");
|
||||||
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
|
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
|
||||||
|
|
||||||
|
|||||||
@@ -42,8 +42,9 @@ import org.springframework.test.context.web.WebAppConfiguration;
|
|||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The GemFireHttpSessionJavaConfigurationTests class is a test suite of test cases testing the configuration of
|
* The GemFireHttpSessionJavaConfigurationTests class is a test suite of test cases
|
||||||
* Spring Session backed by GemFire using Java-based configuration meta-data.
|
* testing the configuration of Spring Session backed by GemFire using Java-based
|
||||||
|
* configuration meta-data.
|
||||||
*
|
*
|
||||||
* @author John Blum
|
* @author John Blum
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
@@ -61,12 +62,14 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
@ContextConfiguration
|
@ContextConfiguration
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
@WebAppConfiguration
|
@WebAppConfiguration
|
||||||
public class GemFireHttpSessionJavaConfigurationTests extends AbstractGemFireIntegrationTests {
|
public class GemFireHttpSessionJavaConfigurationTests
|
||||||
|
extends AbstractGemFireIntegrationTests {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private Cache gemfireCache;
|
private Cache gemfireCache;
|
||||||
|
|
||||||
protected <K, V> Region<K, V> assertCacheAndRegion(Cache gemfireCache, String regionName, DataPolicy dataPolicy) {
|
protected <K, V> Region<K, V> assertCacheAndRegion(Cache gemfireCache,
|
||||||
|
String regionName, DataPolicy dataPolicy) {
|
||||||
assertThat(GemFireUtils.isPeer(gemfireCache)).isTrue();
|
assertThat(GemFireUtils.isPeer(gemfireCache)).isTrue();
|
||||||
|
|
||||||
Region<K, V> region = gemfireCache.getRegion(regionName);
|
Region<K, V> region = gemfireCache.getRegion(regionName);
|
||||||
@@ -78,16 +81,16 @@ public class GemFireHttpSessionJavaConfigurationTests extends AbstractGemFireInt
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void gemfireCacheConfigurationIsValid() {
|
public void gemfireCacheConfigurationIsValid() {
|
||||||
Region<Object, ExpiringSession> example = assertCacheAndRegion(this.gemfireCache, "JavaExample",
|
Region<Object, ExpiringSession> example = assertCacheAndRegion(this.gemfireCache,
|
||||||
DataPolicy.REPLICATE);
|
"JavaExample", DataPolicy.REPLICATE);
|
||||||
|
|
||||||
assertEntryIdleTimeout(example, ExpirationAction.INVALIDATE, 900);
|
assertEntryIdleTimeout(example, ExpirationAction.INVALIDATE, 900);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void verifyGemFireExampleCacheRegionPrincipalNameIndexWasCreatedSuccessfully() {
|
public void verifyGemFireExampleCacheRegionPrincipalNameIndexWasCreatedSuccessfully() {
|
||||||
Region<Object, ExpiringSession> example = assertCacheAndRegion(this.gemfireCache, "JavaExample",
|
Region<Object, ExpiringSession> example = assertCacheAndRegion(this.gemfireCache,
|
||||||
DataPolicy.REPLICATE);
|
"JavaExample", DataPolicy.REPLICATE);
|
||||||
|
|
||||||
QueryService queryService = example.getRegionService().getQueryService();
|
QueryService queryService = example.getRegionService().getQueryService();
|
||||||
|
|
||||||
@@ -100,26 +103,27 @@ public class GemFireHttpSessionJavaConfigurationTests extends AbstractGemFireInt
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void verifyGemFireExampleCacheRegionSessionAttributesIndexWasNotCreated() {
|
public void verifyGemFireExampleCacheRegionSessionAttributesIndexWasNotCreated() {
|
||||||
Region<Object, ExpiringSession> example = assertCacheAndRegion(this.gemfireCache, "JavaExample",
|
Region<Object, ExpiringSession> example = assertCacheAndRegion(this.gemfireCache,
|
||||||
DataPolicy.REPLICATE);
|
"JavaExample", DataPolicy.REPLICATE);
|
||||||
|
|
||||||
QueryService queryService = example.getRegionService().getQueryService();
|
QueryService queryService = example.getRegionService().getQueryService();
|
||||||
|
|
||||||
assertThat(queryService).isNotNull();
|
assertThat(queryService).isNotNull();
|
||||||
|
|
||||||
Index sessionAttributesIndex = queryService.getIndex(example, "sessionAttributesIndex");
|
Index sessionAttributesIndex = queryService.getIndex(example,
|
||||||
|
"sessionAttributesIndex");
|
||||||
|
|
||||||
assertThat(sessionAttributesIndex).isNull();
|
assertThat(sessionAttributesIndex).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableGemFireHttpSession(indexableSessionAttributes = {}, maxInactiveIntervalInSeconds = 900,
|
@EnableGemFireHttpSession(indexableSessionAttributes = {}, maxInactiveIntervalInSeconds = 900, regionName = "JavaExample", serverRegionShortcut = RegionShortcut.REPLICATE)
|
||||||
regionName = "JavaExample", serverRegionShortcut = RegionShortcut.REPLICATE)
|
|
||||||
public static class GemFireConfiguration {
|
public static class GemFireConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
Properties gemfireProperties() {
|
Properties gemfireProperties() {
|
||||||
Properties gemfireProperties = new Properties();
|
Properties gemfireProperties = new Properties();
|
||||||
gemfireProperties.setProperty("name", GemFireHttpSessionJavaConfigurationTests.class.getName());
|
gemfireProperties.setProperty("name",
|
||||||
|
GemFireHttpSessionJavaConfigurationTests.class.getName());
|
||||||
gemfireProperties.setProperty("mcast-port", "0");
|
gemfireProperties.setProperty("mcast-port", "0");
|
||||||
gemfireProperties.setProperty("log-level", "warning");
|
gemfireProperties.setProperty("log-level", "warning");
|
||||||
return gemfireProperties;
|
return gemfireProperties;
|
||||||
|
|||||||
@@ -37,8 +37,9 @@ import org.springframework.test.context.web.WebAppConfiguration;
|
|||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The GemFireHttpSessionXmlConfigurationTests class is a test suite of test cases testing the configuration of
|
* The GemFireHttpSessionXmlConfigurationTests class is a test suite of test cases testing
|
||||||
* Spring Session backed by GemFire using XML configuration meta-data.
|
* the configuration of Spring Session backed by GemFire using XML configuration
|
||||||
|
* meta-data.
|
||||||
*
|
*
|
||||||
* @author John Blum
|
* @author John Blum
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
@@ -56,12 +57,14 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
@ContextConfiguration
|
@ContextConfiguration
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
@WebAppConfiguration
|
@WebAppConfiguration
|
||||||
public class GemFireHttpSessionXmlConfigurationTests extends AbstractGemFireIntegrationTests {
|
public class GemFireHttpSessionXmlConfigurationTests
|
||||||
|
extends AbstractGemFireIntegrationTests {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private Cache gemfireCache;
|
private Cache gemfireCache;
|
||||||
|
|
||||||
protected <K, V> Region<K, V> assertCacheAndRegion(Cache gemfireCache, String regionName, DataPolicy dataPolicy) {
|
protected <K, V> Region<K, V> assertCacheAndRegion(Cache gemfireCache,
|
||||||
|
String regionName, DataPolicy dataPolicy) {
|
||||||
assertThat(GemFireUtils.isPeer(gemfireCache)).isTrue();
|
assertThat(GemFireUtils.isPeer(gemfireCache)).isTrue();
|
||||||
|
|
||||||
Region<K, V> region = gemfireCache.getRegion(regionName);
|
Region<K, V> region = gemfireCache.getRegion(regionName);
|
||||||
@@ -73,14 +76,16 @@ public class GemFireHttpSessionXmlConfigurationTests extends AbstractGemFireInte
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void gemfireCacheConfigurationIsValid() {
|
public void gemfireCacheConfigurationIsValid() {
|
||||||
Region<Object, ExpiringSession> example = assertCacheAndRegion(this.gemfireCache, "XmlExample", DataPolicy.NORMAL);
|
Region<Object, ExpiringSession> example = assertCacheAndRegion(this.gemfireCache,
|
||||||
|
"XmlExample", DataPolicy.NORMAL);
|
||||||
|
|
||||||
assertEntryIdleTimeout(example, ExpirationAction.INVALIDATE, 3600);
|
assertEntryIdleTimeout(example, ExpirationAction.INVALIDATE, 3600);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void verifyGemFireExampleCacheRegionPrincipalNameIndexWasCreatedSuccessfully() {
|
public void verifyGemFireExampleCacheRegionPrincipalNameIndexWasCreatedSuccessfully() {
|
||||||
Region<Object, ExpiringSession> example = assertCacheAndRegion(this.gemfireCache, "XmlExample", DataPolicy.NORMAL);
|
Region<Object, ExpiringSession> example = assertCacheAndRegion(this.gemfireCache,
|
||||||
|
"XmlExample", DataPolicy.NORMAL);
|
||||||
|
|
||||||
QueryService queryService = example.getRegionService().getQueryService();
|
QueryService queryService = example.getRegionService().getQueryService();
|
||||||
|
|
||||||
@@ -93,13 +98,15 @@ public class GemFireHttpSessionXmlConfigurationTests extends AbstractGemFireInte
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void verifyGemFireExampleCacheRegionSessionAttributesIndexWasCreatedSuccessfully() {
|
public void verifyGemFireExampleCacheRegionSessionAttributesIndexWasCreatedSuccessfully() {
|
||||||
Region<Object, ExpiringSession> example = assertCacheAndRegion(this.gemfireCache, "XmlExample", DataPolicy.NORMAL);
|
Region<Object, ExpiringSession> example = assertCacheAndRegion(this.gemfireCache,
|
||||||
|
"XmlExample", DataPolicy.NORMAL);
|
||||||
|
|
||||||
QueryService queryService = example.getRegionService().getQueryService();
|
QueryService queryService = example.getRegionService().getQueryService();
|
||||||
|
|
||||||
assertThat(queryService).isNotNull();
|
assertThat(queryService).isNotNull();
|
||||||
|
|
||||||
Index sessionAttributesIndex = queryService.getIndex(example, "sessionAttributesIndex");
|
Index sessionAttributesIndex = queryService.getIndex(example,
|
||||||
|
"sessionAttributesIndex");
|
||||||
|
|
||||||
assertIndex(sessionAttributesIndex, "s.attributes['one', 'two', 'three']",
|
assertIndex(sessionAttributesIndex, "s.attributes['one', 'two', 'three']",
|
||||||
String.format("%1$s s", example.getFullPath()));
|
String.format("%1$s s", example.getFullPath()));
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2014-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -15,8 +15,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.session.data.mongo;
|
package org.springframework.session.data.mongo;
|
||||||
|
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import com.mongodb.MongoClient;
|
import com.mongodb.MongoClient;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -33,11 +39,6 @@ import org.springframework.session.data.AbstractITests;
|
|||||||
import org.springframework.session.data.mongo.config.annotation.web.http.EnableMongoHttpSession;
|
import org.springframework.session.data.mongo.config.annotation.web.http.EnableMongoHttpSession;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,69 +58,71 @@ public class MongoRepositoryITests extends AbstractITests {
|
|||||||
public void saves() throws InterruptedException {
|
public void saves() throws InterruptedException {
|
||||||
String username = "saves-" + System.currentTimeMillis();
|
String username = "saves-" + System.currentTimeMillis();
|
||||||
|
|
||||||
MongoExpiringSession toSave = repository.createSession();
|
MongoExpiringSession toSave = this.repository.createSession();
|
||||||
String expectedAttributeName = "a";
|
String expectedAttributeName = "a";
|
||||||
String expectedAttributeValue = "b";
|
String expectedAttributeValue = "b";
|
||||||
toSave.setAttribute(expectedAttributeName, expectedAttributeValue);
|
toSave.setAttribute(expectedAttributeName, expectedAttributeValue);
|
||||||
Authentication toSaveToken = new UsernamePasswordAuthenticationToken(username, "password",
|
Authentication toSaveToken = new UsernamePasswordAuthenticationToken(username,
|
||||||
AuthorityUtils.createAuthorityList("ROLE_USER"));
|
"password", AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||||
SecurityContext toSaveContext = SecurityContextHolder.createEmptyContext();
|
SecurityContext toSaveContext = SecurityContextHolder.createEmptyContext();
|
||||||
toSaveContext.setAuthentication(toSaveToken);
|
toSaveContext.setAuthentication(toSaveToken);
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, toSaveContext);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, toSaveContext);
|
||||||
toSave.setAttribute(INDEX_NAME, username);
|
toSave.setAttribute(INDEX_NAME, username);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Session session = repository.getSession(toSave.getId());
|
Session session = this.repository.getSession(toSave.getId());
|
||||||
|
|
||||||
assertThat(session.getId()).isEqualTo(toSave.getId());
|
assertThat(session.getId()).isEqualTo(toSave.getId());
|
||||||
assertThat(session.getAttributeNames()).isEqualTo(toSave.getAttributeNames());
|
assertThat(session.getAttributeNames()).isEqualTo(toSave.getAttributeNames());
|
||||||
assertThat(session.getAttribute(expectedAttributeName)).isEqualTo(toSave.getAttribute(expectedAttributeName));
|
assertThat(session.getAttribute(expectedAttributeName))
|
||||||
|
.isEqualTo(toSave.getAttribute(expectedAttributeName));
|
||||||
|
|
||||||
repository.delete(toSave.getId());
|
this.repository.delete(toSave.getId());
|
||||||
|
|
||||||
String id = toSave.getId();
|
String id = toSave.getId();
|
||||||
assertThat(repository.getSession(id)).isNull();
|
assertThat(this.repository.getSession(id)).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void putAllOnSingleAttrDoesNotRemoveOld() {
|
public void putAllOnSingleAttrDoesNotRemoveOld() {
|
||||||
MongoExpiringSession toSave = repository.createSession();
|
MongoExpiringSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute("a", "b");
|
toSave.setAttribute("a", "b");
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
toSave = repository.getSession(toSave.getId());
|
toSave = this.repository.getSession(toSave.getId());
|
||||||
|
|
||||||
toSave.setAttribute("1", "2");
|
toSave.setAttribute("1", "2");
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
toSave = repository.getSession(toSave.getId());
|
toSave = this.repository.getSession(toSave.getId());
|
||||||
|
|
||||||
Session session = repository.getSession(toSave.getId());
|
Session session = this.repository.getSession(toSave.getId());
|
||||||
assertThat(session.getAttributeNames().size()).isEqualTo(2);
|
assertThat(session.getAttributeNames().size()).isEqualTo(2);
|
||||||
assertThat(session.getAttribute("a")).isEqualTo("b");
|
assertThat(session.getAttribute("a")).isEqualTo("b");
|
||||||
assertThat(session.getAttribute("1")).isEqualTo("2");
|
assertThat(session.getAttribute("1")).isEqualTo("2");
|
||||||
|
|
||||||
repository.delete(toSave.getId());
|
this.repository.delete(toSave.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByPrincipalName() throws Exception {
|
public void findByPrincipalName() throws Exception {
|
||||||
String principalName = "findByPrincipalName" + UUID.randomUUID();
|
String principalName = "findByPrincipalName" + UUID.randomUUID();
|
||||||
MongoExpiringSession toSave = repository.createSession();
|
MongoExpiringSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
|
||||||
principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
|
|
||||||
repository.delete(toSave.getId());
|
this.repository.delete(toSave.getId());
|
||||||
|
|
||||||
findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||||
|
principalName);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(0);
|
assertThat(findByPrincipalName).hasSize(0);
|
||||||
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
||||||
@@ -127,17 +130,18 @@ public class MongoRepositoryITests extends AbstractITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByPrincipalNameNoPrincipalNameChange() throws Exception {
|
public void findByPrincipalNameNoPrincipalNameChange() throws Exception {
|
||||||
String principalName = "findByPrincipalNameNoPrincipalNameChange" + UUID.randomUUID();
|
String principalName = "findByPrincipalNameNoPrincipalNameChange"
|
||||||
MongoExpiringSession toSave = repository.createSession();
|
+ UUID.randomUUID();
|
||||||
|
MongoExpiringSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
toSave.setAttribute("other", "value");
|
toSave.setAttribute("other", "value");
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
|
||||||
principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
@@ -145,19 +149,20 @@ public class MongoRepositoryITests extends AbstractITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByPrincipalNameNoPrincipalNameChangeReload() throws Exception {
|
public void findByPrincipalNameNoPrincipalNameChangeReload() throws Exception {
|
||||||
String principalName = "findByPrincipalNameNoPrincipalNameChangeReload" + UUID.randomUUID();
|
String principalName = "findByPrincipalNameNoPrincipalNameChangeReload"
|
||||||
MongoExpiringSession toSave = repository.createSession();
|
+ UUID.randomUUID();
|
||||||
|
MongoExpiringSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
toSave = repository.getSession(toSave.getId());
|
toSave = this.repository.getSession(toSave.getId());
|
||||||
|
|
||||||
toSave.setAttribute("other", "value");
|
toSave.setAttribute("other", "value");
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
|
||||||
principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
@@ -166,16 +171,16 @@ public class MongoRepositoryITests extends AbstractITests {
|
|||||||
@Test
|
@Test
|
||||||
public void findByDeletedPrincipalName() throws Exception {
|
public void findByDeletedPrincipalName() throws Exception {
|
||||||
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
|
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
|
||||||
MongoExpiringSession toSave = repository.createSession();
|
MongoExpiringSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
toSave.setAttribute(INDEX_NAME, null);
|
toSave.setAttribute(INDEX_NAME, null);
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
|
||||||
principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
}
|
}
|
||||||
@@ -184,19 +189,20 @@ public class MongoRepositoryITests extends AbstractITests {
|
|||||||
public void findByChangedPrincipalName() throws Exception {
|
public void findByChangedPrincipalName() throws Exception {
|
||||||
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
|
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
|
||||||
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
|
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
|
||||||
MongoExpiringSession toSave = repository.createSession();
|
MongoExpiringSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
toSave.setAttribute(INDEX_NAME, principalNameChanged);
|
toSave.setAttribute(INDEX_NAME, principalNameChanged);
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
|
||||||
principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
|
|
||||||
findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME, principalNameChanged);
|
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||||
|
principalNameChanged);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
@@ -205,17 +211,17 @@ public class MongoRepositoryITests extends AbstractITests {
|
|||||||
@Test
|
@Test
|
||||||
public void findByDeletedPrincipalNameReload() throws Exception {
|
public void findByDeletedPrincipalNameReload() throws Exception {
|
||||||
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
|
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
|
||||||
MongoExpiringSession toSave = repository.createSession();
|
MongoExpiringSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
MongoExpiringSession getSession = repository.getSession(toSave.getId());
|
MongoExpiringSession getSession = this.repository.getSession(toSave.getId());
|
||||||
getSession.setAttribute(INDEX_NAME, null);
|
getSession.setAttribute(INDEX_NAME, null);
|
||||||
repository.save(getSession);
|
this.repository.save(getSession);
|
||||||
|
|
||||||
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
|
||||||
principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
}
|
}
|
||||||
@@ -224,21 +230,22 @@ public class MongoRepositoryITests extends AbstractITests {
|
|||||||
public void findByChangedPrincipalNameReload() throws Exception {
|
public void findByChangedPrincipalNameReload() throws Exception {
|
||||||
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
|
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
|
||||||
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
|
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
|
||||||
MongoExpiringSession toSave = repository.createSession();
|
MongoExpiringSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
MongoExpiringSession getSession = repository.getSession(toSave.getId());
|
MongoExpiringSession getSession = this.repository.getSession(toSave.getId());
|
||||||
|
|
||||||
getSession.setAttribute(INDEX_NAME, principalNameChanged);
|
getSession.setAttribute(INDEX_NAME, principalNameChanged);
|
||||||
repository.save(getSession);
|
this.repository.save(getSession);
|
||||||
|
|
||||||
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
|
||||||
principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
|
|
||||||
findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME, principalNameChanged);
|
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||||
|
principalNameChanged);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
@@ -246,20 +253,21 @@ public class MongoRepositoryITests extends AbstractITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findBySecurityPrincipalName() throws Exception {
|
public void findBySecurityPrincipalName() throws Exception {
|
||||||
MongoExpiringSession toSave = repository.createSession();
|
MongoExpiringSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
|
||||||
getSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
|
|
||||||
repository.delete(toSave.getId());
|
this.repository.delete(toSave.getId());
|
||||||
|
|
||||||
findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||||
|
getSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(0);
|
assertThat(findByPrincipalName).hasSize(0);
|
||||||
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
||||||
@@ -267,35 +275,36 @@ public class MongoRepositoryITests extends AbstractITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByPrincipalNameNoSecurityPrincipalNameChange() throws Exception {
|
public void findByPrincipalNameNoSecurityPrincipalNameChange() throws Exception {
|
||||||
MongoExpiringSession toSave = repository.createSession();
|
MongoExpiringSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
toSave.setAttribute("other", "value");
|
toSave.setAttribute("other", "value");
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
|
||||||
getSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByPrincipalNameNoSecurityPrincipalNameChangeReload() throws Exception {
|
public void findByPrincipalNameNoSecurityPrincipalNameChangeReload()
|
||||||
MongoExpiringSession toSave = repository.createSession();
|
throws Exception {
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, context);
|
MongoExpiringSession toSave = this.repository.createSession();
|
||||||
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
toSave = repository.getSession(toSave.getId());
|
toSave = this.repository.getSession(toSave.getId());
|
||||||
|
|
||||||
toSave.setAttribute("other", "value");
|
toSave.setAttribute("other", "value");
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
|
||||||
getSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
@@ -303,35 +312,36 @@ public class MongoRepositoryITests extends AbstractITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByDeletedSecurityPrincipalName() throws Exception {
|
public void findByDeletedSecurityPrincipalName() throws Exception {
|
||||||
MongoExpiringSession toSave = repository.createSession();
|
MongoExpiringSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, null);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, null);
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
|
||||||
getSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByChangedSecurityPrincipalName() throws Exception {
|
public void findByChangedSecurityPrincipalName() throws Exception {
|
||||||
MongoExpiringSession toSave = repository.createSession();
|
MongoExpiringSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, changedContext);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext);
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
|
||||||
getSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
|
|
||||||
findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
|
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||||
|
getChangedSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
@@ -339,38 +349,39 @@ public class MongoRepositoryITests extends AbstractITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByDeletedSecurityPrincipalNameReload() throws Exception {
|
public void findByDeletedSecurityPrincipalNameReload() throws Exception {
|
||||||
MongoExpiringSession toSave = repository.createSession();
|
MongoExpiringSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
MongoExpiringSession getSession = repository.getSession(toSave.getId());
|
MongoExpiringSession getSession = this.repository.getSession(toSave.getId());
|
||||||
getSession.setAttribute(INDEX_NAME, null);
|
getSession.setAttribute(INDEX_NAME, null);
|
||||||
repository.save(getSession);
|
this.repository.save(getSession);
|
||||||
|
|
||||||
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
|
||||||
getChangedSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByChangedSecurityPrincipalNameReload() throws Exception {
|
public void findByChangedSecurityPrincipalNameReload() throws Exception {
|
||||||
MongoExpiringSession toSave = repository.createSession();
|
MongoExpiringSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
MongoExpiringSession getSession = repository.getSession(toSave.getId());
|
MongoExpiringSession getSession = this.repository.getSession(toSave.getId());
|
||||||
|
|
||||||
getSession.setAttribute(SPRING_SECURITY_CONTEXT, changedContext);
|
getSession.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext);
|
||||||
repository.save(getSession);
|
this.repository.save(getSession);
|
||||||
|
|
||||||
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
|
||||||
getSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
|
|
||||||
findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
|
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||||
|
getChangedSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
@@ -379,22 +390,24 @@ public class MongoRepositoryITests extends AbstractITests {
|
|||||||
@Test
|
@Test
|
||||||
public void loadExpiredSession() throws Exception {
|
public void loadExpiredSession() throws Exception {
|
||||||
// given
|
// given
|
||||||
MongoExpiringSession expiredSession = repository.createSession();
|
MongoExpiringSession expiredSession = this.repository.createSession();
|
||||||
long thirtyOneMinutesAgo = System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(31);
|
long thirtyOneMinutesAgo = System.currentTimeMillis()
|
||||||
|
- TimeUnit.MINUTES.toMillis(31);
|
||||||
expiredSession.setLastAccessedTime(thirtyOneMinutesAgo);
|
expiredSession.setLastAccessedTime(thirtyOneMinutesAgo);
|
||||||
repository.save(expiredSession);
|
this.repository.save(expiredSession);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
MongoExpiringSession expiredSessionFromDb = repository.getSession(expiredSession.getId());
|
MongoExpiringSession expiredSessionFromDb = this.repository
|
||||||
|
.getSession(expiredSession.getId());
|
||||||
assertThat(expiredSessionFromDb).isNull();
|
assertThat(expiredSessionFromDb).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getSecurityName() {
|
private String getSecurityName() {
|
||||||
return context.getAuthentication().getName();
|
return this.context.getAuthentication().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getChangedSecurityName() {
|
private String getChangedSecurityName() {
|
||||||
return changedContext.getAuthentication().getName();
|
return this.changedContext.getAuthentication().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 the original author or authors.
|
* Copyright 2014-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -15,12 +15,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.session.data.redis;
|
package org.springframework.session.data.redis;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.*;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -42,6 +41,8 @@ import org.springframework.session.events.SessionCreatedEvent;
|
|||||||
import org.springframework.session.events.SessionDestroyedEvent;
|
import org.springframework.session.events.SessionDestroyedEvent;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@ContextConfiguration
|
@ContextConfiguration
|
||||||
public class RedisOperationsSessionRepositoryITests extends AbstractITests {
|
public class RedisOperationsSessionRepositoryITests extends AbstractITests {
|
||||||
private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
|
private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
|
||||||
@@ -58,86 +59,90 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
|
|||||||
public void saves() throws InterruptedException {
|
public void saves() throws InterruptedException {
|
||||||
String username = "saves-" + System.currentTimeMillis();
|
String username = "saves-" + System.currentTimeMillis();
|
||||||
|
|
||||||
String usernameSessionKey = "spring:session:RedisOperationsSessionRepositoryITests:index:" + INDEX_NAME + ":"
|
String usernameSessionKey = "spring:session:RedisOperationsSessionRepositoryITests:index:"
|
||||||
+ username;
|
+ INDEX_NAME + ":" + username;
|
||||||
|
|
||||||
RedisSession toSave = repository.createSession();
|
RedisSession toSave = this.repository.createSession();
|
||||||
String expectedAttributeName = "a";
|
String expectedAttributeName = "a";
|
||||||
String expectedAttributeValue = "b";
|
String expectedAttributeValue = "b";
|
||||||
toSave.setAttribute(expectedAttributeName, expectedAttributeValue);
|
toSave.setAttribute(expectedAttributeName, expectedAttributeValue);
|
||||||
Authentication toSaveToken = new UsernamePasswordAuthenticationToken(username, "password",
|
Authentication toSaveToken = new UsernamePasswordAuthenticationToken(username,
|
||||||
AuthorityUtils.createAuthorityList("ROLE_USER"));
|
"password", AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||||
SecurityContext toSaveContext = SecurityContextHolder.createEmptyContext();
|
SecurityContext toSaveContext = SecurityContextHolder.createEmptyContext();
|
||||||
toSaveContext.setAuthentication(toSaveToken);
|
toSaveContext.setAuthentication(toSaveToken);
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, toSaveContext);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, toSaveContext);
|
||||||
toSave.setAttribute(INDEX_NAME, username);
|
toSave.setAttribute(INDEX_NAME, username);
|
||||||
registry.clear();
|
this.registry.clear();
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
assertThat(registry.receivedEvent(toSave.getId())).isTrue();
|
assertThat(this.registry.receivedEvent(toSave.getId())).isTrue();
|
||||||
assertThat(registry.getEvent(toSave.getId())).isInstanceOf(SessionCreatedEvent.class);
|
assertThat(this.registry.getEvent(toSave.getId()))
|
||||||
assertThat(redis.boundSetOps(usernameSessionKey).members()).contains(toSave.getId());
|
.isInstanceOf(SessionCreatedEvent.class);
|
||||||
|
assertThat(this.redis.boundSetOps(usernameSessionKey).members())
|
||||||
|
.contains(toSave.getId());
|
||||||
|
|
||||||
Session session = repository.getSession(toSave.getId());
|
Session session = this.repository.getSession(toSave.getId());
|
||||||
|
|
||||||
assertThat(session.getId()).isEqualTo(toSave.getId());
|
assertThat(session.getId()).isEqualTo(toSave.getId());
|
||||||
assertThat(session.getAttributeNames()).isEqualTo(toSave.getAttributeNames());
|
assertThat(session.getAttributeNames()).isEqualTo(toSave.getAttributeNames());
|
||||||
assertThat(session.getAttribute(expectedAttributeName)).isEqualTo(toSave.getAttribute(expectedAttributeName));
|
assertThat(session.getAttribute(expectedAttributeName))
|
||||||
|
.isEqualTo(toSave.getAttribute(expectedAttributeName));
|
||||||
|
|
||||||
registry.clear();
|
this.registry.clear();
|
||||||
|
|
||||||
repository.delete(toSave.getId());
|
this.repository.delete(toSave.getId());
|
||||||
|
|
||||||
assertThat(repository.getSession(toSave.getId())).isNull();
|
assertThat(this.repository.getSession(toSave.getId())).isNull();
|
||||||
assertThat(registry.getEvent(toSave.getId())).isInstanceOf(SessionDestroyedEvent.class);
|
assertThat(this.registry.getEvent(toSave.getId()))
|
||||||
assertThat(redis.boundSetOps(usernameSessionKey).members()).doesNotContain(toSave.getId());
|
.isInstanceOf(SessionDestroyedEvent.class);
|
||||||
|
assertThat(this.redis.boundSetOps(usernameSessionKey).members())
|
||||||
|
.doesNotContain(toSave.getId());
|
||||||
|
|
||||||
assertThat(registry.getEvent(toSave.getId()).getSession().getAttribute(expectedAttributeName))
|
assertThat(this.registry.getEvent(toSave.getId()).getSession()
|
||||||
.isEqualTo(expectedAttributeValue);
|
.getAttribute(expectedAttributeName)).isEqualTo(expectedAttributeValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void putAllOnSingleAttrDoesNotRemoveOld() {
|
public void putAllOnSingleAttrDoesNotRemoveOld() {
|
||||||
RedisSession toSave = repository.createSession();
|
RedisSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute("a", "b");
|
toSave.setAttribute("a", "b");
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
toSave = repository.getSession(toSave.getId());
|
toSave = this.repository.getSession(toSave.getId());
|
||||||
|
|
||||||
toSave.setAttribute("1", "2");
|
toSave.setAttribute("1", "2");
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
toSave = repository.getSession(toSave.getId());
|
toSave = this.repository.getSession(toSave.getId());
|
||||||
|
|
||||||
Session session = repository.getSession(toSave.getId());
|
Session session = this.repository.getSession(toSave.getId());
|
||||||
assertThat(session.getAttributeNames().size()).isEqualTo(2);
|
assertThat(session.getAttributeNames().size()).isEqualTo(2);
|
||||||
assertThat(session.getAttribute("a")).isEqualTo("b");
|
assertThat(session.getAttribute("a")).isEqualTo("b");
|
||||||
assertThat(session.getAttribute("1")).isEqualTo("2");
|
assertThat(session.getAttribute("1")).isEqualTo("2");
|
||||||
|
|
||||||
repository.delete(toSave.getId());
|
this.repository.delete(toSave.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByPrincipalName() throws Exception {
|
public void findByPrincipalName() throws Exception {
|
||||||
String principalName = "findByPrincipalName" + UUID.randomUUID();
|
String principalName = "findByPrincipalName" + UUID.randomUUID();
|
||||||
RedisSession toSave = repository.createSession();
|
RedisSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||||
principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
|
|
||||||
repository.delete(toSave.getId());
|
this.repository.delete(toSave.getId());
|
||||||
assertThat(registry.receivedEvent(toSave.getId())).isTrue();
|
assertThat(this.registry.receivedEvent(toSave.getId())).isTrue();
|
||||||
|
|
||||||
findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||||
|
principalName);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(0);
|
assertThat(findByPrincipalName).hasSize(0);
|
||||||
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
||||||
@@ -145,20 +150,23 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByPrincipalNameExpireRemovesIndex() throws Exception {
|
public void findByPrincipalNameExpireRemovesIndex() throws Exception {
|
||||||
String principalName = "findByPrincipalNameExpireRemovesIndex" + UUID.randomUUID();
|
String principalName = "findByPrincipalNameExpireRemovesIndex"
|
||||||
RedisSession toSave = repository.createSession();
|
+ UUID.randomUUID();
|
||||||
|
RedisSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
String body = "spring:session:RedisOperationsSessionRepositoryITests:sessions:expires:" + toSave.getId();
|
String body = "spring:session:RedisOperationsSessionRepositoryITests:sessions:expires:"
|
||||||
|
+ toSave.getId();
|
||||||
String channel = ":expired";
|
String channel = ":expired";
|
||||||
DefaultMessage message = new DefaultMessage(channel.getBytes("UTF-8"), body.getBytes("UTF-8"));
|
DefaultMessage message = new DefaultMessage(channel.getBytes("UTF-8"),
|
||||||
|
body.getBytes("UTF-8"));
|
||||||
byte[] pattern = new byte[] {};
|
byte[] pattern = new byte[] {};
|
||||||
repository.onMessage(message, pattern);
|
this.repository.onMessage(message, pattern);
|
||||||
|
|
||||||
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||||
principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(0);
|
assertThat(findByPrincipalName).hasSize(0);
|
||||||
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
||||||
@@ -166,17 +174,18 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByPrincipalNameNoPrincipalNameChange() throws Exception {
|
public void findByPrincipalNameNoPrincipalNameChange() throws Exception {
|
||||||
String principalName = "findByPrincipalNameNoPrincipalNameChange" + UUID.randomUUID();
|
String principalName = "findByPrincipalNameNoPrincipalNameChange"
|
||||||
RedisSession toSave = repository.createSession();
|
+ UUID.randomUUID();
|
||||||
|
RedisSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
toSave.setAttribute("other", "value");
|
toSave.setAttribute("other", "value");
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||||
principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
@@ -184,19 +193,20 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByPrincipalNameNoPrincipalNameChangeReload() throws Exception {
|
public void findByPrincipalNameNoPrincipalNameChangeReload() throws Exception {
|
||||||
String principalName = "findByPrincipalNameNoPrincipalNameChangeReload" + UUID.randomUUID();
|
String principalName = "findByPrincipalNameNoPrincipalNameChangeReload"
|
||||||
RedisSession toSave = repository.createSession();
|
+ UUID.randomUUID();
|
||||||
|
RedisSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
toSave = repository.getSession(toSave.getId());
|
toSave = this.repository.getSession(toSave.getId());
|
||||||
|
|
||||||
toSave.setAttribute("other", "value");
|
toSave.setAttribute("other", "value");
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||||
principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
@@ -205,16 +215,16 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
|
|||||||
@Test
|
@Test
|
||||||
public void findByDeletedPrincipalName() throws Exception {
|
public void findByDeletedPrincipalName() throws Exception {
|
||||||
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
|
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
|
||||||
RedisSession toSave = repository.createSession();
|
RedisSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
toSave.setAttribute(INDEX_NAME, null);
|
toSave.setAttribute(INDEX_NAME, null);
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||||
principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
}
|
}
|
||||||
@@ -223,19 +233,20 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
|
|||||||
public void findByChangedPrincipalName() throws Exception {
|
public void findByChangedPrincipalName() throws Exception {
|
||||||
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
|
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
|
||||||
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
|
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
|
||||||
RedisSession toSave = repository.createSession();
|
RedisSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
toSave.setAttribute(INDEX_NAME, principalNameChanged);
|
toSave.setAttribute(INDEX_NAME, principalNameChanged);
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||||
principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
|
|
||||||
findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME, principalNameChanged);
|
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||||
|
principalNameChanged);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
@@ -244,17 +255,17 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
|
|||||||
@Test
|
@Test
|
||||||
public void findByDeletedPrincipalNameReload() throws Exception {
|
public void findByDeletedPrincipalNameReload() throws Exception {
|
||||||
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
|
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
|
||||||
RedisSession toSave = repository.createSession();
|
RedisSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
RedisSession getSession = repository.getSession(toSave.getId());
|
RedisSession getSession = this.repository.getSession(toSave.getId());
|
||||||
getSession.setAttribute(INDEX_NAME, null);
|
getSession.setAttribute(INDEX_NAME, null);
|
||||||
repository.save(getSession);
|
this.repository.save(getSession);
|
||||||
|
|
||||||
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||||
principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
}
|
}
|
||||||
@@ -263,21 +274,22 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
|
|||||||
public void findByChangedPrincipalNameReload() throws Exception {
|
public void findByChangedPrincipalNameReload() throws Exception {
|
||||||
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
|
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
|
||||||
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
|
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
|
||||||
RedisSession toSave = repository.createSession();
|
RedisSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
RedisSession getSession = repository.getSession(toSave.getId());
|
RedisSession getSession = this.repository.getSession(toSave.getId());
|
||||||
|
|
||||||
getSession.setAttribute(INDEX_NAME, principalNameChanged);
|
getSession.setAttribute(INDEX_NAME, principalNameChanged);
|
||||||
repository.save(getSession);
|
this.repository.save(getSession);
|
||||||
|
|
||||||
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||||
principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
|
|
||||||
findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME, principalNameChanged);
|
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||||
|
principalNameChanged);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
@@ -285,21 +297,22 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findBySecurityPrincipalName() throws Exception {
|
public void findBySecurityPrincipalName() throws Exception {
|
||||||
RedisSession toSave = repository.createSession();
|
RedisSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||||
getSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
|
|
||||||
repository.delete(toSave.getId());
|
this.repository.delete(toSave.getId());
|
||||||
assertThat(registry.receivedEvent(toSave.getId())).isTrue();
|
assertThat(this.registry.receivedEvent(toSave.getId())).isTrue();
|
||||||
|
|
||||||
findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||||
|
getSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(0);
|
assertThat(findByPrincipalName).hasSize(0);
|
||||||
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
||||||
@@ -307,19 +320,21 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findBySecurityPrincipalNameExpireRemovesIndex() throws Exception {
|
public void findBySecurityPrincipalNameExpireRemovesIndex() throws Exception {
|
||||||
RedisSession toSave = repository.createSession();
|
RedisSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
String body = "spring:session:RedisOperationsSessionRepositoryITests:sessions:expires:" + toSave.getId();
|
String body = "spring:session:RedisOperationsSessionRepositoryITests:sessions:expires:"
|
||||||
|
+ toSave.getId();
|
||||||
String channel = ":expired";
|
String channel = ":expired";
|
||||||
DefaultMessage message = new DefaultMessage(channel.getBytes("UTF-8"), body.getBytes("UTF-8"));
|
DefaultMessage message = new DefaultMessage(channel.getBytes("UTF-8"),
|
||||||
|
body.getBytes("UTF-8"));
|
||||||
byte[] pattern = new byte[] {};
|
byte[] pattern = new byte[] {};
|
||||||
repository.onMessage(message, pattern);
|
this.repository.onMessage(message, pattern);
|
||||||
|
|
||||||
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||||
getSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(0);
|
assertThat(findByPrincipalName).hasSize(0);
|
||||||
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
||||||
@@ -327,35 +342,36 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByPrincipalNameNoSecurityPrincipalNameChange() throws Exception {
|
public void findByPrincipalNameNoSecurityPrincipalNameChange() throws Exception {
|
||||||
RedisSession toSave = repository.createSession();
|
RedisSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
toSave.setAttribute("other", "value");
|
toSave.setAttribute("other", "value");
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||||
getSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByPrincipalNameNoSecurityPrincipalNameChangeReload() throws Exception {
|
public void findByPrincipalNameNoSecurityPrincipalNameChangeReload()
|
||||||
RedisSession toSave = repository.createSession();
|
throws Exception {
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, context);
|
RedisSession toSave = this.repository.createSession();
|
||||||
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
toSave = repository.getSession(toSave.getId());
|
toSave = this.repository.getSession(toSave.getId());
|
||||||
|
|
||||||
toSave.setAttribute("other", "value");
|
toSave.setAttribute("other", "value");
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||||
getSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
@@ -363,35 +379,36 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByDeletedSecurityPrincipalName() throws Exception {
|
public void findByDeletedSecurityPrincipalName() throws Exception {
|
||||||
RedisSession toSave = repository.createSession();
|
RedisSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, null);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, null);
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||||
getSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByChangedSecurityPrincipalName() throws Exception {
|
public void findByChangedSecurityPrincipalName() throws Exception {
|
||||||
RedisSession toSave = repository.createSession();
|
RedisSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, changedContext);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext);
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||||
getSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
|
|
||||||
findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
|
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||||
|
getChangedSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
@@ -399,49 +416,50 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByDeletedSecurityPrincipalNameReload() throws Exception {
|
public void findByDeletedSecurityPrincipalNameReload() throws Exception {
|
||||||
RedisSession toSave = repository.createSession();
|
RedisSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
RedisSession getSession = repository.getSession(toSave.getId());
|
RedisSession getSession = this.repository.getSession(toSave.getId());
|
||||||
getSession.setAttribute(INDEX_NAME, null);
|
getSession.setAttribute(INDEX_NAME, null);
|
||||||
repository.save(getSession);
|
this.repository.save(getSession);
|
||||||
|
|
||||||
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||||
getChangedSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByChangedSecurityPrincipalNameReload() throws Exception {
|
public void findByChangedSecurityPrincipalNameReload() throws Exception {
|
||||||
RedisSession toSave = repository.createSession();
|
RedisSession toSave = this.repository.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
RedisSession getSession = repository.getSession(toSave.getId());
|
RedisSession getSession = this.repository.getSession(toSave.getId());
|
||||||
|
|
||||||
getSession.setAttribute(SPRING_SECURITY_CONTEXT, changedContext);
|
getSession.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext);
|
||||||
repository.save(getSession);
|
this.repository.save(getSession);
|
||||||
|
|
||||||
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||||
getSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
|
|
||||||
findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
|
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||||
|
getChangedSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getSecurityName() {
|
private String getSecurityName() {
|
||||||
return context.getAuthentication().getName();
|
return this.context.getAuthentication().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getChangedSecurityName() {
|
private String getChangedSecurityName() {
|
||||||
return changedContext.getAuthentication().getName();
|
return this.changedContext.getAuthentication().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
|||||||
@@ -62,7 +62,8 @@ public class EnableRedisHttpSessionExpireSessionDestroyedTests<S extends Expirin
|
|||||||
public void expireFiresSessionExpiredEvent() throws InterruptedException {
|
public void expireFiresSessionExpiredEvent() throws InterruptedException {
|
||||||
S toSave = this.repository.createSession();
|
S toSave = this.repository.createSession();
|
||||||
toSave.setAttribute("a", "b");
|
toSave.setAttribute("a", "b");
|
||||||
Authentication toSaveToken = new UsernamePasswordAuthenticationToken("user", "password", AuthorityUtils.createAuthorityList("ROLE_USER"));
|
Authentication toSaveToken = new UsernamePasswordAuthenticationToken("user",
|
||||||
|
"password", AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||||
SecurityContext toSaveContext = SecurityContextHolder.createEmptyContext();
|
SecurityContext toSaveContext = SecurityContextHolder.createEmptyContext();
|
||||||
toSaveContext.setAuthentication(toSaveToken);
|
toSaveContext.setAuthentication(toSaveToken);
|
||||||
toSave.setAttribute("SPRING_SECURITY_CONTEXT", toSaveContext);
|
toSave.setAttribute("SPRING_SECURITY_CONTEXT", toSaveContext);
|
||||||
@@ -86,7 +87,8 @@ public class EnableRedisHttpSessionExpireSessionDestroyedTests<S extends Expirin
|
|||||||
assertThat(this.registry.receivedEvent()).isTrue();
|
assertThat(this.registry.receivedEvent()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
static class SessionExpiredEventRegistry implements ApplicationListener<SessionExpiredEvent> {
|
static class SessionExpiredEventRegistry
|
||||||
|
implements ApplicationListener<SessionExpiredEvent> {
|
||||||
private boolean receivedEvent;
|
private boolean receivedEvent;
|
||||||
private Object lock;
|
private Object lock;
|
||||||
|
|
||||||
|
|||||||
@@ -53,9 +53,10 @@ public class RedisListenerContainerTaskExecutorITests {
|
|||||||
RedisOperations<Object, Object> redis;
|
RedisOperations<Object, Object> redis;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRedisDelEventsAreDispatchedInSessionTaskExecutor() throws InterruptedException {
|
public void testRedisDelEventsAreDispatchedInSessionTaskExecutor()
|
||||||
BoundSetOperations<Object, Object> ops = this.redis
|
throws InterruptedException {
|
||||||
.boundSetOps("spring:session:RedisListenerContainerTaskExecutorITests:expirations:dummy");
|
BoundSetOperations<Object, Object> ops = this.redis.boundSetOps(
|
||||||
|
"spring:session:RedisListenerContainerTaskExecutorITests:expirations:dummy");
|
||||||
ops.add("value");
|
ops.add("value");
|
||||||
ops.remove("value");
|
ops.remove("value");
|
||||||
assertThat(this.executor.taskDispatched()).isTrue();
|
assertThat(this.executor.taskDispatched()).isTrue();
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ import org.springframework.test.context.web.WebAppConfiguration;
|
|||||||
import org.springframework.util.SocketUtils;
|
import org.springframework.util.SocketUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Integration tests that check the underlying data source - in this case
|
* Integration tests that check the underlying data source - in this case Hazelcast
|
||||||
* Hazelcast Client.
|
* Client.
|
||||||
*
|
*
|
||||||
* @author Vedran Pavic
|
* @author Vedran Pavic
|
||||||
* @author Artem Bilan
|
* @author Artem Bilan
|
||||||
@@ -50,7 +50,6 @@ public class HazelcastClientRepositoryITests<S extends ExpiringSession>
|
|||||||
|
|
||||||
private static HazelcastInstance hazelcastInstance;
|
private static HazelcastInstance hazelcastInstance;
|
||||||
|
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setup() {
|
public static void setup() {
|
||||||
hazelcastInstance = HazelcastITestUtils.embeddedHazelcastServer(PORT);
|
hazelcastInstance = HazelcastITestUtils.embeddedHazelcastServer(PORT);
|
||||||
@@ -70,8 +69,7 @@ public class HazelcastClientRepositoryITests<S extends ExpiringSession>
|
|||||||
@Bean
|
@Bean
|
||||||
public HazelcastInstance embeddedHazelcastClient() {
|
public HazelcastInstance embeddedHazelcastClient() {
|
||||||
ClientConfig clientConfig = new ClientConfig();
|
ClientConfig clientConfig = new ClientConfig();
|
||||||
clientConfig.getNetworkConfig()
|
clientConfig.getNetworkConfig().addAddress("127.0.0.1:" + PORT);
|
||||||
.addAddress("127.0.0.1:" + PORT);
|
|
||||||
return HazelcastClient.newHazelcastClient(clientConfig);
|
return HazelcastClient.newHazelcastClient(clientConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,8 +39,7 @@ public final class HazelcastITestUtils {
|
|||||||
*/
|
*/
|
||||||
public static HazelcastInstance embeddedHazelcastServer(int port) {
|
public static HazelcastInstance embeddedHazelcastServer(int port) {
|
||||||
Config config = new Config();
|
Config config = new Config();
|
||||||
config.getNetworkConfig()
|
config.getNetworkConfig().setPort(port);
|
||||||
.setPort(port);
|
|
||||||
return Hazelcast.newHazelcastInstance(config);
|
return Hazelcast.newHazelcastInstance(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|||||||
import org.springframework.test.context.web.WebAppConfiguration;
|
import org.springframework.test.context.web.WebAppConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Integration tests that check the underlying data source - in this case
|
* Integration tests that check the underlying data source - in this case Hazelcast
|
||||||
* Hazelcast Server.
|
* Server.
|
||||||
*
|
*
|
||||||
* @author Tommy Ludwig
|
* @author Tommy Ludwig
|
||||||
* @author Vedran Pavic
|
* @author Vedran Pavic
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ import org.springframework.test.context.web.WebAppConfiguration;
|
|||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure that the appropriate SessionEvents are fired at the expected times.
|
* Ensure that the appropriate SessionEvents are fired at the expected times. Additionally
|
||||||
* Additionally ensure that the interactions with the {@link SessionRepository}
|
* ensure that the interactions with the {@link SessionRepository} abstraction behave as
|
||||||
* abstraction behave as expected after each SessionEvent.
|
* expected after each SessionEvent.
|
||||||
*
|
*
|
||||||
* @author Tommy Ludwig
|
* @author Tommy Ludwig
|
||||||
*/
|
*/
|
||||||
@@ -78,22 +78,27 @@ public class EnableHazelcastHttpSessionEventsTests<S extends ExpiringSession> {
|
|||||||
String expectedAttributeName = "a";
|
String expectedAttributeName = "a";
|
||||||
String expectedAttributeValue = "b";
|
String expectedAttributeValue = "b";
|
||||||
sessionToSave.setAttribute(expectedAttributeName, expectedAttributeValue);
|
sessionToSave.setAttribute(expectedAttributeName, expectedAttributeValue);
|
||||||
Authentication toSaveToken = new UsernamePasswordAuthenticationToken(username, "password", AuthorityUtils.createAuthorityList("ROLE_USER"));
|
Authentication toSaveToken = new UsernamePasswordAuthenticationToken(username,
|
||||||
|
"password", AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||||
SecurityContext toSaveContext = SecurityContextHolder.createEmptyContext();
|
SecurityContext toSaveContext = SecurityContextHolder.createEmptyContext();
|
||||||
toSaveContext.setAuthentication(toSaveToken);
|
toSaveContext.setAuthentication(toSaveToken);
|
||||||
sessionToSave.setAttribute("SPRING_SECURITY_CONTEXT", toSaveContext);
|
sessionToSave.setAttribute("SPRING_SECURITY_CONTEXT", toSaveContext);
|
||||||
sessionToSave.setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, username);
|
sessionToSave.setAttribute(
|
||||||
|
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, username);
|
||||||
|
|
||||||
this.repository.save(sessionToSave);
|
this.repository.save(sessionToSave);
|
||||||
|
|
||||||
assertThat(this.registry.receivedEvent(sessionToSave.getId())).isTrue();
|
assertThat(this.registry.receivedEvent(sessionToSave.getId())).isTrue();
|
||||||
assertThat(this.registry.getEvent(sessionToSave.getId())).isInstanceOf(SessionCreatedEvent.class);
|
assertThat(this.registry.getEvent(sessionToSave.getId()))
|
||||||
|
.isInstanceOf(SessionCreatedEvent.class);
|
||||||
|
|
||||||
Session session = this.repository.getSession(sessionToSave.getId());
|
Session session = this.repository.getSession(sessionToSave.getId());
|
||||||
|
|
||||||
assertThat(session.getId()).isEqualTo(sessionToSave.getId());
|
assertThat(session.getId()).isEqualTo(sessionToSave.getId());
|
||||||
assertThat(session.getAttributeNames()).isEqualTo(sessionToSave.getAttributeNames());
|
assertThat(session.getAttributeNames())
|
||||||
assertThat(session.getAttribute(expectedAttributeName)).isEqualTo(sessionToSave.getAttribute(expectedAttributeName));
|
.isEqualTo(sessionToSave.getAttributeNames());
|
||||||
|
assertThat(session.getAttribute(expectedAttributeName))
|
||||||
|
.isEqualTo(sessionToSave.getAttribute(expectedAttributeName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -103,13 +108,16 @@ public class EnableHazelcastHttpSessionEventsTests<S extends ExpiringSession> {
|
|||||||
this.repository.save(sessionToSave);
|
this.repository.save(sessionToSave);
|
||||||
|
|
||||||
assertThat(this.registry.receivedEvent(sessionToSave.getId())).isTrue();
|
assertThat(this.registry.receivedEvent(sessionToSave.getId())).isTrue();
|
||||||
assertThat(this.registry.getEvent(sessionToSave.getId())).isInstanceOf(SessionCreatedEvent.class);
|
assertThat(this.registry.getEvent(sessionToSave.getId()))
|
||||||
|
.isInstanceOf(SessionCreatedEvent.class);
|
||||||
this.registry.clear();
|
this.registry.clear();
|
||||||
|
|
||||||
assertThat(sessionToSave.getMaxInactiveIntervalInSeconds()).isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
assertThat(sessionToSave.getMaxInactiveIntervalInSeconds())
|
||||||
|
.isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
|
||||||
|
|
||||||
assertThat(this.registry.receivedEvent(sessionToSave.getId())).isTrue();
|
assertThat(this.registry.receivedEvent(sessionToSave.getId())).isTrue();
|
||||||
assertThat(this.registry.getEvent(sessionToSave.getId())).isInstanceOf(SessionExpiredEvent.class);
|
assertThat(this.registry.getEvent(sessionToSave.getId()))
|
||||||
|
.isInstanceOf(SessionExpiredEvent.class);
|
||||||
|
|
||||||
assertThat(this.repository.getSession(sessionToSave.getId())).isNull();
|
assertThat(this.repository.getSession(sessionToSave.getId())).isNull();
|
||||||
}
|
}
|
||||||
@@ -121,13 +129,15 @@ public class EnableHazelcastHttpSessionEventsTests<S extends ExpiringSession> {
|
|||||||
this.repository.save(sessionToSave);
|
this.repository.save(sessionToSave);
|
||||||
|
|
||||||
assertThat(this.registry.receivedEvent(sessionToSave.getId())).isTrue();
|
assertThat(this.registry.receivedEvent(sessionToSave.getId())).isTrue();
|
||||||
assertThat(this.registry.getEvent(sessionToSave.getId())).isInstanceOf(SessionCreatedEvent.class);
|
assertThat(this.registry.getEvent(sessionToSave.getId()))
|
||||||
|
.isInstanceOf(SessionCreatedEvent.class);
|
||||||
this.registry.clear();
|
this.registry.clear();
|
||||||
|
|
||||||
this.repository.delete(sessionToSave.getId());
|
this.repository.delete(sessionToSave.getId());
|
||||||
|
|
||||||
assertThat(this.registry.receivedEvent(sessionToSave.getId())).isTrue();
|
assertThat(this.registry.receivedEvent(sessionToSave.getId())).isTrue();
|
||||||
assertThat(this.registry.getEvent(sessionToSave.getId())).isInstanceOf(SessionDeletedEvent.class);
|
assertThat(this.registry.getEvent(sessionToSave.getId()))
|
||||||
|
.isInstanceOf(SessionDeletedEvent.class);
|
||||||
|
|
||||||
assertThat(this.repository.getSession(sessionToSave.getId())).isNull();
|
assertThat(this.repository.getSession(sessionToSave.getId())).isNull();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ import org.springframework.util.SocketUtils;
|
|||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the different configuration options for the
|
* Test the different configuration options for the {@link EnableHazelcastHttpSession}
|
||||||
* {@link EnableHazelcastHttpSession} annotation.
|
* annotation.
|
||||||
*
|
*
|
||||||
* @author Tommy Ludwig
|
* @author Tommy Ludwig
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -73,24 +73,27 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
@Before
|
@Before
|
||||||
public void setup() throws Exception {
|
public void setup() throws Exception {
|
||||||
this.context = SecurityContextHolder.createEmptyContext();
|
this.context = SecurityContextHolder.createEmptyContext();
|
||||||
this.context.setAuthentication(new UsernamePasswordAuthenticationToken(
|
this.context.setAuthentication(
|
||||||
"username-" + UUID.randomUUID(), "na", AuthorityUtils.createAuthorityList("ROLE_USER")));
|
new UsernamePasswordAuthenticationToken("username-" + UUID.randomUUID(),
|
||||||
|
"na", AuthorityUtils.createAuthorityList("ROLE_USER")));
|
||||||
|
|
||||||
this.changedContext = SecurityContextHolder.createEmptyContext();
|
this.changedContext = SecurityContextHolder.createEmptyContext();
|
||||||
this.changedContext.setAuthentication(new UsernamePasswordAuthenticationToken(
|
this.changedContext.setAuthentication(new UsernamePasswordAuthenticationToken(
|
||||||
"changedContext-" + UUID.randomUUID(), "na", AuthorityUtils.createAuthorityList("ROLE_USER")));
|
"changedContext-" + UUID.randomUUID(), "na",
|
||||||
|
AuthorityUtils.createAuthorityList("ROLE_USER")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void saves() throws InterruptedException {
|
public void saves() throws InterruptedException {
|
||||||
String username = "saves-" + System.currentTimeMillis();
|
String username = "saves-" + System.currentTimeMillis();
|
||||||
|
|
||||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
|
||||||
|
.createSession();
|
||||||
String expectedAttributeName = "a";
|
String expectedAttributeName = "a";
|
||||||
String expectedAttributeValue = "b";
|
String expectedAttributeValue = "b";
|
||||||
toSave.setAttribute(expectedAttributeName, expectedAttributeValue);
|
toSave.setAttribute(expectedAttributeName, expectedAttributeValue);
|
||||||
Authentication toSaveToken = new UsernamePasswordAuthenticationToken(username, "password",
|
Authentication toSaveToken = new UsernamePasswordAuthenticationToken(username,
|
||||||
AuthorityUtils.createAuthorityList("ROLE_USER"));
|
"password", AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||||
SecurityContext toSaveContext = SecurityContextHolder.createEmptyContext();
|
SecurityContext toSaveContext = SecurityContextHolder.createEmptyContext();
|
||||||
toSaveContext.setAuthentication(toSaveToken);
|
toSaveContext.setAuthentication(toSaveToken);
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, toSaveContext);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, toSaveContext);
|
||||||
@@ -102,7 +105,8 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
|
|
||||||
assertThat(session.getId()).isEqualTo(toSave.getId());
|
assertThat(session.getId()).isEqualTo(toSave.getId());
|
||||||
assertThat(session.getAttributeNames()).isEqualTo(toSave.getAttributeNames());
|
assertThat(session.getAttributeNames()).isEqualTo(toSave.getAttributeNames());
|
||||||
assertThat(session.getAttribute(expectedAttributeName)).isEqualTo(toSave.getAttribute(expectedAttributeName));
|
assertThat(session.getAttribute(expectedAttributeName))
|
||||||
|
.isEqualTo(toSave.getAttribute(expectedAttributeName));
|
||||||
|
|
||||||
this.repository.delete(toSave.getId());
|
this.repository.delete(toSave.getId());
|
||||||
|
|
||||||
@@ -111,7 +115,8 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void putAllOnSingleAttrDoesNotRemoveOld() {
|
public void putAllOnSingleAttrDoesNotRemoveOld() {
|
||||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
|
||||||
|
.createSession();
|
||||||
toSave.setAttribute("a", "b");
|
toSave.setAttribute("a", "b");
|
||||||
|
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
@@ -133,20 +138,22 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
@Test
|
@Test
|
||||||
public void findByPrincipalName() throws Exception {
|
public void findByPrincipalName() throws Exception {
|
||||||
String principalName = "findByPrincipalName" + UUID.randomUUID();
|
String principalName = "findByPrincipalName" + UUID.randomUUID();
|
||||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
|
||||||
|
.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
|
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
|
||||||
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
|
|
||||||
this.repository.delete(toSave.getId());
|
this.repository.delete(toSave.getId());
|
||||||
|
|
||||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||||
|
principalName);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(0);
|
assertThat(findByPrincipalName).hasSize(0);
|
||||||
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
||||||
@@ -154,17 +161,19 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByPrincipalNameExpireRemovesIndex() throws Exception {
|
public void findByPrincipalNameExpireRemovesIndex() throws Exception {
|
||||||
String principalName = "findByPrincipalNameExpireRemovesIndex" + UUID.randomUUID();
|
String principalName = "findByPrincipalNameExpireRemovesIndex"
|
||||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
+ UUID.randomUUID();
|
||||||
|
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
|
||||||
|
.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
toSave.setLastAccessedTime(System.currentTimeMillis() -
|
toSave.setLastAccessedTime(System.currentTimeMillis()
|
||||||
(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS * 1000 + 1000));
|
- (MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS * 1000 + 1000));
|
||||||
|
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
this.repository.cleanUpExpiredSessions();
|
this.repository.cleanUpExpiredSessions();
|
||||||
|
|
||||||
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
|
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
|
||||||
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(0);
|
assertThat(findByPrincipalName).hasSize(0);
|
||||||
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
||||||
@@ -172,8 +181,10 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByPrincipalNameNoPrincipalNameChange() throws Exception {
|
public void findByPrincipalNameNoPrincipalNameChange() throws Exception {
|
||||||
String principalName = "findByPrincipalNameNoPrincipalNameChange" + UUID.randomUUID();
|
String principalName = "findByPrincipalNameNoPrincipalNameChange"
|
||||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
+ UUID.randomUUID();
|
||||||
|
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
|
||||||
|
.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
@@ -181,8 +192,8 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
toSave.setAttribute("other", "value");
|
toSave.setAttribute("other", "value");
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
|
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
|
||||||
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
@@ -190,8 +201,10 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByPrincipalNameNoPrincipalNameChangeReload() throws Exception {
|
public void findByPrincipalNameNoPrincipalNameChangeReload() throws Exception {
|
||||||
String principalName = "findByPrincipalNameNoPrincipalNameChangeReload" + UUID.randomUUID();
|
String principalName = "findByPrincipalNameNoPrincipalNameChangeReload"
|
||||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
+ UUID.randomUUID();
|
||||||
|
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
|
||||||
|
.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
@@ -201,8 +214,8 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
toSave.setAttribute("other", "value");
|
toSave.setAttribute("other", "value");
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
|
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
|
||||||
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
@@ -211,7 +224,8 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
@Test
|
@Test
|
||||||
public void findByDeletedPrincipalName() throws Exception {
|
public void findByDeletedPrincipalName() throws Exception {
|
||||||
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
|
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
|
||||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
|
||||||
|
.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
@@ -219,8 +233,8 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
toSave.setAttribute(INDEX_NAME, null);
|
toSave.setAttribute(INDEX_NAME, null);
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
|
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
|
||||||
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
}
|
}
|
||||||
@@ -229,7 +243,8 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
public void findByChangedPrincipalName() throws Exception {
|
public void findByChangedPrincipalName() throws Exception {
|
||||||
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
|
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
|
||||||
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
|
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
|
||||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
|
||||||
|
.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
@@ -237,11 +252,12 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
toSave.setAttribute(INDEX_NAME, principalNameChanged);
|
toSave.setAttribute(INDEX_NAME, principalNameChanged);
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
|
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
|
||||||
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
|
|
||||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalNameChanged);
|
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||||
|
principalNameChanged);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
@@ -250,17 +266,19 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
@Test
|
@Test
|
||||||
public void findByDeletedPrincipalNameReload() throws Exception {
|
public void findByDeletedPrincipalNameReload() throws Exception {
|
||||||
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
|
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
|
||||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
|
||||||
|
.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
JdbcOperationsSessionRepository.JdbcSession getSession = this.repository.getSession(toSave.getId());
|
JdbcOperationsSessionRepository.JdbcSession getSession = this.repository
|
||||||
|
.getSession(toSave.getId());
|
||||||
getSession.setAttribute(INDEX_NAME, null);
|
getSession.setAttribute(INDEX_NAME, null);
|
||||||
this.repository.save(getSession);
|
this.repository.save(getSession);
|
||||||
|
|
||||||
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
|
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
|
||||||
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
}
|
}
|
||||||
@@ -269,21 +287,24 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
public void findByChangedPrincipalNameReload() throws Exception {
|
public void findByChangedPrincipalNameReload() throws Exception {
|
||||||
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
|
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
|
||||||
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
|
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
|
||||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
|
||||||
|
.createSession();
|
||||||
toSave.setAttribute(INDEX_NAME, principalName);
|
toSave.setAttribute(INDEX_NAME, principalName);
|
||||||
|
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
JdbcOperationsSessionRepository.JdbcSession getSession = this.repository.getSession(toSave.getId());
|
JdbcOperationsSessionRepository.JdbcSession getSession = this.repository
|
||||||
|
.getSession(toSave.getId());
|
||||||
|
|
||||||
getSession.setAttribute(INDEX_NAME, principalNameChanged);
|
getSession.setAttribute(INDEX_NAME, principalNameChanged);
|
||||||
this.repository.save(getSession);
|
this.repository.save(getSession);
|
||||||
|
|
||||||
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
|
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
|
||||||
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
|
|
||||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalNameChanged);
|
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||||
|
principalNameChanged);
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
@@ -291,20 +312,22 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findBySecurityPrincipalName() throws Exception {
|
public void findBySecurityPrincipalName() throws Exception {
|
||||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
|
||||||
|
.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
|
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
|
||||||
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
|
|
||||||
this.repository.delete(toSave.getId());
|
this.repository.delete(toSave.getId());
|
||||||
|
|
||||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||||
|
getSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(0);
|
assertThat(findByPrincipalName).hasSize(0);
|
||||||
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
||||||
@@ -312,16 +335,17 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findBySecurityPrincipalNameExpireRemovesIndex() throws Exception {
|
public void findBySecurityPrincipalNameExpireRemovesIndex() throws Exception {
|
||||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
|
||||||
|
.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
toSave.setLastAccessedTime(System.currentTimeMillis() -
|
toSave.setLastAccessedTime(System.currentTimeMillis()
|
||||||
(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS * 1000 + 1000));
|
- (MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS * 1000 + 1000));
|
||||||
|
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
this.repository.cleanUpExpiredSessions();
|
this.repository.cleanUpExpiredSessions();
|
||||||
|
|
||||||
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
|
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
|
||||||
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(0);
|
assertThat(findByPrincipalName).hasSize(0);
|
||||||
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
||||||
@@ -329,7 +353,8 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByPrincipalNameNoSecurityPrincipalNameChange() throws Exception {
|
public void findByPrincipalNameNoSecurityPrincipalNameChange() throws Exception {
|
||||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
|
||||||
|
.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
@@ -337,16 +362,18 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
toSave.setAttribute("other", "value");
|
toSave.setAttribute("other", "value");
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
|
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
|
||||||
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByPrincipalNameNoSecurityPrincipalNameChangeReload() throws Exception {
|
public void findByPrincipalNameNoSecurityPrincipalNameChangeReload()
|
||||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
throws Exception {
|
||||||
|
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
|
||||||
|
.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
@@ -356,8 +383,8 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
toSave.setAttribute("other", "value");
|
toSave.setAttribute("other", "value");
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
|
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
|
||||||
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
@@ -365,7 +392,8 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByDeletedSecurityPrincipalName() throws Exception {
|
public void findByDeletedSecurityPrincipalName() throws Exception {
|
||||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
|
||||||
|
.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
@@ -373,15 +401,16 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, null);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, null);
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
|
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
|
||||||
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByChangedSecurityPrincipalName() throws Exception {
|
public void findByChangedSecurityPrincipalName() throws Exception {
|
||||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
|
||||||
|
.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
@@ -389,11 +418,12 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext);
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
|
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
|
||||||
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
|
|
||||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
|
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||||
|
getChangedSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
@@ -401,38 +431,43 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByDeletedSecurityPrincipalNameReload() throws Exception {
|
public void findByDeletedSecurityPrincipalNameReload() throws Exception {
|
||||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
|
||||||
|
.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
JdbcOperationsSessionRepository.JdbcSession getSession = this.repository.getSession(toSave.getId());
|
JdbcOperationsSessionRepository.JdbcSession getSession = this.repository
|
||||||
|
.getSession(toSave.getId());
|
||||||
getSession.setAttribute(INDEX_NAME, null);
|
getSession.setAttribute(INDEX_NAME, null);
|
||||||
this.repository.save(getSession);
|
this.repository.save(getSession);
|
||||||
|
|
||||||
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
|
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
|
||||||
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByChangedSecurityPrincipalNameReload() throws Exception {
|
public void findByChangedSecurityPrincipalNameReload() throws Exception {
|
||||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
|
||||||
|
.createSession();
|
||||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||||
|
|
||||||
this.repository.save(toSave);
|
this.repository.save(toSave);
|
||||||
|
|
||||||
JdbcOperationsSessionRepository.JdbcSession getSession = this.repository.getSession(toSave.getId());
|
JdbcOperationsSessionRepository.JdbcSession getSession = this.repository
|
||||||
|
.getSession(toSave.getId());
|
||||||
|
|
||||||
getSession.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext);
|
getSession.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext);
|
||||||
repository.save(getSession);
|
this.repository.save(getSession);
|
||||||
|
|
||||||
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
|
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
|
||||||
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||||
assertThat(findByPrincipalName).isEmpty();
|
assertThat(findByPrincipalName).isEmpty();
|
||||||
|
|
||||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
|
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||||
|
getChangedSecurityName());
|
||||||
|
|
||||||
assertThat(findByPrincipalName).hasSize(1);
|
assertThat(findByPrincipalName).hasSize(1);
|
||||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||||
@@ -452,10 +487,8 @@ public class JdbcOperationsSessionRepositoryITests {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public EmbeddedDatabase dataSource() {
|
public EmbeddedDatabase dataSource() {
|
||||||
return new EmbeddedDatabaseBuilder()
|
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2)
|
||||||
.setType(EmbeddedDatabaseType.H2)
|
.addScript("org/springframework/session/jdbc/schema-h2.sql").build();
|
||||||
.addScript("org/springframework/session/jdbc/schema-h2.sql")
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|||||||
@@ -17,7 +17,8 @@
|
|||||||
package org.springframework.session;
|
package org.springframework.session;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link Session} that contains additional attributes that are useful for determining if a session is expired.
|
* A {@link Session} that contains additional attributes that are useful for determining
|
||||||
|
* if a session is expired.
|
||||||
*
|
*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
@@ -25,37 +26,47 @@ package org.springframework.session;
|
|||||||
public interface ExpiringSession extends Session {
|
public interface ExpiringSession extends Session {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the time when this session was created in milliseconds since midnight of 1/1/1970 GMT.
|
* Gets the time when this session was created in milliseconds since midnight of
|
||||||
|
* 1/1/1970 GMT.
|
||||||
*
|
*
|
||||||
* @return the time when this session was created in milliseconds since midnight of 1/1/1970 GMT.
|
* @return the time when this session was created in milliseconds since midnight of
|
||||||
|
* 1/1/1970 GMT.
|
||||||
*/
|
*/
|
||||||
long getCreationTime();
|
long getCreationTime();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the last accessed time in milliseconds since midnight of 1/1/1970 GMT.
|
* Sets the last accessed time in milliseconds since midnight of 1/1/1970 GMT.
|
||||||
*
|
*
|
||||||
* @param lastAccessedTime the last accessed time in milliseconds since midnight of 1/1/1970 GMT
|
* @param lastAccessedTime the last accessed time in milliseconds since midnight of
|
||||||
|
* 1/1/1970 GMT
|
||||||
*/
|
*/
|
||||||
void setLastAccessedTime(long lastAccessedTime);
|
void setLastAccessedTime(long lastAccessedTime);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the last time this {@link Session} was accessed expressed in milliseconds since midnight of 1/1/1970 GMT.
|
* Gets the last time this {@link Session} was accessed expressed in milliseconds
|
||||||
|
* since midnight of 1/1/1970 GMT.
|
||||||
*
|
*
|
||||||
* @return the last time the client sent a request associated with the session expressed in milliseconds since midnight of 1/1/1970 GMT
|
* @return the last time the client sent a request associated with the session
|
||||||
|
* expressed in milliseconds since midnight of 1/1/1970 GMT
|
||||||
*/
|
*/
|
||||||
long getLastAccessedTime();
|
long getLastAccessedTime();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the maximum inactive interval in seconds between requests before this session will be invalidated. A negative time indicates that the session will never timeout.
|
* Sets the maximum inactive interval in seconds between requests before this session
|
||||||
|
* will be invalidated. A negative time indicates that the session will never timeout.
|
||||||
*
|
*
|
||||||
* @param interval the number of seconds that the {@link Session} should be kept alive between client requests.
|
* @param interval the number of seconds that the {@link Session} should be kept alive
|
||||||
|
* between client requests.
|
||||||
*/
|
*/
|
||||||
void setMaxInactiveIntervalInSeconds(int interval);
|
void setMaxInactiveIntervalInSeconds(int interval);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the maximum inactive interval in seconds between requests before this session will be invalidated. A negative time indicates that the session will never timeout.
|
* Gets the maximum inactive interval in seconds between requests before this session
|
||||||
|
* will be invalidated. A negative time indicates that the session will never timeout.
|
||||||
*
|
*
|
||||||
* @return the maximum inactive interval in seconds between requests before this session will be invalidated. A negative time indicates that the session will never timeout.
|
* @return the maximum inactive interval in seconds between requests before this
|
||||||
|
* session will be invalidated. A negative time indicates that the session will never
|
||||||
|
* timeout.
|
||||||
*/
|
*/
|
||||||
int getMaxInactiveIntervalInSeconds();
|
int getMaxInactiveIntervalInSeconds();
|
||||||
|
|
||||||
|
|||||||
@@ -19,16 +19,16 @@ package org.springframework.session;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extends a basic {@link SessionRepository} to allow finding a session id by
|
* Extends a basic {@link SessionRepository} to allow finding a session id by the
|
||||||
* the principal name. The principal name is defined by the {@link Session}
|
* principal name. The principal name is defined by the {@link Session} attribute with the
|
||||||
* attribute with the name {@link FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME}.
|
* name {@link FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME}.
|
||||||
*
|
*
|
||||||
* @param <S>
|
* @param <S> the type of Session being managed by this
|
||||||
* the type of Session being managed by this
|
|
||||||
* {@link FindByIndexNameSessionRepository}
|
* {@link FindByIndexNameSessionRepository}
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
public interface FindByIndexNameSessionRepository<S extends Session> extends SessionRepository<S> {
|
public interface FindByIndexNameSessionRepository<S extends Session>
|
||||||
|
extends SessionRepository<S> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -37,28 +37,27 @@ public interface FindByIndexNameSessionRepository<S extends Session> extends Ses
|
|||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* It is the responsibility of the developer to ensure the attribute
|
* It is the responsibility of the developer to ensure the attribute is populated
|
||||||
* is populated since Spring Session is not aware of the authentication
|
* since Spring Session is not aware of the authentication mechanism being used.
|
||||||
* mechanism being used.
|
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
String PRINCIPAL_NAME_INDEX_NAME = FindByIndexNameSessionRepository.class.getName().concat(".PRINCIPAL_NAME_INDEX_NAME");
|
String PRINCIPAL_NAME_INDEX_NAME = FindByIndexNameSessionRepository.class.getName()
|
||||||
|
.concat(".PRINCIPAL_NAME_INDEX_NAME");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a Map of the session id to the {@link Session} of all sessions that
|
* Find a Map of the session id to the {@link Session} of all sessions that contain
|
||||||
* contain the session attribute with the name
|
* the session attribute with the name
|
||||||
* {@link FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME} and
|
* {@link FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME} and the value of
|
||||||
* the value of the specified principal name.
|
* the specified principal name.
|
||||||
*
|
*
|
||||||
* @param indexName
|
* @param indexName the name if the index (i.e.
|
||||||
* the name if the index (i.e. {@link FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME})
|
* {@link FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME})
|
||||||
* @param indexValue the value of the index to search for.
|
* @param indexValue the value of the index to search for.
|
||||||
* @return a Map (never null) of the session id to the {@link Session} of
|
* @return a Map (never null) of the session id to the {@link Session} of all sessions
|
||||||
* all sessions that contain the session specified index name and
|
* that contain the session specified index name and the value of the specified index
|
||||||
* the value of the specified index name. If no results are found,
|
* name. If no results are found, an empty Map is returned.
|
||||||
* an empty Map is returned.
|
|
||||||
*/
|
*/
|
||||||
Map<String, S> findByIndexNameAndIndexValue(String indexName, String indexValue);
|
Map<String, S> findByIndexNameAndIndexValue(String indexName, String indexValue);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* A {@link Session} implementation that is backed by a {@link java.util.Map}. The defaults for the properties are:
|
* A {@link Session} implementation that is backed by a {@link java.util.Map}. The
|
||||||
|
* defaults for the properties are:
|
||||||
* </p>
|
* </p>
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>id - a secure random generated id</li>
|
* <li>id - a secure random generated id</li>
|
||||||
@@ -35,7 +36,8 @@ import java.util.concurrent.TimeUnit;
|
|||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* This implementation has no synchronization, so it is best to use the copy constructor when working on multiple threads.
|
* This implementation has no synchronization, so it is best to use the copy constructor
|
||||||
|
* when working on multiple threads.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
@@ -65,9 +67,9 @@ public final class MapSession implements ExpiringSession, Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance with the specified id. This is preferred to the
|
* Creates a new instance with the specified id. This is preferred to the default
|
||||||
* default constructor when the id is known to prevent unnecessary consumption on
|
* constructor when the id is known to prevent unnecessary consumption on entropy
|
||||||
* entropy which can be slow.
|
* which can be slow.
|
||||||
*
|
*
|
||||||
* @param id the identifier to use
|
* @param id the identifier to use
|
||||||
*/
|
*/
|
||||||
@@ -78,14 +80,16 @@ public final class MapSession implements ExpiringSession, Serializable {
|
|||||||
/**
|
/**
|
||||||
* Creates a new instance from the provided {@link Session}.
|
* Creates a new instance from the provided {@link Session}.
|
||||||
*
|
*
|
||||||
* @param session the {@link Session} to initialize this {@link Session} with. Cannot be null.
|
* @param session the {@link Session} to initialize this {@link Session} with. Cannot
|
||||||
|
* be null.
|
||||||
*/
|
*/
|
||||||
public MapSession(ExpiringSession session) {
|
public MapSession(ExpiringSession session) {
|
||||||
if (session == null) {
|
if (session == null) {
|
||||||
throw new IllegalArgumentException("session cannot be null");
|
throw new IllegalArgumentException("session cannot be null");
|
||||||
}
|
}
|
||||||
this.id = session.getId();
|
this.id = session.getId();
|
||||||
this.sessionAttrs = new HashMap<String, Object>(session.getAttributeNames().size());
|
this.sessionAttrs = new HashMap<String, Object>(
|
||||||
|
session.getAttributeNames().size());
|
||||||
for (String attrName : session.getAttributeNames()) {
|
for (String attrName : session.getAttributeNames()) {
|
||||||
Object attrValue = session.getAttribute(attrName);
|
Object attrValue = session.getAttribute(attrName);
|
||||||
this.sessionAttrs.put(attrName, attrValue);
|
this.sessionAttrs.put(attrName, attrValue);
|
||||||
@@ -127,7 +131,8 @@ public final class MapSession implements ExpiringSession, Serializable {
|
|||||||
if (this.maxInactiveInterval < 0) {
|
if (this.maxInactiveInterval < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return now - TimeUnit.SECONDS.toMillis(this.maxInactiveInterval) >= this.lastAccessedTime;
|
return now - TimeUnit.SECONDS
|
||||||
|
.toMillis(this.maxInactiveInterval) >= this.lastAccessedTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@@ -153,15 +158,19 @@ public final class MapSession implements ExpiringSession, Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the time that this {@link Session} was created in milliseconds since midnight of 1/1/1970 GMT. The default is when the {@link Session} was instantiated.
|
* Sets the time that this {@link Session} was created in milliseconds since midnight
|
||||||
* @param creationTime the time that this {@link Session} was created in milliseconds since midnight of 1/1/1970 GMT.
|
* of 1/1/1970 GMT. The default is when the {@link Session} was instantiated.
|
||||||
|
* @param creationTime the time that this {@link Session} was created in milliseconds
|
||||||
|
* since midnight of 1/1/1970 GMT.
|
||||||
*/
|
*/
|
||||||
public void setCreationTime(long creationTime) {
|
public void setCreationTime(long creationTime) {
|
||||||
this.creationTime = creationTime;
|
this.creationTime = creationTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the identifier for this {@link Session}. The id should be a secure random generated value to prevent malicious users from guessing this value. The default is a secure random generated identifier.
|
* Sets the identifier for this {@link Session}. The id should be a secure random
|
||||||
|
* generated value to prevent malicious users from guessing this value. The default is
|
||||||
|
* a secure random generated identifier.
|
||||||
*
|
*
|
||||||
* @param id the identifier for this session.
|
* @param id the identifier for this session.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -23,12 +23,14 @@ import org.springframework.session.events.SessionDeletedEvent;
|
|||||||
import org.springframework.session.events.SessionExpiredEvent;
|
import org.springframework.session.events.SessionExpiredEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link SessionRepository} backed by a {@link java.util.Map} and that uses a {@link MapSession}. By default a
|
* A {@link SessionRepository} backed by a {@link java.util.Map} and that uses a
|
||||||
* {@link java.util.concurrent.ConcurrentHashMap} is used, but a custom {@link java.util.Map} can be injected to use
|
* {@link MapSession}. By default a {@link java.util.concurrent.ConcurrentHashMap} is
|
||||||
* distributed maps provided by NoSQL stores like Redis and Hazelcast.
|
* used, but a custom {@link java.util.Map} can be injected to use distributed maps
|
||||||
|
* provided by NoSQL stores like Redis and Hazelcast.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* The implementation does NOT support firing {@link SessionDeletedEvent} or {@link SessionExpiredEvent}.
|
* The implementation does NOT support firing {@link SessionDeletedEvent} or
|
||||||
|
* {@link SessionExpiredEvent}.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
@@ -36,7 +38,8 @@ import org.springframework.session.events.SessionExpiredEvent;
|
|||||||
*/
|
*/
|
||||||
public class MapSessionRepository implements SessionRepository<ExpiringSession> {
|
public class MapSessionRepository implements SessionRepository<ExpiringSession> {
|
||||||
/**
|
/**
|
||||||
* If non-null, this value is used to override {@link ExpiringSession#setMaxInactiveIntervalInSeconds(int)}.
|
* If non-null, this value is used to override
|
||||||
|
* {@link ExpiringSession#setMaxInactiveIntervalInSeconds(int)}.
|
||||||
*/
|
*/
|
||||||
private Integer defaultMaxInactiveInterval;
|
private Integer defaultMaxInactiveInterval;
|
||||||
|
|
||||||
@@ -50,7 +53,8 @@ public class MapSessionRepository implements SessionRepository<ExpiringSession>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance backed by the provided {@link java.util.Map}. This allows injecting a distributed {@link java.util.Map}.
|
* Creates a new instance backed by the provided {@link java.util.Map}. This allows
|
||||||
|
* injecting a distributed {@link java.util.Map}.
|
||||||
*
|
*
|
||||||
* @param sessions the {@link java.util.Map} to use. Cannot be null.
|
* @param sessions the {@link java.util.Map} to use. Cannot be null.
|
||||||
*/
|
*/
|
||||||
@@ -62,8 +66,10 @@ public class MapSessionRepository implements SessionRepository<ExpiringSession>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If non-null, this value is used to override {@link ExpiringSession#setMaxInactiveIntervalInSeconds(int)}.
|
* If non-null, this value is used to override
|
||||||
* @param defaultMaxInactiveInterval the number of seconds that the {@link Session} should be kept alive between client requests.
|
* {@link ExpiringSession#setMaxInactiveIntervalInSeconds(int)}.
|
||||||
|
* @param defaultMaxInactiveInterval the number of seconds that the {@link Session}
|
||||||
|
* should be kept alive between client requests.
|
||||||
*/
|
*/
|
||||||
public void setDefaultMaxInactiveInterval(int defaultMaxInactiveInterval) {
|
public void setDefaultMaxInactiveInterval(int defaultMaxInactiveInterval) {
|
||||||
this.defaultMaxInactiveInterval = Integer.valueOf(defaultMaxInactiveInterval);
|
this.defaultMaxInactiveInterval = Integer.valueOf(defaultMaxInactiveInterval);
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ package org.springframework.session;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a way to identify a user in an agnostic way. This allows the session to be used by an HttpSession, WebSocket
|
* Provides a way to identify a user in an agnostic way. This allows the session to be
|
||||||
* Session, or even non web related sessions.
|
* used by an HttpSession, WebSocket Session, or even non web related sessions.
|
||||||
*
|
*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
@@ -35,16 +35,20 @@ public interface Session {
|
|||||||
String getId();
|
String getId();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the Object associated with the specified name or null if no Object is associated to that name.
|
* Gets the Object associated with the specified name or null if no Object is
|
||||||
|
* associated to that name.
|
||||||
*
|
*
|
||||||
* @param attributeName the name of the attribute to get
|
* @param attributeName the name of the attribute to get
|
||||||
* @return the Object associated with the specified name or null if no Object is associated to that name
|
* @return the Object associated with the specified name or null if no Object is
|
||||||
|
* associated to that name
|
||||||
* @param <T> The return type of the attribute
|
* @param <T> The return type of the attribute
|
||||||
*/
|
*/
|
||||||
<T> T getAttribute(String attributeName);
|
<T> T getAttribute(String attributeName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the attribute names that have a value associated with it. Each value can be passed into {@link org.springframework.session.Session#getAttribute(String)} to obtain the attribute value.
|
* Gets the attribute names that have a value associated with it. Each value can be
|
||||||
|
* passed into {@link org.springframework.session.Session#getAttribute(String)} to
|
||||||
|
* obtain the attribute value.
|
||||||
*
|
*
|
||||||
* @return the attribute names that have a value associated with it.
|
* @return the attribute names that have a value associated with it.
|
||||||
* @see #getAttribute(String)
|
* @see #getAttribute(String)
|
||||||
@@ -52,10 +56,13 @@ public interface Session {
|
|||||||
Set<String> getAttributeNames();
|
Set<String> getAttributeNames();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the attribute value for the provided attribute name. If the attributeValue is null, it has the same result as removing the attribute with {@link org.springframework.session.Session#removeAttribute(String)} .
|
* Sets the attribute value for the provided attribute name. If the attributeValue is
|
||||||
|
* null, it has the same result as removing the attribute with
|
||||||
|
* {@link org.springframework.session.Session#removeAttribute(String)} .
|
||||||
*
|
*
|
||||||
* @param attributeName the attribute name to set
|
* @param attributeName the attribute name to set
|
||||||
* @param attributeValue the value of the attribute to set. If null, the attribute will be removed.
|
* @param attributeValue the value of the attribute to set. If null, the attribute
|
||||||
|
* will be removed.
|
||||||
*/
|
*/
|
||||||
void setAttribute(String attributeName, Object attributeValue);
|
void setAttribute(String attributeName, Object attributeValue);
|
||||||
|
|
||||||
|
|||||||
@@ -26,22 +26,28 @@ package org.springframework.session;
|
|||||||
public interface SessionRepository<S extends Session> {
|
public interface SessionRepository<S extends Session> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link Session} that is capable of being persisted by this {@link SessionRepository}.
|
* Creates a new {@link Session} that is capable of being persisted by this
|
||||||
|
* {@link SessionRepository}.
|
||||||
*
|
*
|
||||||
* <p>This allows optimizations and customizations in how the {@link Session} is persisted. For example, the
|
* <p>
|
||||||
* implementation returned might keep track of the changes ensuring that only the delta needs to be persisted on
|
* This allows optimizations and customizations in how the {@link Session} is
|
||||||
* a save.</p>
|
* persisted. For example, the implementation returned might keep track of the changes
|
||||||
|
* ensuring that only the delta needs to be persisted on a save.
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @return a new {@link Session} that is capable of being persisted by this {@link SessionRepository}
|
* @return a new {@link Session} that is capable of being persisted by this
|
||||||
|
* {@link SessionRepository}
|
||||||
*/
|
*/
|
||||||
S createSession();
|
S createSession();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures the {@link Session} created by {@link org.springframework.session.SessionRepository#createSession()} is saved.
|
* Ensures the {@link Session} created by
|
||||||
|
* {@link org.springframework.session.SessionRepository#createSession()} is saved.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Some implementations may choose to save as the {@link Session} is updated by returning a {@link Session} that
|
* Some implementations may choose to save as the {@link Session} is updated by
|
||||||
* immediately persists any changes. In this case, this method may not actually do anything.
|
* returning a {@link Session} that immediately persists any changes. In this case,
|
||||||
|
* this method may not actually do anything.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param session the {@link Session} to save
|
* @param session the {@link Session} to save
|
||||||
@@ -49,15 +55,18 @@ public interface SessionRepository<S extends Session> {
|
|||||||
void save(S session);
|
void save(S session);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the {@link Session} by the {@link Session#getId()} or null if no {@link Session} is found.
|
* Gets the {@link Session} by the {@link Session#getId()} or null if no
|
||||||
|
* {@link Session} is found.
|
||||||
*
|
*
|
||||||
* @param id the {@link org.springframework.session.Session#getId()} to lookup
|
* @param id the {@link org.springframework.session.Session#getId()} to lookup
|
||||||
* @return the {@link Session} by the {@link Session#getId()} or null if no {@link Session} is found.
|
* @return the {@link Session} by the {@link Session#getId()} or null if no
|
||||||
|
* {@link Session} is found.
|
||||||
*/
|
*/
|
||||||
S getSession(String id);
|
S getSession(String id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes the {@link Session} with the given {@link Session#getId()} or does nothing if the {@link Session} is not found.
|
* Deletes the {@link Session} with the given {@link Session#getId()} or does nothing
|
||||||
|
* if the {@link Session} is not found.
|
||||||
* @param id the {@link org.springframework.session.Session#getId()} to delete
|
* @param id the {@link org.springframework.session.Session#getId()} to delete
|
||||||
*/
|
*/
|
||||||
void delete(String id);
|
void delete(String id);
|
||||||
|
|||||||
@@ -28,10 +28,9 @@ import org.springframework.session.events.SessionDestroyedEvent;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Add this annotation to an {@code @Configuration} class to expose the
|
* Add this annotation to an {@code @Configuration} class to expose the
|
||||||
* SessionRepositoryFilter as a bean named "springSessionRepositoryFilter" and
|
* SessionRepositoryFilter as a bean named "springSessionRepositoryFilter" and backed by a
|
||||||
* backed by a user provided implementation of {@link SessionRepository}. In
|
* user provided implementation of {@link SessionRepository}. In order to leverage the
|
||||||
* order to leverage the annotation, a single {@link SessionRepository} bean
|
* annotation, a single {@link SessionRepository} bean must be provided. For example:
|
||||||
* must be provided. For example:
|
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* <code>
|
* <code>
|
||||||
@@ -45,15 +44,13 @@ import org.springframework.session.events.SessionDestroyedEvent;
|
|||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* }
|
* }
|
||||||
* </code>
|
* </code> </pre>
|
||||||
* </pre>
|
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* It is important to note that no infrastructure for session expirations is
|
* It is important to note that no infrastructure for session expirations is configured
|
||||||
* configured for you out of the box. This is because things like session
|
* for you out of the box. This is because things like session expiration are highly
|
||||||
* expiration are highly implementation dependent. This means if you require
|
* implementation dependent. This means if you require cleaning up expired sessions, you
|
||||||
* cleaning up expired sessions, you are responsible for cleaning up the expired
|
* are responsible for cleaning up the expired sessions.
|
||||||
* sessions.
|
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
@@ -61,13 +58,12 @@ import org.springframework.session.events.SessionDestroyedEvent;
|
|||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>SessionRepositoryFilter - is responsible for wrapping the
|
* <li>SessionRepositoryFilter - is responsible for wrapping the HttpServletRequest with
|
||||||
* HttpServletRequest with an implementation of HttpSession that is backed by a
|
* an implementation of HttpSession that is backed by a SessionRepository</li>
|
||||||
* SessionRepository</li>
|
* <li>SessionEventHttpSessionListenerAdapter - is responsible for translating Spring
|
||||||
* <li>SessionEventHttpSessionListenerAdapter - is responsible for translating
|
* Session events into HttpSessionEvent. In order for it to work, the implementation of
|
||||||
* Spring Session events into HttpSessionEvent. In order for it to work, the
|
* SessionRepository you provide must support {@link SessionCreatedEvent} and
|
||||||
* implementation of SessionRepository you provide must support
|
* {@link SessionDestroyedEvent}.</li>
|
||||||
* {@link SessionCreatedEvent} and {@link SessionDestroyedEvent}.</li>
|
|
||||||
* <li>
|
* <li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ import org.springframework.session.web.http.SessionEventHttpSessionListenerAdapt
|
|||||||
import org.springframework.session.web.http.SessionRepositoryFilter;
|
import org.springframework.session.web.http.SessionRepositoryFilter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures the basics for setting up Spring Session in a web environment. In
|
* Configures the basics for setting up Spring Session in a web environment. In order to
|
||||||
* order to use it, you must provide a {@link SessionRepository}. For example:
|
* use it, you must provide a {@link SessionRepository}. For example:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* {@literal @Configuration}
|
* {@literal @Configuration}
|
||||||
@@ -54,11 +54,10 @@ import org.springframework.session.web.http.SessionRepositoryFilter;
|
|||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* It is important to note that no infrastructure for session expirations is
|
* It is important to note that no infrastructure for session expirations is configured
|
||||||
* configured for you out of the box. This is because things like session
|
* for you out of the box. This is because things like session expiration are highly
|
||||||
* expiration are highly implementation dependent. This means if you require
|
* implementation dependent. This means if you require cleaning up expired sessions, you
|
||||||
* cleaning up expired sessions, you are responsible for cleaning up the expired
|
* are responsible for cleaning up the expired sessions.
|
||||||
* sessions.
|
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
@@ -66,13 +65,12 @@ import org.springframework.session.web.http.SessionRepositoryFilter;
|
|||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>SessionRepositoryFilter - is responsible for wrapping the
|
* <li>SessionRepositoryFilter - is responsible for wrapping the HttpServletRequest with
|
||||||
* HttpServletRequest with an implementation of HttpSession that is backed by a
|
* an implementation of HttpSession that is backed by a SessionRepository</li>
|
||||||
* SessionRepository</li>
|
* <li>SessionEventHttpSessionListenerAdapter - is responsible for translating Spring
|
||||||
* <li>SessionEventHttpSessionListenerAdapter - is responsible for translating
|
* Session events into HttpSessionEvent. In order for it to work, the implementation of
|
||||||
* Spring Session events into HttpSessionEvent. In order for it to work, the
|
* SessionRepository you provide must support {@link SessionCreatedEvent} and
|
||||||
* implementation of SessionRepository you provide must support
|
* {@link SessionDestroyedEvent}.</li>
|
||||||
* {@link SessionCreatedEvent} and {@link SessionDestroyedEvent}.</li>
|
|
||||||
* <li>
|
* <li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
@@ -98,11 +96,14 @@ public class SpringHttpSessionConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public <S extends ExpiringSession> SessionRepositoryFilter<? extends ExpiringSession> springSessionRepositoryFilter(SessionRepository<S> sessionRepository) {
|
public <S extends ExpiringSession> SessionRepositoryFilter<? extends ExpiringSession> springSessionRepositoryFilter(
|
||||||
SessionRepositoryFilter<S> sessionRepositoryFilter = new SessionRepositoryFilter<S>(sessionRepository);
|
SessionRepository<S> sessionRepository) {
|
||||||
|
SessionRepositoryFilter<S> sessionRepositoryFilter = new SessionRepositoryFilter<S>(
|
||||||
|
sessionRepository);
|
||||||
sessionRepositoryFilter.setServletContext(this.servletContext);
|
sessionRepositoryFilter.setServletContext(this.servletContext);
|
||||||
if (this.httpSessionStrategy instanceof MultiHttpSessionStrategy) {
|
if (this.httpSessionStrategy instanceof MultiHttpSessionStrategy) {
|
||||||
sessionRepositoryFilter.setHttpSessionStrategy((MultiHttpSessionStrategy) this.httpSessionStrategy);
|
sessionRepositoryFilter.setHttpSessionStrategy(
|
||||||
|
(MultiHttpSessionStrategy) this.httpSessionStrategy);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sessionRepositoryFilter.setHttpSessionStrategy(this.httpSessionStrategy);
|
sessionRepositoryFilter.setHttpSessionStrategy(this.httpSessionStrategy);
|
||||||
|
|||||||
@@ -64,8 +64,9 @@ import org.springframework.util.Assert;
|
|||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AbstractGemFireOperationsSessionRepository is an abstract base class encapsulating functionality common
|
* AbstractGemFireOperationsSessionRepository is an abstract base class encapsulating
|
||||||
* to all implementations that support SessionRepository operations backed by GemFire.
|
* functionality common to all implementations that support SessionRepository operations
|
||||||
|
* backed by GemFire.
|
||||||
*
|
*
|
||||||
* @author John Blum
|
* @author John Blum
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
@@ -77,11 +78,13 @@ import org.springframework.util.StringUtils;
|
|||||||
* @see org.springframework.session.ExpiringSession
|
* @see org.springframework.session.ExpiringSession
|
||||||
* @see org.springframework.session.FindByIndexNameSessionRepository
|
* @see org.springframework.session.FindByIndexNameSessionRepository
|
||||||
* @see org.springframework.session.Session
|
* @see org.springframework.session.Session
|
||||||
* @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration
|
* @see org.springframework.session.data.gemfire.config.annotation.web.http.
|
||||||
|
* GemFireHttpSessionConfiguration
|
||||||
* @see com.gemstone.gemfire.cache.Region
|
* @see com.gemstone.gemfire.cache.Region
|
||||||
* @see com.gemstone.gemfire.cache.util.CacheListenerAdapter
|
* @see com.gemstone.gemfire.cache.util.CacheListenerAdapter
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractGemFireOperationsSessionRepository extends CacheListenerAdapter<Object, ExpiringSession>
|
public abstract class AbstractGemFireOperationsSessionRepository
|
||||||
|
extends CacheListenerAdapter<Object, ExpiringSession>
|
||||||
implements InitializingBean, FindByIndexNameSessionRepository<ExpiringSession>,
|
implements InitializingBean, FindByIndexNameSessionRepository<ExpiringSession>,
|
||||||
ApplicationEventPublisherAware {
|
ApplicationEventPublisherAware {
|
||||||
|
|
||||||
@@ -90,6 +93,7 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
private ApplicationEventPublisher applicationEventPublisher = new ApplicationEventPublisher() {
|
private ApplicationEventPublisher applicationEventPublisher = new ApplicationEventPublisher() {
|
||||||
public void publishEvent(ApplicationEvent event) {
|
public void publishEvent(ApplicationEvent event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void publishEvent(Object event) {
|
public void publishEvent(Object event) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -101,8 +105,9 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
private String fullyQualifiedRegionName;
|
private String fullyQualifiedRegionName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance of AbstractGemFireOperationsSessionRepository with a required GemfireOperations instance
|
* Constructs an instance of AbstractGemFireOperationsSessionRepository with a
|
||||||
* used to perform GemFire data access operations and interactions supporting the SessionRepository operations.
|
* required GemfireOperations instance used to perform GemFire data access operations
|
||||||
|
* and interactions supporting the SessionRepository operations.
|
||||||
*
|
*
|
||||||
* @param template the GemfireOperations instance used to interact with GemFire.
|
* @param template the GemfireOperations instance used to interact with GemFire.
|
||||||
* @see org.springframework.data.gemfire.GemfireOperations
|
* @see org.springframework.data.gemfire.GemfireOperations
|
||||||
@@ -123,18 +128,23 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the ApplicationEventPublisher used to publish Session events corresponding to GemFire cache events.
|
* Sets the ApplicationEventPublisher used to publish Session events corresponding to
|
||||||
|
* GemFire cache events.
|
||||||
*
|
*
|
||||||
* @param applicationEventPublisher the Spring ApplicationEventPublisher used to publish Session-based events.
|
* @param applicationEventPublisher the Spring ApplicationEventPublisher used to
|
||||||
|
* publish Session-based events.
|
||||||
* @see org.springframework.context.ApplicationEventPublisher
|
* @see org.springframework.context.ApplicationEventPublisher
|
||||||
*/
|
*/
|
||||||
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
|
public void setApplicationEventPublisher(
|
||||||
Assert.notNull(applicationEventPublisher, "ApplicationEventPublisher must not be null");
|
ApplicationEventPublisher applicationEventPublisher) {
|
||||||
|
Assert.notNull(applicationEventPublisher,
|
||||||
|
"ApplicationEventPublisher must not be null");
|
||||||
this.applicationEventPublisher = applicationEventPublisher;
|
this.applicationEventPublisher = applicationEventPublisher;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the ApplicationEventPublisher used to publish Session events corresponding to GemFire cache events.
|
* Gets the ApplicationEventPublisher used to publish Session events corresponding to
|
||||||
|
* GemFire cache events.
|
||||||
*
|
*
|
||||||
* @return the Spring ApplicationEventPublisher used to publish Session-based events.
|
* @return the Spring ApplicationEventPublisher used to publish Session-based events.
|
||||||
* @see org.springframework.context.ApplicationEventPublisher
|
* @see org.springframework.context.ApplicationEventPublisher
|
||||||
@@ -144,38 +154,43 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the fully-qualified name of the GemFire cache {@link Region} used to store and manage Session data.
|
* Gets the fully-qualified name of the GemFire cache {@link Region} used to store and
|
||||||
|
* manage Session data.
|
||||||
*
|
*
|
||||||
* @return a String indicating the fully qualified name of the GemFire cache {@link Region} used to store
|
* @return a String indicating the fully qualified name of the GemFire cache
|
||||||
* and manage Session data.
|
* {@link Region} used to store and manage Session data.
|
||||||
*/
|
*/
|
||||||
protected String getFullyQualifiedRegionName() {
|
protected String getFullyQualifiedRegionName() {
|
||||||
return this.fullyQualifiedRegionName;
|
return this.fullyQualifiedRegionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the maximum interval in seconds in which a Session can remain inactive before it is considered expired.
|
* Sets the maximum interval in seconds in which a Session can remain inactive before
|
||||||
|
* it is considered expired.
|
||||||
*
|
*
|
||||||
* @param maxInactiveIntervalInSeconds an integer value specifying the maximum interval in seconds that a Session
|
* @param maxInactiveIntervalInSeconds an integer value specifying the maximum
|
||||||
* can remain inactive before it is considered expired.
|
* interval in seconds that a Session can remain inactive before it is considered
|
||||||
|
* expired.
|
||||||
*/
|
*/
|
||||||
public void setMaxInactiveIntervalInSeconds(int maxInactiveIntervalInSeconds) {
|
public void setMaxInactiveIntervalInSeconds(int maxInactiveIntervalInSeconds) {
|
||||||
this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds;
|
this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the maximum interval in seconds in which a Session can remain inactive before it is considered expired.
|
* Gets the maximum interval in seconds in which a Session can remain inactive before
|
||||||
|
* it is considered expired.
|
||||||
*
|
*
|
||||||
* @return an integer value specifying the maximum interval in seconds that a Session can remain inactive
|
* @return an integer value specifying the maximum interval in seconds that a Session
|
||||||
* before it is considered expired.
|
* can remain inactive before it is considered expired.
|
||||||
*/
|
*/
|
||||||
public int getMaxInactiveIntervalInSeconds() {
|
public int getMaxInactiveIntervalInSeconds() {
|
||||||
return this.maxInactiveIntervalInSeconds;
|
return this.maxInactiveIntervalInSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a reference to the GemfireOperations (template) used to perform data access operations
|
* Gets a reference to the GemfireOperations (template) used to perform data access
|
||||||
* and other interactions on the GemFire cache {@link Region} backing this SessionRepository.
|
* operations and other interactions on the GemFire cache {@link Region} backing this
|
||||||
|
* SessionRepository.
|
||||||
*
|
*
|
||||||
* @return a reference to the GemfireOperations used to interact with GemFire.
|
* @return a reference to the GemfireOperations used to interact with GemFire.
|
||||||
* @see org.springframework.data.gemfire.GemfireOperations
|
* @see org.springframework.data.gemfire.GemfireOperations
|
||||||
@@ -185,9 +200,10 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback method during Spring bean initialization that will capture the fully-qualified name
|
* Callback method during Spring bean initialization that will capture the
|
||||||
* of the GemFire cache {@link Region} used to manage Session state and register this SessionRepository
|
* fully-qualified name of the GemFire cache {@link Region} used to manage Session
|
||||||
* as a GemFire {@link com.gemstone.gemfire.cache.CacheListener}.
|
* state and register this SessionRepository as a GemFire
|
||||||
|
* {@link com.gemstone.gemfire.cache.CacheListener}.
|
||||||
*
|
*
|
||||||
* @throws Exception if an error occurs during the initialization process.
|
* @throws Exception if an error occurs during the initialization process.
|
||||||
*/
|
*/
|
||||||
@@ -213,7 +229,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback method triggered when an entry is created in the GemFire cache {@link Region}.
|
* Callback method triggered when an entry is created in the GemFire cache
|
||||||
|
* {@link Region}.
|
||||||
*
|
*
|
||||||
* @param event an EntryEvent containing the details of the cache operation.
|
* @param event an EntryEvent containing the details of the cache operation.
|
||||||
* @see com.gemstone.gemfire.cache.EntryEvent
|
* @see com.gemstone.gemfire.cache.EntryEvent
|
||||||
@@ -222,12 +239,14 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
@Override
|
@Override
|
||||||
public void afterCreate(EntryEvent<Object, ExpiringSession> event) {
|
public void afterCreate(EntryEvent<Object, ExpiringSession> event) {
|
||||||
if (isExpiringSessionOrNull(event.getNewValue())) {
|
if (isExpiringSessionOrNull(event.getNewValue())) {
|
||||||
handleCreated(event.getKey().toString(), toExpiringSession(event.getNewValue()));
|
handleCreated(event.getKey().toString(),
|
||||||
|
toExpiringSession(event.getNewValue()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback method triggered when an entry is destroyed in the GemFire cache {@link Region}.
|
* Callback method triggered when an entry is destroyed in the GemFire cache
|
||||||
|
* {@link Region}.
|
||||||
*
|
*
|
||||||
* @param event an EntryEvent containing the details of the cache operation.
|
* @param event an EntryEvent containing the details of the cache operation.
|
||||||
* @see com.gemstone.gemfire.cache.EntryEvent
|
* @see com.gemstone.gemfire.cache.EntryEvent
|
||||||
@@ -235,11 +254,13 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void afterDestroy(EntryEvent<Object, ExpiringSession> event) {
|
public void afterDestroy(EntryEvent<Object, ExpiringSession> event) {
|
||||||
handleDestroyed(event.getKey().toString(), toExpiringSession(event.getOldValue()));
|
handleDestroyed(event.getKey().toString(),
|
||||||
|
toExpiringSession(event.getOldValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback method triggered when an entry is invalidated in the GemFire cache {@link Region}.
|
* Callback method triggered when an entry is invalidated in the GemFire cache
|
||||||
|
* {@link Region}.
|
||||||
*
|
*
|
||||||
* @param event an EntryEvent containing the details of the cache operation.
|
* @param event an EntryEvent containing the details of the cache operation.
|
||||||
* @see com.gemstone.gemfire.cache.EntryEvent
|
* @see com.gemstone.gemfire.cache.EntryEvent
|
||||||
@@ -318,29 +339,34 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
getApplicationEventPublisher().publishEvent(event);
|
getApplicationEventPublisher().publishEvent(event);
|
||||||
}
|
}
|
||||||
catch (Throwable t) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GemFireSession is a GemFire representation model of a Spring {@link ExpiringSession} for storing and accessing
|
* GemFireSession is a GemFire representation model of a Spring
|
||||||
* Session state information in GemFire. This class implements GemFire's {@link DataSerializable} interface
|
* {@link ExpiringSession} for storing and accessing Session state information in
|
||||||
* to better handle replication of Session information across the GemFire cluster.
|
* GemFire. This class implements GemFire's {@link DataSerializable} interface to
|
||||||
|
* better handle replication of Session information across the GemFire cluster.
|
||||||
*
|
*
|
||||||
* @see java.lang.Comparable
|
* @see java.lang.Comparable
|
||||||
* @see org.springframework.session.ExpiringSession
|
* @see org.springframework.session.ExpiringSession
|
||||||
* @see org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes
|
* @see org.springframework.session.data.gemfire.
|
||||||
|
* AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes
|
||||||
* @see com.gemstone.gemfire.DataSerializable
|
* @see com.gemstone.gemfire.DataSerializable
|
||||||
* @see com.gemstone.gemfire.DataSerializer
|
* @see com.gemstone.gemfire.DataSerializer
|
||||||
* @see com.gemstone.gemfire.Delta
|
* @see com.gemstone.gemfire.Delta
|
||||||
* @see com.gemstone.gemfire.Instantiator
|
* @see com.gemstone.gemfire.Instantiator
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public static class GemFireSession implements Comparable<ExpiringSession>, DataSerializable, Delta, ExpiringSession {
|
public static class GemFireSession implements Comparable<ExpiringSession>,
|
||||||
|
DataSerializable, Delta, ExpiringSession {
|
||||||
|
|
||||||
protected static final boolean DEFAULT_ALLOW_JAVA_SERIALIZATION = true;
|
protected static final boolean DEFAULT_ALLOW_JAVA_SERIALIZATION = true;
|
||||||
|
|
||||||
protected static final DateFormat TO_STRING_DATE_FORMAT = new SimpleDateFormat("YYYY-MM-dd-HH-mm-ss");
|
protected static final DateFormat TO_STRING_DATE_FORMAT = new SimpleDateFormat(
|
||||||
|
"YYYY-MM-dd-HH-mm-ss");
|
||||||
|
|
||||||
protected static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
|
protected static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
|
||||||
|
|
||||||
@@ -360,7 +386,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
private long creationTime;
|
private long creationTime;
|
||||||
private long lastAccessedTime;
|
private long lastAccessedTime;
|
||||||
|
|
||||||
private transient final GemFireSessionAttributes sessionAttributes = new GemFireSessionAttributes(this);
|
private transient final GemFireSessionAttributes sessionAttributes = new GemFireSessionAttributes(
|
||||||
|
this);
|
||||||
|
|
||||||
private transient final SpelExpressionParser parser = new SpelExpressionParser();
|
private transient final SpelExpressionParser parser = new SpelExpressionParser();
|
||||||
|
|
||||||
@@ -460,7 +487,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
private long idleTimeout(long maxInactiveIntervalInSeconds) {
|
private long idleTimeout(long maxInactiveIntervalInSeconds) {
|
||||||
return (System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(maxInactiveIntervalInSeconds));
|
return (System.currentTimeMillis()
|
||||||
|
- TimeUnit.SECONDS.toMillis(maxInactiveIntervalInSeconds));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
@@ -475,7 +503,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
public synchronized void setMaxInactiveIntervalInSeconds(final int maxInactiveIntervalInSeconds) {
|
public synchronized void setMaxInactiveIntervalInSeconds(
|
||||||
|
final int maxInactiveIntervalInSeconds) {
|
||||||
this.delta |= (this.maxInactiveIntervalInSeconds != maxInactiveIntervalInSeconds);
|
this.delta |= (this.maxInactiveIntervalInSeconds != maxInactiveIntervalInSeconds);
|
||||||
this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds;
|
this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds;
|
||||||
}
|
}
|
||||||
@@ -498,7 +527,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
Object authentication = getAttribute(SPRING_SECURITY_CONTEXT);
|
Object authentication = getAttribute(SPRING_SECURITY_CONTEXT);
|
||||||
|
|
||||||
if (authentication != null) {
|
if (authentication != null) {
|
||||||
Expression expression = this.parser.parseExpression("authentication?.name");
|
Expression expression = this.parser
|
||||||
|
.parseExpression("authentication?.name");
|
||||||
principalName = expression.getValue(authentication, String.class);
|
principalName = expression.getValue(authentication, String.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -514,7 +544,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
out.writeInt(getMaxInactiveIntervalInSeconds());
|
out.writeInt(getMaxInactiveIntervalInSeconds());
|
||||||
|
|
||||||
String principalName = getPrincipalName();
|
String principalName = getPrincipalName();
|
||||||
int length = (StringUtils.hasText(principalName) ? principalName.length() : 0);
|
int length = (StringUtils.hasText(principalName) ? principalName.length()
|
||||||
|
: 0);
|
||||||
|
|
||||||
out.writeInt(length);
|
out.writeInt(length);
|
||||||
|
|
||||||
@@ -533,7 +564,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) */
|
/* (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.id = in.readUTF();
|
||||||
this.creationTime = in.readLong();
|
this.creationTime = in.readLong();
|
||||||
setLastAccessedTime(in.readLong());
|
setLastAccessedTime(in.readLong());
|
||||||
@@ -609,9 +641,11 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
@Override
|
@Override
|
||||||
public synchronized String toString() {
|
public synchronized String toString() {
|
||||||
return String.format("{ @type = %1$s, id = %2$s, creationTime = %3$s, lastAccessedTime = %4$s"
|
return String.format(
|
||||||
+ ", maxInactiveIntervalInSeconds = %5$s, principalName = %6$s }", getClass().getName(), getId(),
|
"{ @type = %1$s, id = %2$s, creationTime = %3$s, lastAccessedTime = %4$s"
|
||||||
toString(getCreationTime()), toString(getLastAccessedTime()), getMaxInactiveIntervalInSeconds(),
|
+ ", maxInactiveIntervalInSeconds = %5$s, principalName = %6$s }",
|
||||||
|
getClass().getName(), getId(), toString(getCreationTime()),
|
||||||
|
toString(getLastAccessedTime()), getMaxInactiveIntervalInSeconds(),
|
||||||
getPrincipalName());
|
getPrincipalName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,10 +656,11 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The GemFireSessionAttributes class is a container for Session attributes that implements both
|
* The GemFireSessionAttributes class is a container for Session attributes that
|
||||||
* the {@link DataSerializable} and {@link Delta} GemFire interfaces for efficient storage and distribution
|
* implements both the {@link DataSerializable} and {@link Delta} GemFire interfaces
|
||||||
* (replication) in GemFire. Additionally, GemFireSessionAttributes extends {@link AbstractMap} providing
|
* for efficient storage and distribution (replication) in GemFire. Additionally,
|
||||||
* {@link Map}-like behavior since attributes of a Session are effectively a name to value mapping.
|
* GemFireSessionAttributes extends {@link AbstractMap} providing {@link Map}-like
|
||||||
|
* behavior since attributes of a Session are effectively a name to value mapping.
|
||||||
*
|
*
|
||||||
* @see java.util.AbstractMap
|
* @see java.util.AbstractMap
|
||||||
* @see com.gemstone.gemfire.DataSerializable
|
* @see com.gemstone.gemfire.DataSerializable
|
||||||
@@ -640,7 +675,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
protected static final boolean DEFAULT_ALLOW_JAVA_SERIALIZATION = true;
|
protected static final boolean DEFAULT_ALLOW_JAVA_SERIALIZATION = true;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Instantiator.register(new Instantiator(GemFireSessionAttributes.class, 800828008) {
|
Instantiator.register(
|
||||||
|
new Instantiator(GemFireSessionAttributes.class, 800828008) {
|
||||||
@Override
|
@Override
|
||||||
public DataSerializable newInstance() {
|
public DataSerializable newInstance() {
|
||||||
return new GemFireSessionAttributes();
|
return new GemFireSessionAttributes();
|
||||||
@@ -667,7 +703,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
public void setAttribute(String attributeName, Object attributeValue) {
|
public void setAttribute(String attributeName, Object attributeValue) {
|
||||||
synchronized (this.lock) {
|
synchronized (this.lock) {
|
||||||
if (attributeValue != null) {
|
if (attributeValue != null) {
|
||||||
if (!attributeValue.equals(this.sessionAttributes.put(attributeName, attributeValue))) {
|
if (!attributeValue.equals(
|
||||||
|
this.sessionAttributes.put(attributeName, attributeValue))) {
|
||||||
this.sessionAttributeDeltas.put(attributeName, attributeValue);
|
this.sessionAttributeDeltas.put(attributeName, attributeValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -697,7 +734,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
/* (non-Javadoc) */
|
/* (non-Javadoc) */
|
||||||
public Set<String> getAttributeNames() {
|
public Set<String> getAttributeNames() {
|
||||||
synchronized (this.lock) {
|
synchronized (this.lock) {
|
||||||
return Collections.unmodifiableSet(new HashSet<String>(this.sessionAttributes.keySet()));
|
return Collections.unmodifiableSet(
|
||||||
|
new HashSet<String>(this.sessionAttributes.keySet()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -713,7 +751,10 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
return new AbstractSet<Entry<String, Object>>() {
|
return new AbstractSet<Entry<String, Object>>() {
|
||||||
@Override
|
@Override
|
||||||
public Iterator<Entry<String, Object>> iterator() {
|
public Iterator<Entry<String, Object>> iterator() {
|
||||||
return Collections.unmodifiableMap(GemFireSessionAttributes.this.sessionAttributes).entrySet().iterator();
|
return Collections
|
||||||
|
.unmodifiableMap(
|
||||||
|
GemFireSessionAttributes.this.sessionAttributes)
|
||||||
|
.entrySet().iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -736,7 +777,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
public void from(GemFireSessionAttributes sessionAttributes) {
|
public void from(GemFireSessionAttributes sessionAttributes) {
|
||||||
synchronized (this.lock) {
|
synchronized (this.lock) {
|
||||||
for (String attributeName : sessionAttributes.getAttributeNames()) {
|
for (String attributeName : sessionAttributes.getAttributeNames()) {
|
||||||
setAttribute(attributeName, sessionAttributes.getAttribute(attributeName));
|
setAttribute(attributeName,
|
||||||
|
sessionAttributes.getAttribute(attributeName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -788,7 +830,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
|
|||||||
synchronized (this.lock) {
|
synchronized (this.lock) {
|
||||||
out.writeInt(this.sessionAttributeDeltas.size());
|
out.writeInt(this.sessionAttributeDeltas.size());
|
||||||
|
|
||||||
for (Map.Entry<String, Object> entry : this.sessionAttributeDeltas.entrySet()) {
|
for (Map.Entry<String, Object> entry : this.sessionAttributeDeltas
|
||||||
|
.entrySet()) {
|
||||||
out.writeUTF(entry.getKey());
|
out.writeUTF(entry.getKey());
|
||||||
writeObject(entry.getValue(), out);
|
writeObject(entry.getValue(), out);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,31 +25,33 @@ import org.springframework.data.gemfire.GemfireOperations;
|
|||||||
import org.springframework.session.ExpiringSession;
|
import org.springframework.session.ExpiringSession;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The GemFireOperationsSessionRepository class is a Spring SessionRepository implementation that interfaces with
|
* The GemFireOperationsSessionRepository class is a Spring SessionRepository
|
||||||
* and uses GemFire to back and store Spring Sessions.
|
* implementation that interfaces with and uses GemFire to back and store Spring Sessions.
|
||||||
*
|
*
|
||||||
* @author John Blum
|
* @author John Blum
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
* @see org.springframework.data.gemfire.GemfireOperations
|
* @see org.springframework.data.gemfire.GemfireOperations
|
||||||
* @see org.springframework.session.ExpiringSession
|
* @see org.springframework.session.ExpiringSession
|
||||||
* @see org.springframework.session.Session
|
* @see org.springframework.session.Session
|
||||||
* @see org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository
|
* @see org.springframework.session.data.gemfire.
|
||||||
|
* AbstractGemFireOperationsSessionRepository
|
||||||
*/
|
*/
|
||||||
public class GemFireOperationsSessionRepository extends AbstractGemFireOperationsSessionRepository {
|
public class GemFireOperationsSessionRepository
|
||||||
|
extends AbstractGemFireOperationsSessionRepository {
|
||||||
|
|
||||||
// GemFire OQL query used to lookup Sessions by arbitrary attributes.
|
// GemFire OQL query used to lookup Sessions by arbitrary attributes.
|
||||||
protected static final String FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY =
|
protected static final String FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY = "SELECT s FROM %1$s s WHERE s.attributes['%2$s'] = $1";
|
||||||
"SELECT s FROM %1$s s WHERE s.attributes['%2$s'] = $1";
|
|
||||||
|
|
||||||
// GemFire OQL query used to look up Sessions by principal name.
|
// GemFire OQL query used to look up Sessions by principal name.
|
||||||
protected static final String FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY =
|
protected static final String FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY = "SELECT s FROM %1$s s WHERE s.principalName = $1";
|
||||||
"SELECT s FROM %1$s s WHERE s.principalName = $1";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance of GemFireOperationsSessionRepository initialized with the required GemfireOperations
|
* Constructs an instance of GemFireOperationsSessionRepository initialized with the
|
||||||
* object used to perform data access operations to manage Session state.
|
* required GemfireOperations object used to perform data access operations to manage
|
||||||
|
* Session state.
|
||||||
*
|
*
|
||||||
* @param template the GemfireOperations object used to access and manage Session state in GemFire.
|
* @param template the GemfireOperations object used to access and manage Session
|
||||||
|
* state in GemFire.
|
||||||
* @see org.springframework.data.gemfire.GemfireOperations
|
* @see org.springframework.data.gemfire.GemfireOperations
|
||||||
*/
|
*/
|
||||||
public GemFireOperationsSessionRepository(GemfireOperations template) {
|
public GemFireOperationsSessionRepository(GemfireOperations template) {
|
||||||
@@ -57,20 +59,26 @@ public class GemFireOperationsSessionRepository extends AbstractGemFireOperation
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Looks up all available Sessions with the particular attribute indexed by name having the given value.
|
* Looks up all available Sessions with the particular attribute indexed by name
|
||||||
|
* having the given value.
|
||||||
*
|
*
|
||||||
* @param indexName name of the indexed Session attribute.
|
* @param indexName name of the indexed Session attribute. (e.g.
|
||||||
* (e.g. {@link org.springframework.session.FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME}).
|
* {@link org.springframework.session.FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME}
|
||||||
* @param indexValue value of the indexed Session attribute to search on (e.g. username).
|
* ).
|
||||||
|
* @param indexValue value of the indexed Session attribute to search on (e.g.
|
||||||
|
* username).
|
||||||
* @return a mapping of Session ID to Session instances.
|
* @return a mapping of Session ID to Session instances.
|
||||||
* @see org.springframework.session.ExpiringSession
|
* @see org.springframework.session.ExpiringSession
|
||||||
* @see java.util.Map
|
* @see java.util.Map
|
||||||
* @see #prepareQuery(String)
|
* @see #prepareQuery(String)
|
||||||
*/
|
*/
|
||||||
public Map<String, ExpiringSession> findByIndexNameAndIndexValue(String indexName, String indexValue) {
|
public Map<String, ExpiringSession> findByIndexNameAndIndexValue(String indexName,
|
||||||
SelectResults<ExpiringSession> results = getTemplate().find(prepareQuery(indexName), indexValue);
|
String indexValue) {
|
||||||
|
SelectResults<ExpiringSession> results = getTemplate()
|
||||||
|
.find(prepareQuery(indexName), indexValue);
|
||||||
|
|
||||||
Map<String, ExpiringSession> sessions = new HashMap<String, ExpiringSession>(results.size());
|
Map<String, ExpiringSession> sessions = new HashMap<String, ExpiringSession>(
|
||||||
|
results.size());
|
||||||
|
|
||||||
for (ExpiringSession session : results.asList()) {
|
for (ExpiringSession session : results.asList()) {
|
||||||
sessions.put(session.getId(), session);
|
sessions.put(session.getId(), session);
|
||||||
@@ -80,22 +88,26 @@ public class GemFireOperationsSessionRepository extends AbstractGemFireOperation
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepares the appropriate GemFire OQL query based on the indexed Session attribute name.
|
* Prepares the appropriate GemFire OQL query based on the indexed Session attribute
|
||||||
|
* name.
|
||||||
*
|
*
|
||||||
* @param indexName a String indicating the name of the indexed Session attribute.
|
* @param indexName a String indicating the name of the indexed Session attribute.
|
||||||
* @return an appropriate GemFire OQL statement for querying on a particular indexed Session attribute.
|
* @return an appropriate GemFire OQL statement for querying on a particular indexed
|
||||||
|
* Session attribute.
|
||||||
*/
|
*/
|
||||||
protected String prepareQuery(String indexName) {
|
protected String prepareQuery(String indexName) {
|
||||||
return (PRINCIPAL_NAME_INDEX_NAME.equals(indexName)
|
return (PRINCIPAL_NAME_INDEX_NAME.equals(indexName)
|
||||||
? String.format(FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY, getFullyQualifiedRegionName())
|
? String.format(FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY,
|
||||||
: String.format(FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY, getFullyQualifiedRegionName(), indexName));
|
getFullyQualifiedRegionName())
|
||||||
|
: String.format(FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY,
|
||||||
|
getFullyQualifiedRegionName(), indexName));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link ExpiringSession} instance backed by GemFire.
|
* Constructs a new {@link ExpiringSession} instance backed by GemFire.
|
||||||
*
|
*
|
||||||
* @return an instance of {@link ExpiringSession} backed by GemFire.
|
* @return an instance of {@link ExpiringSession} backed by GemFire.
|
||||||
* @see org.springframework.session.data.gemfire.GemFireOperationsSessionRepository.GemFireSession#create(int)
|
* @see GemFireSession#create(int)
|
||||||
* @see org.springframework.session.ExpiringSession
|
* @see org.springframework.session.ExpiringSession
|
||||||
* @see #getMaxInactiveIntervalInSeconds()
|
* @see #getMaxInactiveIntervalInSeconds()
|
||||||
*/
|
*/
|
||||||
@@ -104,8 +116,8 @@ public class GemFireOperationsSessionRepository extends AbstractGemFireOperation
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a copy of an existing, non-expired {@link ExpiringSession} by ID. If the Session is expired,
|
* Gets a copy of an existing, non-expired {@link ExpiringSession} by ID. If the
|
||||||
* then it is deleted.
|
* Session is expired, then it is deleted.
|
||||||
*
|
*
|
||||||
* @param sessionId a String indicating the ID of the Session to get.
|
* @param sessionId a String indicating the ID of the Session to get.
|
||||||
* @return an existing {@link ExpiringSession} by ID or null if not Session exists.
|
* @return an existing {@link ExpiringSession} by ID or null if not Session exists.
|
||||||
@@ -140,15 +152,16 @@ public class GemFireOperationsSessionRepository extends AbstractGemFireOperation
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes (removes) any existing {@link ExpiringSession} from GemFire. This operation also results in
|
* Deletes (removes) any existing {@link ExpiringSession} from GemFire. This operation
|
||||||
* a SessionDeletedEvent.
|
* also results in a SessionDeletedEvent.
|
||||||
*
|
*
|
||||||
* @param sessionId a String indicating the ID of the Session to remove from GemFire.
|
* @param sessionId a String indicating the ID of the Session to remove from GemFire.
|
||||||
* @see org.springframework.data.gemfire.GemfireOperations#remove(Object)
|
* @see org.springframework.data.gemfire.GemfireOperations#remove(Object)
|
||||||
* @see #handleDeleted(String, ExpiringSession)
|
* @see #handleDeleted(String, ExpiringSession)
|
||||||
*/
|
*/
|
||||||
public void delete(String sessionId) {
|
public void delete(String sessionId) {
|
||||||
handleDeleted(sessionId, getTemplate().<Object, ExpiringSession>remove(sessionId));
|
handleDeleted(sessionId,
|
||||||
|
getTemplate().<Object, ExpiringSession>remove(sessionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,11 +29,13 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add this annotation to an {@code @Configuration} class to expose the SessionRepositoryFilter
|
* Add this annotation to an {@code @Configuration} class to expose the
|
||||||
* as a bean named "springSessionRepositoryFilter" and backed by Pivotal GemFire or Apache Geode.
|
* 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}
|
* In order to leverage the annotation, a single Pivotal GemFire/Apache Geode
|
||||||
* 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:
|
* For example:
|
||||||
*
|
*
|
||||||
@@ -61,12 +63,11 @@ import org.springframework.context.annotation.Import;
|
|||||||
* return clientCacheFactoryBean;
|
* return clientCacheFactoryBean;
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* </code>
|
* </code> </pre>
|
||||||
* </pre>
|
|
||||||
*
|
*
|
||||||
* Alternatively, a Spring Session can be configured to use Pivotal GemFire (Apache Geode) as a client
|
* Alternatively, a Spring Session can be configured to use Pivotal GemFire (Apache Geode)
|
||||||
* using a dedicated GemFire Server cluster and a {@link com.gemstone.gemfire.cache.client.ClientCache}.
|
* as a client using a dedicated GemFire Server cluster and a
|
||||||
* For example:
|
* {@link com.gemstone.gemfire.cache.client.ClientCache}. For example:
|
||||||
*
|
*
|
||||||
* <code>
|
* <code>
|
||||||
* {@literal @Configuration}
|
* {@literal @Configuration}
|
||||||
@@ -92,12 +93,14 @@ import org.springframework.context.annotation.Import;
|
|||||||
* }
|
* }
|
||||||
* </code>
|
* </code>
|
||||||
*
|
*
|
||||||
* More advanced configurations can extend {@link GemFireHttpSessionConfiguration} instead.
|
* More advanced configurations can extend {@link GemFireHttpSessionConfiguration}
|
||||||
|
* instead.
|
||||||
*
|
*
|
||||||
* @author John Blum
|
* @author John Blum
|
||||||
* @see org.springframework.context.annotation.Configuration
|
* @see org.springframework.context.annotation.Configuration
|
||||||
* @see org.springframework.context.annotation.Import
|
* @see org.springframework.context.annotation.Import
|
||||||
* @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration
|
* @see org.springframework.session.data.gemfire.config.annotation.web.http.
|
||||||
|
* GemFireHttpSessionConfiguration
|
||||||
* @see org.springframework.session.config.annotation.web.http.EnableSpringHttpSession
|
* @see org.springframework.session.config.annotation.web.http.EnableSpringHttpSession
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
*/
|
*/
|
||||||
@@ -111,31 +114,35 @@ public @interface EnableGemFireHttpSession {
|
|||||||
/**
|
/**
|
||||||
* Defines the GemFire ClientCache Region DataPolicy.
|
* Defines the GemFire ClientCache Region DataPolicy.
|
||||||
*
|
*
|
||||||
* @return a ClientRegionShortcut used to specify and configure the ClientCache Region DataPolicy.
|
* @return a ClientRegionShortcut used to specify and configure the ClientCache Region
|
||||||
|
* DataPolicy.
|
||||||
* @see com.gemstone.gemfire.cache.client.ClientRegionShortcut
|
* @see com.gemstone.gemfire.cache.client.ClientRegionShortcut
|
||||||
*/
|
*/
|
||||||
ClientRegionShortcut clientRegionShortcut() default ClientRegionShortcut.PROXY;
|
ClientRegionShortcut clientRegionShortcut() default ClientRegionShortcut.PROXY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifies the Session attributes by name that should be indexed for query operations.
|
* Identifies the Session attributes by name that should be indexed for query
|
||||||
* For instance, find all Sessions in GemFire having attribute A defined with value X.
|
* operations. For instance, find all Sessions in GemFire having attribute A defined
|
||||||
|
* with value X.
|
||||||
*
|
*
|
||||||
* @return an array of Strings identifying the names of Session attributes to index.
|
* @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 it is considered expired.
|
* Defines the maximum interval in seconds that a Session can remain inactive before
|
||||||
* Defaults to 1800 seconds, or 30 minutes.
|
* it is considered expired. Defaults to 1800 seconds, or 30 minutes.
|
||||||
*
|
*
|
||||||
* @return an integer value defining the maximum inactive interval in seconds for declaring a Session expired.
|
* @return an integer value defining the maximum inactive interval in seconds for
|
||||||
|
* declaring a Session expired.
|
||||||
*/
|
*/
|
||||||
int maxInactiveIntervalInSeconds() default 1800;
|
int maxInactiveIntervalInSeconds() default 1800;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the name of the GemFire (Client)Cache Region used to store Sessions.
|
* Defines the name of the GemFire (Client)Cache Region used to store Sessions.
|
||||||
*
|
*
|
||||||
* @return a String specifying the name of the GemFire (Client)Cache Region used to store Sessions.
|
* @return a String specifying the name of the GemFire (Client)Cache Region used to
|
||||||
|
* store Sessions.
|
||||||
* @see com.gemstone.gemfire.cache.Region#getName()
|
* @see com.gemstone.gemfire.cache.Region#getName()
|
||||||
*/
|
*/
|
||||||
String regionName() default "ClusteredSpringSessions";
|
String regionName() default "ClusteredSpringSessions";
|
||||||
@@ -143,7 +150,8 @@ public @interface EnableGemFireHttpSession {
|
|||||||
/**
|
/**
|
||||||
* Defines the GemFire, Peer Cache Region DataPolicy.
|
* Defines the GemFire, Peer Cache Region DataPolicy.
|
||||||
*
|
*
|
||||||
* @return a RegionShortcut used to specify and configure the Peer Cache Region DataPolicy.
|
* @return a RegionShortcut used to specify and configure the Peer Cache Region
|
||||||
|
* DataPolicy.
|
||||||
* @see com.gemstone.gemfire.cache.RegionShortcut
|
* @see com.gemstone.gemfire.cache.RegionShortcut
|
||||||
*/
|
*/
|
||||||
RegionShortcut serverRegionShortcut() default RegionShortcut.PARTITION;
|
RegionShortcut serverRegionShortcut() default RegionShortcut.PARTITION;
|
||||||
|
|||||||
@@ -49,8 +49,9 @@ import org.springframework.util.ObjectUtils;
|
|||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The GemFireHttpSessionConfiguration class is a Spring @Configuration class used to configure and initialize
|
* The GemFireHttpSessionConfiguration class is a Spring @Configuration class used to
|
||||||
* Pivotal GemFire (or Apache Geode) as a clustered, replicated HttpSession provider implementation in Spring Session.
|
* configure and initialize Pivotal GemFire (or Apache Geode) as a clustered, replicated
|
||||||
|
* HttpSession provider implementation in Spring Session.
|
||||||
*
|
*
|
||||||
* @author John Blum
|
* @author John Blum
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
@@ -63,9 +64,11 @@ import org.springframework.util.StringUtils;
|
|||||||
* @see org.springframework.data.gemfire.IndexFactoryBean
|
* @see org.springframework.data.gemfire.IndexFactoryBean
|
||||||
* @see org.springframework.data.gemfire.RegionAttributesFactoryBean
|
* @see org.springframework.data.gemfire.RegionAttributesFactoryBean
|
||||||
* @see org.springframework.session.ExpiringSession
|
* @see org.springframework.session.ExpiringSession
|
||||||
* @see org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration
|
* @see org.springframework.session.config.annotation.web.http.
|
||||||
|
* SpringHttpSessionConfiguration
|
||||||
* @see org.springframework.session.data.gemfire.GemFireOperationsSessionRepository
|
* @see org.springframework.session.data.gemfire.GemFireOperationsSessionRepository
|
||||||
* @see org.springframework.session.data.gemfire.config.annotation.web.http.support.GemFireCacheTypeAwareRegionFactoryBean
|
* @see org.springframework.session.data.gemfire.config.annotation.web.http.support.
|
||||||
|
* GemFireCacheTypeAwareRegionFactoryBean
|
||||||
* @see com.gemstone.gemfire.cache.ExpirationAttributes
|
* @see com.gemstone.gemfire.cache.ExpirationAttributes
|
||||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||||
* @see com.gemstone.gemfire.cache.Region
|
* @see com.gemstone.gemfire.cache.Region
|
||||||
@@ -81,7 +84,8 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
|||||||
* The default maximum interval in seconds in which a Session can remain inactive
|
* The default maximum interval in seconds in which a Session can remain inactive
|
||||||
* before it is considered expired.
|
* 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<Object> SPRING_SESSION_GEMFIRE_REGION_KEY_CONSTRAINT = Object.class;
|
protected static final Class<Object> SPRING_SESSION_GEMFIRE_REGION_KEY_CONSTRAINT = Object.class;
|
||||||
protected static final Class<GemFireSession> SPRING_SESSION_GEMFIRE_REGION_VALUE_CONSTRAINT = GemFireSession.class;
|
protected static final Class<GemFireSession> SPRING_SESSION_GEMFIRE_REGION_VALUE_CONSTRAINT = GemFireSession.class;
|
||||||
@@ -121,9 +125,11 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
|||||||
private String[] indexableSessionAttributes = DEFAULT_INDEXABLE_SESSION_ATTRIBUTES;
|
private String[] indexableSessionAttributes = DEFAULT_INDEXABLE_SESSION_ATTRIBUTES;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a reference to the {@link ClassLoader} used to load bean definition class types in a Spring context.
|
* Sets a reference to the {@link ClassLoader} used to load bean definition class
|
||||||
|
* types in a Spring context.
|
||||||
*
|
*
|
||||||
* @param beanClassLoader the ClassLoader used by the Spring container to load bean class types.
|
* @param beanClassLoader the ClassLoader used by the Spring container to load bean
|
||||||
|
* class types.
|
||||||
* @see org.springframework.beans.factory.BeanClassLoaderAware#setBeanClassLoader(ClassLoader)
|
* @see org.springframework.beans.factory.BeanClassLoaderAware#setBeanClassLoader(ClassLoader)
|
||||||
* @see java.lang.ClassLoader
|
* @see java.lang.ClassLoader
|
||||||
*/
|
*/
|
||||||
@@ -132,7 +138,8 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a reference to the {@link ClassLoader} used to load bean definition class types in a Spring context.
|
* Gets a reference to the {@link ClassLoader} used to load bean definition class
|
||||||
|
* types in a Spring context.
|
||||||
*
|
*
|
||||||
* @return the ClassLoader used by the Spring container to load bean class types.
|
* @return the ClassLoader used by the Spring container to load bean class types.
|
||||||
* @see java.lang.ClassLoader
|
* @see java.lang.ClassLoader
|
||||||
@@ -142,10 +149,11 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link ClientRegionShortcut} used to configure the GemFire ClientCache Region
|
* Sets the {@link ClientRegionShortcut} used to configure the GemFire ClientCache
|
||||||
* that will store Spring Sessions.
|
* Region that will store Spring Sessions.
|
||||||
*
|
*
|
||||||
* @param shortcut the ClientRegionShortcut used to configure the GemFire ClientCache Region.
|
* @param shortcut the ClientRegionShortcut used to configure the GemFire ClientCache
|
||||||
|
* Region.
|
||||||
* @see com.gemstone.gemfire.cache.client.ClientRegionShortcut
|
* @see com.gemstone.gemfire.cache.client.ClientRegionShortcut
|
||||||
*/
|
*/
|
||||||
public void setClientRegionShortcut(ClientRegionShortcut shortcut) {
|
public void setClientRegionShortcut(ClientRegionShortcut shortcut) {
|
||||||
@@ -153,22 +161,24 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the {@link ClientRegionShortcut} used to configure the GemFire ClientCache Region
|
* Gets the {@link ClientRegionShortcut} used to configure the GemFire ClientCache
|
||||||
* that will store Spring Sessions. Defaults to {@link ClientRegionShortcut#PROXY}.
|
* Region that will store Spring Sessions. Defaults to
|
||||||
|
* {@link ClientRegionShortcut#PROXY}.
|
||||||
*
|
*
|
||||||
* @return the ClientRegionShortcut used to configure the GemFire ClientCache Region.
|
* @return the ClientRegionShortcut used to configure the GemFire ClientCache Region.
|
||||||
* @see com.gemstone.gemfire.cache.client.ClientRegionShortcut
|
* @see com.gemstone.gemfire.cache.client.ClientRegionShortcut
|
||||||
* @see EnableGemFireHttpSession#clientRegionShortcut()
|
* @see EnableGemFireHttpSession#clientRegionShortcut()
|
||||||
*/
|
*/
|
||||||
protected ClientRegionShortcut getClientRegionShortcut() {
|
protected ClientRegionShortcut getClientRegionShortcut() {
|
||||||
return (this.clientRegionShortcut != null ? this.clientRegionShortcut : DEFAULT_CLIENT_REGION_SHORTCUT);
|
return (this.clientRegionShortcut != null ? this.clientRegionShortcut
|
||||||
|
: DEFAULT_CLIENT_REGION_SHORTCUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the names of all Session attributes that should be indexed by GemFire.
|
* Sets the names of all Session attributes that should be indexed by GemFire.
|
||||||
*
|
*
|
||||||
* @param indexableSessionAttributes an array of Strings indicating the names of all Session attributes
|
* @param indexableSessionAttributes an array of Strings indicating the names of all
|
||||||
* for which an Index will be created by GemFire.
|
* Session attributes for which an Index will be created by GemFire.
|
||||||
*/
|
*/
|
||||||
public void setIndexableSessionAttributes(String[] indexableSessionAttributes) {
|
public void setIndexableSessionAttributes(String[] indexableSessionAttributes) {
|
||||||
this.indexableSessionAttributes = indexableSessionAttributes;
|
this.indexableSessionAttributes = indexableSessionAttributes;
|
||||||
@@ -177,21 +187,23 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
|||||||
/**
|
/**
|
||||||
* Get the names of all Session attributes that should be indexed by GemFire.
|
* Get the names of all Session attributes that should be indexed by GemFire.
|
||||||
*
|
*
|
||||||
* @return an array of Strings indicating the names of all Session attributes for which an Index
|
* @return an array of Strings indicating the names of all Session attributes for
|
||||||
* will be created by GemFire. Defaults to an empty String array if unspecified.
|
* which an Index will be created by GemFire. Defaults to an empty String array if
|
||||||
|
* unspecified.
|
||||||
* @see EnableGemFireHttpSession#indexableSessionAttributes()
|
* @see EnableGemFireHttpSession#indexableSessionAttributes()
|
||||||
*/
|
*/
|
||||||
protected String[] getIndexableSessionAttributes() {
|
protected String[] getIndexableSessionAttributes() {
|
||||||
return (this.indexableSessionAttributes != null ? this.indexableSessionAttributes : DEFAULT_INDEXABLE_SESSION_ATTRIBUTES);
|
return (this.indexableSessionAttributes != null ? this.indexableSessionAttributes
|
||||||
|
: DEFAULT_INDEXABLE_SESSION_ATTRIBUTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the names of all Session attributes that will be indexed by GemFire as single String value constituting
|
* Gets the names of all Session attributes that will be indexed by GemFire as single
|
||||||
* the Index expression of the Index definition.
|
* String value constituting the Index expression of the Index definition.
|
||||||
*
|
*
|
||||||
* @return a String composed of all the named Session attributes on which a GemFire Index will be created
|
* @return a String composed of all the named Session attributes on which a GemFire
|
||||||
* as an Index definition expression. If the indexable Session attributes were not specified, then the
|
* Index will be created as an Index definition expression. If the indexable Session
|
||||||
* wildcard ("*") is returned.
|
* attributes were not specified, then the wildcard ("*") is returned.
|
||||||
* @see com.gemstone.gemfire.cache.query.Index#getIndexedExpression()
|
* @see com.gemstone.gemfire.cache.query.Index#getIndexedExpression()
|
||||||
*/
|
*/
|
||||||
protected String getIndexableSessionAttributesAsGemFireIndexExpression() {
|
protected String getIndexableSessionAttributesAsGemFireIndexExpression() {
|
||||||
@@ -208,20 +220,23 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the maximum interval in seconds in which a Session can remain inactive before it is considered expired.
|
* Sets the maximum interval in seconds in which a Session can remain inactive before
|
||||||
|
* it is considered expired.
|
||||||
*
|
*
|
||||||
* @param maxInactiveIntervalInSeconds an integer value specifying the maximum interval in seconds that a Session
|
* @param maxInactiveIntervalInSeconds an integer value specifying the maximum
|
||||||
* can remain inactive before it is considered expired.
|
* interval in seconds that a Session can remain inactive before it is considered
|
||||||
|
* expired.
|
||||||
*/
|
*/
|
||||||
public void setMaxInactiveIntervalInSeconds(int maxInactiveIntervalInSeconds) {
|
public void setMaxInactiveIntervalInSeconds(int maxInactiveIntervalInSeconds) {
|
||||||
this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds;
|
this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the maximum interval in seconds in which a Session can remain inactive before it is considered expired.
|
* Gets the maximum interval in seconds in which a Session can remain inactive before
|
||||||
|
* it is considered expired.
|
||||||
*
|
*
|
||||||
* @return an integer value specifying the maximum interval in seconds that a Session can remain inactive
|
* @return an integer value specifying the maximum interval in seconds that a Session
|
||||||
* before it is considered expired.
|
* can remain inactive before it is considered expired.
|
||||||
* @see EnableGemFireHttpSession#maxInactiveIntervalInSeconds()
|
* @see EnableGemFireHttpSession#maxInactiveIntervalInSeconds()
|
||||||
*/
|
*/
|
||||||
protected int getMaxInactiveIntervalInSeconds() {
|
protected int getMaxInactiveIntervalInSeconds() {
|
||||||
@@ -229,7 +244,8 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link RegionShortcut} used to configure the GemFire Cache Region that will store Spring Sessions.
|
* Sets the {@link RegionShortcut} used to configure the GemFire Cache Region that
|
||||||
|
* will store Spring Sessions.
|
||||||
*
|
*
|
||||||
* @param shortcut the RegionShortcut used to configure the GemFire Cache Region.
|
* @param shortcut the RegionShortcut used to configure the GemFire Cache Region.
|
||||||
* @see com.gemstone.gemfire.cache.RegionShortcut
|
* @see com.gemstone.gemfire.cache.RegionShortcut
|
||||||
@@ -239,111 +255,131 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the {@link RegionShortcut} used to configure the GemFire Cache Region that will store Spring Sessions.
|
* Gets the {@link RegionShortcut} used to configure the GemFire Cache Region that
|
||||||
* Defaults to {@link RegionShortcut#PARTITION}.
|
* will store Spring Sessions. Defaults to {@link RegionShortcut#PARTITION}.
|
||||||
*
|
*
|
||||||
* @return the RegionShortcut used to configure the GemFire Cache Region.
|
* @return the RegionShortcut used to configure the GemFire Cache Region.
|
||||||
* @see com.gemstone.gemfire.cache.RegionShortcut
|
* @see com.gemstone.gemfire.cache.RegionShortcut
|
||||||
* @see EnableGemFireHttpSession#serverRegionShortcut()
|
* @see EnableGemFireHttpSession#serverRegionShortcut()
|
||||||
*/
|
*/
|
||||||
protected RegionShortcut getServerRegionShortcut() {
|
protected RegionShortcut getServerRegionShortcut() {
|
||||||
return (this.serverRegionShortcut != null ? this.serverRegionShortcut : DEFAULT_SERVER_REGION_SHORTCUT);
|
return (this.serverRegionShortcut != null ? this.serverRegionShortcut
|
||||||
|
: DEFAULT_SERVER_REGION_SHORTCUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the name of the Gemfire (Client)Cache Region used to store Sessions.
|
* Sets the name of the Gemfire (Client)Cache Region used to store Sessions.
|
||||||
*
|
*
|
||||||
* @param springSessionGemFireRegionName a String specifying the name of the GemFire (Client)Cache Region
|
* @param springSessionGemFireRegionName a String specifying the name of the GemFire
|
||||||
* used to store the Session.
|
* (Client)Cache Region used to store the Session.
|
||||||
*/
|
*/
|
||||||
public void setSpringSessionGemFireRegionName(String springSessionGemFireRegionName) {
|
public void setSpringSessionGemFireRegionName(String springSessionGemFireRegionName) {
|
||||||
this.springSessionGemFireRegionName = springSessionGemFireRegionName;
|
this.springSessionGemFireRegionName = springSessionGemFireRegionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the name of the Gemfire (Client)Cache Region used to store Sessions. Defaults to 'ClusteredSpringSessions'.
|
* Gets the name of the Gemfire (Client)Cache Region used to store Sessions. Defaults
|
||||||
|
* to 'ClusteredSpringSessions'.
|
||||||
*
|
*
|
||||||
* @return a String specifying the name of the GemFire (Client)Cache Region
|
* @return a String specifying the name of the GemFire (Client)Cache Region used to
|
||||||
* used to store the Session.
|
* store the Session.
|
||||||
* @see com.gemstone.gemfire.cache.Region#getName()
|
* @see com.gemstone.gemfire.cache.Region#getName()
|
||||||
* @see EnableGemFireHttpSession#regionName()
|
* @see EnableGemFireHttpSession#regionName()
|
||||||
*/
|
*/
|
||||||
protected String getSpringSessionGemFireRegionName() {
|
protected String getSpringSessionGemFireRegionName() {
|
||||||
return (StringUtils.hasText(this.springSessionGemFireRegionName) ? this.springSessionGemFireRegionName
|
return (StringUtils.hasText(this.springSessionGemFireRegionName)
|
||||||
|
? this.springSessionGemFireRegionName
|
||||||
: DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME);
|
: DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback with the {@link AnnotationMetadata} of the class containing @Import annotation that imported
|
* Callback with the {@link AnnotationMetadata} of the class containing @Import
|
||||||
* this @Configuration class.
|
* annotation that imported this @Configuration class.
|
||||||
*
|
*
|
||||||
* @param importMetadata the AnnotationMetadata of the class importing this @Configuration class.
|
* @param importMetadata the AnnotationMetadata of the class importing
|
||||||
* @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession
|
* this @Configuration class.
|
||||||
|
* @see org.springframework.session.data.gemfire.config.annotation.web.http.
|
||||||
|
* EnableGemFireHttpSession
|
||||||
* @see org.springframework.core.type.AnnotationMetadata
|
* @see org.springframework.core.type.AnnotationMetadata
|
||||||
*/
|
*/
|
||||||
public void setImportMetadata(AnnotationMetadata importMetadata) {
|
public void setImportMetadata(AnnotationMetadata importMetadata) {
|
||||||
AnnotationAttributes enableGemFireHttpSessionAnnotationAttributes = AnnotationAttributes.fromMap(
|
AnnotationAttributes enableGemFireHttpSessionAnnotationAttributes = AnnotationAttributes
|
||||||
importMetadata.getAnnotationAttributes(EnableGemFireHttpSession.class.getName()));
|
.fromMap(importMetadata.getAnnotationAttributes(
|
||||||
|
EnableGemFireHttpSession.class.getName()));
|
||||||
|
|
||||||
setClientRegionShortcut(ClientRegionShortcut.class.cast(enableGemFireHttpSessionAnnotationAttributes.getEnum(
|
setClientRegionShortcut(ClientRegionShortcut.class
|
||||||
"clientRegionShortcut")));
|
.cast(enableGemFireHttpSessionAnnotationAttributes
|
||||||
|
.getEnum("clientRegionShortcut")));
|
||||||
|
|
||||||
setIndexableSessionAttributes(enableGemFireHttpSessionAnnotationAttributes.getStringArray(
|
setIndexableSessionAttributes(enableGemFireHttpSessionAnnotationAttributes
|
||||||
"indexableSessionAttributes"));
|
.getStringArray("indexableSessionAttributes"));
|
||||||
|
|
||||||
setMaxInactiveIntervalInSeconds(enableGemFireHttpSessionAnnotationAttributes.getNumber(
|
setMaxInactiveIntervalInSeconds(enableGemFireHttpSessionAnnotationAttributes
|
||||||
"maxInactiveIntervalInSeconds").intValue());
|
.getNumber("maxInactiveIntervalInSeconds").intValue());
|
||||||
|
|
||||||
setServerRegionShortcut(RegionShortcut.class.cast(enableGemFireHttpSessionAnnotationAttributes.getEnum(
|
setServerRegionShortcut(
|
||||||
"serverRegionShortcut")));
|
RegionShortcut.class.cast(enableGemFireHttpSessionAnnotationAttributes
|
||||||
|
.getEnum("serverRegionShortcut")));
|
||||||
|
|
||||||
setSpringSessionGemFireRegionName(enableGemFireHttpSessionAnnotationAttributes.getString("regionName"));
|
setSpringSessionGemFireRegionName(
|
||||||
|
enableGemFireHttpSessionAnnotationAttributes.getString("regionName"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the Spring SessionRepository bean used to interact with GemFire as a Spring Session provider.
|
* Defines the Spring SessionRepository bean used to interact with GemFire as a Spring
|
||||||
|
* Session provider.
|
||||||
*
|
*
|
||||||
* @param gemfireOperations an instance of {@link GemfireOperations} used to manage Spring Sessions in GemFire.
|
* @param gemfireOperations an instance of {@link GemfireOperations} used to manage
|
||||||
* @return a GemFireOperationsSessionRepository for managing (clustering/replicating) Sessions using GemFire.
|
* Spring Sessions in GemFire.
|
||||||
|
* @return a GemFireOperationsSessionRepository for managing (clustering/replicating)
|
||||||
|
* Sessions using GemFire.
|
||||||
* @see org.springframework.session.data.gemfire.GemFireOperationsSessionRepository
|
* @see org.springframework.session.data.gemfire.GemFireOperationsSessionRepository
|
||||||
* @see org.springframework.data.gemfire.GemfireOperations
|
* @see org.springframework.data.gemfire.GemfireOperations
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public GemFireOperationsSessionRepository sessionRepository(@Qualifier("sessionRegionTemplate")
|
public GemFireOperationsSessionRepository sessionRepository(
|
||||||
GemfireOperations gemfireOperations) {
|
@Qualifier("sessionRegionTemplate") GemfireOperations gemfireOperations) {
|
||||||
|
|
||||||
GemFireOperationsSessionRepository sessionRepository = new GemFireOperationsSessionRepository(gemfireOperations);
|
GemFireOperationsSessionRepository sessionRepository = new GemFireOperationsSessionRepository(
|
||||||
|
gemfireOperations);
|
||||||
|
|
||||||
sessionRepository.setMaxInactiveIntervalInSeconds(getMaxInactiveIntervalInSeconds());
|
sessionRepository
|
||||||
|
.setMaxInactiveIntervalInSeconds(getMaxInactiveIntervalInSeconds());
|
||||||
|
|
||||||
return sessionRepository;
|
return sessionRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines a Spring GemfireTemplate bean used to interact with GemFire's (Client)Cache {@link Region}
|
* Defines a Spring GemfireTemplate bean used to interact with GemFire's (Client)Cache
|
||||||
* storing Sessions.
|
* {@link Region} storing Sessions.
|
||||||
*
|
*
|
||||||
* @param gemFireCache reference to the single GemFire cache instance used by the {@link GemfireTemplate}
|
* @param gemFireCache reference to the single GemFire cache instance used by the
|
||||||
* to perform GemFire cache data access operations.
|
* {@link GemfireTemplate} to perform GemFire cache data access operations.
|
||||||
* @return a {@link GemfireTemplate} used to interact with GemFire's (Client)Cache {@link Region} storing Sessions.
|
* @return a {@link GemfireTemplate} used to interact with GemFire's (Client)Cache
|
||||||
|
* {@link Region} storing Sessions.
|
||||||
* @see org.springframework.data.gemfire.GemfireTemplate
|
* @see org.springframework.data.gemfire.GemfireTemplate
|
||||||
* @see com.gemstone.gemfire.cache.Region
|
* @see com.gemstone.gemfire.cache.Region
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@DependsOn(DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME)
|
@DependsOn(DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME)
|
||||||
public GemfireTemplate sessionRegionTemplate(GemFireCache gemFireCache) {
|
public GemfireTemplate sessionRegionTemplate(GemFireCache gemFireCache) {
|
||||||
return new GemfireTemplate(gemFireCache.getRegion(getSpringSessionGemFireRegionName()));
|
return new GemfireTemplate(
|
||||||
|
gemFireCache.getRegion(getSpringSessionGemFireRegionName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines a Spring GemFire {@link com.gemstone.gemfire.cache.Cache} {@link Region} bean used to store
|
* Defines a Spring GemFire {@link com.gemstone.gemfire.cache.Cache} {@link Region}
|
||||||
* and manage Sessions using either a client-server or peer-to-peer (p2p) topology.
|
* bean used to store and manage Sessions using either a client-server or peer-to-peer
|
||||||
|
* (p2p) topology.
|
||||||
*
|
*
|
||||||
* @param gemfireCache a reference to the GemFire {@link com.gemstone.gemfire.cache.Cache}.
|
* @param gemfireCache a reference to the GemFire
|
||||||
* @param sessionRegionAttributes the GemFire {@link RegionAttributes} used to configure the {@link Region}.
|
* {@link com.gemstone.gemfire.cache.Cache}.
|
||||||
* @return a {@link GemFireCacheTypeAwareRegionFactoryBean} used to configure and initialize a GemFire Cache
|
* @param sessionRegionAttributes the GemFire {@link RegionAttributes} used to
|
||||||
* {@link Region} for storing and managing Sessions.
|
* configure the {@link Region}.
|
||||||
* @see org.springframework.session.data.gemfire.config.annotation.web.http.support.GemFireCacheTypeAwareRegionFactoryBean
|
* @return a {@link GemFireCacheTypeAwareRegionFactoryBean} used to configure and
|
||||||
|
* initialize a GemFire Cache {@link Region} for storing and managing Sessions.
|
||||||
|
* @see org.springframework.session.data.gemfire.config.annotation.web.http.support.
|
||||||
|
* GemFireCacheTypeAwareRegionFactoryBean
|
||||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||||
* @see com.gemstone.gemfire.cache.RegionAttributes
|
* @see com.gemstone.gemfire.cache.RegionAttributes
|
||||||
* @see #getClientRegionShortcut()
|
* @see #getClientRegionShortcut()
|
||||||
@@ -351,11 +387,11 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
|||||||
* @see #getServerRegionShortcut()
|
* @see #getServerRegionShortcut()
|
||||||
*/
|
*/
|
||||||
@Bean(name = DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME)
|
@Bean(name = DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME)
|
||||||
public GemFireCacheTypeAwareRegionFactoryBean<Object, ExpiringSession> sessionRegion(GemFireCache gemfireCache,
|
public GemFireCacheTypeAwareRegionFactoryBean<Object, ExpiringSession> sessionRegion(
|
||||||
|
GemFireCache gemfireCache,
|
||||||
RegionAttributes<Object, ExpiringSession> sessionRegionAttributes) {
|
RegionAttributes<Object, ExpiringSession> sessionRegionAttributes) {
|
||||||
|
|
||||||
GemFireCacheTypeAwareRegionFactoryBean<Object, ExpiringSession> serverRegion =
|
GemFireCacheTypeAwareRegionFactoryBean<Object, ExpiringSession> serverRegion = new GemFireCacheTypeAwareRegionFactoryBean<Object, ExpiringSession>();
|
||||||
new GemFireCacheTypeAwareRegionFactoryBean<Object, ExpiringSession>();
|
|
||||||
|
|
||||||
serverRegion.setGemfireCache(gemfireCache);
|
serverRegion.setGemfireCache(gemfireCache);
|
||||||
serverRegion.setClientRegionShortcut(getClientRegionShortcut());
|
serverRegion.setClientRegionShortcut(getClientRegionShortcut());
|
||||||
@@ -367,13 +403,14 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines a Spring GemFire {@link RegionAttributes} bean used to configure and initialize the GemFire cache
|
* Defines a Spring GemFire {@link RegionAttributes} bean used to configure and
|
||||||
* {@link Region} storing Sessions. Expiration is also configured for the {@link Region} on the basis that the
|
* initialize the GemFire cache {@link Region} storing Sessions. Expiration is also
|
||||||
* GemFire cache {@link Region} is a not a proxy, on either the client or server.
|
* configured for the {@link Region} on the basis that the GemFire cache
|
||||||
|
* {@link Region} is a not a proxy, on either the client or server.
|
||||||
*
|
*
|
||||||
* @param gemfireCache a reference to the GemFire cache.
|
* @param gemfireCache a reference to the GemFire cache.
|
||||||
* @return an instance of {@link RegionAttributes} used to configure and initialize the GemFire cache {@link Region}
|
* @return an instance of {@link RegionAttributes} used to configure and initialize
|
||||||
* for storing and managing Sessions.
|
* the GemFire cache {@link Region} for storing and managing Sessions.
|
||||||
* @see org.springframework.data.gemfire.RegionAttributesFactoryBean
|
* @see org.springframework.data.gemfire.RegionAttributesFactoryBean
|
||||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||||
* @see com.gemstone.gemfire.cache.PartitionAttributes
|
* @see com.gemstone.gemfire.cache.PartitionAttributes
|
||||||
@@ -381,44 +418,49 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
|||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@SuppressWarnings({ "unchecked", "deprecation" })
|
@SuppressWarnings({ "unchecked", "deprecation" })
|
||||||
public RegionAttributesFactoryBean sessionRegionAttributes(GemFireCache gemfireCache) {
|
public RegionAttributesFactoryBean sessionRegionAttributes(
|
||||||
|
GemFireCache gemfireCache) {
|
||||||
RegionAttributesFactoryBean regionAttributes = new RegionAttributesFactoryBean();
|
RegionAttributesFactoryBean regionAttributes = new RegionAttributesFactoryBean();
|
||||||
|
|
||||||
regionAttributes.setKeyConstraint(SPRING_SESSION_GEMFIRE_REGION_KEY_CONSTRAINT);
|
regionAttributes.setKeyConstraint(SPRING_SESSION_GEMFIRE_REGION_KEY_CONSTRAINT);
|
||||||
regionAttributes.setValueConstraint(SPRING_SESSION_GEMFIRE_REGION_VALUE_CONSTRAINT);
|
regionAttributes
|
||||||
|
.setValueConstraint(SPRING_SESSION_GEMFIRE_REGION_VALUE_CONSTRAINT);
|
||||||
|
|
||||||
if (isExpirationAllowed(gemfireCache)) {
|
if (isExpirationAllowed(gemfireCache)) {
|
||||||
regionAttributes.setStatisticsEnabled(true);
|
regionAttributes.setStatisticsEnabled(true);
|
||||||
regionAttributes.setEntryIdleTimeout(new ExpirationAttributes(
|
regionAttributes.setEntryIdleTimeout(new ExpirationAttributes(
|
||||||
Math.max(getMaxInactiveIntervalInSeconds(), 0), ExpirationAction.INVALIDATE));
|
Math.max(getMaxInactiveIntervalInSeconds(), 0),
|
||||||
|
ExpirationAction.INVALIDATE));
|
||||||
}
|
}
|
||||||
|
|
||||||
return regionAttributes;
|
return regionAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether expiration configuration is allowed to be set on the GemFire cache {@link Region}
|
* Determines whether expiration configuration is allowed to be set on the GemFire
|
||||||
* used to store and manage Sessions.
|
* cache {@link Region} used to store and manage Sessions.
|
||||||
*
|
*
|
||||||
* @param gemfireCache a reference to the GemFire cache.
|
* @param gemfireCache a reference to the GemFire cache.
|
||||||
* @return a boolean indicating if a {@link Region} can be configured for Region entry idle-timeout expiration.
|
* @return a boolean indicating if a {@link Region} can be configured for Region entry
|
||||||
|
* idle-timeout expiration.
|
||||||
* @see GemFireUtils#isClient(GemFireCache)
|
* @see GemFireUtils#isClient(GemFireCache)
|
||||||
* @see GemFireUtils#isProxy(ClientRegionShortcut)
|
* @see GemFireUtils#isProxy(ClientRegionShortcut)
|
||||||
* @see GemFireUtils#isProxy(RegionShortcut)
|
* @see GemFireUtils#isProxy(RegionShortcut)
|
||||||
*/
|
*/
|
||||||
boolean isExpirationAllowed(GemFireCache gemfireCache) {
|
boolean isExpirationAllowed(GemFireCache gemfireCache) {
|
||||||
return !(GemFireUtils.isClient(gemfireCache) ? GemFireUtils.isProxy(getClientRegionShortcut())
|
return !(GemFireUtils.isClient(gemfireCache)
|
||||||
|
? GemFireUtils.isProxy(getClientRegionShortcut())
|
||||||
: GemFireUtils.isProxy(getServerRegionShortcut()));
|
: GemFireUtils.isProxy(getServerRegionShortcut()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines a Spring GemFire Index bean on the GemFire cache {@link Region} storing and managing Sessions,
|
* Defines a Spring GemFire Index bean on the GemFire cache {@link Region} storing and
|
||||||
* specifically on the 'principalName' property for quick lookup and queries. This index will only be created
|
* managing Sessions, specifically on the 'principalName' property for quick lookup
|
||||||
* on a server @{link Region}.
|
* and queries. This index will only be created on a server @{link Region}.
|
||||||
*
|
*
|
||||||
* @param gemfireCache a reference to the GemFire cache.
|
* @param gemfireCache a reference to the GemFire cache.
|
||||||
* @return a IndexFactoryBean creating an GemFire Index on the 'principalName' property of Sessions stored
|
* @return a IndexFactoryBean creating an GemFire Index on the 'principalName'
|
||||||
* in the GemFire cache {@link Region}.
|
* property of Sessions stored in the GemFire cache {@link Region}.
|
||||||
* @see org.springframework.data.gemfire.IndexFactoryBean
|
* @see org.springframework.data.gemfire.IndexFactoryBean
|
||||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||||
*/
|
*/
|
||||||
@@ -445,12 +487,14 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines a Spring GemFire Index bean on the GemFire cache {@link Region} storing and managing Sessions,
|
* Defines a Spring GemFire Index bean on the GemFire cache {@link Region} storing and
|
||||||
* specifically on Session attributes for quick lookup and queries on Session attribute names with a given value.
|
* managing Sessions, specifically on Session attributes for quick lookup and queries
|
||||||
* This index will only be created on a server @{link Region}.
|
* on Session attribute names with a given value. This index will only be created on a
|
||||||
|
* server @{link Region}.
|
||||||
*
|
*
|
||||||
* @param gemfireCache a reference to the GemFire cache.
|
* @param gemfireCache a reference to the GemFire cache.
|
||||||
* @return a IndexFactoryBean creating an GemFire Index on attributes of Sessions stored in the GemFire cache {@link Region}.
|
* @return a IndexFactoryBean creating an GemFire Index on attributes of Sessions
|
||||||
|
* stored in the GemFire cache {@link Region}.
|
||||||
* @see org.springframework.data.gemfire.IndexFactoryBean
|
* @see org.springframework.data.gemfire.IndexFactoryBean
|
||||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||||
*/
|
*/
|
||||||
@@ -460,7 +504,8 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
|||||||
IndexFactoryBean index = new IndexFactoryBean() {
|
IndexFactoryBean index = new IndexFactoryBean() {
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
if (GemFireUtils.isPeer(gemfireCache) && !ObjectUtils.isEmpty(getIndexableSessionAttributes())) {
|
if (GemFireUtils.isPeer(gemfireCache)
|
||||||
|
&& !ObjectUtils.isEmpty(getIndexableSessionAttributes())) {
|
||||||
super.afterPropertiesSet();
|
super.afterPropertiesSet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -468,8 +513,10 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
|
|||||||
|
|
||||||
index.setCache(gemfireCache);
|
index.setCache(gemfireCache);
|
||||||
index.setName("sessionAttributesIndex");
|
index.setName("sessionAttributesIndex");
|
||||||
index.setExpression(String.format("s.attributes[%1$s]", getIndexableSessionAttributesAsGemFireIndexExpression()));
|
index.setExpression(String.format("s.attributes[%1$s]",
|
||||||
index.setFrom(String.format("%1$s s", GemFireUtils.toRegionPath(getSpringSessionGemFireRegionName())));
|
getIndexableSessionAttributesAsGemFireIndexExpression()));
|
||||||
|
index.setFrom(String.format("%1$s s",
|
||||||
|
GemFireUtils.toRegionPath(getSpringSessionGemFireRegionName())));
|
||||||
index.setOverride(true);
|
index.setOverride(true);
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
|
|||||||
@@ -34,8 +34,9 @@ import org.springframework.util.Assert;
|
|||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The GemFireCacheTypeAwareRegionFactoryBean class is a Spring {@link FactoryBean} used to construct, configure
|
* The GemFireCacheTypeAwareRegionFactoryBean class is a Spring {@link FactoryBean} used
|
||||||
* and initialize the GemFire cache {@link Region} used to store and manage Session state.
|
* to construct, configure and initialize the GemFire cache {@link Region} used to store
|
||||||
|
* and manage Session state.
|
||||||
*
|
*
|
||||||
* @param <K> the type of keys
|
* @param <K> the type of keys
|
||||||
* @param <V> the type of values
|
* @param <V> the type of values
|
||||||
@@ -45,7 +46,8 @@ import org.springframework.util.StringUtils;
|
|||||||
* @see org.springframework.beans.factory.InitializingBean
|
* @see org.springframework.beans.factory.InitializingBean
|
||||||
* @see org.springframework.data.gemfire.GenericRegionFactoryBean
|
* @see org.springframework.data.gemfire.GenericRegionFactoryBean
|
||||||
* @see org.springframework.data.gemfire.client.ClientRegionFactoryBean
|
* @see org.springframework.data.gemfire.client.ClientRegionFactoryBean
|
||||||
* @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration
|
* @see org.springframework.session.data.gemfire.config.annotation.web.http.
|
||||||
|
* GemFireHttpSessionConfiguration
|
||||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||||
* @see com.gemstone.gemfire.cache.InterestResultPolicy
|
* @see com.gemstone.gemfire.cache.InterestResultPolicy
|
||||||
* @see com.gemstone.gemfire.cache.Region
|
* @see com.gemstone.gemfire.cache.Region
|
||||||
@@ -53,16 +55,14 @@ import org.springframework.util.StringUtils;
|
|||||||
* @see com.gemstone.gemfire.cache.RegionShortcut
|
* @see com.gemstone.gemfire.cache.RegionShortcut
|
||||||
* @see com.gemstone.gemfire.cache.client.ClientRegionShortcut
|
* @see com.gemstone.gemfire.cache.client.ClientRegionShortcut
|
||||||
*/
|
*/
|
||||||
public class GemFireCacheTypeAwareRegionFactoryBean<K, V> implements FactoryBean<Region<K, V>>, InitializingBean {
|
public class GemFireCacheTypeAwareRegionFactoryBean<K, V>
|
||||||
|
implements FactoryBean<Region<K, V>>, InitializingBean {
|
||||||
|
|
||||||
protected static final ClientRegionShortcut DEFAULT_CLIENT_REGION_SHORTCUT =
|
protected static final ClientRegionShortcut DEFAULT_CLIENT_REGION_SHORTCUT = GemFireHttpSessionConfiguration.DEFAULT_CLIENT_REGION_SHORTCUT;
|
||||||
GemFireHttpSessionConfiguration.DEFAULT_CLIENT_REGION_SHORTCUT;
|
|
||||||
|
|
||||||
protected static final RegionShortcut DEFAULT_SERVER_REGION_SHORTCUT =
|
protected static final RegionShortcut DEFAULT_SERVER_REGION_SHORTCUT = GemFireHttpSessionConfiguration.DEFAULT_SERVER_REGION_SHORTCUT;
|
||||||
GemFireHttpSessionConfiguration.DEFAULT_SERVER_REGION_SHORTCUT;
|
|
||||||
|
|
||||||
protected static final String DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME =
|
protected static final String DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME = GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME;
|
||||||
GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME;
|
|
||||||
|
|
||||||
private ClientRegionShortcut clientRegionShortcut;
|
private ClientRegionShortcut clientRegionShortcut;
|
||||||
|
|
||||||
@@ -77,9 +77,10 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> implements FactoryBean
|
|||||||
private String regionName;
|
private String regionName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Post-construction initialization callback to create, configure and initialize the GemFire cache {@link Region}
|
* Post-construction initialization callback to create, configure and initialize the
|
||||||
* used to store, replicate (distribute) and manage Session state. This method intelligently handles
|
* GemFire cache {@link Region} used to store, replicate (distribute) and manage
|
||||||
* both client-server and peer-to-peer (p2p) GemFire supported distributed system topologies.
|
* Session state. This method intelligently handles both client-server and
|
||||||
|
* peer-to-peer (p2p) GemFire supported distributed system topologies.
|
||||||
*
|
*
|
||||||
* @throws Exception if the initialization of the GemFire cache {@link Region} fails.
|
* @throws Exception if the initialization of the GemFire cache {@link Region} fails.
|
||||||
* @see org.springframework.session.data.gemfire.support.GemFireUtils#isClient(GemFireCache)
|
* @see org.springframework.session.data.gemfire.support.GemFireUtils#isClient(GemFireCache)
|
||||||
@@ -95,13 +96,16 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> implements FactoryBean
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a GemFire cache {@link Region} using a peer-to-peer (p2p) GemFire topology to store
|
* Constructs a GemFire cache {@link Region} using a peer-to-peer (p2p) GemFire
|
||||||
* and manage Session state in a GemFire server cluster accessible from a GemFire cache client.
|
* topology to store and manage Session state in a GemFire server cluster accessible
|
||||||
|
* from a GemFire cache client.
|
||||||
*
|
*
|
||||||
* @param gemfireCache a reference to the GemFire {@link com.gemstone.gemfire.cache.Cache}.
|
* @param gemfireCache a reference to the GemFire
|
||||||
* @return a peer-to-peer-based GemFire cache {@link Region} to store and manage Session state.
|
* {@link com.gemstone.gemfire.cache.Cache}.
|
||||||
* @throws Exception if the instantiation, configuration and initialization
|
* @return a peer-to-peer-based GemFire cache {@link Region} to store and manage
|
||||||
* of the GemFire cache {@link Region} fails.
|
* Session state.
|
||||||
|
* @throws Exception if the instantiation, configuration and initialization of the
|
||||||
|
* GemFire cache {@link Region} fails.
|
||||||
* @see org.springframework.data.gemfire.GenericRegionFactoryBean
|
* @see org.springframework.data.gemfire.GenericRegionFactoryBean
|
||||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||||
* @see com.gemstone.gemfire.cache.Region
|
* @see com.gemstone.gemfire.cache.Region
|
||||||
@@ -122,13 +126,16 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> implements FactoryBean
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a GemFire cache {@link Region} using the client-server GemFire topology to store
|
* Constructs a GemFire cache {@link Region} using the client-server GemFire topology
|
||||||
* and manage Session state in a GemFire server cluster accessible from a GemFire cache client.
|
* to store and manage Session state in a GemFire server cluster accessible from a
|
||||||
|
* GemFire cache client.
|
||||||
*
|
*
|
||||||
* @param gemfireCache a reference to the GemFire {@link com.gemstone.gemfire.cache.Cache}.
|
* @param gemfireCache a reference to the GemFire
|
||||||
* @return a client-server-based GemFire cache {@link Region} to store and manage Session state.
|
* {@link com.gemstone.gemfire.cache.Cache}.
|
||||||
* @throws Exception if the instantiation, configuration and initialization
|
* @return a client-server-based GemFire cache {@link Region} to store and manage
|
||||||
* of the GemFire cache {@link Region} fails.
|
* Session state.
|
||||||
|
* @throws Exception if the instantiation, configuration and initialization of the
|
||||||
|
* GemFire cache {@link Region} fails.
|
||||||
* @see org.springframework.data.gemfire.client.ClientRegionFactoryBean
|
* @see org.springframework.data.gemfire.client.ClientRegionFactoryBean
|
||||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||||
* @see com.gemstone.gemfire.cache.Region
|
* @see com.gemstone.gemfire.cache.Region
|
||||||
@@ -155,12 +162,14 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> implements FactoryBean
|
|||||||
/**
|
/**
|
||||||
* Registers interests in all keys when the client {@link Region} is non-local.
|
* 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.
|
* @return an array of Interests specifying the server notifications of interests to
|
||||||
|
* the client.
|
||||||
* @see org.springframework.data.gemfire.client.Interest
|
* @see org.springframework.data.gemfire.client.Interest
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* Decides whether interests will be registered for all keys. Interests is only registered on a client
|
* Decides whether interests will be registered for all keys. Interests is only
|
||||||
* and typically only when the client is a (CACHING) PROXY to the server (i.e. non-LOCAL 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.
|
* @param register a boolean value indicating whether interests should be registered.
|
||||||
* @return an array of Interests KEY/VALUE registrations.
|
* @return an array of Interests KEY/VALUE registrations.
|
||||||
@@ -168,13 +177,14 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> implements FactoryBean
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected Interest<K>[] registerInterests(boolean register) {
|
protected Interest<K>[] registerInterests(boolean register) {
|
||||||
return (!register ? new Interest[0] : new Interest[] {
|
return (!register ? new Interest[0]
|
||||||
new Interest<String>("ALL_KEYS", InterestResultPolicy.KEYS)
|
: new Interest[] {
|
||||||
});
|
new Interest<String>("ALL_KEYS", InterestResultPolicy.KEYS) });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a reference to the constructed GemFire cache {@link Region} used to store and manage Session state.
|
* Returns a reference to the constructed GemFire cache {@link Region} used to store
|
||||||
|
* and manage Session state.
|
||||||
*
|
*
|
||||||
* @return the {@link Region} used to store and manage Session state.
|
* @return the {@link Region} used to store and manage Session state.
|
||||||
* @throws Exception if the {@link Region} reference cannot be obtained.
|
* @throws Exception if the {@link Region} reference cannot be obtained.
|
||||||
@@ -185,8 +195,8 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> implements FactoryBean
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the specific type of GemFire cache {@link Region} this factory creates when initialized
|
* Returns the specific type of GemFire cache {@link Region} this factory creates when
|
||||||
* or Region.class when uninitialized.
|
* initialized or Region.class when uninitialized.
|
||||||
*
|
*
|
||||||
* @return the GemFire cache {@link Region} class type constructed by this factory.
|
* @return the GemFire cache {@link Region} class type constructed by this factory.
|
||||||
* @see com.gemstone.gemfire.cache.Region
|
* @see com.gemstone.gemfire.cache.Region
|
||||||
@@ -197,19 +207,22 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> implements FactoryBean
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true indicating the GemFire cache {@link Region} created by this factory is the sole instance.
|
* Returns true indicating the GemFire cache {@link Region} created by this factory is
|
||||||
|
* the sole instance.
|
||||||
*
|
*
|
||||||
* @return true to indicate the GemFire cache {@link Region} storing and managing Sessions is a Singleton.
|
* @return true to indicate the GemFire cache {@link Region} storing and managing
|
||||||
|
* Sessions is a Singleton.
|
||||||
*/
|
*/
|
||||||
public boolean isSingleton() {
|
public boolean isSingleton() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link Region} data policy used by the GemFire cache client to manage Session state.
|
* Sets the {@link Region} data policy used by the GemFire cache client to manage
|
||||||
|
* Session state.
|
||||||
*
|
*
|
||||||
* @param clientRegionShortcut a {@link ClientRegionShortcut} to specify the client {@link Region}
|
* @param clientRegionShortcut a {@link ClientRegionShortcut} to specify the client
|
||||||
* data management policy.
|
* {@link Region} data management policy.
|
||||||
* @see com.gemstone.gemfire.cache.client.ClientRegionShortcut
|
* @see com.gemstone.gemfire.cache.client.ClientRegionShortcut
|
||||||
*/
|
*/
|
||||||
public void setClientRegionShortcut(ClientRegionShortcut clientRegionShortcut) {
|
public void setClientRegionShortcut(ClientRegionShortcut clientRegionShortcut) {
|
||||||
@@ -217,19 +230,22 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> implements FactoryBean
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link Region} data policy used by the GemFire cache client to manage Session state. Defaults to
|
* Returns the {@link Region} data policy used by the GemFire cache client to manage
|
||||||
* {@link ClientRegionShortcut#PROXY}.
|
* Session state. Defaults to {@link ClientRegionShortcut#PROXY}.
|
||||||
*
|
*
|
||||||
* @return a {@link ClientRegionShortcut} specifying the client {@link Region} data management policy.
|
* @return a {@link ClientRegionShortcut} specifying the client {@link Region} data
|
||||||
|
* management policy.
|
||||||
* @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration#DEFAULT_CLIENT_REGION_SHORTCUT
|
* @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration#DEFAULT_CLIENT_REGION_SHORTCUT
|
||||||
* @see com.gemstone.gemfire.cache.client.ClientRegionShortcut
|
* @see com.gemstone.gemfire.cache.client.ClientRegionShortcut
|
||||||
*/
|
*/
|
||||||
protected ClientRegionShortcut getClientRegionShortcut() {
|
protected ClientRegionShortcut getClientRegionShortcut() {
|
||||||
return (this.clientRegionShortcut != null ? this.clientRegionShortcut : DEFAULT_CLIENT_REGION_SHORTCUT);
|
return (this.clientRegionShortcut != null ? this.clientRegionShortcut
|
||||||
|
: DEFAULT_CLIENT_REGION_SHORTCUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a reference to the GemFire cache used to construct the appropriate {@link Region}.
|
* Sets a reference to the GemFire cache used to construct the appropriate
|
||||||
|
* {@link Region}.
|
||||||
*
|
*
|
||||||
* @param gemfireCache a reference to the GemFire cache.
|
* @param gemfireCache a reference to the GemFire cache.
|
||||||
* @throws IllegalArgumentException if the {@link GemFireCache} reference is null.
|
* @throws IllegalArgumentException if the {@link GemFireCache} reference is null.
|
||||||
@@ -240,21 +256,24 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> implements FactoryBean
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a reference to the GemFire cache used to construct the appropriate {@link Region}.
|
* Returns a reference to the GemFire cache used to construct the appropriate
|
||||||
|
* {@link Region}.
|
||||||
*
|
*
|
||||||
* @return a reference to the GemFire cache.
|
* @return a reference to the GemFire cache.
|
||||||
* @throws IllegalStateException if the {@link GemFireCache} reference is null.
|
* @throws IllegalStateException if the {@link GemFireCache} reference is null.
|
||||||
*/
|
*/
|
||||||
protected GemFireCache getGemfireCache() {
|
protected GemFireCache getGemfireCache() {
|
||||||
Assert.state(this.gemfireCache != null, "A reference to a GemFireCache was not properly configured");
|
Assert.state(this.gemfireCache != null,
|
||||||
|
"A reference to a GemFireCache was not properly configured");
|
||||||
return this.gemfireCache;
|
return this.gemfireCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the GemFire {@link RegionAttributes} used to configure the GemFire cache {@link Region} used to
|
* Sets the GemFire {@link RegionAttributes} used to configure the GemFire cache
|
||||||
* store and manage Session state.
|
* {@link Region} used to store and manage Session state.
|
||||||
*
|
*
|
||||||
* @param regionAttributes the GemFire {@link RegionAttributes} used to configure the GemFire cache {@link Region}.
|
* @param regionAttributes the GemFire {@link RegionAttributes} used to configure the
|
||||||
|
* GemFire cache {@link Region}.
|
||||||
* @see com.gemstone.gemfire.cache.RegionAttributes
|
* @see com.gemstone.gemfire.cache.RegionAttributes
|
||||||
*/
|
*/
|
||||||
public void setRegionAttributes(RegionAttributes<K, V> regionAttributes) {
|
public void setRegionAttributes(RegionAttributes<K, V> regionAttributes) {
|
||||||
@@ -262,10 +281,11 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> implements FactoryBean
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the GemFire {@link RegionAttributes} used to configure the GemFire cache {@link Region} used to
|
* Returns the GemFire {@link RegionAttributes} used to configure the GemFire cache
|
||||||
* store and manage Session state.
|
* {@link Region} used to store and manage Session state.
|
||||||
*
|
*
|
||||||
* @return the GemFire {@link RegionAttributes} used to configure the GemFire cache {@link Region}.
|
* @return the GemFire {@link RegionAttributes} used to configure the GemFire cache
|
||||||
|
* {@link Region}.
|
||||||
* @see com.gemstone.gemfire.cache.RegionAttributes
|
* @see com.gemstone.gemfire.cache.RegionAttributes
|
||||||
*/
|
*/
|
||||||
protected RegionAttributes<K, V> getRegionAttributes() {
|
protected RegionAttributes<K, V> getRegionAttributes() {
|
||||||
@@ -273,7 +293,8 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> implements FactoryBean
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the name of the GemFire cache {@link Region} use to store and manage Session state.
|
* Sets the name of the GemFire cache {@link Region} use to store and manage Session
|
||||||
|
* state.
|
||||||
*
|
*
|
||||||
* @param regionName a String specifying the name of the GemFire cache {@link Region}.
|
* @param regionName a String specifying the name of the GemFire cache {@link Region}.
|
||||||
*/
|
*/
|
||||||
@@ -282,20 +303,23 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> implements FactoryBean
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the configured name of the GemFire cache {@link Region} use to store and manage Session state.
|
* Returns the configured name of the GemFire cache {@link Region} use to store and
|
||||||
* Defaults to "ClusteredSpringSessions"
|
* manage Session state. Defaults to "ClusteredSpringSessions"
|
||||||
*
|
*
|
||||||
* @return a String specifying the name of the GemFire cache {@link Region}.
|
* @return a String specifying the name of the GemFire cache {@link Region}.
|
||||||
* @see com.gemstone.gemfire.cache.Region#getName()
|
* @see com.gemstone.gemfire.cache.Region#getName()
|
||||||
*/
|
*/
|
||||||
protected String getRegionName() {
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link Region} data policy used by the GemFire peer cache to manage Session state.
|
* Sets the {@link Region} data policy used by the GemFire peer cache to manage
|
||||||
|
* Session state.
|
||||||
*
|
*
|
||||||
* @param serverRegionShortcut a {@link RegionShortcut} to specify the peer {@link Region} data management policy.
|
* @param serverRegionShortcut a {@link RegionShortcut} to specify the peer
|
||||||
|
* {@link Region} data management policy.
|
||||||
* @see com.gemstone.gemfire.cache.RegionShortcut
|
* @see com.gemstone.gemfire.cache.RegionShortcut
|
||||||
*/
|
*/
|
||||||
public void setServerRegionShortcut(RegionShortcut serverRegionShortcut) {
|
public void setServerRegionShortcut(RegionShortcut serverRegionShortcut) {
|
||||||
@@ -303,14 +327,16 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> implements FactoryBean
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link Region} data policy used by the GemFire peer cache to manage Session state. Defaults to
|
* Returns the {@link Region} data policy used by the GemFire peer cache to manage
|
||||||
* {@link RegionShortcut#PARTITION}.
|
* Session state. Defaults to {@link RegionShortcut#PARTITION}.
|
||||||
*
|
*
|
||||||
* @return a {@link RegionShortcut} specifying the peer {@link Region} data management policy.
|
* @return a {@link RegionShortcut} specifying the peer {@link Region} data management
|
||||||
|
* policy.
|
||||||
* @see com.gemstone.gemfire.cache.RegionShortcut
|
* @see com.gemstone.gemfire.cache.RegionShortcut
|
||||||
*/
|
*/
|
||||||
protected RegionShortcut getServerRegionShortcut() {
|
protected RegionShortcut getServerRegionShortcut() {
|
||||||
return (this.serverRegionShortcut != null ? this.serverRegionShortcut : DEFAULT_SERVER_REGION_SHORTCUT);
|
return (this.serverRegionShortcut != null ? this.serverRegionShortcut
|
||||||
|
: DEFAULT_SERVER_REGION_SHORTCUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
|
|||||||
import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
|
import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GemFireUtils is an abstract, extensible utility class for working with GemFire types and functionality
|
* GemFireUtils is an abstract, extensible utility class for working with GemFire types
|
||||||
* and is used by Spring Session's GemFire adapter support classes.
|
* and functionality and is used by Spring Session's GemFire adapter support classes.
|
||||||
*
|
*
|
||||||
* @author John Blum
|
* @author John Blum
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
@@ -40,8 +40,8 @@ public abstract class GemFireUtils {
|
|||||||
* Null-safe method to close the given {@link Closeable} object.
|
* Null-safe method to close the given {@link Closeable} object.
|
||||||
*
|
*
|
||||||
* @param obj the {@link Closeable} object to close.
|
* @param obj the {@link Closeable} object to close.
|
||||||
* @return true if the {@link Closeable} object is not null and was successfully closed,
|
* @return true if the {@link Closeable} object is not null and was successfully
|
||||||
* otherwise return false.
|
* closed, otherwise return false.
|
||||||
* @see java.io.Closeable
|
* @see java.io.Closeable
|
||||||
*/
|
*/
|
||||||
public static boolean close(Closeable obj) {
|
public static boolean close(Closeable obj) {
|
||||||
@@ -67,7 +67,8 @@ public abstract class GemFireUtils {
|
|||||||
*/
|
*/
|
||||||
public static boolean isClient(GemFireCache gemFireCache) {
|
public static boolean isClient(GemFireCache gemFireCache) {
|
||||||
boolean client = (gemFireCache instanceof ClientCache);
|
boolean client = (gemFireCache instanceof ClientCache);
|
||||||
client &= (!(gemFireCache instanceof GemFireCacheImpl) || ((GemFireCacheImpl) gemFireCache).isClient());
|
client &= (!(gemFireCache instanceof GemFireCacheImpl)
|
||||||
|
|| ((GemFireCacheImpl) gemFireCache).isClient());
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +88,8 @@ public abstract class GemFireUtils {
|
|||||||
* Determines whether the given {@link ClientRegionShortcut} is local only.
|
* Determines whether the given {@link ClientRegionShortcut} is local only.
|
||||||
*
|
*
|
||||||
* @param shortcut the ClientRegionShortcut to evaluate.
|
* @param shortcut the ClientRegionShortcut to evaluate.
|
||||||
* @return a boolean value indicating if the {@link ClientRegionShortcut} is local or not.
|
* @return a boolean value indicating if the {@link ClientRegionShortcut} is local or
|
||||||
|
* not.
|
||||||
* @see com.gemstone.gemfire.cache.client.ClientRegionShortcut
|
* @see com.gemstone.gemfire.cache.client.ClientRegionShortcut
|
||||||
*/
|
*/
|
||||||
public static boolean isLocal(ClientRegionShortcut shortcut) {
|
public static boolean isLocal(ClientRegionShortcut shortcut) {
|
||||||
@@ -104,12 +106,12 @@ public abstract class GemFireUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether the client {@link ClientRegionShortcut} is a proxy-based shortcut.
|
* Determines whether the client {@link ClientRegionShortcut} is a proxy-based
|
||||||
* NOTE: "proxy"-based Regions keep no local state.
|
* shortcut. NOTE: "proxy"-based Regions keep no local state.
|
||||||
*
|
*
|
||||||
* @param shortcut the client {@link ClientRegionShortcut} to evaluate.
|
* @param shortcut the client {@link ClientRegionShortcut} to evaluate.
|
||||||
* @return a boolean value indicating whether the client {@link ClientRegionShortcut} refers to
|
* @return a boolean value indicating whether the client {@link ClientRegionShortcut}
|
||||||
* a proxy-based shortcut.
|
* refers to a proxy-based shortcut.
|
||||||
* @see com.gemstone.gemfire.cache.client.ClientRegionShortcut
|
* @see com.gemstone.gemfire.cache.client.ClientRegionShortcut
|
||||||
*/
|
*/
|
||||||
public static boolean isProxy(ClientRegionShortcut shortcut) {
|
public static boolean isProxy(ClientRegionShortcut shortcut) {
|
||||||
@@ -122,11 +124,12 @@ public abstract class GemFireUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether the peer {@link RegionShortcut} is a proxy-based shortcut. NOTE: "proxy"-based Regions
|
* Determines whether the peer {@link RegionShortcut} is a proxy-based shortcut. NOTE:
|
||||||
* keep no local state.
|
* "proxy"-based Regions keep no local state.
|
||||||
*
|
*
|
||||||
* @param shortcut the peer {@link RegionShortcut} to evaluate.
|
* @param shortcut the peer {@link RegionShortcut} to evaluate.
|
||||||
* @return a boolean value indicating whether the peer {@link RegionShortcut} refers to a proxy-based shortcut.
|
* @return a boolean value indicating whether the peer {@link RegionShortcut} refers
|
||||||
|
* to a proxy-based shortcut.
|
||||||
* @see com.gemstone.gemfire.cache.RegionShortcut
|
* @see com.gemstone.gemfire.cache.RegionShortcut
|
||||||
*/
|
*/
|
||||||
public static boolean isProxy(RegionShortcut shortcut) {
|
public static boolean isProxy(RegionShortcut shortcut) {
|
||||||
|
|||||||
@@ -1,7 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* 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.mongo;
|
package org.springframework.session.data.mongo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.core.convert.converter.GenericConverter;
|
import org.springframework.core.convert.converter.GenericConverter;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.data.mongodb.core.IndexOperations;
|
import org.springframework.data.mongodb.core.IndexOperations;
|
||||||
@@ -9,12 +27,10 @@ import org.springframework.data.mongodb.core.index.Index;
|
|||||||
import org.springframework.data.mongodb.core.index.IndexInfo;
|
import org.springframework.data.mongodb.core.index.IndexInfo;
|
||||||
import org.springframework.data.mongodb.core.query.Query;
|
import org.springframework.data.mongodb.core.query.Query;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for serializing and deserializing session objects.
|
* Base class for serializing and deserializing session objects. To create custom
|
||||||
* To create custom serializer you have to implement this interface
|
* serializer you have to implement this interface and simply register your class as a
|
||||||
* and simply register your class as a bean.
|
* bean.
|
||||||
*
|
*
|
||||||
* @author Jakub Kubrynski
|
* @author Jakub Kubrynski
|
||||||
* @since 1.2
|
* @since 1.2
|
||||||
@@ -26,7 +42,7 @@ public abstract class AbstractMongoSessionConverter implements GenericConverter
|
|||||||
protected static final String EXPIRE_AT_FIELD_NAME = "expireAt";
|
protected static final String EXPIRE_AT_FIELD_NAME = "expireAt";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns query to be executed to return sessions based on a particular index
|
* Returns query to be executed to return sessions based on a particular index.
|
||||||
* @param indexName name of the index
|
* @param indexName name of the index
|
||||||
* @param indexValue value to query against
|
* @param indexValue value to query against
|
||||||
* @return built query or null if indexName is not supported
|
* @return built query or null if indexName is not supported
|
||||||
@@ -34,23 +50,26 @@ public abstract class AbstractMongoSessionConverter implements GenericConverter
|
|||||||
protected abstract Query getQueryForIndex(String indexName, Object indexValue);
|
protected abstract Query getQueryForIndex(String indexName, Object indexValue);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method ensures that there is a TTL index on {@literal expireAt} field.
|
* Method ensures that there is a TTL index on {@literal expireAt} field. It's has
|
||||||
* It's has {@literal expireAfterSeconds} set to zero seconds, so the expiration
|
* {@literal expireAfterSeconds} set to zero seconds, so the expiration time is
|
||||||
* time is controlled by the application.
|
* controlled by the application.
|
||||||
*
|
*
|
||||||
* It can be extended in custom converters when there is a need for creating
|
* It can be extended in custom converters when there is a need for creating
|
||||||
* additional custom indexes.
|
* additional custom indexes.
|
||||||
|
* @param sessionCollectionIndexes {@link IndexOperations} to use
|
||||||
*/
|
*/
|
||||||
protected void ensureIndexes(IndexOperations sessionCollectionIndexes) {
|
protected void ensureIndexes(IndexOperations sessionCollectionIndexes) {
|
||||||
List<IndexInfo> indexInfo = sessionCollectionIndexes.getIndexInfo();
|
List<IndexInfo> indexInfo = sessionCollectionIndexes.getIndexInfo();
|
||||||
for (IndexInfo info : indexInfo) {
|
for (IndexInfo info : indexInfo) {
|
||||||
if (EXPIRE_AT_FIELD_NAME.equals(info.getName())) {
|
if (EXPIRE_AT_FIELD_NAME.equals(info.getName())) {
|
||||||
LOG.debug("TTL index on field " + EXPIRE_AT_FIELD_NAME + " already exists");
|
LOG.debug(
|
||||||
|
"TTL index on field " + EXPIRE_AT_FIELD_NAME + " already exists");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG.info("Creating TTL index on field " + EXPIRE_AT_FIELD_NAME);
|
LOG.info("Creating TTL index on field " + EXPIRE_AT_FIELD_NAME);
|
||||||
sessionCollectionIndexes
|
sessionCollectionIndexes
|
||||||
.ensureIndex(new Index(EXPIRE_AT_FIELD_NAME, Sort.Direction.ASC).named(EXPIRE_AT_FIELD_NAME).expire(0));
|
.ensureIndex(new Index(EXPIRE_AT_FIELD_NAME, Sort.Direction.ASC)
|
||||||
|
.named(EXPIRE_AT_FIELD_NAME).expire(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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.mongo;
|
package org.springframework.session.data.mongo;
|
||||||
|
|
||||||
import org.springframework.expression.Expression;
|
import org.springframework.expression.Expression;
|
||||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class to extract principal name from {@code Authentication} object
|
* Utility class to extract principal name from {@code Authentication} object.
|
||||||
*
|
*
|
||||||
* @author Jakub Kubrynski
|
* @author Jakub Kubrynski
|
||||||
*/
|
*/
|
||||||
class AuthenticationParser {
|
final class AuthenticationParser {
|
||||||
|
|
||||||
private static final String NAME_EXPRESSION = "authentication?.name";
|
private static final String NAME_EXPRESSION = "authentication?.name";
|
||||||
|
|
||||||
private static final SpelExpressionParser PARSER = new SpelExpressionParser();
|
private static final SpelExpressionParser PARSER = new SpelExpressionParser();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts principal name from authentication
|
* Extracts principal name from authentication.
|
||||||
*
|
*
|
||||||
* @param authentication Authentication object
|
* @param authentication Authentication object
|
||||||
* @return principal name
|
* @return principal name
|
||||||
@@ -27,4 +42,7 @@ class AuthenticationParser {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AuthenticationParser() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2014-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -15,15 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.session.data.mongo;
|
package org.springframework.session.data.mongo;
|
||||||
|
|
||||||
import com.mongodb.BasicDBObject;
|
|
||||||
import com.mongodb.DBObject;
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.springframework.core.convert.TypeDescriptor;
|
|
||||||
import org.springframework.data.mongodb.core.query.Criteria;
|
|
||||||
import org.springframework.data.mongodb.core.query.Query;
|
|
||||||
import org.springframework.session.Session;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -35,11 +26,20 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME;
|
import com.mongodb.BasicDBObject;
|
||||||
|
import com.mongodb.DBObject;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import org.springframework.core.convert.TypeDescriptor;
|
||||||
|
import org.springframework.data.mongodb.core.query.Criteria;
|
||||||
|
import org.springframework.data.mongodb.core.query.Query;
|
||||||
|
import org.springframework.session.FindByIndexNameSessionRepository;
|
||||||
|
import org.springframework.session.Session;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@code AbstractMongoSessionConverter} implementation transforming {@code MongoExpiringSession} to/from a BSON object
|
* {@code AbstractMongoSessionConverter} implementation transforming.
|
||||||
* using standard Java serialization
|
* {@code MongoExpiringSession} to/from a BSON object using standard Java serialization
|
||||||
*
|
*
|
||||||
* @author Jakub Kubrynski
|
* @author Jakub Kubrynski
|
||||||
* @since 1.2
|
* @since 1.2
|
||||||
@@ -57,25 +57,30 @@ class JdkMongoSessionConverter extends AbstractMongoSessionConverter {
|
|||||||
private static final String PRINCIPAL_FIELD_NAME = "principal";
|
private static final String PRINCIPAL_FIELD_NAME = "principal";
|
||||||
private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
|
private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
|
||||||
|
|
||||||
|
@Override
|
||||||
public Query getQueryForIndex(String indexName, Object indexValue) {
|
public Query getQueryForIndex(String indexName, Object indexValue) {
|
||||||
if (PRINCIPAL_NAME_INDEX_NAME.equals(indexName)) {
|
if (FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME
|
||||||
|
.equals(indexName)) {
|
||||||
return Query.query(Criteria.where(PRINCIPAL_FIELD_NAME).is(indexValue));
|
return Query.query(Criteria.where(PRINCIPAL_FIELD_NAME).is(indexValue));
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<ConvertiblePair> getConvertibleTypes() {
|
public Set<ConvertiblePair> getConvertibleTypes() {
|
||||||
return Collections.singleton(new ConvertiblePair(DBObject.class, MongoExpiringSession.class));
|
return Collections.singleton(
|
||||||
|
new ConvertiblePair(DBObject.class, MongoExpiringSession.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
public Object convert(Object source, TypeDescriptor sourceType,
|
||||||
|
TypeDescriptor targetType) {
|
||||||
if (source == null) {
|
if (source == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DBObject.class.isAssignableFrom(sourceType.getType())) {
|
if (DBObject.class.isAssignableFrom(sourceType.getType())) {
|
||||||
return convert((DBObject) source);
|
return convert((DBObject) source);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return convert((MongoExpiringSession) source);
|
return convert((MongoExpiringSession) source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,24 +108,29 @@ class JdkMongoSessionConverter extends AbstractMongoSessionConverter {
|
|||||||
outputStream.writeObject(attributes);
|
outputStream.writeObject(attributes);
|
||||||
outputStream.flush();
|
outputStream.flush();
|
||||||
return out.toByteArray();
|
return out.toByteArray();
|
||||||
} catch (IOException e) {
|
}
|
||||||
|
catch (IOException e) {
|
||||||
LOG.error("Exception during session serialization", e);
|
LOG.error("Exception during session serialization", e);
|
||||||
throw new IllegalStateException("Cannot serialize session", e);
|
throw new IllegalStateException("Cannot serialize session", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String extractPrincipal(Session expiringSession) {
|
private String extractPrincipal(Session expiringSession) {
|
||||||
String resolvedPrincipal = AuthenticationParser.extractName(expiringSession.getAttribute(SPRING_SECURITY_CONTEXT));
|
String resolvedPrincipal = AuthenticationParser
|
||||||
|
.extractName(expiringSession.getAttribute(SPRING_SECURITY_CONTEXT));
|
||||||
if (resolvedPrincipal != null) {
|
if (resolvedPrincipal != null) {
|
||||||
return resolvedPrincipal;
|
return resolvedPrincipal;
|
||||||
} else {
|
}
|
||||||
return expiringSession.getAttribute(PRINCIPAL_NAME_INDEX_NAME);
|
else {
|
||||||
|
return expiringSession.getAttribute(
|
||||||
|
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private MongoExpiringSession convert(DBObject sessionWrapper) {
|
private MongoExpiringSession convert(DBObject sessionWrapper) {
|
||||||
MongoExpiringSession session =
|
MongoExpiringSession session = new MongoExpiringSession(
|
||||||
new MongoExpiringSession((String) sessionWrapper.get(ID), (Integer) sessionWrapper.get(MAX_INTERVAL));
|
(String) sessionWrapper.get(ID),
|
||||||
|
(Integer) sessionWrapper.get(MAX_INTERVAL));
|
||||||
session.setCreationTime((Long) sessionWrapper.get(CREATION_TIME));
|
session.setCreationTime((Long) sessionWrapper.get(CREATION_TIME));
|
||||||
session.setLastAccessedTime((Long) sessionWrapper.get(LAST_ACCESSED_TIME));
|
session.setLastAccessedTime((Long) sessionWrapper.get(LAST_ACCESSED_TIME));
|
||||||
session.setExpireAt((Date) sessionWrapper.get(EXPIRE_AT_FIELD_NAME));
|
session.setExpireAt((Date) sessionWrapper.get(EXPIRE_AT_FIELD_NAME));
|
||||||
@@ -131,17 +141,21 @@ class JdkMongoSessionConverter extends AbstractMongoSessionConverter {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void deserializeAttributes(DBObject sessionWrapper, Session session) {
|
private void deserializeAttributes(DBObject sessionWrapper, Session session) {
|
||||||
try {
|
try {
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream((byte[]) sessionWrapper.get(ATTRIBUTES));
|
ByteArrayInputStream in = new ByteArrayInputStream(
|
||||||
|
(byte[]) sessionWrapper.get(ATTRIBUTES));
|
||||||
ObjectInputStream objectInputStream = new ObjectInputStream(in);
|
ObjectInputStream objectInputStream = new ObjectInputStream(in);
|
||||||
Map<String, Object> attributes = (Map<String, Object>) objectInputStream.readObject();
|
Map<String, Object> attributes = (Map<String, Object>) objectInputStream
|
||||||
|
.readObject();
|
||||||
for (Map.Entry<String, Object> entry : attributes.entrySet()) {
|
for (Map.Entry<String, Object> entry : attributes.entrySet()) {
|
||||||
session.setAttribute(entry.getKey(), entry.getValue());
|
session.setAttribute(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
objectInputStream.close();
|
objectInputStream.close();
|
||||||
} catch (IOException e) {
|
}
|
||||||
|
catch (IOException e) {
|
||||||
LOG.error("Exception during session deserialization", e);
|
LOG.error("Exception during session deserialization", e);
|
||||||
throw new IllegalStateException("Cannot deserialize session", e);
|
throw new IllegalStateException("Cannot deserialize session", e);
|
||||||
} catch (ClassNotFoundException e) {
|
}
|
||||||
|
catch (ClassNotFoundException e) {
|
||||||
LOG.error("Exception during session deserialization", e);
|
LOG.error("Exception during session deserialization", e);
|
||||||
throw new IllegalStateException("Cannot deserialize session", e);
|
throw new IllegalStateException("Cannot deserialize session", e);
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user