Compare commits

...

10 Commits

Author SHA1 Message Date
Rob Winch
23ccfa6666 Release version 1.3.1.RELEASE 2017-04-27 14:56:58 -05:00
Vedran Pavic
a64e6d1a9c Use explicit constraints in JDBC schema scripts
Fixes gh-765
2017-04-26 23:33:35 +02:00
Vedran Pavic
598715f219 Remove logging for "Skip invoking on" response committed
Fixes gh-764
2017-04-26 23:18:00 +02:00
Sebastian Laskawiec
4d90fcc7a8 Add link to Infinispan for Spring Session documentation
Fixes gh-763
2017-04-26 23:17:33 +02:00
John Blum
4f57c6c6c1 Fix invalid not null assertions
Fixes gh-762
2017-04-26 23:16:55 +02:00
Vedran Pavic
c210a4a3cf Prevent NPE inMongoOperationsSessionRepository when creating session if max inactive interval is undefined
Fixes gh-761
2017-04-26 23:15:40 +02:00
Rob Winch
a1380d722b SpringSessionRememberMeServices rm SecurityContext attribute
SpringSessionRememberMeServices use to invalidate the session which would
cause Spring Security's saved request to be lost.

Now SpringSessionRememberMeServices deletes the SecurityContext from the
HttpSession instead.

Fixes gh-752
2017-04-26 09:09:12 -05:00
Rob Winch
c029922bf4 Update to Spring Data Redis 1.7.10
Note the Spring 3 tests must stick to 1.7.1

Fixes gh-756
2017-04-26 07:56:15 -05:00
John Blum
6b55f3f7d2 Restore proper behavior of HttpSession created events in GemFire support when client Region is a PROXY in the client/server topology
Fixes gh-757

(cherry picked from commit c0c404ab96)
Signed-off-by: John Blum <jblum@pivotal.io>
2017-04-25 20:41:13 -07:00
John Blum
6668e41b0a Improve GemFire SessionRepository, Session copy logic to avoid issues with delta propagation on updates
Upgrade to Spring Data GemFire 1.8.10.RELEASE

Fixes #gh-755
2017-04-21 15:48:40 -07:00
30 changed files with 1715 additions and 846 deletions

View File

@@ -1200,6 +1200,7 @@ Spring Session is Open Source software released under the http://www.apache.org/
[[community-extensions]]
=== Community Extensions
https://github.com/maseev/spring-session-orientdb[Spring Session OrientDB]
http://infinispan.org/docs/dev/user_guide/user_guide.html#externalizing_session_using_spring_session[Spring Session Infinispan]
[[minimum-requirements]]
== Minimum Requirements

View File

@@ -1,30 +1,32 @@
assertjVersion=2.5.0
bootstrapVersion=2.3.2
commonsPoolVersion=2.4.2
jacksonVersion=2.6.5
jspApiVersion=2.0
servletApiVersion=3.0.1
jstlelVersion=1.2.5
version=1.3.1.BUILD-SNAPSHOT
springDataRedisVersion=1.7.1.RELEASE
html5ShivVersion=3.7.3
commonsLoggingVersion=1.2
commonsPoolVersion=2.4.2
gebVersion=0.13.1
groovyVersion=2.4.4
h2Version=1.4.192
hazelcastVersion=3.6.5
html5ShivVersion=3.7.3
httpClientVersion=4.5.1
jacksonVersion=2.6.5
jedisVersion=2.8.1
jspApiVersion=2.0
jstlVersion=1.2.1
jstlelVersion=1.2.5
junitVersion=4.12
lettuceVersion=3.5.0.Final
gebVersion=0.13.1
mockitoVersion=1.10.19
hazelcastVersion=3.6.5
seleniumVersion=2.52.0
springDataGeodeVersion=1.0.0.APACHE-GEODE-INCUBATING-M2
springSecurityVersion=4.2.0.RELEASE
springVersion=4.3.4.RELEASE
httpClientVersion=4.5.1
jedisVersion=2.8.1
h2Version=1.4.192
springDataMongoVersion=1.9.4.RELEASE
springShellVersion=1.1.0.RELEASE
springDataGemFireVersion=1.8.5.RELEASE
assertjVersion=2.5.0
servletApiVersion=3.0.1
spockVersion=1.0-groovy-2.4
springVersion=4.3.4.RELEASE
springDataGemFireVersion=1.8.10.RELEASE
springDataGeodeVersion=1.0.0.INCUBATING-RELEASE
springDataMongoVersion=1.9.4.RELEASE
springDataRedisVersion=1.7.10.RELEASE
# We cannot go beyond this version with Spring 3 support
springDataRedisSpring3Version=1.7.1.RELEASE
springSecurityVersion=4.2.0.RELEASE
springShellVersion=1.1.0.RELEASE
webjarsTaglibVersion=0.3
jstlVersion=1.2.1
groovyVersion=2.4.4
version=1.3.1.RELEASE

View File

@@ -9,6 +9,9 @@ configurations.spring3TestRuntime {
&& details.requested.name != 'spring-messaging') {
details.useVersion '3.2.14.RELEASE'
}
if (details.requested.name == 'spring-data-redis') {
details.useVersion springDataRedisSpring3Version
}
}
}

View File

@@ -36,6 +36,7 @@ import com.gemstone.gemfire.cache.client.ClientCache;
import com.gemstone.gemfire.cache.client.ClientCacheFactory;
import com.gemstone.gemfire.cache.query.Index;
import com.gemstone.gemfire.cache.server.CacheServer;
import org.junit.Before;
import org.springframework.beans.factory.annotation.Autowired;
@@ -47,8 +48,8 @@ import org.springframework.session.events.AbstractSessionEvent;
import static org.assertj.core.api.Assertions.assertThat;
/**
* AbstractGemFireIntegrationTests is an abstract base class encapsulating common
* operations for writing Spring Session GemFire integration tests.
* {@link AbstractGemFireIntegrationTests} is an abstract base class encapsulating common
* operations for writing Spring Session Data GemFire integration tests.
*
* @author John Blum
* @since 1.1.0
@@ -74,8 +75,7 @@ public abstract class AbstractGemFireIntegrationTests {
protected static final long DEFAULT_WAIT_DURATION = TimeUnit.SECONDS.toMillis(20);
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";
@@ -83,7 +83,7 @@ public abstract class AbstractGemFireIntegrationTests {
System.getProperty("spring.session.data.gemfire.log-file", "server.log");
protected static final String GEMFIRE_LOG_LEVEL =
System.getProperty("spring.session.data.gemfire.log-level", "warning");
System.getProperty("spring.session.data.gemfire.log-level", "error");
@Autowired
protected Cache gemfireCache;
@@ -258,7 +258,7 @@ public abstract class AbstractGemFireIntegrationTests {
/* (non-Javadoc) */
protected static int waitForProcessToStop(Process process, File directory, long duration) {
final long timeout = (System.currentTimeMillis() + duration);
long timeout = (System.currentTimeMillis() + duration);
try {
while (process.isAlive() && System.currentTimeMillis() < timeout) {
@@ -282,7 +282,7 @@ public abstract class AbstractGemFireIntegrationTests {
/* (non-Javadoc) */
@SuppressWarnings("all")
protected static boolean waitOnCondition(Condition condition, long duration) {
final long timeout = (System.currentTimeMillis() + duration);
long timeout = (System.currentTimeMillis() + duration);
try {
while (!condition.evaluate() && System.currentTimeMillis() < timeout) {
@@ -311,6 +311,13 @@ public abstract class AbstractGemFireIntegrationTests {
return processControl;
}
/* (non-Javadoc) */
protected void assertValidSession(ExpiringSession session) {
assertThat(session).isNotNull();
assertThat(session.getId()).isNotEmpty();
assertThat(session.isExpired()).isFalse();
}
/* (non-Javadoc) */
protected void assertRegion(Region<?, ?> actualRegion, String expectedName, DataPolicy expectedDataPolicy) {
assertThat(actualRegion).isNotNull();
@@ -335,6 +342,7 @@ public abstract class AbstractGemFireIntegrationTests {
/* (non-Javadoc) */
protected void assertEntryIdleTimeout(ExpirationAttributes actualExpirationAttributes,
ExpirationAction expectedAction, int expectedTimeout) {
assertThat(actualExpirationAttributes).isNotNull();
assertThat(actualExpirationAttributes.getAction()).isEqualTo(expectedAction);
assertThat(actualExpirationAttributes.getTimeout()).isEqualTo(expectedTimeout);
@@ -379,6 +387,12 @@ public abstract class AbstractGemFireIntegrationTests {
return (T) session;
}
/* (non-Javadoc) */
protected <T extends ExpiringSession> T delete(T session) {
this.gemfireSessionRepository.delete(session);
return session;
}
/* (non-Javadoc) */
protected <T extends ExpiringSession> T expire(T session) {
session.setLastAccessedTime(0L);
@@ -446,5 +460,4 @@ public abstract class AbstractGemFireIntegrationTests {
protected interface Condition {
boolean evaluate();
}
}

View File

@@ -31,6 +31,8 @@ import com.gemstone.gemfire.cache.DataPolicy;
import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.RegionAttributes;
import com.gemstone.gemfire.cache.client.ClientCache;
import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
@@ -58,7 +60,7 @@ import org.springframework.session.events.SessionDeletedEvent;
import org.springframework.session.events.SessionExpiredEvent;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.SocketUtils;
@@ -66,28 +68,29 @@ import org.springframework.util.SocketUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* The ClientServerGemFireOperationsSessionRepositoryIntegrationTests class is a test
* suite of test cases testing the functionality of GemFire-backed Spring Sessions using a
* GemFire client-server topology.
* Integration tests to test the functionality of GemFire-backed Spring Sessions using
* the GemFire client-server topology.
*
* @author John Blum
* @since 1.1.0
* @see org.junit.Test
* @see org.junit.runner.RunWith
* @see org.springframework.context.ConfigurableApplicationContext
* @see org.springframework.session.ExpiringSession
* @see org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests
* @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession
* @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration
* @see org.springframework.test.annotation.DirtiesContext
* @see org.springframework.test.context.ContextConfiguration
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
* @see org.springframework.test.context.junit4.SpringRunner
* @see org.springframework.test.context.web.WebAppConfiguration
* @see com.gemstone.gemfire.cache.Cache
* @see com.gemstone.gemfire.cache.Region
* @see com.gemstone.gemfire.cache.client.ClientCache
* @see com.gemstone.gemfire.cache.client.Pool
* @see com.gemstone.gemfire.cache.server.CacheServer
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ClientServerGemFireOperationsSessionRepositoryIntegrationTests.SpringSessionGemFireClientConfiguration.class)
@RunWith(SpringRunner.class)
@ContextConfiguration(classes =
ClientServerGemFireOperationsSessionRepositoryIntegrationTests.SpringSessionDataGemFireClientConfiguration.class)
@DirtiesContext
@WebAppConfiguration
public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
@@ -108,32 +111,33 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
@BeforeClass
public static void startGemFireServer() throws IOException {
final long t0 = System.currentTimeMillis();
long t0 = System.currentTimeMillis();
final int port = SocketUtils.findAvailableTcpPort();
int port = SocketUtils.findAvailableTcpPort();
System.err.printf("Starting a GemFire Server on [%1$s] listening on port [%2$d]%n",
SpringSessionGemFireServerConfiguration.SERVER_HOSTNAME, port);
System.err.printf("Starting a GemFire Server running on host [%1$s] listening on port [%2$d]%n",
SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port);
System.setProperty("spring.session.data.gemfire.port", String.valueOf(port));
String processWorkingDirectoryPathname = String.format("gemfire-client-server-tests-%1$s",
TIMESTAMP.format(new Date()));
String processWorkingDirectoryPathname =
String.format("gemfire-client-server-tests-%1$s", TIMESTAMP.format(new Date()));
processWorkingDirectory = createDirectory(processWorkingDirectoryPathname);
gemfireServer = run(SpringSessionGemFireServerConfiguration.class, processWorkingDirectory,
gemfireServer = run(SpringSessionDataGemFireServerConfiguration.class, processWorkingDirectory,
String.format("-Dspring.session.data.gemfire.port=%1$d", port));
assertThat(waitForCacheServerToStart(SpringSessionGemFireServerConfiguration.SERVER_HOSTNAME, port)).isTrue();
assertThat(waitForCacheServerToStart(SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port))
.isTrue();
System.err.printf("GemFire Server [startup time = %1$d ms]%n", System.currentTimeMillis() - t0);
}
@AfterClass
public static void stopGemFireServerAndDeleteArtifacts() {
public static void stopGemFireServer() {
if (gemfireServer != null) {
gemfireServer.destroyForcibly();
gemfireServer.destroy();
System.err.printf("GemFire Server [exit code = %1$d]%n",
waitForProcessToStop(gemfireServer, processWorkingDirectory));
}
@@ -158,7 +162,7 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
springSessionGemFireRegion.getAttributes();
assertThat(springSessionGemFireRegionAttributes).isNotNull();
assertThat(springSessionGemFireRegionAttributes.getDataPolicy()).isEqualTo(DataPolicy.EMPTY);
assertThat(springSessionGemFireRegionAttributes.getDataPolicy()).isEqualTo(DataPolicy.NORMAL);
}
@After
@@ -168,7 +172,7 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
@Test
public void createSessionFiresSessionCreatedEvent() {
final long beforeOrAtCreationTime = System.currentTimeMillis();
long beforeOrAtCreationTime = System.currentTimeMillis();
ExpiringSession expectedSession = save(createSession());
@@ -178,12 +182,19 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
ExpiringSession createdSession = sessionEvent.getSession();
assertThat(createdSession).isEqualTo(expectedSession);
assertThat(createdSession.getId()).isNotNull();
assertThat(createdSession.getId()).isEqualTo(expectedSession.getId());
assertThat(createdSession.getCreationTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime);
assertThat(createdSession.getLastAccessedTime()).isEqualTo(createdSession.getCreationTime());
assertThat(createdSession.getMaxInactiveIntervalInSeconds()).isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
createdSession.setAttribute("attrOne", 1);
assertThat(save(touch(createdSession)).getAttribute("attrOne")).isEqualTo(1);
sessionEvent = this.sessionEventListener.waitForSessionEvent(500);
assertThat(sessionEvent).isNull();
this.gemfireSessionRepository.delete(expectedSession.getId());
}
@@ -194,19 +205,13 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
AbstractSessionEvent sessionEvent = this.sessionEventListener.waitForSessionEvent(500);
assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class);
assertThat(sessionEvent.<ExpiringSession>getSession()).isEqualTo(expectedSession);
assertThat(sessionEvent.getSession()).isEqualTo(expectedSession);
assertThat(this.sessionEventListener.getSessionEvent()).isNull();
ExpiringSession savedSession = this.gemfireSessionRepository.getSession(expectedSession.getId());
assertThat(savedSession).isEqualTo(expectedSession);
// NOTE for some reason or another, performing a GemFire (Client)Cache
// Region.get(key)
// causes a Region CREATE event... o.O
// calling sessionEventListener.getSessionEvent() here to clear the event
this.sessionEventListener.getSessionEvent();
sessionEvent = this.sessionEventListener.waitForSessionEvent(
TimeUnit.SECONDS.toMillis(MAX_INACTIVE_INTERVAL_IN_SECONDS + 1));
@@ -240,15 +245,15 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
}
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME,
maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
static class SpringSessionGemFireClientConfiguration {
clientRegionShortcut = ClientRegionShortcut.CACHING_PROXY,
maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
static class SpringSessionDataGemFireClientConfiguration {
@Bean
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
Properties gemfireProperties() {
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
@@ -271,17 +276,14 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
PoolFactoryBean poolFactory = new PoolFactoryBean();
poolFactory.setFreeConnectionTimeout(5000); // 5 seconds
poolFactory.setKeepAlive(false);
poolFactory.setMaxConnections(SpringSessionGemFireServerConfiguration.MAX_CONNECTIONS);
poolFactory.setPingInterval(TimeUnit.SECONDS.toMillis(5));
poolFactory.setReadTimeout(2000); // 2 seconds
poolFactory.setRetryAttempts(1);
poolFactory.setSubscriptionEnabled(true);
poolFactory.setThreadLocalConnections(false);
poolFactory.setServers(Collections.singletonList(new ConnectionEndpoint(
SpringSessionGemFireServerConfiguration.SERVER_HOSTNAME, port)));
SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port)));
return poolFactory;
}
@@ -293,9 +295,9 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
// used for debugging purposes
@SuppressWarnings("resource")
public static void main(final String[] args) {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = new AnnotationConfigApplicationContext(
SpringSessionGemFireClientConfiguration.class);
SpringSessionDataGemFireClientConfiguration.class);
applicationContext.registerShutdownHook();
@@ -308,31 +310,29 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
}
}
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME, maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
static class SpringSessionGemFireServerConfiguration {
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME,
maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
static class SpringSessionDataGemFireServerConfiguration {
static final int MAX_CONNECTIONS = 50;
static final String SERVER_HOSTNAME = "localhost";
@Bean
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
Properties gemfireProperties() {
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("name", name());
gemfireProperties.setProperty("mcast-port", "0");
gemfireProperties.setProperty("log-file", "server.log");
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
return gemfireProperties;
}
String name() {
return SpringSessionGemFireServerConfiguration.class.getName();
return ClientServerGemFireOperationsSessionRepositoryIntegrationTests.class.getName();
}
@Bean
@@ -351,22 +351,22 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
CacheServerFactoryBean cacheServerFactory = new CacheServerFactoryBean();
cacheServerFactory.setCache(gemfireCache);
cacheServerFactory.setAutoStartup(true);
cacheServerFactory.setBindAddress(SERVER_HOSTNAME);
cacheServerFactory.setCache(gemfireCache);
cacheServerFactory.setMaxConnections(MAX_CONNECTIONS);
cacheServerFactory.setPort(port);
return cacheServerFactory;
}
@SuppressWarnings("resource")
public static void main(final String[] args) throws IOException {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
SpringSessionGemFireServerConfiguration.class);
public static void main(String[] args) throws IOException {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(SpringSessionDataGemFireServerConfiguration.class);
context.registerShutdownHook();
writeProcessControlFile(WORKING_DIRECTORY);
}
}
}

View File

@@ -0,0 +1,285 @@
/*
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.session.data.gemfire;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.client.ClientCache;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.data.gemfire.CacheFactoryBean;
import org.springframework.data.gemfire.client.ClientCacheFactoryBean;
import org.springframework.data.gemfire.client.PoolFactoryBean;
import org.springframework.data.gemfire.server.CacheServerFactoryBean;
import org.springframework.data.gemfire.support.ConnectionEndpoint;
import org.springframework.session.ExpiringSession;
import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.SocketUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests testing the addition/removal of HTTP Session Attributes
* and the proper persistence of the HTTP Session state in a GemFire cache
* across a client/server topology.
*
* @author John Blum
* @see org.junit.Test
* @see org.junit.runner.RunWith
* @see org.springframework.context.ConfigurableApplicationContext
* @see org.springframework.session.ExpiringSession
* @see org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests
* @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession
* @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration
* @see org.springframework.test.context.ContextConfiguration
* @see org.springframework.test.context.junit4.SpringRunner
* @see com.gemstone.gemfire.cache.Cache
* @see com.gemstone.gemfire.cache.Region
* @see com.gemstone.gemfire.cache.client.ClientCache
* @since 1.3.1
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(classes =
ClientServerHttpSessionAttributesDeltaIntegrationTests.SpringSessionDataGemFireClientConfiguration.class)
public class ClientServerHttpSessionAttributesDeltaIntegrationTests extends AbstractGemFireIntegrationTests {
private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 1;
private static final DateFormat TIMESTAMP = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
private static File processWorkingDirectory;
private static Process gemfireServer;
@BeforeClass
public static void startGemFireServer() throws IOException {
long t0 = System.currentTimeMillis();
int port = SocketUtils.findAvailableTcpPort();
System.err.printf("Starting a GemFire Server running on host [%1$s] listening on port [%2$d]%n",
SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port);
System.setProperty("spring.session.data.gemfire.port", String.valueOf(port));
String processWorkingDirectoryPathname =
String.format("gemfire-client-server-tests-%1$s", TIMESTAMP.format(new Date()));
processWorkingDirectory = createDirectory(processWorkingDirectoryPathname);
gemfireServer = run(SpringSessionDataGemFireServerConfiguration.class, processWorkingDirectory,
String.format("-Dspring.session.data.gemfire.port=%1$d", port));
assertThat(waitForCacheServerToStart(SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port))
.isTrue();
System.err.printf("GemFire Server [startup time = %1$d ms]%n", System.currentTimeMillis() - t0);
}
@AfterClass
public static void stopGemFireServer() {
if (gemfireServer != null) {
gemfireServer.destroy();
System.err.printf("GemFire Server [exit code = %1$d]%n",
waitForProcessToStop(gemfireServer, processWorkingDirectory));
}
if (Boolean.valueOf(System.getProperty("spring.session.data.gemfire.fork.clean", Boolean.TRUE.toString()))) {
FileSystemUtils.deleteRecursively(processWorkingDirectory);
}
assertThat(waitForClientCacheToClose(DEFAULT_WAIT_DURATION)).isTrue();
}
@Test
public void sessionCreationAndAccessIsSuccessful() {
ExpiringSession session = save(touch(createSession()));
assertThat(session).isNotNull();
assertThat(session.isExpired()).isFalse();
session.setAttribute("attrOne", 1);
session.setAttribute("attrTwo", 2);
save(touch(session));
ExpiringSession loadedSession = get(session.getId());
assertThat(loadedSession).isNotNull();
assertThat(loadedSession.isExpired()).isFalse();
assertThat(loadedSession).isNotSameAs(session);
assertThat(loadedSession.getId()).isEqualTo(session.getId());
assertThat(loadedSession.<Integer>getAttribute("attrOne")).isEqualTo(1);
assertThat(loadedSession.<Integer>getAttribute("attrTwo")).isEqualTo(2);
loadedSession.removeAttribute("attrTwo");
assertThat(loadedSession.getAttributeNames()).doesNotContain("attrTwo");
assertThat(loadedSession.getAttributeNames()).hasSize(1);
save(touch(loadedSession));
ExpiringSession reloadedSession = get(loadedSession.getId());
assertThat(reloadedSession).isNotNull();
assertThat(reloadedSession.isExpired()).isFalse();
assertThat(reloadedSession).isNotSameAs(loadedSession);
assertThat(reloadedSession.getId()).isEqualTo(loadedSession.getId());
assertThat(reloadedSession.getAttributeNames()).hasSize(1);
assertThat(reloadedSession.getAttributeNames()).doesNotContain("attrTwo");
assertThat(reloadedSession.<Integer>getAttribute("attrOne")).isEqualTo(1);
}
@EnableGemFireHttpSession
static class SpringSessionDataGemFireClientConfiguration {
@Bean
static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
Properties gemfireProperties() {
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
return gemfireProperties;
}
@Bean
ClientCacheFactoryBean gemfireCache() {
ClientCacheFactoryBean clientCacheFactory = new ClientCacheFactoryBean();
clientCacheFactory.setClose(true);
clientCacheFactory.setProperties(gemfireProperties());
return clientCacheFactory;
}
@Bean
PoolFactoryBean gemfirePool(@Value("${spring.session.data.gemfire.port:"
+ DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) {
PoolFactoryBean poolFactory = new PoolFactoryBean();
poolFactory.setKeepAlive(false);
poolFactory.setPingInterval(TimeUnit.SECONDS.toMillis(5));
poolFactory.setReadTimeout(2000); // 2 seconds
poolFactory.setRetryAttempts(1);
poolFactory.setSubscriptionEnabled(true);
poolFactory.setServers(Collections.singletonList(new ConnectionEndpoint(
SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port)));
return poolFactory;
}
// used for debugging purposes
@SuppressWarnings("resource")
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext =
new AnnotationConfigApplicationContext(SpringSessionDataGemFireClientConfiguration.class);
applicationContext.registerShutdownHook();
ClientCache clientCache = applicationContext.getBean(ClientCache.class);
for (InetSocketAddress server : clientCache.getCurrentServers()) {
System.err.printf("GemFire Server [host: %1$s, port: %2$d]%n",
server.getHostName(), server.getPort());
}
}
}
@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
static class SpringSessionDataGemFireServerConfiguration {
static final String SERVER_HOSTNAME = "localhost";
@Bean
static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
Properties gemfireProperties() {
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("name", name());
gemfireProperties.setProperty("mcast-port", "0");
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
return gemfireProperties;
}
String name() {
return ClientServerHttpSessionAttributesDeltaIntegrationTests.class.getName();
}
@Bean
CacheFactoryBean gemfireCache() {
CacheFactoryBean gemfireCache = new CacheFactoryBean();
gemfireCache.setClose(true);
gemfireCache.setProperties(gemfireProperties());
return gemfireCache;
}
@Bean
CacheServerFactoryBean gemfireCacheServer(Cache gemfireCache,
@Value("${spring.session.data.gemfire.port:" + DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) {
CacheServerFactoryBean cacheServerFactory = new CacheServerFactoryBean();
cacheServerFactory.setCache(gemfireCache);
cacheServerFactory.setAutoStartup(true);
cacheServerFactory.setBindAddress(SERVER_HOSTNAME);
cacheServerFactory.setPort(port);
return cacheServerFactory;
}
@SuppressWarnings("resource")
public static void main(String[] args) throws IOException {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(SpringSessionDataGemFireServerConfiguration.class);
context.registerShutdownHook();
writeProcessControlFile(WORKING_DIRECTORY);
}
}
}

View File

@@ -0,0 +1,310 @@
/*
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.session.data.gemfire;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.client.ClientCache;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.data.gemfire.CacheFactoryBean;
import org.springframework.data.gemfire.client.ClientCacheFactoryBean;
import org.springframework.data.gemfire.client.PoolFactoryBean;
import org.springframework.data.gemfire.server.CacheServerFactoryBean;
import org.springframework.data.gemfire.support.ConnectionEndpoint;
import org.springframework.session.ExpiringSession;
import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession;
import org.springframework.session.events.AbstractSessionEvent;
import org.springframework.session.events.SessionCreatedEvent;
import org.springframework.session.events.SessionDeletedEvent;
import org.springframework.session.events.SessionExpiredEvent;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.SocketUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* The ClientServerProxyRegionSessionOperationsIntegrationTests class...
*
* @author John Blum
* @since 1.0.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(classes =
ClientServerProxyRegionSessionOperationsIntegrationTests.SpringSessionDataGemFireClientConfiguration.class)
public class ClientServerProxyRegionSessionOperationsIntegrationTests extends AbstractGemFireIntegrationTests {
private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 1;
private static final DateFormat TIMESTAMP = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
private static File processWorkingDirectory;
private static Process gemfireServer;
@Autowired
private SessionEventListener sessionEventListener;
@BeforeClass
public static void startGemFireServer() throws IOException {
long t0 = System.currentTimeMillis();
int port = SocketUtils.findAvailableTcpPort();
System.err.printf("Starting a GemFire Server running on host [%1$s] listening on port [%2$d]%n",
SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port);
System.setProperty("spring.session.data.gemfire.port", String.valueOf(port));
String processWorkingDirectoryPathname =
String.format("gemfire-client-server-tests-%1$s", TIMESTAMP.format(new Date()));
processWorkingDirectory = createDirectory(processWorkingDirectoryPathname);
gemfireServer = run(SpringSessionDataGemFireServerConfiguration.class, processWorkingDirectory,
String.format("-Dspring.session.data.gemfire.port=%1$d", port));
assertThat(waitForCacheServerToStart(SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port))
.isTrue();
System.err.printf("GemFire Server [startup time = %1$d ms]%n", System.currentTimeMillis() - t0);
}
@AfterClass
public static void stopGemFireServer() {
if (gemfireServer != null) {
gemfireServer.destroy();
System.err.printf("GemFire Server [exit code = %1$d]%n",
waitForProcessToStop(gemfireServer, processWorkingDirectory));
}
if (Boolean.valueOf(System.getProperty("spring.session.data.gemfire.fork.clean", Boolean.TRUE.toString()))) {
FileSystemUtils.deleteRecursively(processWorkingDirectory);
}
assertThat(waitForClientCacheToClose(DEFAULT_WAIT_DURATION)).isTrue();
}
@Test
public void createReadUpdateExpireRecreateDeleteRecreateSessionResultsCorrectSessionCreatedEvents() {
ExpiringSession session = save(touch(createSession()));
assertValidSession(session);
AbstractSessionEvent sessionEvent = this.sessionEventListener.waitForSessionEvent(500);
assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class);
assertThat(sessionEvent.getSessionId()).isEqualTo(session.getId());
// GET
ExpiringSession loadedSession = get(session.getId());
assertThat(loadedSession).isNotNull();
assertThat(loadedSession.getId()).isEqualTo(session.getId());
assertThat(loadedSession.getCreationTime()).isEqualTo(session.getCreationTime());
assertThat(loadedSession.getLastAccessedTime()).isGreaterThanOrEqualTo((session.getLastAccessedTime()));
sessionEvent = this.sessionEventListener.waitForSessionEvent(500);
assertThat(sessionEvent).isNull();
loadedSession.setAttribute("attrOne", 1);
loadedSession.setAttribute("attrTwo", 2);
// UPDATE
save(touch(loadedSession));
sessionEvent = this.sessionEventListener.waitForSessionEvent(500);
assertThat(sessionEvent).isNull();
// EXPIRE
sessionEvent = this.sessionEventListener.waitForSessionEvent(
TimeUnit.SECONDS.toMillis(MAX_INACTIVE_INTERVAL_IN_SECONDS + 1));
assertThat(sessionEvent).isInstanceOf(SessionExpiredEvent.class);
assertThat(sessionEvent.getSessionId()).isEqualTo(session.getId());
// RECREATE
save(touch(session));
sessionEvent = this.sessionEventListener.waitForSessionEvent(500);
assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class);
assertThat(sessionEvent.getSessionId()).isEqualTo(session.getId());
// DELETE
delete(session);
sessionEvent = this.sessionEventListener.waitForSessionEvent(500);
assertThat(sessionEvent).isInstanceOf(SessionDeletedEvent.class);
assertThat(sessionEvent.getSessionId()).isEqualTo(session.getId());
// RECREATE
save(touch(session));
sessionEvent = this.sessionEventListener.waitForSessionEvent(500);
assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class);
assertThat(sessionEvent.getSessionId()).isEqualTo(session.getId());
}
@EnableGemFireHttpSession
static class SpringSessionDataGemFireClientConfiguration {
@Bean
static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
Properties gemfireProperties() {
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
return gemfireProperties;
}
@Bean
ClientCacheFactoryBean gemfireCache() {
ClientCacheFactoryBean clientCacheFactory = new ClientCacheFactoryBean();
clientCacheFactory.setClose(true);
clientCacheFactory.setProperties(gemfireProperties());
return clientCacheFactory;
}
@Bean
PoolFactoryBean gemfirePool(@Value("${spring.session.data.gemfire.port:"
+ DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) {
PoolFactoryBean poolFactory = new PoolFactoryBean();
poolFactory.setKeepAlive(false);
poolFactory.setPingInterval(TimeUnit.SECONDS.toMillis(5));
poolFactory.setReadTimeout(2000); // 2 seconds
poolFactory.setRetryAttempts(1);
poolFactory.setSubscriptionEnabled(true);
poolFactory.setServers(Collections.singletonList(new ConnectionEndpoint(
SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port)));
return poolFactory;
}
@Bean
public SessionEventListener sessionEventListener() {
return new SessionEventListener();
}
// used for debugging purposes
@SuppressWarnings("resource")
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext =
new AnnotationConfigApplicationContext(SpringSessionDataGemFireClientConfiguration.class);
applicationContext.registerShutdownHook();
ClientCache clientCache = applicationContext.getBean(ClientCache.class);
for (InetSocketAddress server : clientCache.getCurrentServers()) {
System.err.printf("GemFire Server [host: %1$s, port: %2$d]%n",
server.getHostName(), server.getPort());
}
}
}
@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
static class SpringSessionDataGemFireServerConfiguration {
static final String SERVER_HOSTNAME = "localhost";
@Bean
static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
Properties gemfireProperties() {
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("name", name());
gemfireProperties.setProperty("mcast-port", "0");
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
return gemfireProperties;
}
String name() {
return ClientServerProxyRegionSessionOperationsIntegrationTests.class.getName();
}
@Bean
CacheFactoryBean gemfireCache() {
CacheFactoryBean gemfireCache = new CacheFactoryBean();
gemfireCache.setClose(true);
gemfireCache.setProperties(gemfireProperties());
return gemfireCache;
}
@Bean
CacheServerFactoryBean gemfireCacheServer(Cache gemfireCache,
@Value("${spring.session.data.gemfire.port:" + DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) {
CacheServerFactoryBean cacheServerFactory = new CacheServerFactoryBean();
cacheServerFactory.setCache(gemfireCache);
cacheServerFactory.setAutoStartup(true);
cacheServerFactory.setBindAddress(SERVER_HOSTNAME);
cacheServerFactory.setPort(port);
return cacheServerFactory;
}
@SuppressWarnings("resource")
public static void main(String[] args) throws IOException {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(SpringSessionDataGemFireServerConfiguration.class);
context.registerShutdownHook();
writeProcessControlFile(WORKING_DIRECTORY);
}
}
}

View File

@@ -39,8 +39,11 @@ import com.gemstone.gemfire.Delta;
import com.gemstone.gemfire.Instantiator;
import com.gemstone.gemfire.InvalidDeltaException;
import com.gemstone.gemfire.cache.EntryEvent;
import com.gemstone.gemfire.cache.Operation;
import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
import com.gemstone.gemfire.internal.concurrent.ConcurrentHashSet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -57,11 +60,13 @@ import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.Session;
import org.springframework.session.SessionRepository;
import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration;
import org.springframework.session.data.gemfire.support.GemFireUtils;
import org.springframework.session.events.SessionCreatedEvent;
import org.springframework.session.events.SessionDeletedEvent;
import org.springframework.session.events.SessionDestroyedEvent;
import org.springframework.session.events.SessionExpiredEvent;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
@@ -90,6 +95,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
}
};
private final Set<Integer> cachedSessionIds = new ConcurrentHashSet<Integer>();
private final GemfireOperations template;
protected final Log logger = newLogger();
@@ -216,8 +223,49 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
}
/* (non-Javadoc) */
boolean isExpiringSessionOrNull(Object obj) {
return (obj == null || obj instanceof ExpiringSession);
boolean isCreate(EntryEvent<?, ?> event) {
return (isCreate(event.getOperation()) && isNotUpdate(event) && isExpiringSessionOrNull(event.getNewValue()));
}
/* (non-Javadoc) */
private boolean isCreate(Operation operation) {
return (operation.isCreate() && !Operation.LOCAL_LOAD_CREATE.equals(operation));
}
/**
* Used to determine whether the developer is storing (HTTP) Sessions with other, arbitrary application
* domain objects in the same GemFire cache {@link Region}; crazier things have happened!
*
* @param obj {@link Object} to evaluate.
* @return a boolean value indicating whether the {@link Object} from the entry event is indeed
* a {@link ExpiringSession}.
* @see org.springframework.session.ExpiringSession
*/
private boolean isExpiringSessionOrNull(Object obj) {
return (obj instanceof ExpiringSession || obj == null);
}
/* (non-Javadoc) */
private boolean isNotUpdate(EntryEvent event) {
return (isNotProxyRegion() || !this.cachedSessionIds.contains(ObjectUtils.nullSafeHashCode(event.getKey())));
}
/* (non-Javadoc) */
private boolean isNotProxyRegion() {
return !isProxyRegion();
}
/* (non-Javadoc) */
private boolean isProxyRegion() {
return GemFireUtils.isProxy(((GemfireAccessor) getTemplate()).getRegion());
}
boolean forget(Object sessionId) {
return this.cachedSessionIds.remove(ObjectUtils.nullSafeHashCode(sessionId));
}
boolean remember(Object sessionId) {
return (isProxyRegion() && this.cachedSessionIds.add(ObjectUtils.nullSafeHashCode(sessionId)));
}
/* (non-Javadoc) */
@@ -226,16 +274,15 @@ 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 {@link EntryEvent} containing the details of the cache {@link Region} operation.
* @see com.gemstone.gemfire.cache.EntryEvent
* @see #handleCreated(String, ExpiringSession)
*/
@Override
public void afterCreate(EntryEvent<Object, ExpiringSession> event) {
if (isExpiringSessionOrNull(event.getNewValue())) {
if (isCreate(event)) {
handleCreated(event.getKey().toString(), toExpiringSession(event.getNewValue()));
}
}
@@ -266,6 +313,19 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
handleExpired(event.getKey().toString(), toExpiringSession(event.getOldValue()));
}
/**
* Deletes the given {@link Session} from GemFire.
*
* @param session {@link Session} to delete.
* @return {@literal null}.
* @see org.springframework.session.Session
* @see #delete(String)
*/
protected ExpiringSession delete(Session session) {
delete(session.getId());
return null;
}
/**
* Causes Session created events to be published to the Spring application context.
*
@@ -276,6 +336,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
* @see #publishEvent(ApplicationEvent)
*/
protected void handleCreated(String sessionId, ExpiringSession session) {
remember(sessionId);
publishEvent(session != null ? new SessionCreatedEvent(this, session)
: new SessionCreatedEvent(this, sessionId));
}
@@ -290,6 +352,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
* @see #publishEvent(ApplicationEvent)
*/
protected void handleDeleted(String sessionId, ExpiringSession session) {
forget(sessionId);
publishEvent(session != null ? new SessionDeletedEvent(this, session)
: new SessionDeletedEvent(this, sessionId));
}
@@ -304,6 +368,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
* @see #publishEvent(ApplicationEvent)
*/
protected void handleDestroyed(String sessionId, ExpiringSession session) {
forget(sessionId);
publishEvent(session != null ? new SessionDestroyedEvent(this, session)
: new SessionDestroyedEvent(this, sessionId));
}
@@ -318,6 +384,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
* @see #publishEvent(ApplicationEvent)
*/
protected void handleExpired(String sessionId, ExpiringSession session) {
forget(sessionId);
publishEvent(session != null ? new SessionExpiredEvent(this, session)
: new SessionExpiredEvent(this, sessionId));
}
@@ -334,10 +402,23 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
getApplicationEventPublisher().publishEvent(event);
}
catch (Throwable t) {
this.logger.error(String.format("error occurred publishing event (%1$s)", event), t);
this.logger.error(String.format("Error occurred publishing event [%s]", event), t);
}
}
/**
* Updates the {@link ExpiringSession#setLastAccessedTime(long)} property of the {@link ExpiringSession}.
*
* @param <T> {@link Class} sub-type of the {@link ExpiringSession}.
* @param expiringSession {@link ExpiringSession} to touch.
* @return the {@link ExpiringSession}.
* @see org.springframework.session.ExpiringSession#setLastAccessedTime(long)
*/
protected <T extends ExpiringSession> T touch(T expiringSession) {
expiringSession.setLastAccessedTime(System.currentTimeMillis());
return expiringSession;
}
/**
* GemFireSession is a GemFire representation model of a Spring {@link ExpiringSession}
* that stores and manages Session state information in GemFire. This class implements
@@ -362,8 +443,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
private long creationTime;
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();
@@ -399,11 +480,13 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
return session;
}
public static GemFireSession copy(ExpiringSession session) {
return new GemFireSession(session);
}
/* (non-Javadoc) */
public static GemFireSession from(ExpiringSession expiringSession) {
GemFireSession session = new GemFireSession(expiringSession);
session.setLastAccessedTime(System.currentTimeMillis());
return session;
public static GemFireSession from(ExpiringSession session) {
return (session instanceof GemFireSession ? (GemFireSession) session : copy(session));
}
/* (non-Javadoc) */

View File

@@ -119,15 +119,12 @@ public class GemFireOperationsSessionRepository extends AbstractGemFireOperation
ExpiringSession storedSession = getTemplate().get(sessionId);
if (storedSession != null) {
if (storedSession.isExpired()) {
delete(storedSession.getId());
}
else {
return GemFireSession.from(storedSession);
}
storedSession = storedSession.isExpired()
? delete(storedSession)
: touch(GemFireSession.from(storedSession));
}
return null;
return storedSession;
}
/**
@@ -138,7 +135,7 @@ public class GemFireOperationsSessionRepository extends AbstractGemFireOperation
* @see org.springframework.session.ExpiringSession
*/
public void save(ExpiringSession session) {
getTemplate().put(session.getId(), new GemFireSession(session));
getTemplate().put(session.getId(), GemFireSession.from(session));
}
/**
@@ -152,5 +149,4 @@ public class GemFireOperationsSessionRepository extends AbstractGemFireOperation
public void delete(String sessionId) {
handleDeleted(sessionId, getTemplate().<Object, ExpiringSession>remove(sessionId));
}
}

View File

@@ -20,6 +20,7 @@ import java.io.Closeable;
import java.io.IOException;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.DataPolicy;
import com.gemstone.gemfire.cache.GemFireCache;
import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.RegionShortcut;
@@ -122,6 +123,19 @@ public abstract class GemFireUtils {
}
}
/**
* Determines whether the given {@link Region} is a PROXY, which would be indicated by the {@link Region}
* having a {@link DataPolicy} of {@link DataPolicy#EMPTY}.
*
* @param region {@link Region} to evaluate.
* @return a boolean value indicating whether the {@link Region} is a PROXY.
* @see com.gemstone.gemfire.cache.DataPolicy
* @see com.gemstone.gemfire.cache.Region
*/
public static boolean isProxy(Region<?, ?> region) {
return DataPolicy.EMPTY.equals(region.getAttributes().getDataPolicy());
}
/**
* Determines whether the peer {@link RegionShortcut} is a proxy-based shortcut. NOTE:
* "proxy"-based Regions keep no local state.
@@ -153,5 +167,4 @@ public abstract class GemFireUtils {
public static String toRegionPath(String regionName) {
return String.format("%1$s%2$s", Region.SEPARATOR, regionName);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2016 the original author or authors.
* Copyright 2014-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -66,7 +66,11 @@ public class MongoOperationsSessionRepository
}
public MongoExpiringSession createSession() {
return new MongoExpiringSession(this.maxInactiveIntervalInSeconds);
MongoExpiringSession session = new MongoExpiringSession();
if (this.maxInactiveIntervalInSeconds != null) {
session.setMaxInactiveIntervalInSeconds(this.maxInactiveIntervalInSeconds);
}
return session;
}
public void save(MongoExpiringSession session) {

View File

@@ -694,7 +694,7 @@ public class RedisOperationsSessionRepository implements
* was retrieved. Cannot be null.
*/
RedisSession(MapSession cached) {
Assert.notNull("MapSession cannot be null");
Assert.notNull(cached, "MapSession cannot be null");
this.cached = cached;
this.originalPrincipalName = PRINCIPAL_NAME_RESOLVER.resolvePrincipal(this);
}

View File

@@ -658,7 +658,7 @@ public class JdbcOperationsSessionRepository implements
}
JdbcSession(ExpiringSession delegate) {
Assert.notNull("ExpiringSession cannot be null");
Assert.notNull(delegate, "ExpiringSession cannot be null");
this.delegate = delegate;
}

View File

@@ -26,6 +26,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.util.Assert;
/**
@@ -57,6 +58,8 @@ public class SpringSessionRememberMeServices
private int validitySeconds = THIRTY_DAYS_SECONDS;
private String sessionAttrToDeleteOnLoginFail = HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY;
public final Authentication autoLogin(HttpServletRequest request,
HttpServletResponse response) {
return null;
@@ -132,7 +135,7 @@ public class SpringSessionRememberMeServices
logger.debug("Interactive login attempt was unsuccessful.");
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate();
session.removeAttribute(this.sessionAttrToDeleteOnLoginFail);
}
}
}

View File

@@ -226,9 +226,6 @@ abstract class OnCommittedResponseWrapper extends HttpServletResponseWrapper {
onResponseCommitted();
disableOnResponseCommitted();
}
else if (this.logger.isDebugEnabled()) {
this.logger.debug("Skip invoking on");
}
}
/**

View File

@@ -1,5 +1,5 @@
CREATE TABLE SPRING_SESSION (
SESSION_ID CHAR(36),
SESSION_ID CHAR(36) NOT NULL,
CREATION_TIME BIGINT NOT NULL,
LAST_ACCESS_TIME BIGINT NOT NULL,
MAX_INACTIVE_INTERVAL INT NOT NULL,
@@ -10,9 +10,9 @@ CREATE TABLE SPRING_SESSION (
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
SESSION_ID CHAR(36),
ATTRIBUTE_NAME VARCHAR(200),
ATTRIBUTE_BYTES BLOB,
SESSION_ID CHAR(36) NOT NULL,
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
ATTRIBUTE_BYTES BLOB NOT NULL,
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
);

View File

@@ -1,5 +1,5 @@
CREATE TABLE SPRING_SESSION (
SESSION_ID CHAR(36),
SESSION_ID CHAR(36) NOT NULL,
CREATION_TIME BIGINT NOT NULL,
LAST_ACCESS_TIME BIGINT NOT NULL,
MAX_INACTIVE_INTERVAL INT NOT NULL,
@@ -10,9 +10,9 @@ CREATE TABLE SPRING_SESSION (
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
SESSION_ID CHAR(36),
ATTRIBUTE_NAME VARCHAR(200),
ATTRIBUTE_BYTES BLOB,
SESSION_ID CHAR(36) NOT NULL,
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
ATTRIBUTE_BYTES BLOB NOT NULL,
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
);

View File

@@ -1,5 +1,5 @@
CREATE TABLE SPRING_SESSION (
SESSION_ID CHAR(36),
SESSION_ID CHAR(36) NOT NULL,
CREATION_TIME BIGINT NOT NULL,
LAST_ACCESS_TIME BIGINT NOT NULL,
MAX_INACTIVE_INTERVAL INT NOT NULL,
@@ -10,9 +10,9 @@ CREATE TABLE SPRING_SESSION (
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
SESSION_ID CHAR(36),
ATTRIBUTE_NAME VARCHAR(200),
ATTRIBUTE_BYTES LONGVARBINARY,
SESSION_ID CHAR(36) NOT NULL,
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
ATTRIBUTE_BYTES LONGVARBINARY NOT NULL,
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
);

View File

@@ -1,5 +1,5 @@
CREATE TABLE SPRING_SESSION (
SESSION_ID CHAR(36),
SESSION_ID CHAR(36) NOT NULL,
CREATION_TIME BIGINT NOT NULL,
LAST_ACCESS_TIME BIGINT NOT NULL,
MAX_INACTIVE_INTERVAL INT NOT NULL,
@@ -10,9 +10,9 @@ CREATE TABLE SPRING_SESSION (
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
SESSION_ID CHAR(36),
ATTRIBUTE_NAME VARCHAR(200),
ATTRIBUTE_BYTES LONGVARBINARY,
SESSION_ID CHAR(36) NOT NULL,
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
ATTRIBUTE_BYTES LONGVARBINARY NOT NULL,
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
);

View File

@@ -1,5 +1,5 @@
CREATE TABLE SPRING_SESSION (
SESSION_ID CHAR(36),
SESSION_ID CHAR(36) NOT NULL,
CREATION_TIME BIGINT NOT NULL,
LAST_ACCESS_TIME BIGINT NOT NULL,
MAX_INACTIVE_INTERVAL INT NOT NULL,
@@ -10,9 +10,9 @@ CREATE TABLE SPRING_SESSION (
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
SESSION_ID CHAR(36),
ATTRIBUTE_NAME VARCHAR(200),
ATTRIBUTE_BYTES BLOB,
SESSION_ID CHAR(36) NOT NULL,
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
ATTRIBUTE_BYTES BLOB NOT NULL,
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
) ENGINE=InnoDB;

View File

@@ -1,5 +1,5 @@
CREATE TABLE SPRING_SESSION (
SESSION_ID CHAR(36),
SESSION_ID CHAR(36) NOT NULL,
CREATION_TIME NUMBER(19,0) NOT NULL,
LAST_ACCESS_TIME NUMBER(19,0) NOT NULL,
MAX_INACTIVE_INTERVAL NUMBER(10,0) NOT NULL,
@@ -10,9 +10,9 @@ CREATE TABLE SPRING_SESSION (
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
SESSION_ID CHAR(36),
ATTRIBUTE_NAME VARCHAR2(200 CHAR),
ATTRIBUTE_BYTES BLOB,
SESSION_ID CHAR(36) NOT NULL,
ATTRIBUTE_NAME VARCHAR2(200 CHAR) NOT NULL,
ATTRIBUTE_BYTES BLOB NOT NULL,
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
);

View File

@@ -1,5 +1,5 @@
CREATE TABLE SPRING_SESSION (
SESSION_ID CHAR(36),
SESSION_ID CHAR(36) NOT NULL,
CREATION_TIME BIGINT NOT NULL,
LAST_ACCESS_TIME BIGINT NOT NULL,
MAX_INACTIVE_INTERVAL INT NOT NULL,
@@ -10,9 +10,9 @@ CREATE TABLE SPRING_SESSION (
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
SESSION_ID CHAR(36),
ATTRIBUTE_NAME VARCHAR(200),
ATTRIBUTE_BYTES BYTEA,
SESSION_ID CHAR(36) NOT NULL,
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
ATTRIBUTE_BYTES BYTEA NOT NULL,
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
);

View File

@@ -1,5 +1,5 @@
CREATE TABLE SPRING_SESSION (
SESSION_ID CHARACTER(36),
SESSION_ID CHARACTER(36) NOT NULL,
CREATION_TIME INTEGER NOT NULL,
LAST_ACCESS_TIME INTEGER NOT NULL,
MAX_INACTIVE_INTERVAL INTEGER NOT NULL,
@@ -10,9 +10,9 @@ CREATE TABLE SPRING_SESSION (
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
SESSION_ID CHAR(36),
ATTRIBUTE_NAME VARCHAR(200),
ATTRIBUTE_BYTES BLOB,
SESSION_ID CHAR(36) NOT NULL,
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
ATTRIBUTE_BYTES BLOB NOT NULL,
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
);

View File

@@ -1,5 +1,5 @@
CREATE TABLE SPRING_SESSION (
SESSION_ID CHAR(36),
SESSION_ID CHAR(36) NOT NULL,
CREATION_TIME BIGINT NOT NULL,
LAST_ACCESS_TIME BIGINT NOT NULL,
MAX_INACTIVE_INTERVAL INT NOT NULL,
@@ -10,9 +10,9 @@ CREATE TABLE SPRING_SESSION (
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
SESSION_ID CHAR(36),
ATTRIBUTE_NAME VARCHAR(200),
ATTRIBUTE_BYTES IMAGE,
SESSION_ID CHAR(36) NOT NULL,
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
ATTRIBUTE_BYTES IMAGE NOT NULL,
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
);

View File

@@ -1,5 +1,5 @@
CREATE TABLE SPRING_SESSION (
SESSION_ID CHAR(36),
SESSION_ID CHAR(36) NOT NULL,
CREATION_TIME BIGINT NOT NULL,
LAST_ACCESS_TIME BIGINT NOT NULL,
MAX_INACTIVE_INTERVAL INT NOT NULL,
@@ -10,9 +10,9 @@ CREATE TABLE SPRING_SESSION (
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
SESSION_ID CHAR(36),
ATTRIBUTE_NAME VARCHAR(200),
ATTRIBUTE_BYTES IMAGE,
SESSION_ID CHAR(36) NOT NULL,
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
ATTRIBUTE_BYTES IMAGE NOT NULL,
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
) LOCK DATAROWS;

View File

@@ -24,6 +24,7 @@ import java.util.concurrent.TimeUnit;
import com.gemstone.gemfire.cache.AttributesMutator;
import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.query.SelectResults;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -89,32 +90,23 @@ public class GemFireOperationsSessionRepositoryTest {
@Before
public void setup() throws Exception {
given(this.mockRegion.getAttributesMutator())
.willReturn(this.mockAttributesMutator);
given(this.mockRegion.getAttributesMutator()).willReturn(this.mockAttributesMutator);
given(this.mockRegion.getFullPath()).willReturn("/Example");
given(this.mockTemplate.<Object, ExpiringSession>getRegion())
.willReturn(this.mockRegion);
given(this.mockTemplate.<Object, ExpiringSession>getRegion()).willReturn(this.mockRegion);
this.sessionRepository = new GemFireOperationsSessionRepository(
this.mockTemplate);
this.sessionRepository
.setApplicationEventPublisher(this.mockApplicationEventPublisher);
this.sessionRepository
.setMaxInactiveIntervalInSeconds(MAX_INACTIVE_INTERVAL_IN_SECONDS);
this.sessionRepository = new GemFireOperationsSessionRepository(this.mockTemplate);
this.sessionRepository.setApplicationEventPublisher(this.mockApplicationEventPublisher);
this.sessionRepository.setMaxInactiveIntervalInSeconds(MAX_INACTIVE_INTERVAL_IN_SECONDS);
this.sessionRepository.afterPropertiesSet();
assertThat(this.sessionRepository.getApplicationEventPublisher())
.isSameAs(this.mockApplicationEventPublisher);
assertThat(this.sessionRepository.getFullyQualifiedRegionName())
.isEqualTo("/Example");
assertThat(this.sessionRepository.getMaxInactiveIntervalInSeconds())
.isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
assertThat(this.sessionRepository.getApplicationEventPublisher()).isSameAs(this.mockApplicationEventPublisher);
assertThat(this.sessionRepository.getFullyQualifiedRegionName()).isEqualTo("/Example");
assertThat(this.sessionRepository.getMaxInactiveIntervalInSeconds()).isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
}
@After
public void tearDown() {
verify(this.mockAttributesMutator, times(1))
.addCacheListener(same(this.sessionRepository));
verify(this.mockAttributesMutator, times(1)).addCacheListener(same(this.sessionRepository));
verify(this.mockRegion, times(1)).getFullPath();
verify(this.mockTemplate, times(1)).getRegion();
}
@@ -128,21 +120,18 @@ public class GemFireOperationsSessionRepositoryTest {
SelectResults<Object> mockSelectResults = mock(SelectResults.class);
given(mockSelectResults.asList())
.willReturn(Collections.<Object>singletonList(mockSession));
given(mockSelectResults.asList()).willReturn(Collections.<Object>singletonList(mockSession));
String indexName = "vip";
String indexValue = "rwinch";
String expectedQql = String.format(
GemFireOperationsSessionRepository.FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY,
this.sessionRepository.getFullyQualifiedRegionName(), indexName);
String expectedQql = String.format(GemFireOperationsSessionRepository.FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY,
this.sessionRepository.getFullyQualifiedRegionName(), indexName);
given(this.mockTemplate.find(eq(expectedQql), eq(indexValue)))
.willReturn(mockSelectResults);
given(this.mockTemplate.find(eq(expectedQql), eq(indexValue))).willReturn(mockSelectResults);
Map<String, ExpiringSession> sessions = this.sessionRepository
.findByIndexNameAndIndexValue(indexName, indexValue);
Map<String, ExpiringSession> sessions =
this.sessionRepository.findByIndexNameAndIndexValue(indexName, indexValue);
assertThat(sessions).isNotNull();
assertThat(sessions.size()).isEqualTo(1);
@@ -158,8 +147,7 @@ public class GemFireOperationsSessionRepositoryTest {
public void findByPrincipalNameFindsMatchingSessions() throws Exception {
ExpiringSession mockSessionOne = mock(ExpiringSession.class, "MockSessionOne");
ExpiringSession mockSessionTwo = mock(ExpiringSession.class, "MockSessionTwo");
ExpiringSession mockSessionThree = mock(ExpiringSession.class,
"MockSessionThree");
ExpiringSession mockSessionThree = mock(ExpiringSession.class, "MockSessionThree");
given(mockSessionOne.getId()).willReturn("1");
given(mockSessionTwo.getId()).willReturn("2");
@@ -167,22 +155,18 @@ public class GemFireOperationsSessionRepositoryTest {
SelectResults<Object> mockSelectResults = mock(SelectResults.class);
given(mockSelectResults.asList()).willReturn(
Arrays.<Object>asList(mockSessionOne, mockSessionTwo, mockSessionThree));
given(mockSelectResults.asList())
.willReturn(Arrays.<Object>asList(mockSessionOne, mockSessionTwo, mockSessionThree));
String principalName = "jblum";
String expectedOql = String.format(
GemFireOperationsSessionRepository.FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY,
this.sessionRepository.getFullyQualifiedRegionName());
String expectedOql = String.format(GemFireOperationsSessionRepository.FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY,
this.sessionRepository.getFullyQualifiedRegionName());
given(this.mockTemplate.find(eq(expectedOql), eq(principalName)))
.willReturn(mockSelectResults);
given(this.mockTemplate.find(eq(expectedOql), eq(principalName))).willReturn(mockSelectResults);
Map<String, ExpiringSession> sessions = this.sessionRepository
.findByIndexNameAndIndexValue(
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
principalName);
Map<String, ExpiringSession> sessions = this.sessionRepository.findByIndexNameAndIndexValue(
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, principalName);
assertThat(sessions).isNotNull();
assertThat(sessions.size()).isEqualTo(3);
@@ -206,17 +190,13 @@ public class GemFireOperationsSessionRepositoryTest {
String principalName = "jblum";
String expectedOql = String.format(
GemFireOperationsSessionRepository.FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY,
this.sessionRepository.getFullyQualifiedRegionName());
String expectedOql = String.format(GemFireOperationsSessionRepository.FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY,
this.sessionRepository.getFullyQualifiedRegionName());
given(this.mockTemplate.find(eq(expectedOql), eq(principalName)))
.willReturn(mockSelectResults);
given(this.mockTemplate.find(eq(expectedOql), eq(principalName))).willReturn(mockSelectResults);
Map<String, ExpiringSession> sessions = this.sessionRepository
.findByIndexNameAndIndexValue(
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
principalName);
Map<String, ExpiringSession> sessions = this.sessionRepository.findByIndexNameAndIndexValue(
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, principalName);
assertThat(sessions).isNotNull();
assertThat(sessions.isEmpty()).isTrue();
@@ -227,11 +207,11 @@ public class GemFireOperationsSessionRepositoryTest {
@Test
public void prepareQueryReturnsPrincipalNameOql() {
String actualQql = this.sessionRepository
.prepareQuery(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME);
String expectedOql = String.format(
GemFireOperationsSessionRepository.FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY,
this.sessionRepository.getFullyQualifiedRegionName());
String actualQql =
this.sessionRepository.prepareQuery(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME);
String expectedOql = String.format(GemFireOperationsSessionRepository.FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY,
this.sessionRepository.getFullyQualifiedRegionName());
assertThat(actualQql).isEqualTo(expectedOql);
}
@@ -240,29 +220,24 @@ public class GemFireOperationsSessionRepositoryTest {
public void prepareQueryReturnsIndexNameValueOql() {
String attributeName = "testAttributeName";
String actualOql = this.sessionRepository.prepareQuery(attributeName);
String expectedOql = String.format(
GemFireOperationsSessionRepository.FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY,
this.sessionRepository.getFullyQualifiedRegionName(), attributeName);
String expectedOql = String.format(GemFireOperationsSessionRepository.FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY,
this.sessionRepository.getFullyQualifiedRegionName(), attributeName);
assertThat(actualOql).isEqualTo(expectedOql);
}
@Test
public void createProperlyInitializedSession() {
final long beforeOrAtCreationTime = System.currentTimeMillis();
long beforeOrAtCreationTime = System.currentTimeMillis();
ExpiringSession session = this.sessionRepository.createSession();
assertThat(session).isInstanceOf(
AbstractGemFireOperationsSessionRepository.GemFireSession.class);
assertThat(session).isInstanceOf(AbstractGemFireOperationsSessionRepository.GemFireSession.class);
assertThat(session.getId()).isNotNull();
assertThat(session.getAttributeNames().isEmpty()).isTrue();
assertThat(session.getCreationTime())
.isGreaterThanOrEqualTo(beforeOrAtCreationTime);
assertThat(session.getLastAccessedTime())
.isGreaterThanOrEqualTo(beforeOrAtCreationTime);
assertThat(session.getMaxInactiveIntervalInSeconds())
.isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
assertThat(session.getCreationTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime);
assertThat(session.getLastAccessedTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime);
assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
}
@Test
@@ -277,23 +252,21 @@ public class GemFireOperationsSessionRepositoryTest {
given(this.mockTemplate.remove(eq(expectedSessionId))).willReturn(mockSession);
willAnswer(new Answer<Void>() {
public Void answer(final InvocationOnMock invocation) throws Throwable {
ApplicationEvent applicationEvent = invocation.getArgumentAt(0,
ApplicationEvent.class);
public Void answer(InvocationOnMock invocation) throws Throwable {
ApplicationEvent applicationEvent = invocation.getArgumentAt(0, ApplicationEvent.class);
assertThat(applicationEvent).isInstanceOf(SessionDeletedEvent.class);
AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent;
assertThat(sessionEvent.getSource()).isSameAs(
GemFireOperationsSessionRepositoryTest.this.sessionRepository);
assertThat(sessionEvent.getSource())
.isSameAs(GemFireOperationsSessionRepositoryTest.this.sessionRepository);
assertThat(sessionEvent.getSession()).isSameAs(mockSession);
assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSessionId);
return null;
}
}).given(this.mockApplicationEventPublisher)
.publishEvent(any(ApplicationEvent.class));
}).given(this.mockApplicationEventPublisher).publishEvent(any(ApplicationEvent.class));
assertThat(this.sessionRepository.getSession(expectedSessionId)).isNull();
@@ -302,16 +275,15 @@ public class GemFireOperationsSessionRepositoryTest {
verify(mockSession, times(1)).isExpired();
verify(mockSession, times(2)).getId();
verify(this.mockApplicationEventPublisher, times(1))
.publishEvent(isA(SessionDeletedEvent.class));
.publishEvent(isA(SessionDeletedEvent.class));
}
@Test
public void getSessionFindsMatchingNonExpiredSessionById() {
final String expectedId = "1";
String expectedId = "1";
final long expectedCreationTime = System.currentTimeMillis();
final long currentLastAccessedTime = (expectedCreationTime
+ TimeUnit.MINUTES.toMillis(5));
long expectedCreationTime = System.currentTimeMillis();
long currentLastAccessedTime = (expectedCreationTime + TimeUnit.MINUTES.toMillis(5));
ExpiringSession mockSession = mock(ExpiringSession.class);
@@ -319,8 +291,7 @@ public class GemFireOperationsSessionRepositoryTest {
given(mockSession.getId()).willReturn(expectedId);
given(mockSession.getCreationTime()).willReturn(expectedCreationTime);
given(mockSession.getLastAccessedTime()).willReturn(currentLastAccessedTime);
given(mockSession.getAttributeNames())
.willReturn(Collections.singleton("attrOne"));
given(mockSession.getAttributeNames()).willReturn(Collections.singleton("attrOne"));
given(mockSession.getAttribute(eq("attrOne"))).willReturn("test");
given(this.mockTemplate.get(eq(expectedId))).willReturn(mockSession);
@@ -329,14 +300,10 @@ public class GemFireOperationsSessionRepositoryTest {
assertThat(actualSession).isNotSameAs(mockSession);
assertThat(actualSession.getId()).isEqualTo(expectedId);
assertThat(actualSession.getCreationTime()).isEqualTo(expectedCreationTime);
assertThat(actualSession.getLastAccessedTime())
.isNotEqualTo(currentLastAccessedTime);
assertThat(actualSession.getLastAccessedTime())
.isGreaterThanOrEqualTo(expectedCreationTime);
assertThat(actualSession.getAttributeNames())
.isEqualTo(Collections.singleton("attrOne"));
assertThat(String.valueOf(actualSession.getAttribute("attrOne")))
.isEqualTo("test");
assertThat(actualSession.getLastAccessedTime()).isNotEqualTo(currentLastAccessedTime);
assertThat(actualSession.getLastAccessedTime()).isGreaterThanOrEqualTo(expectedCreationTime);
assertThat(actualSession.getAttributeNames()).isEqualTo(Collections.singleton("attrOne"));
assertThat(String.valueOf(actualSession.getAttribute("attrOne"))).isEqualTo("test");
verify(this.mockTemplate, times(1)).get(eq(expectedId));
verify(mockSession, times(1)).isExpired();
@@ -358,8 +325,7 @@ public class GemFireOperationsSessionRepositoryTest {
final String expectedSessionId = "1";
final long expectedCreationTime = System.currentTimeMillis();
final long expectedLastAccessTime = (expectedCreationTime
+ TimeUnit.MINUTES.toMillis(5));
final long expectedLastAccessTime = (expectedCreationTime + TimeUnit.MINUTES.toMillis(5));
ExpiringSession mockSession = mock(ExpiringSession.class);
@@ -371,27 +337,22 @@ public class GemFireOperationsSessionRepositoryTest {
given(mockSession.getAttributeNames()).willReturn(Collections.<String>emptySet());
given(this.mockTemplate.put(eq(expectedSessionId),
isA(AbstractGemFireOperationsSessionRepository.GemFireSession.class)))
.willAnswer(new Answer<ExpiringSession>() {
public ExpiringSession answer(
final InvocationOnMock invocation) throws Throwable {
ExpiringSession session = invocation.getArgumentAt(1,
ExpiringSession.class);
isA(AbstractGemFireOperationsSessionRepository.GemFireSession.class)))
.willAnswer(new Answer<ExpiringSession>() {
public ExpiringSession answer(InvocationOnMock invocation) throws Throwable {
ExpiringSession session = invocation.getArgumentAt(1, ExpiringSession.class);
assertThat(session).isNotNull();
assertThat(session.getId()).isEqualTo(expectedSessionId);
assertThat(session.getCreationTime())
.isEqualTo(expectedCreationTime);
assertThat(session.getLastAccessedTime())
.isEqualTo(expectedLastAccessTime);
assertThat(session.getMaxInactiveIntervalInSeconds())
.isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
assertThat(session.getAttributeNames().isEmpty())
.isTrue();
assertThat(session).isNotNull();
assertThat(session.getId()).isEqualTo(expectedSessionId);
assertThat(session.getCreationTime()).isEqualTo(expectedCreationTime);
assertThat(session.getLastAccessedTime()).isEqualTo(expectedLastAccessTime);
assertThat(session.getMaxInactiveIntervalInSeconds())
.isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
assertThat(session.getAttributeNames().isEmpty()).isTrue();
return null;
}
});
return null;
}
});
this.sessionRepository.save(mockSession);
@@ -401,7 +362,7 @@ public class GemFireOperationsSessionRepositoryTest {
verify(mockSession, times(1)).getMaxInactiveIntervalInSeconds();
verify(mockSession, times(1)).getAttributeNames();
verify(this.mockTemplate, times(1)).put(eq(expectedSessionId),
isA(AbstractGemFireOperationsSessionRepository.GemFireSession.class));
isA(AbstractGemFireOperationsSessionRepository.GemFireSession.class));
}
@Test
@@ -415,29 +376,27 @@ public class GemFireOperationsSessionRepositoryTest {
willAnswer(new Answer<Void>() {
public Void answer(final InvocationOnMock invocation) throws Throwable {
ApplicationEvent applicationEvent = invocation.getArgumentAt(0,
ApplicationEvent.class);
ApplicationEvent applicationEvent = invocation.getArgumentAt(0, ApplicationEvent.class);
assertThat(applicationEvent).isInstanceOf(SessionDeletedEvent.class);
AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent;
assertThat(sessionEvent.getSource()).isSameAs(
GemFireOperationsSessionRepositoryTest.this.sessionRepository);
assertThat(sessionEvent.getSource())
.isSameAs(GemFireOperationsSessionRepositoryTest.this.sessionRepository);
assertThat(sessionEvent.getSession()).isSameAs(mockSession);
assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSessionId);
return null;
}
}).given(this.mockApplicationEventPublisher)
.publishEvent(isA(SessionDeletedEvent.class));
}).given(this.mockApplicationEventPublisher).publishEvent(isA(SessionDeletedEvent.class));
this.sessionRepository.delete(expectedSessionId);
verify(mockSession, times(1)).getId();
verify(this.mockTemplate, times(1)).remove(eq(expectedSessionId));
verify(this.mockApplicationEventPublisher, times(1))
.publishEvent(isA(SessionDeletedEvent.class));
.publishEvent(isA(SessionDeletedEvent.class));
}
@Test
@@ -448,32 +407,29 @@ public class GemFireOperationsSessionRepositoryTest {
willAnswer(new Answer<Void>() {
public Void answer(final InvocationOnMock invocation) throws Throwable {
ApplicationEvent applicationEvent = invocation.getArgumentAt(0,
ApplicationEvent.class);
ApplicationEvent applicationEvent = invocation.getArgumentAt(0, ApplicationEvent.class);
assertThat(applicationEvent).isInstanceOf(SessionDeletedEvent.class);
AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent;
assertThat(sessionEvent.getSource()).isSameAs(
GemFireOperationsSessionRepositoryTest.this.sessionRepository);
assertThat(sessionEvent.getSource()).
isSameAs(GemFireOperationsSessionRepositoryTest.this.sessionRepository);
assertThat(sessionEvent.getSession()).isNull();
assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSessionId);
return null;
}
}).given(this.mockApplicationEventPublisher)
.publishEvent(isA(SessionDeletedEvent.class));
}).given(this.mockApplicationEventPublisher).publishEvent(isA(SessionDeletedEvent.class));
this.sessionRepository.delete(expectedSessionId);
verify(this.mockTemplate, times(1)).remove(eq(expectedSessionId));
verify(this.mockApplicationEventPublisher, times(1))
.publishEvent(isA(SessionDeletedEvent.class));
.publishEvent(isA(SessionDeletedEvent.class));
}
protected abstract class GemfireOperationsAccessor extends GemfireAccessor
implements GemfireOperations {
}
}

View File

@@ -20,13 +20,18 @@ import java.io.Closeable;
import java.io.IOException;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.DataPolicy;
import com.gemstone.gemfire.cache.GemFireCache;
import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.RegionAttributes;
import com.gemstone.gemfire.cache.RegionShortcut;
import com.gemstone.gemfire.cache.client.ClientCache;
import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@@ -52,8 +57,7 @@ public class GemFireUtilsTest {
}
@Test
public void closeNonNullCloseableObjectThrowingIOExceptionReturnsFalse()
throws IOException {
public void closeNonNullCloseableObjectThrowingIOExceptionReturnsFalse() throws IOException {
Closeable mockCloseable = mock(Closeable.class);
willThrow(new IOException("test")).given(mockCloseable).close();
assertThat(GemFireUtils.close(mockCloseable)).isFalse();
@@ -101,17 +105,14 @@ public class GemFireUtilsTest {
assertThat(GemFireUtils.isLocal(ClientRegionShortcut.LOCAL_HEAP_LRU)).isTrue();
assertThat(GemFireUtils.isLocal(ClientRegionShortcut.LOCAL_OVERFLOW)).isTrue();
assertThat(GemFireUtils.isLocal(ClientRegionShortcut.LOCAL_PERSISTENT)).isTrue();
assertThat(GemFireUtils.isLocal(ClientRegionShortcut.LOCAL_PERSISTENT_OVERFLOW))
.isTrue();
assertThat(GemFireUtils.isLocal(ClientRegionShortcut.LOCAL_PERSISTENT_OVERFLOW)).isTrue();
}
@Test
public void clientRegionShortcutIsNotLocal() {
assertThat(GemFireUtils.isLocal(ClientRegionShortcut.CACHING_PROXY)).isFalse();
assertThat(GemFireUtils.isLocal(ClientRegionShortcut.CACHING_PROXY_HEAP_LRU))
.isFalse();
assertThat(GemFireUtils.isLocal(ClientRegionShortcut.CACHING_PROXY_OVERFLOW))
.isFalse();
assertThat(GemFireUtils.isLocal(ClientRegionShortcut.CACHING_PROXY_HEAP_LRU)).isFalse();
assertThat(GemFireUtils.isLocal(ClientRegionShortcut.CACHING_PROXY_OVERFLOW)).isFalse();
assertThat(GemFireUtils.isLocal(ClientRegionShortcut.PROXY)).isFalse();
}
@@ -123,56 +124,72 @@ public class GemFireUtilsTest {
@Test
public void clientRegionShortcutIsNotProxy() {
assertThat(GemFireUtils.isProxy(ClientRegionShortcut.CACHING_PROXY)).isFalse();
assertThat(GemFireUtils.isProxy(ClientRegionShortcut.CACHING_PROXY_HEAP_LRU))
.isFalse();
assertThat(GemFireUtils.isProxy(ClientRegionShortcut.CACHING_PROXY_OVERFLOW))
.isFalse();
assertThat(GemFireUtils.isProxy(ClientRegionShortcut.CACHING_PROXY_HEAP_LRU)).isFalse();
assertThat(GemFireUtils.isProxy(ClientRegionShortcut.CACHING_PROXY_OVERFLOW)).isFalse();
assertThat(GemFireUtils.isProxy(ClientRegionShortcut.LOCAL)).isFalse();
assertThat(GemFireUtils.isProxy(ClientRegionShortcut.LOCAL_HEAP_LRU)).isFalse();
assertThat(GemFireUtils.isProxy(ClientRegionShortcut.LOCAL_OVERFLOW)).isFalse();
assertThat(GemFireUtils.isProxy(ClientRegionShortcut.LOCAL_PERSISTENT)).isFalse();
assertThat(GemFireUtils.isProxy(ClientRegionShortcut.LOCAL_PERSISTENT_OVERFLOW))
.isFalse();
assertThat(GemFireUtils.isProxy(ClientRegionShortcut.LOCAL_PERSISTENT_OVERFLOW)).isFalse();
}
@Test
public void regionShortcutIsProxy() {
assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_PROXY)).isTrue();
assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_PROXY_REDUNDANT))
.isTrue();
assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_PROXY_REDUNDANT)).isTrue();
assertThat(GemFireUtils.isProxy(RegionShortcut.REPLICATE_PROXY)).isTrue();
}
@Test
public void regionIsProxy() {
Region mockRegion = mock(Region.class);
RegionAttributes mockRegionAttributes = mock(RegionAttributes.class);
given(mockRegion.getAttributes()).willReturn(mockRegionAttributes);
given(mockRegionAttributes.getDataPolicy()).willReturn(DataPolicy.EMPTY);
assertThat(GemFireUtils.isProxy(mockRegion)).isTrue();
verify(mockRegion, times(1)).getAttributes();
verify(mockRegionAttributes, times(1)).getDataPolicy();
}
@Test
public void regionIsNotProxy() {
Region mockRegion = mock(Region.class);
RegionAttributes mockRegionAttributes = mock(RegionAttributes.class);
given(mockRegion.getAttributes()).willReturn(mockRegionAttributes);
given(mockRegionAttributes.getDataPolicy()).willReturn(DataPolicy.NORMAL);
assertThat(GemFireUtils.isProxy(mockRegion)).isFalse();
verify(mockRegion, times(1)).getAttributes();
verify(mockRegionAttributes, times(1)).getDataPolicy();
}
@Test
public void regionShortcutIsNotProxy() {
assertThat(GemFireUtils.isProxy(RegionShortcut.LOCAL)).isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.LOCAL_HEAP_LRU)).isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.LOCAL_OVERFLOW)).isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.LOCAL_PERSISTENT)).isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.LOCAL_PERSISTENT_OVERFLOW))
.isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.LOCAL_PERSISTENT_OVERFLOW)).isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.REPLICATE)).isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.REPLICATE_HEAP_LRU)).isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.REPLICATE_OVERFLOW)).isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.REPLICATE_PERSISTENT)).isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.REPLICATE_PERSISTENT_OVERFLOW))
.isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.REPLICATE_PERSISTENT_OVERFLOW)).isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION)).isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_HEAP_LRU)).isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_OVERFLOW)).isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_PERSISTENT)).isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_PERSISTENT_OVERFLOW))
.isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_PERSISTENT_OVERFLOW)).isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_REDUNDANT)).isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_REDUNDANT_HEAP_LRU))
.isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_REDUNDANT_OVERFLOW))
.isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_REDUNDANT_PERSISTENT))
.isFalse();
assertThat(GemFireUtils
.isProxy(RegionShortcut.PARTITION_REDUNDANT_PERSISTENT_OVERFLOW))
.isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_REDUNDANT_HEAP_LRU)).isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_REDUNDANT_OVERFLOW)).isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_REDUNDANT_PERSISTENT)).isFalse();
assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_REDUNDANT_PERSISTENT_OVERFLOW)).isFalse();
}
@Test
@@ -183,5 +200,4 @@ public class GemFireUtilsTest {
assertThat(GemFireUtils.toRegionPath("/")).isEqualTo("//");
assertThat(GemFireUtils.toRegionPath("")).isEqualTo("/");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2016 the original author or authors.
* Copyright 2014-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.session.data.mongo;
import java.util.Collections;
@@ -44,28 +45,44 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/**
* Tests for {@link MongoOperationsSessionRepository}.
*
* @author Jakub Kubrynski
* @author Vedran Pavic
*/
@RunWith(MockitoJUnitRunner.class)
public class MongoOperationsSessionRepositoryTests {
@Mock
MongoOperations mongoOperations;
@Mock
AbstractMongoSessionConverter converter;
private MongoOperations mongoOperations;
MongoOperationsSessionRepository sut;
@Mock
private AbstractMongoSessionConverter converter;
private MongoOperationsSessionRepository repository;
@Before
public void setUp() throws Exception {
this.sut = new MongoOperationsSessionRepository(this.mongoOperations);
this.sut.setMongoSessionConverter(this.converter);
this.repository = new MongoOperationsSessionRepository(this.mongoOperations);
this.repository.setMongoSessionConverter(this.converter);
}
@Test
public void shouldCreateSession() throws Exception {
// when
ExpiringSession session = this.sut.createSession();
ExpiringSession session = this.repository.createSession();
// then
assertThat(session.getId()).isNotEmpty();
assertThat(session.getMaxInactiveIntervalInSeconds())
.isEqualTo(MongoOperationsSessionRepository.DEFAULT_INACTIVE_INTERVAL);
}
@Test
public void shouldCreateSessionWhenMaxInactiveIntervalNotDefined() throws Exception {
// when
this.repository.setMaxInactiveIntervalInSeconds(null);
ExpiringSession session = this.repository.createSession();
// then
assertThat(session.getId()).isNotEmpty();
@@ -87,7 +104,7 @@ public class MongoOperationsSessionRepositoryTests {
.getCollection(MongoOperationsSessionRepository.DEFAULT_COLLECTION_NAME))
.willReturn(collection);
// when
this.sut.save(session);
this.repository.save(session);
// then
verify(collection).save(dbSession);
@@ -106,7 +123,7 @@ public class MongoOperationsSessionRepositoryTests {
TypeDescriptor.valueOf(MongoExpiringSession.class))).willReturn(session);
// when
ExpiringSession retrievedSession = this.sut.getSession(sessionId);
ExpiringSession retrievedSession = this.repository.getSession(sessionId);
// then
assertThat(retrievedSession).isEqualTo(session);
@@ -127,7 +144,7 @@ public class MongoOperationsSessionRepositoryTests {
TypeDescriptor.valueOf(MongoExpiringSession.class))).willReturn(session);
// when
this.sut.getSession(sessionId);
this.repository.getSession(sessionId);
// then
verify(this.mongoOperations).remove(any(DBObject.class),
@@ -140,7 +157,7 @@ public class MongoOperationsSessionRepositoryTests {
String sessionId = UUID.randomUUID().toString();
// when
this.sut.delete(sessionId);
this.repository.delete(sessionId);
// then
verify(this.mongoOperations).remove(any(DBObject.class),
@@ -165,7 +182,7 @@ public class MongoOperationsSessionRepositoryTests {
given(this.converter.convert(dbSession, TypeDescriptor.valueOf(DBObject.class),
TypeDescriptor.valueOf(MongoExpiringSession.class))).willReturn(session);
// when
Map<String, MongoExpiringSession> sessionsMap = this.sut
Map<String, MongoExpiringSession> sessionsMap = this.repository
.findByIndexNameAndIndexValue(principalNameIndexName, "john");
// then
@@ -179,7 +196,7 @@ public class MongoOperationsSessionRepositoryTests {
String index = "some_not_supported_index_name";
// when
Map<String, MongoExpiringSession> sessionsMap = this.sut
Map<String, MongoExpiringSession> sessionsMap = this.repository
.findByIndexNameAndIndexValue(index, "some_value");
// then

View File

@@ -25,6 +25,7 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
@@ -103,8 +104,9 @@ public class SpringSessionRememberMeServicesTests {
verifyZeroInteractions(request, response);
}
// gh-752
@Test
public void loginFailInvalidatesSession() {
public void loginFailRemoveSecurityContext() {
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
HttpSession session = mock(HttpSession.class);
@@ -112,7 +114,7 @@ public class SpringSessionRememberMeServicesTests {
this.rememberMeServices = new SpringSessionRememberMeServices();
this.rememberMeServices.loginFail(request, response);
verify(request, times(1)).getSession(eq(false));
verify(session, times(1)).invalidate();
verify(session, times(1)).removeAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
verifyZeroInteractions(request, response, session);
}