Additional Checkstyle Fixes

Issue gh-393
This commit is contained in:
Rob Winch
2016-03-07 15:32:03 -06:00
parent 7f3302253b
commit f0200696ef
189 changed files with 4591 additions and 3201 deletions

View File

@@ -48,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.
* AbstractGemFireIntegrationTests is an abstract base class encapsulating common
* operations for writing Spring Session GemFire integration tests.
*
* @author John Blum
* @since 1.1.0
@@ -64,24 +64,25 @@ import static org.assertj.core.api.Assertions.assertThat;
* @see com.gemstone.gemfire.cache.server.CacheServer
*/
public class AbstractGemFireIntegrationTests {
public static final String GEMFIRE_LOG_LEVEL = System.getProperty(
"spring.session.data.gemfire.log-level", "warning");
public static final String GEMFIRE_LOG_LEVEL = System
.getProperty("spring.session.data.gemfire.log-level", "warning");
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 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";
protected static final String GEMFIRE_LOG_FILE_NAME = System.getProperty(
"spring.session.data.gemfire.log-file", "server.log");
protected static final String GEMFIRE_LOG_FILE_NAME = System
.getProperty("spring.session.data.gemfire.log-file", "server.log");
@Autowired
protected Cache gemfireCache;
@@ -91,15 +92,17 @@ public class AbstractGemFireIntegrationTests {
@Before
public void setup() {
System.setProperty("gemfire.Query.VERBOSE", String.valueOf(isQueryDebuggingEnabled()));
System.setProperty("gemfire.Query.VERBOSE",
String.valueOf(isQueryDebuggingEnabled()));
}
/* (non-Javadoc) */
protected static File createDirectory(String pathname) {
File directory = new File(WORKING_DIRECTORY, pathname);
assertThat(directory.isDirectory() || directory.mkdirs()).as(
String.format("Failed to create directory (%1$s)", directory)).isTrue();
assertThat(directory.isDirectory() || directory.mkdirs())
.as(String.format("Failed to create directory (%1$s)", directory))
.isTrue();
directory.deleteOnExit();
@@ -107,7 +110,8 @@ public class AbstractGemFireIntegrationTests {
}
/* (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>();
String javaHome = System.getProperty("java.home");
@@ -118,7 +122,8 @@ public class AbstractGemFireIntegrationTests {
commandLine.add("-ea");
commandLine.add(String.format("-Dgemfire.log-file=%1$s", GEMFIRE_LOG_FILE_NAME));
commandLine.add(String.format("-Dgemfire.log-level=%1$s", GEMFIRE_LOG_LEVEL));
commandLine.add(String.format("-Dgemfire.Query.VERBOSE=%1$s", GEMFIRE_QUERY_DEBUG));
commandLine
.add(String.format("-Dgemfire.Query.VERBOSE=%1$s", GEMFIRE_QUERY_DEBUG));
commandLine.addAll(extractJvmArguments(args));
commandLine.add("-classpath");
commandLine.add(System.getProperty("java.class.path"));
@@ -157,11 +162,10 @@ public class AbstractGemFireIntegrationTests {
}
/* (non-Javadoc) */
protected static Process run(Class<?> type, File directory, String... args) throws IOException {
return new ProcessBuilder()
.command(createJavaProcessCommandLine(type, args))
.directory(directory)
.start();
protected static Process run(Class<?> type, File directory, String... args)
throws IOException {
return new ProcessBuilder().command(createJavaProcessCommandLine(type, args))
.directory(directory).start();
}
/* (non-Javadoc) */
@@ -170,8 +174,10 @@ public class AbstractGemFireIntegrationTests {
}
/* (non-Javadoc) */
protected static boolean waitForCacheServerToStart(CacheServer cacheServer, long duration) {
return waitForCacheServerToStart(cacheServer.getBindAddress(), cacheServer.getPort(), duration);
protected static boolean waitForCacheServerToStart(CacheServer cacheServer,
long duration) {
return waitForCacheServerToStart(cacheServer.getBindAddress(),
cacheServer.getPort(), duration);
}
/* (non-Javadoc) */
@@ -180,7 +186,8 @@ public class AbstractGemFireIntegrationTests {
}
/* (non-Javadoc) */
protected static boolean waitForCacheServerToStart(final String host, final int port, long duration) {
protected static boolean waitForCacheServerToStart(final String host, final int port,
long duration) {
return waitOnCondition(new Condition() {
AtomicBoolean connected = new AtomicBoolean(false);
@@ -204,7 +211,8 @@ public class AbstractGemFireIntegrationTests {
}, 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.
/* (non-Javadoc) */
protected static boolean waitForClientCacheToClose() {
@@ -239,7 +247,8 @@ public class AbstractGemFireIntegrationTests {
/* (non-Javadoc) */
@SuppressWarnings("all")
protected static boolean waitForProcessToStart(Process process, File directory, long duration) {
protected static boolean waitForProcessToStart(Process process, File directory,
long duration) {
final File processControl = new File(directory, DEFAULT_PROCESS_CONTROL_FILENAME);
waitOnCondition(new Condition() {
@@ -257,7 +266,8 @@ public class AbstractGemFireIntegrationTests {
}
/* (non-Javadoc) */
protected static int waitForProcessToStop(Process process, File directory, long duration) {
protected static int waitForProcessToStop(Process process, File directory,
long duration) {
final long timeout = (System.currentTimeMillis() + duration);
try {
@@ -312,24 +322,30 @@ public class AbstractGemFireIntegrationTests {
}
/* (non-Javadoc) */
protected void assertRegion(Region<?, ?> actualRegion, String expectedName, DataPolicy expectedDataPolicy) {
protected void assertRegion(Region<?, ?> actualRegion, String expectedName,
DataPolicy expectedDataPolicy) {
assertThat(actualRegion).isNotNull();
assertThat(actualRegion.getName()).isEqualTo(expectedName);
assertThat(actualRegion.getFullPath()).isEqualTo(GemFireUtils.toRegionPath(expectedName));
assertThat(actualRegion.getFullPath())
.isEqualTo(GemFireUtils.toRegionPath(expectedName));
assertThat(actualRegion.getAttributes()).isNotNull();
assertThat(actualRegion.getAttributes().getDataPolicy()).isEqualTo(expectedDataPolicy);
assertThat(actualRegion.getAttributes().getDataPolicy())
.isEqualTo(expectedDataPolicy);
}
/* (non-Javadoc) */
protected void assertIndex(Index index, String expectedExpression, String expectedFromClause) {
protected void assertIndex(Index index, String expectedExpression,
String expectedFromClause) {
assertThat(index).isNotNull();
assertThat(index.getIndexedExpression()).isEqualTo(expectedExpression);
assertThat(index.getFromClause()).isEqualTo(expectedFromClause);
}
/* (non-Javadoc) */
protected void assertEntryIdleTimeout(Region<?, ?> region, ExpirationAction expectedAction, int expectedTimeout) {
assertEntryIdleTimeout(region.getAttributes().getEntryIdleTimeout(), expectedAction, expectedTimeout);
protected void assertEntryIdleTimeout(Region<?, ?> region,
ExpirationAction expectedAction, int expectedTimeout) {
assertEntryIdleTimeout(region.getAttributes().getEntryIdleTimeout(),
expectedAction, expectedTimeout);
}
/* (non-Javadoc) */
@@ -404,13 +420,14 @@ public class AbstractGemFireIntegrationTests {
}
/**
* The SessionEventListener class is a Spring {@link ApplicationListener} listening for Spring HTTP Session
* application events.
* The SessionEventListener class is a Spring {@link ApplicationListener} listening
* for Spring HTTP Session application events.
*
* @see org.springframework.context.ApplicationListener
* @see org.springframework.session.events.AbstractSessionEvent
*/
public static class SessionEventListener implements ApplicationListener<AbstractSessionEvent> {
public static class SessionEventListener
implements ApplicationListener<AbstractSessionEvent> {
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 {
boolean evaluate();

View File

@@ -60,7 +60,8 @@ public class HttpSessionGemFireIndexingITests extends AbstractGemFireIntegration
sessionRepository.save(session);
// tag::findbyindexname-get[]
Map<String, ExpiringSession> idToSessions = sessionRepository.findByIndexNameAndIndexValue(indexName, username);
Map<String, ExpiringSession> idToSessions = sessionRepository
.findByIndexNameAndIndexValue(indexName, username);
// end::findbyindexname-get[]
assertThat(idToSessions.keySet()).containsOnly(session.getId());
@@ -78,12 +79,15 @@ public class HttpSessionGemFireIndexingITests extends AbstractGemFireIntegration
Authentication authentication = context.getAuthentication();
// end::findbyspringsecurityindexname-context[]
session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context);
session.setAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY,
context);
sessionRepository.save(session);
// tag::findbyspringsecurityindexname-get[]
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[]
assertThat(idToSessions.keySet()).containsOnly(session.getId());

View File

@@ -39,7 +39,8 @@ public class GemFireHttpSessionConfig {
gemfireProperties.setProperty("name", GemFireHttpSessionConfig.class.getName());
gemfireProperties.setProperty("mcast-port", "0");
gemfireProperties.setProperty("log-level", AbstractGemFireIntegrationTests.GEMFIRE_LOG_LEVEL);
gemfireProperties.setProperty("log-level",
AbstractGemFireIntegrationTests.GEMFIRE_LOG_LEVEL);
return gemfireProperties;
}

View File

@@ -34,7 +34,8 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = GemFireHttpSessionConfig.class)
public class HttpSessionGemFireIndexingCustomITests extends AbstractGemFireIntegrationTests {
public class HttpSessionGemFireIndexingCustomITests
extends AbstractGemFireIntegrationTests {
@Test
public void findByIndexName() {
@@ -49,7 +50,8 @@ public class HttpSessionGemFireIndexingCustomITests extends AbstractGemFireInteg
sessionRepository.save(session);
// tag::findbyindexname-get[]
Map<String, ExpiringSession> idToSessions = sessionRepository.findByIndexNameAndIndexValue(indexName, attrValue);
Map<String, ExpiringSession> idToSessions = sessionRepository
.findByIndexNameAndIndexValue(indexName, attrValue);
// end::findbyindexname-get[]
assertThat(idToSessions.keySet()).containsOnly(session.getId());

View File

@@ -41,7 +41,8 @@ public class FindByIndexNameSessionRepositoryTests {
public void setUsername() {
// tag::set-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[]
}
@@ -50,8 +51,10 @@ public class FindByIndexNameSessionRepositoryTests {
public void findByUsername() {
// tag::findby-username[]
String username = "username";
Map<String, Session> sessionIdToSession =
this.sessionRepository.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, username);
Map<String, Session> sessionIdToSession = this.sessionRepository
.findByIndexNameAndIndexValue(
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
username);
// end::findby-username[]
}
}

View File

@@ -45,7 +45,6 @@ public class HttpSessionConfigurationNoOpConfigureRedisActionXmlTests {
assertThat(this.filter).isNotNull();
}
static RedisConnectionFactory connectionFactory() {
return mock(RedisConnectionFactory.class);
}

View File

@@ -68,7 +68,6 @@ public class IndexDocTests {
}
// end::repository-demo[]
@Test
public void expireRepositoryDemo() {
ExpiringRepositoryDemo<ExpiringSession> demo = new ExpiringRepositoryDemo<ExpiringSession>();
@@ -102,8 +101,8 @@ public class IndexDocTests {
public void newRedisOperationsSessionRepository() {
// tag::new-redisoperationssessionrepository[]
JedisConnectionFactory factory = new JedisConnectionFactory();
SessionRepository<? extends ExpiringSession> repository =
new RedisOperationsSessionRepository(factory);
SessionRepository<? extends ExpiringSession> repository = new RedisOperationsSessionRepository(
factory);
// end::new-redisoperationssessionrepository[]
}

View File

@@ -51,7 +51,9 @@ public abstract class AbstractHttpSessionListenerTests {
public void springSessionDestroyedTranslatedToSpringSecurityDestroyed() {
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());
}
@@ -64,12 +66,16 @@ public abstract class AbstractHttpSessionListenerTests {
return factory;
}
static class SecuritySessionDestroyedListener implements ApplicationListener<SessionDestroyedEvent> {
static class SecuritySessionDestroyedListener
implements ApplicationListener<SessionDestroyedEvent> {
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) {
this.event = event;

View File

@@ -30,12 +30,10 @@ import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
@Configuration
@EnableScheduling
@EnableWebSocketMessageBroker
public class WebSocketConfig
extends AbstractWebSocketMessageBrokerConfigurer {
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/messages")
.withSockJS();
registry.addEndpoint("/messages").withSockJS();
}
@Override

View File

@@ -18,8 +18,8 @@ package sample.config;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
// tag::class[]
@EnableRedisHttpSession // <1>
public class HttpSessionConfig { }
public class HttpSessionConfig {
}
// end::class[]

View File

@@ -29,8 +29,6 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
}
}

View File

@@ -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.DefaultCookieSerializer;
@EnableRedisHttpSession
public class Config {

View File

@@ -19,8 +19,7 @@ package sample;
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
// tag::class[]
public class Initializer
extends AbstractHttpSessionApplicationInitializer { // <1>
public class Initializer extends AbstractHttpSessionApplicationInitializer { // <1>
public Initializer() {
super(Config.class); // <2>

View File

@@ -29,7 +29,8 @@ import javax.servlet.http.HttpServletResponse;
public class SessionServlet extends HttpServlet {
@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 attributeValue = req.getParameter("attributeValue");
req.getSession().setAttribute(attributeName, attributeValue);

View File

@@ -33,7 +33,9 @@ import org.springframework.context.annotation.Configuration;
public class GeoConfig {
@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();
}

View File

@@ -25,5 +25,6 @@ import org.springframework.session.data.redis.config.annotation.web.http.EnableR
*/
// tag::class[]
@EnableRedisHttpSession // <1>
public class HttpSessionConfig { }
public class HttpSessionConfig {
}
// end::class[]

View File

@@ -31,24 +31,14 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
// tag::config[]
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.anyRequest().authenticated()
.and()
.logout()
.permitAll();
http.formLogin().loginPage("/login").permitAll().and().authorizeRequests()
.antMatchers("/resources/**").permitAll().anyRequest().authenticated()
.and().logout().permitAll();
}
// end::config[]
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
}
}

View File

@@ -43,17 +43,21 @@ public class IndexController {
@RequestMapping("/")
public String index(Principal principal, Model model) {
Collection<? extends ExpiringSession> usersSessions =
this.sessions.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
principal.getName()).values();
Collection<? extends ExpiringSession> usersSessions = this.sessions
.findByIndexNameAndIndexValue(
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
principal.getName())
.values();
model.addAttribute("sessions", usersSessions);
return "index";
}
// end::findbyusername[]
@RequestMapping(value = "/sessions/{sessionIdToDelete}", method = RequestMethod.DELETE)
public String removeSession(Principal principal, @PathVariable String sessionIdToDelete) {
Set<String> usersSessionIds = this.sessions.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
public String removeSession(Principal principal,
@PathVariable String sessionIdToDelete) {
Set<String> usersSessionIds = this.sessions.findByIndexNameAndIndexValue(
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
principal.getName()).keySet();
if (usersSessionIds.contains(sessionIdToDelete)) {
this.sessions.delete(sessionIdToDelete);

View File

@@ -35,10 +35,10 @@ import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
/**
* Inserts the session details into the session for every request. Some users
* may prefer to insert session details only after authentication. This is fine,
* but it may be valuable to the most up to date information so that if someone
* stole the user's session id it can be observed.
* Inserts the session details into the session for every request. Some users may prefer
* to insert session details only after authentication. This is fine, but it may be
* valuable to the most up to date information so that if someone stole the user's session
* id it can be observed.
*
* @author Rob Winch
*
@@ -57,8 +57,8 @@ public class SessionDetailsFilter extends OncePerRequestFilter {
}
// tag::dofilterinternal[]
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
HttpSession session = request.getSession(false);
@@ -109,4 +109,3 @@ public class SessionDetailsFilter extends OncePerRequestFilter {
}
}
// end::class[]

View File

@@ -48,16 +48,19 @@ public class SessionDetailsFilterTests {
@Test
public void getGeoLocationHanldesInvalidIp() {
assertThat(this.filter.getGeoLocation("a")).isEqualTo(SessionDetailsFilter.UNKNOWN);
assertThat(this.filter.getGeoLocation("a"))
.isEqualTo(SessionDetailsFilter.UNKNOWN);
}
@Test
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
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");
}
}

View File

@@ -38,8 +38,8 @@ public class Config {
netConfig.setPort(SocketUtils.findAvailableTcpPort());
System.out.println("Hazelcast port #: " + netConfig.getPort());
cfg.setNetworkConfig(netConfig);
SerializerConfig serializer = new SerializerConfig().setTypeClass(
Object.class).setImplementation(new ObjectStreamSerializer());
SerializerConfig serializer = new SerializerConfig().setTypeClass(Object.class)
.setImplementation(new ObjectStreamSerializer());
cfg.getSerializationConfig().addSerializerConfig(serializer);
return Hazelcast.newHazelcastInstance(cfg);

View File

@@ -27,11 +27,10 @@ import com.hazelcast.nio.ObjectDataOutput;
import com.hazelcast.nio.serialization.StreamSerializer;
/**
* A {@link StreamSerializer} that uses Java serialization to persist the
* session. This is certainly not the most efficient way to persist sessions,
* but the example is intended to demonstrate using minimal dependencies. For
* better serialization methods try using <a
* href="https://github.com/EsotericSoftware/kryo">Kryo</a>.
* A {@link StreamSerializer} that uses Java serialization to persist the session. This is
* certainly not the most efficient way to persist sessions, but the example is intended
* to demonstrate using minimal dependencies. For better serialization methods try using
* <a href="https://github.com/EsotericSoftware/kryo">Kryo</a>.
*
* @author Rob Winch
*
@@ -48,8 +47,7 @@ public class ObjectStreamSerializer implements StreamSerializer<Object> {
out.flush();
}
public Object read(ObjectDataInput objectDataInput)
throws IOException {
public Object read(ObjectDataInput objectDataInput) throws IOException {
ObjectInputStream in = new ObjectInputStream((InputStream) objectDataInput);
try {
return in.readObject();

View File

@@ -28,8 +28,6 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
public class SecurityConfig {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
}
}

View File

@@ -19,8 +19,7 @@ package sample;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
// tag::class[]
public class SecurityInitializer extends
AbstractSecurityWebApplicationInitializer {
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
public SecurityInitializer() {
super(SecurityConfig.class, Config.class);

View File

@@ -28,7 +28,8 @@ import javax.servlet.http.HttpServletResponse;
public class SessionServlet extends HttpServlet {
@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 attributeValue = req.getParameter("attributeValue");
req.getSession().setAttribute(attributeName, attributeValue);

View File

@@ -53,8 +53,7 @@ public class Initializer implements ServletContextListener {
NetworkConfig netConfig = new NetworkConfig();
netConfig.setPort(getAvailablePort());
cfg.setNetworkConfig(netConfig);
SerializerConfig serializer = new SerializerConfig()
.setTypeClass(Object.class)
SerializerConfig serializer = new SerializerConfig().setTypeClass(Object.class)
.setImplementation(new ObjectStreamSerializer());
cfg.getSerializationConfig().addSerializerConfig(serializer);
MapConfig mc = new MapConfig();
@@ -65,10 +64,10 @@ public class Initializer implements ServletContextListener {
this.instance = Hazelcast.newHazelcastInstance(cfg);
Map<String, ExpiringSession> sessions = this.instance.getMap(sessionMapName);
SessionRepository<ExpiringSession> sessionRepository =
new MapSessionRepository(sessions);
SessionRepositoryFilter<ExpiringSession> filter =
new SessionRepositoryFilter<ExpiringSession>(sessionRepository);
SessionRepository<ExpiringSession> sessionRepository = new MapSessionRepository(
sessions);
SessionRepositoryFilter<ExpiringSession> filter = new SessionRepositoryFilter<ExpiringSession>(
sessionRepository);
Dynamic fr = sc.addFilter("springSessionFilter", filter);
fr.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
}

View File

@@ -27,11 +27,10 @@ import com.hazelcast.nio.ObjectDataOutput;
import com.hazelcast.nio.serialization.StreamSerializer;
/**
* A {@link StreamSerializer} that uses Java serialization to persist the
* session. This is certainly not the most efficient way to persist sessions,
* but the example is intended to demonstrate using minimal dependencies. For
* better serialization methods try using <a
* href="https://github.com/EsotericSoftware/kryo">Kryo</a>.
* A {@link StreamSerializer} that uses Java serialization to persist the session. This is
* certainly not the most efficient way to persist sessions, but the example is intended
* to demonstrate using minimal dependencies. For better serialization methods try using
* <a href="https://github.com/EsotericSoftware/kryo">Kryo</a>.
*
* @author Rob Winch
*
@@ -48,8 +47,7 @@ public class ObjectStreamSerializer implements StreamSerializer<Object> {
out.flush();
}
public Object read(ObjectDataInput objectDataInput)
throws IOException {
public Object read(ObjectDataInput objectDataInput) throws IOException {
ObjectInputStream in = new ObjectInputStream((InputStream) objectDataInput);
try {
return in.readObject();

View File

@@ -31,7 +31,8 @@ import javax.servlet.http.HttpServletResponse;
public class SessionServlet extends HttpServlet {
@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 attributeValue = req.getParameter("attributeValue");
req.getSession().setAttribute(attributeName, attributeValue);

View File

@@ -27,7 +27,8 @@ import org.springframework.context.annotation.ImportResource;
public class Application {
public static void main(final String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Application.class);
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
Application.class);
context.registerShutdownHook();
}
}

View File

@@ -51,7 +51,8 @@ public class GemFireCacheServerReadyBeanPostProcessor implements BeanPostProcess
// tag::class[]
static {
ClientMembership.registerClientMembershipListener(new ClientMembershipListenerAdapter() {
ClientMembership
.registerClientMembershipListener(new ClientMembershipListenerAdapter() {
public void memberJoined(final ClientMembershipEvent event) {
if (!event.isClient()) {
latch.countDown();
@@ -64,17 +65,21 @@ public class GemFireCacheServerReadyBeanPostProcessor implements BeanPostProcess
@Resource(name = "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) {
String host = getServerHost(DEFAULT_SERVER_HOST);
Assert.isTrue(waitForCacheServerToStart(host, this.port), String.format(
"GemFire Server failed to start [host: '%1$s', port: %2$d]%n", host, this.port));
Assert.isTrue(waitForCacheServerToStart(host, this.port),
String.format(
"GemFire Server failed to start [host: '%1$s', port: %2$d]%n",
host, this.port));
}
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) {
try {
latch.await(DEFAULT_WAIT_DURATION, TimeUnit.MILLISECONDS);
@@ -93,7 +98,8 @@ public class GemFireCacheServerReadyBeanPostProcessor implements BeanPostProcess
}
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) {
@@ -109,8 +115,10 @@ public class GemFireCacheServerReadyBeanPostProcessor implements BeanPostProcess
Socket socket = null;
try {
// NOTE: this code is not intended to be an atomic, compound action (a possible race condition);
// opening another connection (at the expense of using system resources) after connectivity
// NOTE: this code is not intended to be an atomic, compound action (a
// 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
if (!connected.get()) {
socket = new Socket(host, port);

View File

@@ -55,8 +55,8 @@ public class ClientConfig {
System.setProperty("gemfire.log-level",
System.getProperty("sample.httpsession.gemfire.log-level", "warning"));
ClientMembership.registerClientMembershipListener(
new ClientMembershipListenerAdapter() {
ClientMembership
.registerClientMembershipListener(new ClientMembershipListenerAdapter() {
public void memberJoined(ClientMembershipEvent event) {
if (!event.isClient()) {
latch.countDown();
@@ -77,7 +77,8 @@ public class ClientConfig {
@Bean(name = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME)
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();
@@ -91,8 +92,8 @@ public class ClientConfig {
poolFactory.setSubscriptionEnabled(true);
poolFactory.setThreadLocalConnections(false);
poolFactory.setServerEndpoints(Collections.singletonList(new ConnectionEndpoint(
ServerConfig.SERVER_HOSTNAME, port)));
poolFactory.setServerEndpoints(Collections.singletonList(
new ConnectionEndpoint(ServerConfig.SERVER_HOSTNAME, port)));
return poolFactory;
}
@@ -111,27 +112,29 @@ public class ClientConfig {
@Bean
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() {
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) {
Assert.isTrue(waitForCacheServerToStart(ServerConfig.SERVER_HOSTNAME, port),
String.format("GemFire Server failed to start [hostname: %1$s, port: %2$d]",
Assert.isTrue(
waitForCacheServerToStart(ServerConfig.SERVER_HOSTNAME, port),
String.format(
"GemFire Server failed to start [hostname: %1$s, port: %2$d]",
ServerConfig.SERVER_HOSTNAME, port));
}
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) {
try {
latch.await(DEFAULT_WAIT_DURATION,
TimeUnit.MILLISECONDS);
latch.await(DEFAULT_WAIT_DURATION, TimeUnit.MILLISECONDS);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
@@ -161,8 +164,10 @@ public class ClientConfig {
Socket socket = null;
try {
// NOTE: this code is not intended to be an atomic, compound action (a possible race condition);
// opening another connection (at the expense of using system resources) after connectivity
// NOTE: this code is not intended to be an atomic, compound action (a
// 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
if (!connected.get()) {
socket = new Socket(host, port);

View File

@@ -19,8 +19,7 @@ package sample;
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
// tag::class[]
public class Initializer
extends AbstractHttpSessionApplicationInitializer { // <1>
public class Initializer extends AbstractHttpSessionApplicationInitializer { // <1>
public Initializer() {
super(ClientConfig.class); // <2>

View File

@@ -84,8 +84,7 @@ public class ServerConfig {
@SuppressWarnings("resource")
public static void main(final String[] args) throws IOException { // <5>
new AnnotationConfigApplicationContext(ServerConfig.class)
.registerShutdownHook();
new AnnotationConfigApplicationContext(ServerConfig.class).registerShutdownHook();
}
}
// end::class[]

View File

@@ -19,8 +19,7 @@ package sample;
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
// tag::class[]
public class Initializer
extends AbstractHttpSessionApplicationInitializer { // <1>
public class Initializer extends AbstractHttpSessionApplicationInitializer { // <1>
public Initializer() {
super(Config.class); // <2>

View File

@@ -15,15 +15,19 @@
*/
package sample;
import javax.servlet.*;
import javax.servlet.http.*;
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[]
public class SessionServlet extends HttpServlet {
@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 attributeValue = req.getParameter("attributeValue");
req.getSession().setAttribute(attributeName, attributeValue);

View File

@@ -34,8 +34,7 @@ public class Config {
public EmbeddedDatabase dataSource() {
return new EmbeddedDatabaseBuilder() // <2>
.setType(EmbeddedDatabaseType.H2)
.addScript("org/springframework/session/jdbc/schema-h2.sql")
.build();
.addScript("org/springframework/session/jdbc/schema-h2.sql").build();
}
@Bean

View File

@@ -18,8 +18,7 @@ package sample;
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
// tag::class[]
public class Initializer
extends AbstractHttpSessionApplicationInitializer { // <1>
public class Initializer extends AbstractHttpSessionApplicationInitializer { // <1>
public Initializer() {
super(Config.class); // <2>

View File

@@ -15,17 +15,21 @@
*/
package sample;
import javax.servlet.*;
import javax.servlet.annotation.*;
import javax.servlet.http.*;
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[]
@WebServlet("/session")
public class SessionServlet extends HttpServlet {
@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 attributeValue = req.getParameter("attributeValue");
req.getSession().setAttribute(attributeName, attributeValue);

View File

@@ -27,7 +27,8 @@ import javax.servlet.http.HttpServletResponse;
public class SessionServlet extends HttpServlet {
@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 attributeValue = req.getParameter("attributeValue");
req.getSession().setAttribute(attributeName, attributeValue);

View File

@@ -19,8 +19,7 @@ package sample;
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
// tag::class[]
public class Initializer
extends AbstractHttpSessionApplicationInitializer { // <1>
public class Initializer extends AbstractHttpSessionApplicationInitializer { // <1>
public Initializer() {
super(Config.class); // <2>

View File

@@ -29,7 +29,8 @@ import javax.servlet.http.HttpServletResponse;
public class SessionServlet extends HttpServlet {
@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 attributeValue = req.getParameter("attributeValue");
req.getSession().setAttribute(attributeName, attributeValue);

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -16,16 +16,15 @@
package sample
import geb.spock.*
import org.springframework.beans.factory.annotation.Value
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 pages.*
import sample.pages.HomePage
import sample.pages.LoginPage
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

View File

@@ -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
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* 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.
* 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 sample;

View File

@@ -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");
* 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;
// tag::class[]
@EnableMongoHttpSession // <1>
public class HttpSessionConfig { }
public class HttpSessionConfig {
}
// end::class[]

View File

@@ -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
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* 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.
* 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 sample.config;
@@ -28,8 +28,6 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
}
}

View File

@@ -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
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* 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.
* 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 sample.mvc;

View File

@@ -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.status;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {HttpSessionConfig.class, SecurityConfig.class, MvcConfig.class})
@ContextConfiguration(classes = { HttpSessionConfig.class, SecurityConfig.class,
MvcConfig.class })
@WebAppConfiguration
public class RestMockMvcTests {
@@ -59,25 +59,20 @@ public class RestMockMvcTests {
@Before
public void setup() {
this.mvc = MockMvcBuilders.webAppContextSetup(this.context)
.alwaysDo(print())
.addFilters(this.sessionRepositoryFilter)
.apply(springSecurity())
.build();
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).alwaysDo(print())
.addFilters(this.sessionRepositoryFilter).apply(springSecurity()).build();
}
@Test
public void noSessionOnNoCredentials() throws Exception {
this.mvc.perform(get("/"))
.andExpect(header().doesNotExist("x-auth-token"))
this.mvc.perform(get("/")).andExpect(header().doesNotExist("x-auth-token"))
.andExpect(status().isUnauthorized());
}
@WithMockUser
@Test
public void autheticatedAnnotation() throws Exception {
this.mvc.perform(get("/"))
.andExpect(content().string("{\"username\":\"user\"}"));
this.mvc.perform(get("/")).andExpect(content().string("{\"username\":\"user\"}"));
}

View File

@@ -21,7 +21,6 @@ import org.springframework.security.web.context.AbstractSecurityWebApplicationIn
/**
* @author Rob Winch
*/
public class SecurityInitializer extends
AbstractSecurityWebApplicationInitializer {
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}

View File

@@ -28,8 +28,6 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
public class SecurityConfig {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
}
}

View File

@@ -19,8 +19,7 @@ package sample;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
// tag::class[]
public class SecurityInitializer extends
AbstractSecurityWebApplicationInitializer {
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
public SecurityInitializer() {
super(SecurityConfig.class, Config.class);

View File

@@ -28,7 +28,8 @@ import javax.servlet.http.HttpServletResponse;
public class SessionServlet extends HttpServlet {
@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 attributeValue = req.getParameter("attributeValue");
req.getSession().setAttribute(attributeName, attributeValue);

View File

@@ -44,11 +44,11 @@ public class UserAccountsFilter implements Filter {
HttpServletRequest httpRequest = (HttpServletRequest) request;
// tag::HttpSessionManager[]
HttpSessionManager sessionManager =
(HttpSessionManager) httpRequest.getAttribute(HttpSessionManager.class.getName());
HttpSessionManager sessionManager = (HttpSessionManager) httpRequest
.getAttribute(HttpSessionManager.class.getName());
// end::HttpSessionManager[]
SessionRepository<Session> repo =
(SessionRepository<Session>) httpRequest.getAttribute(SessionRepository.class.getName());
SessionRepository<Session> repo = (SessionRepository<Session>) httpRequest
.getAttribute(SessionRepository.class.getName());
String currentSessionAlias = sessionManager.getCurrentSessionAlias(httpRequest);
Map<String, String> sessionIds = sessionManager.getSessionIds(httpRequest);
@@ -85,7 +85,8 @@ public class UserAccountsFilter implements Filter {
// tag::addAccountUrl[]
String addAlias = unauthenticatedAlias == null ? // <1>
sessionManager.getNewSessionAlias(httpRequest) : // <2>
sessionManager.getNewSessionAlias(httpRequest)
: // <2>
unauthenticatedAlias; // <3>
String addAccountUrl = sessionManager.encodeURL(contextPath, addAlias); // <4>
// end::addAccountUrl[]

View File

@@ -23,8 +23,8 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Initializes the H2 {@link WebServlet} so we can access our in memory database
* from the URL "/h2".
* Initializes the H2 {@link WebServlet} so we can access our in memory database from the
* URL "/h2".
*
* @author Rob Winch
*/

View File

@@ -34,8 +34,7 @@ import org.springframework.session.data.redis.config.annotation.web.http.EnableR
@EnableGlobalMethodSecurity(prePostEnabled = true)
// tag::enable-redis-httpsession[]
@EnableRedisHttpSession // (maxInactiveIntervalInSeconds = 60)
public class WebSecurityConfig
extends WebSecurityConfigurerAdapter {
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
// end::enable-redis-httpsession[]
// @formatter:off

View File

@@ -32,8 +32,7 @@ public class WebSocketConfig
extends AbstractSessionWebSocketMessageBrokerConfigurer<ExpiringSession> { // <1>
protected void configureStompEndpoints(StompEndpointRegistry registry) { // <2>
registry.addEndpoint("/messages")
.withSockJS();
registry.addEndpoint("/messages").withSockJS();
}
public void configureMessageBroker(MessageBrokerRegistry registry) {

View File

@@ -24,8 +24,10 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
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
*/
@@ -33,12 +35,16 @@ import org.springframework.session.ExpiringSession;
public class WebSocketHandlersConfig<S extends ExpiringSession> {
@Bean
public WebSocketConnectHandler<S> webSocketConnectHandler(SimpMessageSendingOperations messagingTemplate, ActiveWebSocketUserRepository repository) {
public WebSocketConnectHandler<S> webSocketConnectHandler(
SimpMessageSendingOperations messagingTemplate,
ActiveWebSocketUserRepository repository) {
return new WebSocketConnectHandler<S>(messagingTemplate, repository);
}
@Bean
public WebSocketDisconnectHandler<S> webSocketDisconnectHandler(SimpMessageSendingOperations messagingTemplate, ActiveWebSocketUserRepository repository) {
public WebSocketDisconnectHandler<S> webSocketDisconnectHandler(
SimpMessageSendingOperations messagingTemplate,
ActiveWebSocketUserRepository repository) {
return new WebSocketDisconnectHandler<S>(messagingTemplate, repository);
}
}

View File

@@ -24,7 +24,8 @@ import org.springframework.security.config.annotation.web.socket.AbstractSecurit
* @author Rob Winch
*/
@Configuration
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
public class WebSocketSecurityConfig
extends AbstractSecurityWebSocketMessageBrokerConfigurer {
// @formatter:off
@Override

View File

@@ -56,5 +56,4 @@ public class ActiveWebSocketUser {
this.connectionTime = connectionTime;
}
}

View File

@@ -21,7 +21,8 @@ import java.util.List;
import org.springframework.data.jpa.repository.Query;
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}")
List<String> findAllActiveUsers();

View File

@@ -59,6 +59,4 @@ public class InstantMessage {
this.created = created;
}
}

View File

@@ -44,7 +44,8 @@ public class MessageController {
private ActiveWebSocketUserRepository activeUserRepository;
@Autowired
public MessageController(ActiveWebSocketUserRepository activeUserRepository, SimpMessageSendingOperations messagingTemplate) {
public MessageController(ActiveWebSocketUserRepository activeUserRepository,
SimpMessageSendingOperations messagingTemplate) {
this.activeUserRepository = activeUserRepository;
this.messagingTemplate = messagingTemplate;
}

View File

@@ -27,16 +27,14 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
/**
* Annotate Spring MVC method arguments with this annotation to indicate you
* wish to specify the argument with the value of the current
* {@link Authentication#getPrincipal()} found on the
* {@link SecurityContextHolder}.
* Annotate Spring MVC method arguments with this annotation to indicate you wish to
* specify the argument with the value of the current
* {@link Authentication#getPrincipal()} found on the {@link SecurityContextHolder}.
*
* <p>
* Creating your own annotation that uses {@link AuthenticationPrincipal} as a
* meta annotation creates a layer of indirection between your code and Spring
* Security's. For simplicity, you could instead use the
* {@link AuthenticationPrincipal} directly.
* Creating your own annotation that uses {@link AuthenticationPrincipal} as a meta
* annotation creates a layer of indirection between your code and Spring Security's. For
* simplicity, you could instead use the {@link AuthenticationPrincipal} directly.
* </p>
*
* @author Rob Winch

View File

@@ -42,8 +42,12 @@ public class UserRepositoryUserDetailsService implements UserDetailsService {
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)
throws UsernameNotFoundException {

View File

@@ -29,11 +29,13 @@ import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
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 SimpMessageSendingOperations messagingTemplate;
public WebSocketConnectHandler(SimpMessageSendingOperations messagingTemplate, ActiveWebSocketUserRepository repository) {
public WebSocketConnectHandler(SimpMessageSendingOperations messagingTemplate,
ActiveWebSocketUserRepository repository) {
super();
this.messagingTemplate = messagingTemplate;
this.repository = repository;
@@ -46,7 +48,9 @@ public class WebSocketConnectHandler<S> implements ApplicationListener<SessionCo
return;
}
String id = SimpMessageHeaderAccessor.getSessionId(headers);
this.repository.save(new ActiveWebSocketUser(id, user.getName(), Calendar.getInstance()));
this.messagingTemplate.convertAndSend("/topic/friends/signin", Arrays.asList(user.getName()));
this.repository.save(
new ActiveWebSocketUser(id, user.getName(), Calendar.getInstance()));
this.messagingTemplate.convertAndSend("/topic/friends/signin",
Arrays.asList(user.getName()));
}
}

View File

@@ -25,11 +25,13 @@ import org.springframework.context.ApplicationListener;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
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 SimpMessageSendingOperations messagingTemplate;
public WebSocketDisconnectHandler(SimpMessageSendingOperations messagingTemplate, ActiveWebSocketUserRepository repository) {
public WebSocketDisconnectHandler(SimpMessageSendingOperations messagingTemplate,
ActiveWebSocketUserRepository repository) {
super();
this.messagingTemplate = messagingTemplate;
this.repository = repository;
@@ -46,7 +48,8 @@ public class WebSocketDisconnectHandler<S> implements ApplicationListener<Sessio
}
this.repository.delete(id);
this.messagingTemplate.convertAndSend("/topic/friends/signout", Arrays.asList(user.getUsername()));
this.messagingTemplate.convertAndSend("/topic/friends/signout",
Arrays.asList(user.getUsername()));
}
}

View File

@@ -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;
import java.util.UUID;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
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.web.WebAppConfiguration;
import java.util.UUID;
/**
* Base class for repositories integration tests
*
@@ -30,14 +46,18 @@ public abstract class AbstractITests {
@Before
public void setup() {
if (registry != null) {
registry.clear();
if (this.registry != null) {
this.registry.clear();
}
context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(new UsernamePasswordAuthenticationToken("username-" + UUID.randomUUID(), "na", AuthorityUtils.createAuthorityList("ROLE_USER")));
this.context = SecurityContextHolder.createEmptyContext();
this.context.setAuthentication(
new UsernamePasswordAuthenticationToken("username-" + UUID.randomUUID(),
"na", AuthorityUtils.createAuthorityList("ROLE_USER")));
changedContext = SecurityContextHolder.createEmptyContext();
changedContext.setAuthentication(new UsernamePasswordAuthenticationToken("changedContext-" + UUID.randomUUID(), "na", AuthorityUtils.createAuthorityList("ROLE_USER")));
this.changedContext = SecurityContextHolder.createEmptyContext();
this.changedContext.setAuthentication(new UsernamePasswordAuthenticationToken(
"changedContext-" + UUID.randomUUID(), "na",
AuthorityUtils.createAuthorityList("ROLE_USER")));
}
}

View File

@@ -45,12 +45,14 @@ public class SessionEventRegistry implements ApplicationListener<AbstractSession
}
@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);
}
@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);
synchronized (lock) {
if (!this.events.containsKey(sessionId)) {

View File

@@ -47,8 +47,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.
* AbstractGemFireIntegrationTests is an abstract base class encapsulating common
* operations for writing Spring Session GemFire integration tests.
*
* @author John Blum
* @since 1.1.0
@@ -65,22 +65,24 @@ import static org.assertj.core.api.Assertions.assertThat;
public abstract class AbstractGemFireIntegrationTests {
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 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";
protected static final String GEMFIRE_LOG_FILE_NAME = System.getProperty(
"spring.session.data.gemfire.log-file", "server.log");
protected static final String GEMFIRE_LOG_FILE_NAME = 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");
protected static final String GEMFIRE_LOG_LEVEL = System
.getProperty("spring.session.data.gemfire.log-level", "warning");
@Autowired
protected Cache gemfireCache;
@@ -90,15 +92,17 @@ public abstract class AbstractGemFireIntegrationTests {
@Before
public void setup() {
System.setProperty("gemfire.Query.VERBOSE", String.valueOf(isQueryDebuggingEnabled()));
System.setProperty("gemfire.Query.VERBOSE",
String.valueOf(isQueryDebuggingEnabled()));
}
/* (non-Javadoc) */
protected static File createDirectory(String pathname) {
File directory = new File(WORKING_DIRECTORY, pathname);
assertThat(directory.isDirectory() || directory.mkdirs()).as(
String.format("Failed to create directory (%1$s)", directory)).isTrue();
assertThat(directory.isDirectory() || directory.mkdirs())
.as(String.format("Failed to create directory (%1$s)", directory))
.isTrue();
directory.deleteOnExit();
@@ -106,7 +110,8 @@ public abstract class AbstractGemFireIntegrationTests {
}
/* (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>();
String javaHome = System.getProperty("java.home");
@@ -117,7 +122,8 @@ public abstract class AbstractGemFireIntegrationTests {
commandLine.add("-ea");
commandLine.add(String.format("-Dgemfire.log-file=%1$s", GEMFIRE_LOG_FILE_NAME));
commandLine.add(String.format("-Dgemfire.log-level=%1$s", GEMFIRE_LOG_LEVEL));
commandLine.add(String.format("-Dgemfire.Query.VERBOSE=%1$s", GEMFIRE_QUERY_DEBUG));
commandLine
.add(String.format("-Dgemfire.Query.VERBOSE=%1$s", GEMFIRE_QUERY_DEBUG));
commandLine.addAll(extractJvmArguments(args));
commandLine.add("-classpath");
commandLine.add(System.getProperty("java.class.path"));
@@ -156,11 +162,10 @@ public abstract class AbstractGemFireIntegrationTests {
}
/* (non-Javadoc) */
protected static Process run(Class<?> type, File directory, String... args) throws IOException {
return new ProcessBuilder()
.command(createJavaProcessCommandLine(type, args))
.directory(directory)
.start();
protected static Process run(Class<?> type, File directory, String... args)
throws IOException {
return new ProcessBuilder().command(createJavaProcessCommandLine(type, args))
.directory(directory).start();
}
/* (non-Javadoc) */
@@ -169,8 +174,10 @@ public abstract class AbstractGemFireIntegrationTests {
}
/* (non-Javadoc) */
protected static boolean waitForCacheServerToStart(CacheServer cacheServer, long duration) {
return waitForCacheServerToStart(cacheServer.getBindAddress(), cacheServer.getPort(), duration);
protected static boolean waitForCacheServerToStart(CacheServer cacheServer,
long duration) {
return waitForCacheServerToStart(cacheServer.getBindAddress(),
cacheServer.getPort(), duration);
}
/* (non-Javadoc) */
@@ -179,7 +186,8 @@ public abstract class AbstractGemFireIntegrationTests {
}
/* (non-Javadoc) */
protected static boolean waitForCacheServerToStart(final String host, final int port, long duration) {
protected static boolean waitForCacheServerToStart(final String host, final int port,
long duration) {
return waitOnCondition(new Condition() {
AtomicBoolean connected = new AtomicBoolean(false);
@@ -203,7 +211,8 @@ public abstract class AbstractGemFireIntegrationTests {
}, 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.
/* (non-Javadoc) */
protected static boolean waitForClientCacheToClose() {
@@ -238,7 +247,8 @@ public abstract class AbstractGemFireIntegrationTests {
/* (non-Javadoc) */
@SuppressWarnings("all")
protected static boolean waitForProcessToStart(Process process, File directory, long duration) {
protected static boolean waitForProcessToStart(Process process, File directory,
long duration) {
final File processControl = new File(directory, DEFAULT_PROCESS_CONTROL_FILENAME);
waitOnCondition(new Condition() {
@@ -256,7 +266,8 @@ public abstract class AbstractGemFireIntegrationTests {
}
/* (non-Javadoc) */
protected static int waitForProcessToStop(Process process, File directory, long duration) {
protected static int waitForProcessToStop(Process process, File directory,
long duration) {
final long timeout = (System.currentTimeMillis() + duration);
try {
@@ -311,24 +322,30 @@ public abstract class AbstractGemFireIntegrationTests {
}
/* (non-Javadoc) */
protected void assertRegion(Region<?, ?> actualRegion, String expectedName, DataPolicy expectedDataPolicy) {
protected void assertRegion(Region<?, ?> actualRegion, String expectedName,
DataPolicy expectedDataPolicy) {
assertThat(actualRegion).isNotNull();
assertThat(actualRegion.getName()).isEqualTo(expectedName);
assertThat(actualRegion.getFullPath()).isEqualTo(GemFireUtils.toRegionPath(expectedName));
assertThat(actualRegion.getFullPath())
.isEqualTo(GemFireUtils.toRegionPath(expectedName));
assertThat(actualRegion.getAttributes()).isNotNull();
assertThat(actualRegion.getAttributes().getDataPolicy()).isEqualTo(expectedDataPolicy);
assertThat(actualRegion.getAttributes().getDataPolicy())
.isEqualTo(expectedDataPolicy);
}
/* (non-Javadoc) */
protected void assertIndex(Index index, String expectedExpression, String expectedFromClause) {
protected void assertIndex(Index index, String expectedExpression,
String expectedFromClause) {
assertThat(index).isNotNull();
assertThat(index.getIndexedExpression()).isEqualTo(expectedExpression);
assertThat(index.getFromClause()).isEqualTo(expectedFromClause);
}
/* (non-Javadoc) */
protected void assertEntryIdleTimeout(Region<?, ?> region, ExpirationAction expectedAction, int expectedTimeout) {
assertEntryIdleTimeout(region.getAttributes().getEntryIdleTimeout(), expectedAction, expectedTimeout);
protected void assertEntryIdleTimeout(Region<?, ?> region,
ExpirationAction expectedAction, int expectedTimeout) {
assertEntryIdleTimeout(region.getAttributes().getEntryIdleTimeout(),
expectedAction, expectedTimeout);
}
/* (non-Javadoc) */
@@ -403,13 +420,14 @@ public abstract class AbstractGemFireIntegrationTests {
}
/**
* The SessionEventListener class is a Spring {@link ApplicationListener} listening for Spring HTTP Session
* application events.
* The SessionEventListener class is a Spring {@link ApplicationListener} listening
* for Spring HTTP Session application events.
*
* @see org.springframework.context.ApplicationListener
* @see org.springframework.session.events.AbstractSessionEvent
*/
public static class SessionEventListener implements ApplicationListener<AbstractSessionEvent> {
public static class SessionEventListener
implements ApplicationListener<AbstractSessionEvent> {
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 {
boolean evaluate();

View File

@@ -69,16 +69,19 @@ 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.
* The ClientServerGemFireOperationsSessionRepositoryIntegrationTests class is a test
* suite of test cases testing the functionality of GemFire-backed Spring Sessions using a
* GemFire client-server topology.
*
* @author John Blum
* @since 1.1.0
* @see org.junit.Test
* @see org.junit.runner.RunWith
* @see org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests
* @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession
* @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration
* @see org.springframework.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
@@ -89,15 +92,16 @@ import static org.assertj.core.api.Assertions.assertThat;
* @see com.gemstone.gemfire.cache.server.CacheServer
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes =
ClientServerGemFireOperationsSessionRepositoryIntegrationTests.SpringSessionGemFireClientConfiguration.class)
@ContextConfiguration(classes = ClientServerGemFireOperationsSessionRepositoryIntegrationTests.SpringSessionGemFireClientConfiguration.class)
@DirtiesContext
@WebAppConfiguration
public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests extends AbstractGemFireIntegrationTests {
public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests
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 final DateFormat TIMESTAMP = new SimpleDateFormat(
"yyyy-MM-dd-HH-mm-ss");
private static File processWorkingDirectory;
@@ -114,21 +118,25 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
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);
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(SpringSessionGemFireServerConfiguration.class,
processWorkingDirectory,
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
@@ -139,7 +147,8 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
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);
}
@@ -150,16 +159,17 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
public void setup() {
assertThat(GemFireUtils.isClient(gemfireCache)).isTrue();
Region<Object, ExpiringSession> springSessionGemFireRegion = gemfireCache.getRegion(
SPRING_SESSION_GEMFIRE_REGION_NAME);
Region<Object, ExpiringSession> springSessionGemFireRegion = gemfireCache
.getRegion(SPRING_SESSION_GEMFIRE_REGION_NAME);
assertThat(springSessionGemFireRegion).isNotNull();
RegionAttributes<Object, ExpiringSession> springSessionGemFireRegionAttributes =
springSessionGemFireRegion.getAttributes();
RegionAttributes<Object, ExpiringSession> springSessionGemFireRegionAttributes = springSessionGemFireRegion
.getAttributes();
assertThat(springSessionGemFireRegionAttributes).isNotNull();
assertThat(springSessionGemFireRegionAttributes.getDataPolicy()).isEqualTo(DataPolicy.EMPTY);
assertThat(springSessionGemFireRegionAttributes.getDataPolicy())
.isEqualTo(DataPolicy.EMPTY);
}
@After
@@ -173,7 +183,8 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
ExpiringSession expectedSession = save(createSession());
AbstractSessionEvent sessionEvent = this.sessionEventListener.waitForSessionEvent(500);
AbstractSessionEvent sessionEvent = this.sessionEventListener
.waitForSessionEvent(500);
assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class);
@@ -181,9 +192,12 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
assertThat(createdSession).isEqualTo(expectedSession);
assertThat(createdSession.getId()).isNotNull();
assertThat(createdSession.getCreationTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime);
assertThat(createdSession.getLastAccessedTime()).isEqualTo(createdSession.getCreationTime());
assertThat(createdSession.getMaxInactiveIntervalInSeconds()).isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
assertThat(createdSession.getCreationTime())
.isGreaterThanOrEqualTo(beforeOrAtCreationTime);
assertThat(createdSession.getLastAccessedTime())
.isEqualTo(createdSession.getCreationTime());
assertThat(createdSession.getMaxInactiveIntervalInSeconds())
.isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
this.gemfireSessionRepository.delete(expectedSession.getId());
}
@@ -192,28 +206,32 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
public void getExistingNonExpiredSessionBeforeAndAfterExpiration() {
ExpiringSession expectedSession = save(touch(createSession()));
AbstractSessionEvent sessionEvent = this.sessionEventListener.waitForSessionEvent(500);
AbstractSessionEvent sessionEvent = this.sessionEventListener
.waitForSessionEvent(500);
assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class);
assertThat(sessionEvent.<ExpiringSession>getSession()).isEqualTo(expectedSession);
assertThat(this.sessionEventListener.getSessionEvent()).isNull();
ExpiringSession savedSession = this.gemfireSessionRepository.getSession(expectedSession.getId());
ExpiringSession savedSession = this.gemfireSessionRepository
.getSession(expectedSession.getId());
assertThat(savedSession).isEqualTo(expectedSession);
// 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
// calling sessionEventListener.getSessionEvent() here to clear the event
this.sessionEventListener.getSessionEvent();
sessionEvent = this.sessionEventListener.waitForSessionEvent(TimeUnit.SECONDS.toMillis(
MAX_INACTIVE_INTERVAL_IN_SECONDS + 1));
sessionEvent = this.sessionEventListener.waitForSessionEvent(
TimeUnit.SECONDS.toMillis(MAX_INACTIVE_INTERVAL_IN_SECONDS + 1));
assertThat(sessionEvent).isInstanceOf(SessionExpiredEvent.class);
assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSession.getId());
ExpiringSession expiredSession = this.gemfireSessionRepository.getSession(expectedSession.getId());
ExpiringSession expiredSession = this.gemfireSessionRepository
.getSession(expectedSession.getId());
assertThat(expiredSession).isNull();
}
@@ -222,7 +240,8 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
public void deleteExistingNonExpiredSessionFiresSessionDeletedEventAndReturnsNullOnGet() {
ExpiringSession expectedSession = save(touch(createSession()));
AbstractSessionEvent sessionEvent = this.sessionEventListener.waitForSessionEvent(500);
AbstractSessionEvent sessionEvent = this.sessionEventListener
.waitForSessionEvent(500);
assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class);
assertThat(sessionEvent.<ExpiringSession>getSession()).isEqualTo(expectedSession);
@@ -234,13 +253,13 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
assertThat(sessionEvent).isInstanceOf(SessionDeletedEvent.class);
assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSession.getId());
ExpiringSession deletedSession = this.gemfireSessionRepository.getSession(expectedSession.getId());
ExpiringSession deletedSession = this.gemfireSessionRepository
.getSession(expectedSession.getId());
assertThat(deletedSession).isNull();
}
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME,
maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME, maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
static class SpringSessionGemFireClientConfiguration {
@Bean
@@ -251,13 +270,16 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
@Bean
Properties gemfireProperties() {
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("name", ClientServerGemFireOperationsSessionRepositoryIntegrationTests.class.getName());
gemfireProperties.setProperty("name",
ClientServerGemFireOperationsSessionRepositoryIntegrationTests.class
.getName());
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
return gemfireProperties;
}
@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() {
@Override
protected Properties resolveGemfireProperties() {
@@ -268,15 +290,18 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
poolFactory.setName(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME);
poolFactory.setFreeConnectionTimeout(5000); // 5 seconds
poolFactory.setKeepAlive(false);
poolFactory.setMaxConnections(SpringSessionGemFireServerConfiguration.MAX_CONNECTIONS);
poolFactory.setMaxConnections(
SpringSessionGemFireServerConfiguration.MAX_CONNECTIONS);
poolFactory.setPingInterval(TimeUnit.SECONDS.toMillis(5));
poolFactory.setReadTimeout(2000); // 2 seconds
poolFactory.setRetryAttempts(2);
poolFactory.setSubscriptionEnabled(true);
poolFactory.setThreadLocalConnections(false);
poolFactory.setServerEndpoints(Collections.singletonList(new ConnectionEndpoint(
SpringSessionGemFireServerConfiguration.SERVER_HOSTNAME, port)));
poolFactory
.setServerEndpoints(Collections.singletonList(new ConnectionEndpoint(
SpringSessionGemFireServerConfiguration.SERVER_HOSTNAME,
port)));
return poolFactory;
}
@@ -315,8 +340,7 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
}
}
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME,
maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME, maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
static class SpringSessionGemFireServerConfiguration {
static final int MAX_CONNECTIONS = 50;
@@ -331,7 +355,8 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
Properties gemfireProperties() {
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("name", SpringSessionGemFireServerConfiguration.class.getName());
gemfireProperties.setProperty("name",
SpringSessionGemFireServerConfiguration.class.getName());
gemfireProperties.setProperty("mcast-port", "0");
gemfireProperties.setProperty("log-file", "server.log");
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
@@ -351,7 +376,8 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
@Bean
CacheServerFactoryBean gemfireCacheServer(Cache gemfireCache,
@Value("${spring.session.data.gemfire.port:" + DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) {
@Value("${spring.session.data.gemfire.port:" + DEFAULT_GEMFIRE_SERVER_PORT
+ "}") int port) {
CacheServerFactoryBean cacheServerFactory = new CacheServerFactoryBean();
@@ -366,7 +392,8 @@ public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests exte
@SuppressWarnings("resource")
public static void main(final String[] args) throws IOException {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringSessionGemFireServerConfiguration.class);
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
SpringSessionGemFireServerConfiguration.class);
context.registerShutdownHook();
writeProcessControlFile(WORKING_DIRECTORY);
}

View File

@@ -55,8 +55,9 @@ import org.springframework.util.ObjectUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* The GemFireOperationsSessionRepositoryIntegrationTests class is a test suite of test cases testing
* the findByPrincipalName query method on the GemFireOpeationsSessionRepository class.
* The GemFireOperationsSessionRepositoryIntegrationTests class is a test suite of test
* cases testing the findByPrincipalName query method on the
* GemFireOpeationsSessionRepository class.
*
* @author John Blum
* @since 1.1.0
@@ -75,7 +76,8 @@ import static org.assertj.core.api.Assertions.assertThat;
@ContextConfiguration
@DirtiesContext
@WebAppConfiguration
public class GemFireOperationsSessionRepositoryIntegrationTests extends AbstractGemFireIntegrationTests {
public class GemFireOperationsSessionRepositoryIntegrationTests
extends AbstractGemFireIntegrationTests {
private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 300;
@@ -90,48 +92,63 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
@Before
public void setup() {
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.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.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);
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) {
return this.gemfireSessionRepository.findByIndexNameAndIndexValue(indexName, indexValue);
protected Map<String, ExpiringSession> doFindByIndexNameAndIndexValue(
String indexName, String indexValue) {
return this.gemfireSessionRepository.findByIndexNameAndIndexValue(indexName,
indexValue);
}
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" })
protected Map<String, ExpiringSession> doFindByPrincipalName(String regionName, String principalName) {
protected Map<String, ExpiringSession> doFindByPrincipalName(String regionName,
String principalName) {
try {
Region<String, ExpiringSession> region = this.gemfireCache.getRegion(regionName);
Region<String, ExpiringSession> region = this.gemfireCache
.getRegion(regionName);
assertThat(region).isNotNull();
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());
Query query = queryService.newQuery(queryString);
SelectResults<ExpiringSession> results = (SelectResults<ExpiringSession>) query.execute(
new Object[] { principalName });
SelectResults<ExpiringSession> results = (SelectResults<ExpiringSession>) query
.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()) {
sessions.put(session.getId(), session);
@@ -149,17 +166,22 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
return true;
}
protected ExpiringSession setAttribute(ExpiringSession session, String attributeName, Object attributeValue) {
protected ExpiringSession setAttribute(ExpiringSession session, String attributeName,
Object attributeValue) {
session.setAttribute(attributeName, attributeValue);
return session;
}
@Test
public void findSessionsByIndexedSessionAttributeNameValues() {
ExpiringSession johnBlumSession = save(touch(setAttribute(createSession("johnBlum"), "vip", "yes")));
ExpiringSession robWinchSession = save(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 johnBlumSession = save(
touch(setAttribute(createSession("johnBlum"), "vip", "yes")));
ExpiringSession robWinchSession = save(
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")));
assertThat(get(johnBlumSession.getId())).isEqualTo(johnBlumSession);
@@ -173,7 +195,8 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
assertThat(get(sourDoeSession.getId())).isEqualTo(sourDoeSession);
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.size()).isEqualTo(2);
@@ -183,7 +206,8 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
assertThat(vipSessions.containsKey(pieDoeSession.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.size()).isEqualTo(1);
@@ -193,7 +217,8 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
assertThat(nonVipSessions.containsKey(pieDoeSession.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.isEmpty()).isTrue();
@@ -241,7 +266,8 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
save(toSave);
Map<String, ExpiringSession> findByPrincipalName = doFindByPrincipalName(getSecurityName());
Map<String, ExpiringSession> findByPrincipalName = doFindByPrincipalName(
getSecurityName());
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
}
@@ -255,7 +281,8 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext);
save(toSave);
Map<String, ExpiringSession> findByPrincipalName = doFindByPrincipalName(getSecurityName());
Map<String, ExpiringSession> findByPrincipalName = doFindByPrincipalName(
getSecurityName());
assertThat(findByPrincipalName).isEmpty();
findByPrincipalName = doFindByPrincipalName(getChangedSecurityName());
@@ -264,7 +291,8 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
@Test
public void findsNoSessionsByNonExistingPrincipal() {
Map<String, ExpiringSession> nonExistingPrincipalSessions = doFindByPrincipalName("nonExistingPrincipalName");
Map<String, ExpiringSession> nonExistingPrincipalSessions = doFindByPrincipalName(
"nonExistingPrincipalName");
assertThat(nonExistingPrincipalSessions).isNotNull();
assertThat(nonExistingPrincipalSessions.isEmpty()).isTrue();
@@ -274,10 +302,12 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
public void findsNoSessionsAfterPrincipalIsRemoved() {
String username = "doesNotFindAfterPrincipalRemoved";
ExpiringSession session = save(touch(createSession(username)));
session.setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, null);
session.setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
null);
save(session);
Map<String, ExpiringSession> nonExistingPrincipalSessions = doFindByPrincipalName(username);
Map<String, ExpiringSession> nonExistingPrincipalSessions = doFindByPrincipalName(
username);
assertThat(nonExistingPrincipalSessions).isNotNull();
assertThat(nonExistingPrincipalSessions.isEmpty()).isTrue();
@@ -287,12 +317,14 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
public void saveAndReadSessionWithAttributes() {
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(
"booleanAttribute", "numericAttribute", "stringAttribute", "personAttribute");
List<String> expectedAttributeNames = Arrays.asList("booleanAttribute",
"numericAttribute", "stringAttribute", "personAttribute");
Person jonDoe = new Person("Jon", "Doe");
@@ -303,21 +335,32 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
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).isInstanceOf(AbstractGemFireOperationsSessionRepository.GemFireSession.class);
assertThat(((AbstractGemFireOperationsSessionRepository.GemFireSession) savedSession).getPrincipalName()).isEqualTo("jblum");
assertThat(savedSession).isInstanceOf(
AbstractGemFireOperationsSessionRepository.GemFireSession.class);
assertThat(
((AbstractGemFireOperationsSessionRepository.GemFireSession) savedSession)
.getPrincipalName()).isEqualTo("jblum");
assertThat(savedSession.getAttributeNames().containsAll(expectedAttributeNames)).as(
String.format("Expected (%1$s); but was (%2$s)", expectedAttributeNames, savedSession.getAttributeNames()))
assertThat(savedSession.getAttributeNames().containsAll(expectedAttributeNames))
.as(String.format("Expected (%1$s); but was (%2$s)",
expectedAttributeNames, savedSession.getAttributeNames()))
.isTrue();
assertThat(Boolean.valueOf(String.valueOf(savedSession.getAttribute(expectedAttributeNames.get(0))))).isTrue();
assertThat(Double.valueOf(String.valueOf(savedSession.getAttribute(expectedAttributeNames.get(1)))))
assertThat(Boolean.valueOf(
String.valueOf(savedSession.getAttribute(expectedAttributeNames.get(0)))))
.isTrue();
assertThat(Double.valueOf(
String.valueOf(savedSession.getAttribute(expectedAttributeNames.get(1)))))
.isEqualTo(Math.PI);
assertThat(String.valueOf(savedSession.getAttribute(expectedAttributeNames.get(2)))).isEqualTo("test");
assertThat(savedSession.getAttribute(expectedAttributeNames.get(3))).isEqualTo(jonDoe);
assertThat(
String.valueOf(savedSession.getAttribute(expectedAttributeNames.get(2))))
.isEqualTo("test");
assertThat(savedSession.getAttribute(expectedAttributeNames.get(3)))
.isEqualTo(jonDoe);
}
private String getSecurityName() {
@@ -328,15 +371,15 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
return this.changedContext.getAuthentication().getName();
}
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME,
maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME, maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
static class SpringSessionGemFireConfiguration {
@Bean
Properties gemfireProperties() {
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("name", GemFireOperationsSessionRepositoryIntegrationTests.class.getName());
gemfireProperties.setProperty("name",
GemFireOperationsSessionRepositoryIntegrationTests.class.getName());
gemfireProperties.setProperty("mcast-port", "0");
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);
@@ -370,7 +413,8 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
}
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;
}
@@ -399,7 +443,8 @@ public class GemFireOperationsSessionRepositoryIntegrationTests extends Abstract
@SuppressWarnings("all")
public int compareTo(final Person person) {
int compareValue = getLastName().compareTo(person.getLastName());
return (compareValue != 0 ? compareValue : getFirstName().compareTo(person.getFirstName()));
return (compareValue != 0 ? compareValue
: getFirstName().compareTo(person.getFirstName()));
}
@Override

View File

@@ -47,8 +47,9 @@ import org.springframework.test.context.web.WebAppConfiguration;
import static org.assertj.core.api.Assertions.assertThat;
/**
* The EnableGemFireHttpSessionEventsIntegrationTests class is a test suite of test cases testing the Session Event
* functionality and behavior of the GemFireOperationsSessionRepository and GemFire's configuration.
* The EnableGemFireHttpSessionEventsIntegrationTests class is a test suite of test cases
* testing the Session Event functionality and behavior of the
* GemFireOperationsSessionRepository and GemFire's configuration.
*
* @author John Blum
* @since 1.1.0
@@ -70,7 +71,8 @@ import static org.assertj.core.api.Assertions.assertThat;
@ContextConfiguration
@DirtiesContext
@WebAppConfiguration
public class EnableGemFireHttpSessionEventsIntegrationTests extends AbstractGemFireIntegrationTests {
public class EnableGemFireHttpSessionEventsIntegrationTests
extends AbstractGemFireIntegrationTests {
private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 1;
@@ -84,14 +86,17 @@ public class EnableGemFireHttpSessionEventsIntegrationTests extends AbstractGemF
public void setup() {
assertThat(GemFireUtils.isPeer(this.gemfireCache)).isTrue();
assertThat(this.gemfireSessionRepository).isNotNull();
assertThat(this.gemfireSessionRepository.getMaxInactiveIntervalInSeconds()).isEqualTo(
MAX_INACTIVE_INTERVAL_IN_SECONDS);
assertThat(this.gemfireSessionRepository.getMaxInactiveIntervalInSeconds())
.isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
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);
assertEntryIdleTimeout(sessionRegion, ExpirationAction.INVALIDATE, MAX_INACTIVE_INTERVAL_IN_SECONDS);
assertRegion(sessionRegion, SPRING_SESSION_GEMFIRE_REGION_NAME,
DataPolicy.REPLICATE);
assertEntryIdleTimeout(sessionRegion, ExpirationAction.INVALIDATE,
MAX_INACTIVE_INTERVAL_IN_SECONDS);
}
@After
@@ -113,9 +118,12 @@ public class EnableGemFireHttpSessionEventsIntegrationTests extends AbstractGemF
assertThat(createdSession).isEqualTo(expectedSession);
assertThat(createdSession.getId()).isNotNull();
assertThat(createdSession.getCreationTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime);
assertThat(createdSession.getLastAccessedTime()).isEqualTo(createdSession.getCreationTime());
assertThat(createdSession.getMaxInactiveIntervalInSeconds()).isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
assertThat(createdSession.getCreationTime())
.isGreaterThanOrEqualTo(beforeOrAtCreationTime);
assertThat(createdSession.getLastAccessedTime())
.isEqualTo(createdSession.getCreationTime());
assertThat(createdSession.getMaxInactiveIntervalInSeconds())
.isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
assertThat(createdSession.isExpired()).isFalse();
}
@@ -126,7 +134,8 @@ public class EnableGemFireHttpSessionEventsIntegrationTests extends AbstractGemF
assertThat(expectedSession.isExpired()).isFalse();
// 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);
}
@@ -143,18 +152,21 @@ public class EnableGemFireHttpSessionEventsIntegrationTests extends AbstractGemF
assertThat(createdSession).isEqualTo(expectedSession);
assertThat(createdSession.isExpired()).isTrue();
assertThat(this.gemfireSessionRepository.getSession(createdSession.getId())).isNull();
assertThat(this.gemfireSessionRepository.getSession(createdSession.getId()))
.isNull();
}
@Test
public void getNonExistingSession() {
assertThat(this.gemfireSessionRepository.getSession(UUID.randomUUID().toString())).isNull();
assertThat(this.gemfireSessionRepository.getSession(UUID.randomUUID().toString()))
.isNull();
}
@Test
public void deleteExistingNonExpiredSession() {
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.isExpired()).isFalse();
@@ -169,7 +181,8 @@ public class EnableGemFireHttpSessionEventsIntegrationTests extends AbstractGemF
ExpiringSession deletedSession = sessionEvent.getSession();
assertThat(deletedSession).isEqualTo(savedSession);
assertThat(this.gemfireSessionRepository.getSession(deletedSession.getId())).isNull();
assertThat(this.gemfireSessionRepository.getSession(deletedSession.getId()))
.isNull();
}
@Test
@@ -184,8 +197,9 @@ public class EnableGemFireHttpSessionEventsIntegrationTests extends AbstractGemF
assertThat(createdSession).isEqualTo(expectedSession);
sessionEvent = this.sessionEventListener.waitForSessionEvent(TimeUnit.SECONDS.toMillis(
this.gemfireSessionRepository.getMaxInactiveIntervalInSeconds() + 1));
sessionEvent = this.sessionEventListener.waitForSessionEvent(TimeUnit.SECONDS
.toMillis(this.gemfireSessionRepository.getMaxInactiveIntervalInSeconds()
+ 1));
assertThat(sessionEvent).isInstanceOf(SessionExpiredEvent.class);
@@ -201,7 +215,8 @@ public class EnableGemFireHttpSessionEventsIntegrationTests extends AbstractGemF
assertThat(sessionEvent).isInstanceOf(SessionDeletedEvent.class);
assertThat(sessionEvent.getSession()).isNull();
assertThat(sessionEvent.getSessionId()).isEqualTo(expiredSession.getId());
assertThat(this.gemfireSessionRepository.getSession(sessionEvent.getSessionId())).isNull();
assertThat(this.gemfireSessionRepository.getSession(sessionEvent.getSessionId()))
.isNull();
}
@Test
@@ -219,16 +234,15 @@ public class EnableGemFireHttpSessionEventsIntegrationTests extends AbstractGemF
assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSessionId);
}
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME,
maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS,
serverRegionShortcut = RegionShortcut.REPLICATE)
@EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME, maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS, serverRegionShortcut = RegionShortcut.REPLICATE)
static class SpringSessionGemFireConfiguration {
@Bean
Properties gemfireProperties() {
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("name", EnableGemFireHttpSessionEventsIntegrationTests.class.getName());
gemfireProperties.setProperty("name",
EnableGemFireHttpSessionEventsIntegrationTests.class.getName());
gemfireProperties.setProperty("mcast-port", "0");
gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL);

View File

@@ -42,8 +42,9 @@ import org.springframework.test.context.web.WebAppConfiguration;
import static org.assertj.core.api.Assertions.assertThat;
/**
* The GemFireHttpSessionJavaConfigurationTests class is a test suite of test cases testing the configuration of
* Spring Session backed by GemFire using Java-based configuration meta-data.
* The GemFireHttpSessionJavaConfigurationTests class is a test suite of test cases
* testing the configuration of Spring Session backed by GemFire using Java-based
* configuration meta-data.
*
* @author John Blum
* @since 1.1.0
@@ -61,12 +62,14 @@ import static org.assertj.core.api.Assertions.assertThat;
@ContextConfiguration
@DirtiesContext
@WebAppConfiguration
public class GemFireHttpSessionJavaConfigurationTests extends AbstractGemFireIntegrationTests {
public class GemFireHttpSessionJavaConfigurationTests
extends AbstractGemFireIntegrationTests {
@Autowired
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();
Region<K, V> region = gemfireCache.getRegion(regionName);
@@ -78,16 +81,16 @@ public class GemFireHttpSessionJavaConfigurationTests extends AbstractGemFireInt
@Test
public void gemfireCacheConfigurationIsValid() {
Region<Object, ExpiringSession> example = assertCacheAndRegion(this.gemfireCache, "JavaExample",
DataPolicy.REPLICATE);
Region<Object, ExpiringSession> example = assertCacheAndRegion(this.gemfireCache,
"JavaExample", DataPolicy.REPLICATE);
assertEntryIdleTimeout(example, ExpirationAction.INVALIDATE, 900);
}
@Test
public void verifyGemFireExampleCacheRegionPrincipalNameIndexWasCreatedSuccessfully() {
Region<Object, ExpiringSession> example = assertCacheAndRegion(this.gemfireCache, "JavaExample",
DataPolicy.REPLICATE);
Region<Object, ExpiringSession> example = assertCacheAndRegion(this.gemfireCache,
"JavaExample", DataPolicy.REPLICATE);
QueryService queryService = example.getRegionService().getQueryService();
@@ -100,26 +103,27 @@ public class GemFireHttpSessionJavaConfigurationTests extends AbstractGemFireInt
@Test
public void verifyGemFireExampleCacheRegionSessionAttributesIndexWasNotCreated() {
Region<Object, ExpiringSession> example = assertCacheAndRegion(this.gemfireCache, "JavaExample",
DataPolicy.REPLICATE);
Region<Object, ExpiringSession> example = assertCacheAndRegion(this.gemfireCache,
"JavaExample", DataPolicy.REPLICATE);
QueryService queryService = example.getRegionService().getQueryService();
assertThat(queryService).isNotNull();
Index sessionAttributesIndex = queryService.getIndex(example, "sessionAttributesIndex");
Index sessionAttributesIndex = queryService.getIndex(example,
"sessionAttributesIndex");
assertThat(sessionAttributesIndex).isNull();
}
@EnableGemFireHttpSession(indexableSessionAttributes = {}, maxInactiveIntervalInSeconds = 900,
regionName = "JavaExample", serverRegionShortcut = RegionShortcut.REPLICATE)
@EnableGemFireHttpSession(indexableSessionAttributes = {}, maxInactiveIntervalInSeconds = 900, regionName = "JavaExample", serverRegionShortcut = RegionShortcut.REPLICATE)
public static class GemFireConfiguration {
@Bean
Properties gemfireProperties() {
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("name", GemFireHttpSessionJavaConfigurationTests.class.getName());
gemfireProperties.setProperty("name",
GemFireHttpSessionJavaConfigurationTests.class.getName());
gemfireProperties.setProperty("mcast-port", "0");
gemfireProperties.setProperty("log-level", "warning");
return gemfireProperties;

View File

@@ -37,8 +37,9 @@ import org.springframework.test.context.web.WebAppConfiguration;
import static org.assertj.core.api.Assertions.assertThat;
/**
* The GemFireHttpSessionXmlConfigurationTests class is a test suite of test cases testing the configuration of
* Spring Session backed by GemFire using XML configuration meta-data.
* The GemFireHttpSessionXmlConfigurationTests class is a test suite of test cases testing
* the configuration of Spring Session backed by GemFire using XML configuration
* meta-data.
*
* @author John Blum
* @since 1.1.0
@@ -56,12 +57,14 @@ import static org.assertj.core.api.Assertions.assertThat;
@ContextConfiguration
@DirtiesContext
@WebAppConfiguration
public class GemFireHttpSessionXmlConfigurationTests extends AbstractGemFireIntegrationTests {
public class GemFireHttpSessionXmlConfigurationTests
extends AbstractGemFireIntegrationTests {
@Autowired
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();
Region<K, V> region = gemfireCache.getRegion(regionName);
@@ -73,14 +76,16 @@ public class GemFireHttpSessionXmlConfigurationTests extends AbstractGemFireInte
@Test
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);
}
@Test
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();
@@ -93,13 +98,15 @@ public class GemFireHttpSessionXmlConfigurationTests extends AbstractGemFireInte
@Test
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();
assertThat(queryService).isNotNull();
Index sessionAttributesIndex = queryService.getIndex(example, "sessionAttributesIndex");
Index sessionAttributesIndex = queryService.getIndex(example,
"sessionAttributesIndex");
assertIndex(sessionAttributesIndex, "s.attributes['one', 'two', 'three']",
String.format("%1$s s", example.getFullPath()));

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -15,8 +15,14 @@
*/
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 org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.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;
/**
@@ -57,69 +58,71 @@ public class MongoRepositoryITests extends AbstractITests {
public void saves() throws InterruptedException {
String username = "saves-" + System.currentTimeMillis();
MongoExpiringSession toSave = repository.createSession();
MongoExpiringSession toSave = this.repository.createSession();
String expectedAttributeName = "a";
String expectedAttributeValue = "b";
toSave.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();
toSaveContext.setAuthentication(toSaveToken);
toSave.setAttribute(SPRING_SECURITY_CONTEXT, toSaveContext);
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.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();
assertThat(repository.getSession(id)).isNull();
assertThat(this.repository.getSession(id)).isNull();
}
@Test
public void putAllOnSingleAttrDoesNotRemoveOld() {
MongoExpiringSession toSave = repository.createSession();
MongoExpiringSession toSave = this.repository.createSession();
toSave.setAttribute("a", "b");
repository.save(toSave);
toSave = repository.getSession(toSave.getId());
this.repository.save(toSave);
toSave = this.repository.getSession(toSave.getId());
toSave.setAttribute("1", "2");
repository.save(toSave);
toSave = repository.getSession(toSave.getId());
this.repository.save(toSave);
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.getAttribute("a")).isEqualTo("b");
assertThat(session.getAttribute("1")).isEqualTo("2");
repository.delete(toSave.getId());
this.repository.delete(toSave.getId());
}
@Test
public void findByPrincipalName() throws Exception {
String principalName = "findByPrincipalName" + UUID.randomUUID();
MongoExpiringSession toSave = repository.createSession();
MongoExpiringSession toSave = this.repository.createSession();
toSave.setAttribute(INDEX_NAME, principalName);
repository.save(toSave);
this.repository.save(toSave);
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalName);
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).hasSize(1);
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.keySet()).doesNotContain(toSave.getId());
@@ -127,17 +130,18 @@ public class MongoRepositoryITests extends AbstractITests {
@Test
public void findByPrincipalNameNoPrincipalNameChange() throws Exception {
String principalName = "findByPrincipalNameNoPrincipalNameChange" + UUID.randomUUID();
MongoExpiringSession toSave = repository.createSession();
String principalName = "findByPrincipalNameNoPrincipalNameChange"
+ UUID.randomUUID();
MongoExpiringSession toSave = this.repository.createSession();
toSave.setAttribute(INDEX_NAME, principalName);
repository.save(toSave);
this.repository.save(toSave);
toSave.setAttribute("other", "value");
repository.save(toSave);
this.repository.save(toSave);
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalName);
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
@@ -145,19 +149,20 @@ public class MongoRepositoryITests extends AbstractITests {
@Test
public void findByPrincipalNameNoPrincipalNameChangeReload() throws Exception {
String principalName = "findByPrincipalNameNoPrincipalNameChangeReload" + UUID.randomUUID();
MongoExpiringSession toSave = repository.createSession();
String principalName = "findByPrincipalNameNoPrincipalNameChangeReload"
+ UUID.randomUUID();
MongoExpiringSession toSave = this.repository.createSession();
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");
repository.save(toSave);
this.repository.save(toSave);
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalName);
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
@@ -166,16 +171,16 @@ public class MongoRepositoryITests extends AbstractITests {
@Test
public void findByDeletedPrincipalName() throws Exception {
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
MongoExpiringSession toSave = repository.createSession();
MongoExpiringSession toSave = this.repository.createSession();
toSave.setAttribute(INDEX_NAME, principalName);
repository.save(toSave);
this.repository.save(toSave);
toSave.setAttribute(INDEX_NAME, null);
repository.save(toSave);
this.repository.save(toSave);
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalName);
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).isEmpty();
}
@@ -184,19 +189,20 @@ public class MongoRepositoryITests extends AbstractITests {
public void findByChangedPrincipalName() throws Exception {
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
MongoExpiringSession toSave = repository.createSession();
MongoExpiringSession toSave = this.repository.createSession();
toSave.setAttribute(INDEX_NAME, principalName);
repository.save(toSave);
this.repository.save(toSave);
toSave.setAttribute(INDEX_NAME, principalNameChanged);
repository.save(toSave);
this.repository.save(toSave);
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalName);
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).isEmpty();
findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME, principalNameChanged);
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalNameChanged);
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
@@ -205,17 +211,17 @@ public class MongoRepositoryITests extends AbstractITests {
@Test
public void findByDeletedPrincipalNameReload() throws Exception {
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
MongoExpiringSession toSave = repository.createSession();
MongoExpiringSession toSave = this.repository.createSession();
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);
repository.save(getSession);
this.repository.save(getSession);
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalName);
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).isEmpty();
}
@@ -224,21 +230,22 @@ public class MongoRepositoryITests extends AbstractITests {
public void findByChangedPrincipalNameReload() throws Exception {
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
MongoExpiringSession toSave = repository.createSession();
MongoExpiringSession toSave = this.repository.createSession();
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);
repository.save(getSession);
this.repository.save(getSession);
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalName);
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).isEmpty();
findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME, principalNameChanged);
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalNameChanged);
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
@@ -246,20 +253,21 @@ public class MongoRepositoryITests extends AbstractITests {
@Test
public void findBySecurityPrincipalName() throws Exception {
MongoExpiringSession toSave = repository.createSession();
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);
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
getSecurityName());
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
assertThat(findByPrincipalName).hasSize(1);
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.keySet()).doesNotContain(toSave.getId());
@@ -267,35 +275,36 @@ public class MongoRepositoryITests extends AbstractITests {
@Test
public void findByPrincipalNameNoSecurityPrincipalNameChange() throws Exception {
MongoExpiringSession toSave = repository.createSession();
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.setAttribute("other", "value");
repository.save(toSave);
this.repository.save(toSave);
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
getSecurityName());
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
}
@Test
public void findByPrincipalNameNoSecurityPrincipalNameChangeReload() throws Exception {
MongoExpiringSession toSave = repository.createSession();
toSave.setAttribute(SPRING_SECURITY_CONTEXT, context);
public void findByPrincipalNameNoSecurityPrincipalNameChangeReload()
throws Exception {
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");
repository.save(toSave);
this.repository.save(toSave);
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
getSecurityName());
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
@@ -303,35 +312,36 @@ public class MongoRepositoryITests extends AbstractITests {
@Test
public void findByDeletedSecurityPrincipalName() throws Exception {
MongoExpiringSession toSave = repository.createSession();
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.setAttribute(SPRING_SECURITY_CONTEXT, null);
repository.save(toSave);
this.repository.save(toSave);
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
getSecurityName());
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
assertThat(findByPrincipalName).isEmpty();
}
@Test
public void findByChangedSecurityPrincipalName() throws Exception {
MongoExpiringSession toSave = repository.createSession();
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.setAttribute(SPRING_SECURITY_CONTEXT, changedContext);
repository.save(toSave);
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext);
this.repository.save(toSave);
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
getSecurityName());
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
assertThat(findByPrincipalName).isEmpty();
findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
getChangedSecurityName());
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
@@ -339,38 +349,39 @@ public class MongoRepositoryITests extends AbstractITests {
@Test
public void findByDeletedSecurityPrincipalNameReload() throws Exception {
MongoExpiringSession toSave = repository.createSession();
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);
MongoExpiringSession getSession = repository.getSession(toSave.getId());
MongoExpiringSession getSession = this.repository.getSession(toSave.getId());
getSession.setAttribute(INDEX_NAME, null);
repository.save(getSession);
this.repository.save(getSession);
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
getChangedSecurityName());
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
assertThat(findByPrincipalName).isEmpty();
}
@Test
public void findByChangedSecurityPrincipalNameReload() throws Exception {
MongoExpiringSession toSave = repository.createSession();
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);
MongoExpiringSession getSession = repository.getSession(toSave.getId());
MongoExpiringSession getSession = this.repository.getSession(toSave.getId());
getSession.setAttribute(SPRING_SECURITY_CONTEXT, changedContext);
repository.save(getSession);
getSession.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext);
this.repository.save(getSession);
Map<String, MongoExpiringSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
getSecurityName());
Map<String, MongoExpiringSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
assertThat(findByPrincipalName).isEmpty();
findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
getChangedSecurityName());
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
@@ -379,22 +390,24 @@ public class MongoRepositoryITests extends AbstractITests {
@Test
public void loadExpiredSession() throws Exception {
// given
MongoExpiringSession expiredSession = repository.createSession();
long thirtyOneMinutesAgo = System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(31);
MongoExpiringSession expiredSession = this.repository.createSession();
long thirtyOneMinutesAgo = System.currentTimeMillis()
- TimeUnit.MINUTES.toMillis(31);
expiredSession.setLastAccessedTime(thirtyOneMinutesAgo);
repository.save(expiredSession);
this.repository.save(expiredSession);
// then
MongoExpiringSession expiredSessionFromDb = repository.getSession(expiredSession.getId());
MongoExpiringSession expiredSessionFromDb = this.repository
.getSession(expiredSession.getId());
assertThat(expiredSessionFromDb).isNull();
}
private String getSecurityName() {
return context.getAuthentication().getName();
return this.context.getAuthentication().getName();
}
private String getChangedSecurityName() {
return changedContext.getAuthentication().getName();
return this.changedContext.getAuthentication().getName();
}
@Configuration

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -15,12 +15,11 @@
*/
package org.springframework.session.data.redis;
import static org.assertj.core.api.Assertions.*;
import java.util.Map;
import java.util.UUID;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.test.context.ContextConfiguration;
import static org.assertj.core.api.Assertions.assertThat;
@ContextConfiguration
public class RedisOperationsSessionRepositoryITests extends AbstractITests {
private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
@@ -58,86 +59,90 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
public void saves() throws InterruptedException {
String username = "saves-" + System.currentTimeMillis();
String usernameSessionKey = "spring:session:RedisOperationsSessionRepositoryITests:index:" + INDEX_NAME + ":"
+ username;
String usernameSessionKey = "spring:session:RedisOperationsSessionRepositoryITests:index:"
+ INDEX_NAME + ":" + username;
RedisSession toSave = repository.createSession();
RedisSession toSave = this.repository.createSession();
String expectedAttributeName = "a";
String expectedAttributeValue = "b";
toSave.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();
toSaveContext.setAuthentication(toSaveToken);
toSave.setAttribute(SPRING_SECURITY_CONTEXT, toSaveContext);
toSave.setAttribute(INDEX_NAME, username);
registry.clear();
this.registry.clear();
repository.save(toSave);
this.repository.save(toSave);
assertThat(registry.receivedEvent(toSave.getId())).isTrue();
assertThat(registry.getEvent(toSave.getId())).isInstanceOf(SessionCreatedEvent.class);
assertThat(redis.boundSetOps(usernameSessionKey).members()).contains(toSave.getId());
assertThat(this.registry.receivedEvent(toSave.getId())).isTrue();
assertThat(this.registry.getEvent(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.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(registry.getEvent(toSave.getId())).isInstanceOf(SessionDestroyedEvent.class);
assertThat(redis.boundSetOps(usernameSessionKey).members()).doesNotContain(toSave.getId());
assertThat(this.repository.getSession(toSave.getId())).isNull();
assertThat(this.registry.getEvent(toSave.getId()))
.isInstanceOf(SessionDestroyedEvent.class);
assertThat(this.redis.boundSetOps(usernameSessionKey).members())
.doesNotContain(toSave.getId());
assertThat(registry.getEvent(toSave.getId()).getSession().getAttribute(expectedAttributeName))
.isEqualTo(expectedAttributeValue);
assertThat(this.registry.getEvent(toSave.getId()).getSession()
.getAttribute(expectedAttributeName)).isEqualTo(expectedAttributeValue);
}
@Test
public void putAllOnSingleAttrDoesNotRemoveOld() {
RedisSession toSave = repository.createSession();
RedisSession toSave = this.repository.createSession();
toSave.setAttribute("a", "b");
repository.save(toSave);
toSave = repository.getSession(toSave.getId());
this.repository.save(toSave);
toSave = this.repository.getSession(toSave.getId());
toSave.setAttribute("1", "2");
repository.save(toSave);
toSave = repository.getSession(toSave.getId());
this.repository.save(toSave);
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.getAttribute("a")).isEqualTo("b");
assertThat(session.getAttribute("1")).isEqualTo("2");
repository.delete(toSave.getId());
this.repository.delete(toSave.getId());
}
@Test
public void findByPrincipalName() throws Exception {
String principalName = "findByPrincipalName" + UUID.randomUUID();
RedisSession toSave = repository.createSession();
RedisSession toSave = this.repository.createSession();
toSave.setAttribute(INDEX_NAME, principalName);
repository.save(toSave);
this.repository.save(toSave);
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalName);
Map<String, RedisSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
repository.delete(toSave.getId());
assertThat(registry.receivedEvent(toSave.getId())).isTrue();
this.repository.delete(toSave.getId());
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.keySet()).doesNotContain(toSave.getId());
@@ -145,20 +150,23 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
@Test
public void findByPrincipalNameExpireRemovesIndex() throws Exception {
String principalName = "findByPrincipalNameExpireRemovesIndex" + UUID.randomUUID();
RedisSession toSave = repository.createSession();
String principalName = "findByPrincipalNameExpireRemovesIndex"
+ UUID.randomUUID();
RedisSession toSave = this.repository.createSession();
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";
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[] {};
repository.onMessage(message, pattern);
this.repository.onMessage(message, pattern);
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalName);
Map<String, RedisSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).hasSize(0);
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
@@ -166,17 +174,18 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
@Test
public void findByPrincipalNameNoPrincipalNameChange() throws Exception {
String principalName = "findByPrincipalNameNoPrincipalNameChange" + UUID.randomUUID();
RedisSession toSave = repository.createSession();
String principalName = "findByPrincipalNameNoPrincipalNameChange"
+ UUID.randomUUID();
RedisSession toSave = this.repository.createSession();
toSave.setAttribute(INDEX_NAME, principalName);
repository.save(toSave);
this.repository.save(toSave);
toSave.setAttribute("other", "value");
repository.save(toSave);
this.repository.save(toSave);
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalName);
Map<String, RedisSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
@@ -184,19 +193,20 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
@Test
public void findByPrincipalNameNoPrincipalNameChangeReload() throws Exception {
String principalName = "findByPrincipalNameNoPrincipalNameChangeReload" + UUID.randomUUID();
RedisSession toSave = repository.createSession();
String principalName = "findByPrincipalNameNoPrincipalNameChangeReload"
+ UUID.randomUUID();
RedisSession toSave = this.repository.createSession();
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");
repository.save(toSave);
this.repository.save(toSave);
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalName);
Map<String, RedisSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
@@ -205,16 +215,16 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
@Test
public void findByDeletedPrincipalName() throws Exception {
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
RedisSession toSave = repository.createSession();
RedisSession toSave = this.repository.createSession();
toSave.setAttribute(INDEX_NAME, principalName);
repository.save(toSave);
this.repository.save(toSave);
toSave.setAttribute(INDEX_NAME, null);
repository.save(toSave);
this.repository.save(toSave);
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalName);
Map<String, RedisSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).isEmpty();
}
@@ -223,19 +233,20 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
public void findByChangedPrincipalName() throws Exception {
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
RedisSession toSave = repository.createSession();
RedisSession toSave = this.repository.createSession();
toSave.setAttribute(INDEX_NAME, principalName);
repository.save(toSave);
this.repository.save(toSave);
toSave.setAttribute(INDEX_NAME, principalNameChanged);
repository.save(toSave);
this.repository.save(toSave);
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalName);
Map<String, RedisSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).isEmpty();
findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME, principalNameChanged);
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalNameChanged);
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
@@ -244,17 +255,17 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
@Test
public void findByDeletedPrincipalNameReload() throws Exception {
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
RedisSession toSave = repository.createSession();
RedisSession toSave = this.repository.createSession();
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);
repository.save(getSession);
this.repository.save(getSession);
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalName);
Map<String, RedisSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).isEmpty();
}
@@ -263,21 +274,22 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
public void findByChangedPrincipalNameReload() throws Exception {
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
RedisSession toSave = repository.createSession();
RedisSession toSave = this.repository.createSession();
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);
repository.save(getSession);
this.repository.save(getSession);
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalName);
Map<String, RedisSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).isEmpty();
findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME, principalNameChanged);
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalNameChanged);
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
@@ -285,21 +297,22 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
@Test
public void findBySecurityPrincipalName() throws Exception {
RedisSession toSave = repository.createSession();
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);
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
getSecurityName());
Map<String, RedisSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
repository.delete(toSave.getId());
assertThat(registry.receivedEvent(toSave.getId())).isTrue();
this.repository.delete(toSave.getId());
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.keySet()).doesNotContain(toSave.getId());
@@ -307,19 +320,21 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
@Test
public void findBySecurityPrincipalNameExpireRemovesIndex() throws Exception {
RedisSession toSave = repository.createSession();
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);
String body = "spring:session:RedisOperationsSessionRepositoryITests:sessions:expires:" + toSave.getId();
String body = "spring:session:RedisOperationsSessionRepositoryITests:sessions:expires:"
+ toSave.getId();
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[] {};
repository.onMessage(message, pattern);
this.repository.onMessage(message, pattern);
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
getSecurityName());
Map<String, RedisSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
assertThat(findByPrincipalName).hasSize(0);
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
@@ -327,35 +342,36 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
@Test
public void findByPrincipalNameNoSecurityPrincipalNameChange() throws Exception {
RedisSession toSave = repository.createSession();
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.setAttribute("other", "value");
repository.save(toSave);
this.repository.save(toSave);
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
getSecurityName());
Map<String, RedisSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
}
@Test
public void findByPrincipalNameNoSecurityPrincipalNameChangeReload() throws Exception {
RedisSession toSave = repository.createSession();
toSave.setAttribute(SPRING_SECURITY_CONTEXT, context);
public void findByPrincipalNameNoSecurityPrincipalNameChangeReload()
throws Exception {
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");
repository.save(toSave);
this.repository.save(toSave);
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
getSecurityName());
Map<String, RedisSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
@@ -363,35 +379,36 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
@Test
public void findByDeletedSecurityPrincipalName() throws Exception {
RedisSession toSave = repository.createSession();
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.setAttribute(SPRING_SECURITY_CONTEXT, null);
repository.save(toSave);
this.repository.save(toSave);
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
getSecurityName());
Map<String, RedisSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
assertThat(findByPrincipalName).isEmpty();
}
@Test
public void findByChangedSecurityPrincipalName() throws Exception {
RedisSession toSave = repository.createSession();
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.setAttribute(SPRING_SECURITY_CONTEXT, changedContext);
repository.save(toSave);
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext);
this.repository.save(toSave);
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
getSecurityName());
Map<String, RedisSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
assertThat(findByPrincipalName).isEmpty();
findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
getChangedSecurityName());
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
@@ -399,49 +416,50 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
@Test
public void findByDeletedSecurityPrincipalNameReload() throws Exception {
RedisSession toSave = repository.createSession();
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);
RedisSession getSession = repository.getSession(toSave.getId());
RedisSession getSession = this.repository.getSession(toSave.getId());
getSession.setAttribute(INDEX_NAME, null);
repository.save(getSession);
this.repository.save(getSession);
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
getChangedSecurityName());
Map<String, RedisSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
assertThat(findByPrincipalName).isEmpty();
}
@Test
public void findByChangedSecurityPrincipalNameReload() throws Exception {
RedisSession toSave = repository.createSession();
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);
RedisSession getSession = repository.getSession(toSave.getId());
RedisSession getSession = this.repository.getSession(toSave.getId());
getSession.setAttribute(SPRING_SECURITY_CONTEXT, changedContext);
repository.save(getSession);
getSession.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext);
this.repository.save(getSession);
Map<String, RedisSession> findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME,
getSecurityName());
Map<String, RedisSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
assertThat(findByPrincipalName).isEmpty();
findByPrincipalName = repository.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
getChangedSecurityName());
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
}
private String getSecurityName() {
return context.getAuthentication().getName();
return this.context.getAuthentication().getName();
}
private String getChangedSecurityName() {
return changedContext.getAuthentication().getName();
return this.changedContext.getAuthentication().getName();
}
@Configuration

View File

@@ -62,7 +62,8 @@ public class EnableRedisHttpSessionExpireSessionDestroyedTests<S extends Expirin
public void expireFiresSessionExpiredEvent() throws InterruptedException {
S toSave = this.repository.createSession();
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();
toSaveContext.setAuthentication(toSaveToken);
toSave.setAttribute("SPRING_SECURITY_CONTEXT", toSaveContext);
@@ -86,7 +87,8 @@ public class EnableRedisHttpSessionExpireSessionDestroyedTests<S extends Expirin
assertThat(this.registry.receivedEvent()).isTrue();
}
static class SessionExpiredEventRegistry implements ApplicationListener<SessionExpiredEvent> {
static class SessionExpiredEventRegistry
implements ApplicationListener<SessionExpiredEvent> {
private boolean receivedEvent;
private Object lock;

View File

@@ -53,9 +53,10 @@ public class RedisListenerContainerTaskExecutorITests {
RedisOperations<Object, Object> redis;
@Test
public void testRedisDelEventsAreDispatchedInSessionTaskExecutor() throws InterruptedException {
BoundSetOperations<Object, Object> ops = this.redis
.boundSetOps("spring:session:RedisListenerContainerTaskExecutorITests:expirations:dummy");
public void testRedisDelEventsAreDispatchedInSessionTaskExecutor()
throws InterruptedException {
BoundSetOperations<Object, Object> ops = this.redis.boundSetOps(
"spring:session:RedisListenerContainerTaskExecutorITests:expirations:dummy");
ops.add("value");
ops.remove("value");
assertThat(this.executor.taskDispatched()).isTrue();

View File

@@ -33,8 +33,8 @@ import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.util.SocketUtils;
/**
* Integration tests that check the underlying data source - in this case
* Hazelcast Client.
* Integration tests that check the underlying data source - in this case Hazelcast
* Client.
*
* @author Vedran Pavic
* @author Artem Bilan
@@ -50,7 +50,6 @@ public class HazelcastClientRepositoryITests<S extends ExpiringSession>
private static HazelcastInstance hazelcastInstance;
@BeforeClass
public static void setup() {
hazelcastInstance = HazelcastITestUtils.embeddedHazelcastServer(PORT);
@@ -70,8 +69,7 @@ public class HazelcastClientRepositoryITests<S extends ExpiringSession>
@Bean
public HazelcastInstance embeddedHazelcastClient() {
ClientConfig clientConfig = new ClientConfig();
clientConfig.getNetworkConfig()
.addAddress("127.0.0.1:" + PORT);
clientConfig.getNetworkConfig().addAddress("127.0.0.1:" + PORT);
return HazelcastClient.newHazelcastClient(clientConfig);
}

View File

@@ -39,8 +39,7 @@ public final class HazelcastITestUtils {
*/
public static HazelcastInstance embeddedHazelcastServer(int port) {
Config config = new Config();
config.getNetworkConfig()
.setPort(port);
config.getNetworkConfig().setPort(port);
return Hazelcast.newHazelcastInstance(config);
}

View File

@@ -28,8 +28,8 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
/**
* Integration tests that check the underlying data source - in this case
* Hazelcast Server.
* Integration tests that check the underlying data source - in this case Hazelcast
* Server.
*
* @author Tommy Ludwig
* @author Vedran Pavic

View File

@@ -45,9 +45,9 @@ import org.springframework.test.context.web.WebAppConfiguration;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Ensure that the appropriate SessionEvents are fired at the expected times.
* Additionally ensure that the interactions with the {@link SessionRepository}
* abstraction behave as expected after each SessionEvent.
* Ensure that the appropriate SessionEvents are fired at the expected times. Additionally
* ensure that the interactions with the {@link SessionRepository} abstraction behave as
* expected after each SessionEvent.
*
* @author Tommy Ludwig
*/
@@ -78,22 +78,27 @@ public class EnableHazelcastHttpSessionEventsTests<S extends ExpiringSession> {
String expectedAttributeName = "a";
String expectedAttributeValue = "b";
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();
toSaveContext.setAuthentication(toSaveToken);
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);
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());
assertThat(session.getId()).isEqualTo(sessionToSave.getId());
assertThat(session.getAttributeNames()).isEqualTo(sessionToSave.getAttributeNames());
assertThat(session.getAttribute(expectedAttributeName)).isEqualTo(sessionToSave.getAttribute(expectedAttributeName));
assertThat(session.getAttributeNames())
.isEqualTo(sessionToSave.getAttributeNames());
assertThat(session.getAttribute(expectedAttributeName))
.isEqualTo(sessionToSave.getAttribute(expectedAttributeName));
}
@Test
@@ -103,13 +108,16 @@ public class EnableHazelcastHttpSessionEventsTests<S extends ExpiringSession> {
this.repository.save(sessionToSave);
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();
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.getEvent(sessionToSave.getId())).isInstanceOf(SessionExpiredEvent.class);
assertThat(this.registry.getEvent(sessionToSave.getId()))
.isInstanceOf(SessionExpiredEvent.class);
assertThat(this.repository.getSession(sessionToSave.getId())).isNull();
}
@@ -121,13 +129,15 @@ public class EnableHazelcastHttpSessionEventsTests<S extends ExpiringSession> {
this.repository.save(sessionToSave);
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.repository.delete(sessionToSave.getId());
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();
}

View File

@@ -37,8 +37,8 @@ import org.springframework.util.SocketUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Test the different configuration options for the
* {@link EnableHazelcastHttpSession} annotation.
* Test the different configuration options for the {@link EnableHazelcastHttpSession}
* annotation.
*
* @author Tommy Ludwig
*/

View File

@@ -73,24 +73,27 @@ public class JdbcOperationsSessionRepositoryITests {
@Before
public void setup() throws Exception {
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.setAuthentication(new UsernamePasswordAuthenticationToken(
"changedContext-" + UUID.randomUUID(), "na", AuthorityUtils.createAuthorityList("ROLE_USER")));
"changedContext-" + UUID.randomUUID(), "na",
AuthorityUtils.createAuthorityList("ROLE_USER")));
}
@Test
public void saves() throws InterruptedException {
String username = "saves-" + System.currentTimeMillis();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
String expectedAttributeName = "a";
String expectedAttributeValue = "b";
toSave.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();
toSaveContext.setAuthentication(toSaveToken);
toSave.setAttribute(SPRING_SECURITY_CONTEXT, toSaveContext);
@@ -102,7 +105,8 @@ public class JdbcOperationsSessionRepositoryITests {
assertThat(session.getId()).isEqualTo(toSave.getId());
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());
@@ -111,7 +115,8 @@ public class JdbcOperationsSessionRepositoryITests {
@Test
public void putAllOnSingleAttrDoesNotRemoveOld() {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute("a", "b");
this.repository.save(toSave);
@@ -133,20 +138,22 @@ public class JdbcOperationsSessionRepositoryITests {
@Test
public void findByPrincipalName() throws Exception {
String principalName = "findByPrincipalName" + UUID.randomUUID();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(INDEX_NAME, principalName);
this.repository.save(toSave);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(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.keySet()).doesNotContain(toSave.getId());
@@ -154,17 +161,19 @@ public class JdbcOperationsSessionRepositoryITests {
@Test
public void findByPrincipalNameExpireRemovesIndex() throws Exception {
String principalName = "findByPrincipalNameExpireRemovesIndex" + UUID.randomUUID();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
String principalName = "findByPrincipalNameExpireRemovesIndex"
+ UUID.randomUUID();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(INDEX_NAME, principalName);
toSave.setLastAccessedTime(System.currentTimeMillis() -
(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS * 1000 + 1000));
toSave.setLastAccessedTime(System.currentTimeMillis()
- (MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS * 1000 + 1000));
this.repository.save(toSave);
this.repository.cleanUpExpiredSessions();
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).hasSize(0);
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
@@ -172,8 +181,10 @@ public class JdbcOperationsSessionRepositoryITests {
@Test
public void findByPrincipalNameNoPrincipalNameChange() throws Exception {
String principalName = "findByPrincipalNameNoPrincipalNameChange" + UUID.randomUUID();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
String principalName = "findByPrincipalNameNoPrincipalNameChange"
+ UUID.randomUUID();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(INDEX_NAME, principalName);
this.repository.save(toSave);
@@ -181,8 +192,8 @@ public class JdbcOperationsSessionRepositoryITests {
toSave.setAttribute("other", "value");
this.repository.save(toSave);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
@@ -190,8 +201,10 @@ public class JdbcOperationsSessionRepositoryITests {
@Test
public void findByPrincipalNameNoPrincipalNameChangeReload() throws Exception {
String principalName = "findByPrincipalNameNoPrincipalNameChangeReload" + UUID.randomUUID();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
String principalName = "findByPrincipalNameNoPrincipalNameChangeReload"
+ UUID.randomUUID();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(INDEX_NAME, principalName);
this.repository.save(toSave);
@@ -201,8 +214,8 @@ public class JdbcOperationsSessionRepositoryITests {
toSave.setAttribute("other", "value");
this.repository.save(toSave);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
@@ -211,7 +224,8 @@ public class JdbcOperationsSessionRepositoryITests {
@Test
public void findByDeletedPrincipalName() throws Exception {
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(INDEX_NAME, principalName);
this.repository.save(toSave);
@@ -219,8 +233,8 @@ public class JdbcOperationsSessionRepositoryITests {
toSave.setAttribute(INDEX_NAME, null);
this.repository.save(toSave);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).isEmpty();
}
@@ -229,7 +243,8 @@ public class JdbcOperationsSessionRepositoryITests {
public void findByChangedPrincipalName() throws Exception {
String principalName = "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);
this.repository.save(toSave);
@@ -237,11 +252,12 @@ public class JdbcOperationsSessionRepositoryITests {
toSave.setAttribute(INDEX_NAME, principalNameChanged);
this.repository.save(toSave);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).isEmpty();
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalNameChanged);
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalNameChanged);
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
@@ -250,17 +266,19 @@ public class JdbcOperationsSessionRepositoryITests {
@Test
public void findByDeletedPrincipalNameReload() throws Exception {
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(INDEX_NAME, principalName);
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);
this.repository.save(getSession);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).isEmpty();
}
@@ -269,21 +287,24 @@ public class JdbcOperationsSessionRepositoryITests {
public void findByChangedPrincipalNameReload() throws Exception {
String principalName = "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);
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);
this.repository.save(getSession);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
assertThat(findByPrincipalName).isEmpty();
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalNameChanged);
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalNameChanged);
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
@@ -291,20 +312,22 @@ public class JdbcOperationsSessionRepositoryITests {
@Test
public void findBySecurityPrincipalName() throws Exception {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
this.repository.save(toSave);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(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.keySet()).doesNotContain(toSave.getId());
@@ -312,16 +335,17 @@ public class JdbcOperationsSessionRepositoryITests {
@Test
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.setLastAccessedTime(System.currentTimeMillis() -
(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS * 1000 + 1000));
toSave.setLastAccessedTime(System.currentTimeMillis()
- (MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS * 1000 + 1000));
this.repository.save(toSave);
this.repository.cleanUpExpiredSessions();
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
assertThat(findByPrincipalName).hasSize(0);
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
@@ -329,7 +353,8 @@ public class JdbcOperationsSessionRepositoryITests {
@Test
public void findByPrincipalNameNoSecurityPrincipalNameChange() throws Exception {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
this.repository.save(toSave);
@@ -337,16 +362,18 @@ public class JdbcOperationsSessionRepositoryITests {
toSave.setAttribute("other", "value");
this.repository.save(toSave);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
}
@Test
public void findByPrincipalNameNoSecurityPrincipalNameChangeReload() throws Exception {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
public void findByPrincipalNameNoSecurityPrincipalNameChangeReload()
throws Exception {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
this.repository.save(toSave);
@@ -356,8 +383,8 @@ public class JdbcOperationsSessionRepositoryITests {
toSave.setAttribute("other", "value");
this.repository.save(toSave);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
@@ -365,7 +392,8 @@ public class JdbcOperationsSessionRepositoryITests {
@Test
public void findByDeletedSecurityPrincipalName() throws Exception {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
this.repository.save(toSave);
@@ -373,15 +401,16 @@ public class JdbcOperationsSessionRepositoryITests {
toSave.setAttribute(SPRING_SECURITY_CONTEXT, null);
this.repository.save(toSave);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
assertThat(findByPrincipalName).isEmpty();
}
@Test
public void findByChangedSecurityPrincipalName() throws Exception {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
this.repository.save(toSave);
@@ -389,11 +418,12 @@ public class JdbcOperationsSessionRepositoryITests {
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext);
this.repository.save(toSave);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
assertThat(findByPrincipalName).isEmpty();
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
getChangedSecurityName());
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
@@ -401,38 +431,43 @@ public class JdbcOperationsSessionRepositoryITests {
@Test
public void findByDeletedSecurityPrincipalNameReload() throws Exception {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
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);
this.repository.save(getSession);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
assertThat(findByPrincipalName).isEmpty();
}
@Test
public void findByChangedSecurityPrincipalNameReload() throws Exception {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
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);
repository.save(getSession);
this.repository.save(getSession);
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName =
this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
Map<String, JdbcOperationsSessionRepository.JdbcSession> findByPrincipalName = this.repository
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
assertThat(findByPrincipalName).isEmpty();
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
getChangedSecurityName());
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
@@ -452,10 +487,8 @@ public class JdbcOperationsSessionRepositoryITests {
@Bean
public EmbeddedDatabase dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("org/springframework/session/jdbc/schema-h2.sql")
.build();
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2)
.addScript("org/springframework/session/jdbc/schema-h2.sql").build();
}
@Bean

View File

@@ -17,7 +17,8 @@
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
* @since 1.0
@@ -25,37 +26,47 @@ package org.springframework.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();
/**
* 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);
/**
* 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();
/**
* 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);
/**
* 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();

View File

@@ -19,16 +19,16 @@ package org.springframework.session;
import java.util.Map;
/**
* Extends a basic {@link SessionRepository} to allow finding a session id by
* the principal name. The principal name is defined by the {@link Session}
* attribute with the name {@link FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME}.
* Extends a basic {@link SessionRepository} to allow finding a session id by the
* principal name. The principal name is defined by the {@link Session} attribute with the
* name {@link FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME}.
*
* @param <S>
* the type of Session being managed by this
* @param <S> the type of Session being managed by this
* {@link FindByIndexNameSessionRepository}
* @author Rob Winch
*/
public interface FindByIndexNameSessionRepository<S extends Session> extends SessionRepository<S> {
public interface FindByIndexNameSessionRepository<S extends Session>
extends SessionRepository<S> {
/**
* <p>
@@ -37,28 +37,27 @@ public interface FindByIndexNameSessionRepository<S extends Session> extends Ses
* </p>
*
* <p>
* It is the responsibility of the developer to ensure the attribute
* is populated since Spring Session is not aware of the authentication
* mechanism being used.
* It is the responsibility of the developer to ensure the attribute is populated
* since Spring Session is not aware of the authentication mechanism being used.
* </p>
*
* @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
* contain the session attribute with the name
* {@link FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME} and
* the value of the specified principal name.
* Find a Map of the session id to the {@link Session} of all sessions that contain
* the session attribute with the name
* {@link FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME} and the value of
* the specified principal name.
*
* @param indexName
* the name if the index (i.e. {@link FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME})
* @param indexName the name if the index (i.e.
* {@link FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME})
* @param indexValue the value of the index to search for.
* @return a Map (never null) of the session id to the {@link Session} of
* all sessions that contain the session specified index name and
* the value of the specified index name. If no results are found,
* an empty Map is returned.
* @return a Map (never null) of the session id to the {@link Session} of all sessions
* that contain the session specified index name and the value of the specified index
* name. If no results are found, an empty Map is returned.
*/
Map<String, S> findByIndexNameAndIndexValue(String indexName, String indexValue);
}

View File

@@ -25,7 +25,8 @@ import java.util.concurrent.TimeUnit;
/**
* <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>
* <ul>
* <li>id - a secure random generated id</li>
@@ -35,7 +36,8 @@ import java.util.concurrent.TimeUnit;
* </ul>
*
* <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>
*
* @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
* default constructor when the id is known to prevent unnecessary consumption on
* entropy which can be slow.
* Creates a new instance with the specified id. This is preferred to the default
* constructor when the id is known to prevent unnecessary consumption on entropy
* which can be slow.
*
* @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}.
*
* @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) {
if (session == null) {
throw new IllegalArgumentException("session cannot be null");
}
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()) {
Object attrValue = session.getAttribute(attrName);
this.sessionAttrs.put(attrName, attrValue);
@@ -127,7 +131,8 @@ public final class MapSession implements ExpiringSession, Serializable {
if (this.maxInactiveInterval < 0) {
return false;
}
return now - TimeUnit.SECONDS.toMillis(this.maxInactiveInterval) >= this.lastAccessedTime;
return now - TimeUnit.SECONDS
.toMillis(this.maxInactiveInterval) >= this.lastAccessedTime;
}
@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.
* @param creationTime the time that this {@link Session} was created in milliseconds since midnight of 1/1/1970 GMT.
* 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.
* @param creationTime the time that this {@link Session} was created in milliseconds
* since midnight of 1/1/1970 GMT.
*/
public void setCreationTime(long 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.
*/

View File

@@ -23,12 +23,14 @@ import org.springframework.session.events.SessionDeletedEvent;
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
* {@link java.util.concurrent.ConcurrentHashMap} is used, but a custom {@link java.util.Map} can be injected to use
* distributed maps provided by NoSQL stores like Redis and Hazelcast.
* A {@link SessionRepository} backed by a {@link java.util.Map} and that uses a
* {@link MapSession}. By default a {@link java.util.concurrent.ConcurrentHashMap} is
* used, but a custom {@link java.util.Map} can be injected to use distributed maps
* provided by NoSQL stores like Redis and Hazelcast.
*
* <p>
* The implementation does NOT support firing {@link SessionDeletedEvent} or {@link SessionExpiredEvent}.
* The implementation does NOT support firing {@link SessionDeletedEvent} or
* {@link SessionExpiredEvent}.
* </p>
*
* @author Rob Winch
@@ -36,7 +38,8 @@ import org.springframework.session.events.SessionExpiredEvent;
*/
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;
@@ -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.
*/
@@ -62,8 +66,10 @@ public class MapSessionRepository implements SessionRepository<ExpiringSession>
}
/**
* If non-null, this value is used to override {@link ExpiringSession#setMaxInactiveIntervalInSeconds(int)}.
* @param defaultMaxInactiveInterval the number of seconds that the {@link Session} should be kept alive between client requests.
* If non-null, this value is used to override
* {@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) {
this.defaultMaxInactiveInterval = Integer.valueOf(defaultMaxInactiveInterval);

View File

@@ -19,8 +19,8 @@ package org.springframework.session;
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
* Session, or even non web related sessions.
* Provides a way to identify a user in an agnostic way. This allows the session to be
* used by an HttpSession, WebSocket Session, or even non web related sessions.
*
* @author Rob Winch
* @since 1.0
@@ -35,16 +35,20 @@ public interface Session {
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
* @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
*/
<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.
* @see #getAttribute(String)
@@ -52,10 +56,13 @@ public interface Session {
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 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);

View File

@@ -26,22 +26,28 @@ package org.springframework.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
* implementation returned might keep track of the changes ensuring that only the delta needs to be persisted on
* a save.</p>
* <p>
* This allows optimizations and customizations in how the {@link Session} is
* 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();
/**
* 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>
* Some implementations may choose to save as the {@link Session} is updated by returning a {@link Session} that
* immediately persists any changes. In this case, this method may not actually do anything.
* Some implementations may choose to save as the {@link Session} is updated by
* returning a {@link Session} that immediately persists any changes. In this case,
* this method may not actually do anything.
* </p>
*
* @param session the {@link Session} to save
@@ -49,15 +55,18 @@ public interface SessionRepository<S extends 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
* @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);
/**
* 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
*/
void delete(String id);

View File

@@ -28,10 +28,9 @@ import org.springframework.session.events.SessionDestroyedEvent;
/**
* Add this annotation to an {@code @Configuration} class to expose the
* SessionRepositoryFilter as a bean named "springSessionRepositoryFilter" and
* backed by a user provided implementation of {@link SessionRepository}. In
* order to leverage the annotation, a single {@link SessionRepository} bean
* must be provided. For example:
* SessionRepositoryFilter as a bean named "springSessionRepositoryFilter" and backed by a
* user provided implementation of {@link SessionRepository}. In order to leverage the
* annotation, a single {@link SessionRepository} bean must be provided. For example:
*
* <pre>
* <code>
@@ -45,15 +44,13 @@ import org.springframework.session.events.SessionDestroyedEvent;
* }
*
* }
* </code>
* </pre>
* </code> </pre>
*
* <p>
* It is important to note that no infrastructure for session expirations is
* configured for you out of the box. This is because things like session
* expiration are highly implementation dependent. This means if you require
* cleaning up expired sessions, you are responsible for cleaning up the expired
* sessions.
* It is important to note that no infrastructure for session expirations is configured
* for you out of the box. This is because things like session expiration are highly
* implementation dependent. This means if you require cleaning up expired sessions, you
* are responsible for cleaning up the expired sessions.
* </p>
*
* <p>
@@ -61,13 +58,12 @@ import org.springframework.session.events.SessionDestroyedEvent;
* </p>
*
* <ul>
* <li>SessionRepositoryFilter - is responsible for wrapping the
* HttpServletRequest with an implementation of HttpSession that is backed by a
* SessionRepository</li>
* <li>SessionEventHttpSessionListenerAdapter - is responsible for translating
* Spring Session events into HttpSessionEvent. In order for it to work, the
* implementation of SessionRepository you provide must support
* {@link SessionCreatedEvent} and {@link SessionDestroyedEvent}.</li>
* <li>SessionRepositoryFilter - is responsible for wrapping the HttpServletRequest with
* an implementation of HttpSession that is backed by a SessionRepository</li>
* <li>SessionEventHttpSessionListenerAdapter - is responsible for translating Spring
* Session events into HttpSessionEvent. In order for it to work, the implementation of
* SessionRepository you provide must support {@link SessionCreatedEvent} and
* {@link SessionDestroyedEvent}.</li>
* <li>
* </ul>
*

View File

@@ -37,8 +37,8 @@ import org.springframework.session.web.http.SessionEventHttpSessionListenerAdapt
import org.springframework.session.web.http.SessionRepositoryFilter;
/**
* Configures the basics for setting up Spring Session in a web environment. In
* order to use it, you must provide a {@link SessionRepository}. For example:
* Configures the basics for setting up Spring Session in a web environment. In order to
* use it, you must provide a {@link SessionRepository}. For example:
*
* <pre>
* {@literal @Configuration}
@@ -54,11 +54,10 @@ import org.springframework.session.web.http.SessionRepositoryFilter;
* </pre>
*
* <p>
* It is important to note that no infrastructure for session expirations is
* configured for you out of the box. This is because things like session
* expiration are highly implementation dependent. This means if you require
* cleaning up expired sessions, you are responsible for cleaning up the expired
* sessions.
* It is important to note that no infrastructure for session expirations is configured
* for you out of the box. This is because things like session expiration are highly
* implementation dependent. This means if you require cleaning up expired sessions, you
* are responsible for cleaning up the expired sessions.
* </p>
*
* <p>
@@ -66,13 +65,12 @@ import org.springframework.session.web.http.SessionRepositoryFilter;
* </p>
*
* <ul>
* <li>SessionRepositoryFilter - is responsible for wrapping the
* HttpServletRequest with an implementation of HttpSession that is backed by a
* SessionRepository</li>
* <li>SessionEventHttpSessionListenerAdapter - is responsible for translating
* Spring Session events into HttpSessionEvent. In order for it to work, the
* implementation of SessionRepository you provide must support
* {@link SessionCreatedEvent} and {@link SessionDestroyedEvent}.</li>
* <li>SessionRepositoryFilter - is responsible for wrapping the HttpServletRequest with
* an implementation of HttpSession that is backed by a SessionRepository</li>
* <li>SessionEventHttpSessionListenerAdapter - is responsible for translating Spring
* Session events into HttpSessionEvent. In order for it to work, the implementation of
* SessionRepository you provide must support {@link SessionCreatedEvent} and
* {@link SessionDestroyedEvent}.</li>
* <li>
* </ul>
*
@@ -98,11 +96,14 @@ public class SpringHttpSessionConfiguration {
}
@Bean
public <S extends ExpiringSession> SessionRepositoryFilter<? extends ExpiringSession> springSessionRepositoryFilter(SessionRepository<S> sessionRepository) {
SessionRepositoryFilter<S> sessionRepositoryFilter = new SessionRepositoryFilter<S>(sessionRepository);
public <S extends ExpiringSession> SessionRepositoryFilter<? extends ExpiringSession> springSessionRepositoryFilter(
SessionRepository<S> sessionRepository) {
SessionRepositoryFilter<S> sessionRepositoryFilter = new SessionRepositoryFilter<S>(
sessionRepository);
sessionRepositoryFilter.setServletContext(this.servletContext);
if (this.httpSessionStrategy instanceof MultiHttpSessionStrategy) {
sessionRepositoryFilter.setHttpSessionStrategy((MultiHttpSessionStrategy) this.httpSessionStrategy);
sessionRepositoryFilter.setHttpSessionStrategy(
(MultiHttpSessionStrategy) this.httpSessionStrategy);
}
else {
sessionRepositoryFilter.setHttpSessionStrategy(this.httpSessionStrategy);

View File

@@ -64,8 +64,9 @@ import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* AbstractGemFireOperationsSessionRepository is an abstract base class encapsulating functionality common
* to all implementations that support SessionRepository operations backed by GemFire.
* AbstractGemFireOperationsSessionRepository is an abstract base class encapsulating
* functionality common to all implementations that support SessionRepository operations
* backed by GemFire.
*
* @author John Blum
* @since 1.1.0
@@ -77,11 +78,13 @@ import org.springframework.util.StringUtils;
* @see org.springframework.session.ExpiringSession
* @see org.springframework.session.FindByIndexNameSessionRepository
* @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.util.CacheListenerAdapter
*/
public abstract class AbstractGemFireOperationsSessionRepository extends CacheListenerAdapter<Object, ExpiringSession>
public abstract class AbstractGemFireOperationsSessionRepository
extends CacheListenerAdapter<Object, ExpiringSession>
implements InitializingBean, FindByIndexNameSessionRepository<ExpiringSession>,
ApplicationEventPublisherAware {
@@ -90,6 +93,7 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
private ApplicationEventPublisher applicationEventPublisher = new ApplicationEventPublisher() {
public void publishEvent(ApplicationEvent event) {
}
public void publishEvent(Object event) {
}
};
@@ -101,8 +105,9 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
private String fullyQualifiedRegionName;
/**
* Constructs an instance of AbstractGemFireOperationsSessionRepository with a required GemfireOperations instance
* used to perform GemFire data access operations and interactions supporting the SessionRepository operations.
* Constructs an instance of AbstractGemFireOperationsSessionRepository with a
* 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.
* @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
*/
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
Assert.notNull(applicationEventPublisher, "ApplicationEventPublisher must not be null");
public void setApplicationEventPublisher(
ApplicationEventPublisher applicationEventPublisher) {
Assert.notNull(applicationEventPublisher,
"ApplicationEventPublisher must not be null");
this.applicationEventPublisher = applicationEventPublisher;
}
/**
* 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.
* @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
* and manage Session data.
* @return a String indicating the fully qualified name of the GemFire cache
* {@link Region} used to store and manage Session data.
*/
protected String getFullyQualifiedRegionName() {
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
* can remain inactive before it is considered expired.
* @param maxInactiveIntervalInSeconds an integer value specifying the maximum
* interval in seconds that a Session can remain inactive before it is considered
* expired.
*/
public void setMaxInactiveIntervalInSeconds(int 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
* before it is considered expired.
* @return an integer value specifying the maximum interval in seconds that a Session
* can remain inactive before it is considered expired.
*/
public int getMaxInactiveIntervalInSeconds() {
return this.maxInactiveIntervalInSeconds;
}
/**
* Gets a reference to the GemfireOperations (template) used to perform data access operations
* and other interactions on the GemFire cache {@link Region} backing this SessionRepository.
* Gets a reference to the GemfireOperations (template) used to perform data access
* operations and other interactions on the GemFire cache {@link Region} backing this
* SessionRepository.
*
* @return a reference to the GemfireOperations used to interact with GemFire.
* @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
* of the GemFire cache {@link Region} used to manage Session state and register this SessionRepository
* as a GemFire {@link com.gemstone.gemfire.cache.CacheListener}.
* Callback method during Spring bean initialization that will capture the
* fully-qualified name of the GemFire cache {@link Region} used to manage Session
* state and register this SessionRepository as a GemFire
* {@link com.gemstone.gemfire.cache.CacheListener}.
*
* @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.
* @see com.gemstone.gemfire.cache.EntryEvent
@@ -222,12 +239,14 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
@Override
public void afterCreate(EntryEvent<Object, ExpiringSession> event) {
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.
* @see com.gemstone.gemfire.cache.EntryEvent
@@ -235,11 +254,13 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
*/
@Override
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.
* @see com.gemstone.gemfire.cache.EntryEvent
@@ -318,29 +339,34 @@ 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 (%1$s)", event), t);
}
}
/**
* GemFireSession is a GemFire representation model of a Spring {@link ExpiringSession} for storing and accessing
* Session state information in GemFire. This class implements GemFire's {@link DataSerializable} interface
* to better handle replication of Session information across the GemFire cluster.
* GemFireSession is a GemFire representation model of a Spring
* {@link ExpiringSession} for storing and accessing Session state information in
* 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 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.DataSerializer
* @see com.gemstone.gemfire.Delta
* @see com.gemstone.gemfire.Instantiator
*/
@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 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";
@@ -360,7 +386,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();
@@ -460,7 +487,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
/* (non-Javadoc) */
private long idleTimeout(long maxInactiveIntervalInSeconds) {
return (System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(maxInactiveIntervalInSeconds));
return (System.currentTimeMillis()
- TimeUnit.SECONDS.toMillis(maxInactiveIntervalInSeconds));
}
/* (non-Javadoc) */
@@ -475,7 +503,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
}
/* (non-Javadoc) */
public synchronized void setMaxInactiveIntervalInSeconds(final int maxInactiveIntervalInSeconds) {
public synchronized void setMaxInactiveIntervalInSeconds(
final int maxInactiveIntervalInSeconds) {
this.delta |= (this.maxInactiveIntervalInSeconds != maxInactiveIntervalInSeconds);
this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds;
}
@@ -498,7 +527,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
Object authentication = getAttribute(SPRING_SECURITY_CONTEXT);
if (authentication != null) {
Expression expression = this.parser.parseExpression("authentication?.name");
Expression expression = this.parser
.parseExpression("authentication?.name");
principalName = expression.getValue(authentication, String.class);
}
}
@@ -514,7 +544,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
out.writeInt(getMaxInactiveIntervalInSeconds());
String principalName = getPrincipalName();
int length = (StringUtils.hasText(principalName) ? principalName.length() : 0);
int length = (StringUtils.hasText(principalName) ? principalName.length()
: 0);
out.writeInt(length);
@@ -533,7 +564,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
}
/* (non-Javadoc) */
public synchronized void fromData(DataInput in) throws ClassNotFoundException, IOException {
public synchronized void fromData(DataInput in)
throws ClassNotFoundException, IOException {
this.id = in.readUTF();
this.creationTime = in.readLong();
setLastAccessedTime(in.readLong());
@@ -609,9 +641,11 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
/* (non-Javadoc) */
@Override
public synchronized String toString() {
return String.format("{ @type = %1$s, id = %2$s, creationTime = %3$s, lastAccessedTime = %4$s"
+ ", maxInactiveIntervalInSeconds = %5$s, principalName = %6$s }", getClass().getName(), getId(),
toString(getCreationTime()), toString(getLastAccessedTime()), getMaxInactiveIntervalInSeconds(),
return String.format(
"{ @type = %1$s, id = %2$s, creationTime = %3$s, lastAccessedTime = %4$s"
+ ", maxInactiveIntervalInSeconds = %5$s, principalName = %6$s }",
getClass().getName(), getId(), toString(getCreationTime()),
toString(getLastAccessedTime()), getMaxInactiveIntervalInSeconds(),
getPrincipalName());
}
@@ -622,10 +656,11 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
}
/**
* The GemFireSessionAttributes class is a container for Session attributes that implements both
* the {@link DataSerializable} and {@link Delta} GemFire interfaces for efficient storage and distribution
* (replication) in GemFire. Additionally, GemFireSessionAttributes extends {@link AbstractMap} providing
* {@link Map}-like behavior since attributes of a Session are effectively a name to value mapping.
* The GemFireSessionAttributes class is a container for Session attributes that
* implements both the {@link DataSerializable} and {@link Delta} GemFire interfaces
* for efficient storage and distribution (replication) in GemFire. Additionally,
* 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 com.gemstone.gemfire.DataSerializable
@@ -640,7 +675,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
protected static final boolean DEFAULT_ALLOW_JAVA_SERIALIZATION = true;
static {
Instantiator.register(new Instantiator(GemFireSessionAttributes.class, 800828008) {
Instantiator.register(
new Instantiator(GemFireSessionAttributes.class, 800828008) {
@Override
public DataSerializable newInstance() {
return new GemFireSessionAttributes();
@@ -667,7 +703,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
public void setAttribute(String attributeName, Object attributeValue) {
synchronized (this.lock) {
if (attributeValue != null) {
if (!attributeValue.equals(this.sessionAttributes.put(attributeName, attributeValue))) {
if (!attributeValue.equals(
this.sessionAttributes.put(attributeName, attributeValue))) {
this.sessionAttributeDeltas.put(attributeName, attributeValue);
}
}
@@ -697,7 +734,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
/* (non-Javadoc) */
public Set<String> getAttributeNames() {
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>>() {
@Override
public Iterator<Entry<String, Object>> iterator() {
return Collections.unmodifiableMap(GemFireSessionAttributes.this.sessionAttributes).entrySet().iterator();
return Collections
.unmodifiableMap(
GemFireSessionAttributes.this.sessionAttributes)
.entrySet().iterator();
}
@Override
@@ -736,7 +777,8 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi
public void from(GemFireSessionAttributes sessionAttributes) {
synchronized (this.lock) {
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) {
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());
writeObject(entry.getValue(), out);
}

View File

@@ -25,31 +25,33 @@ import org.springframework.data.gemfire.GemfireOperations;
import org.springframework.session.ExpiringSession;
/**
* The GemFireOperationsSessionRepository class is a Spring SessionRepository implementation that interfaces with
* and uses GemFire to back and store Spring Sessions.
* The GemFireOperationsSessionRepository class is a Spring SessionRepository
* implementation that interfaces with and uses GemFire to back and store Spring Sessions.
*
* @author John Blum
* @since 1.1.0
* @see org.springframework.data.gemfire.GemfireOperations
* @see org.springframework.session.ExpiringSession
* @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.
protected static final String FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY =
"SELECT s FROM %1$s s WHERE s.attributes['%2$s'] = $1";
protected static final String FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY = "SELECT s FROM %1$s s WHERE s.attributes['%2$s'] = $1";
// GemFire OQL query used to look up Sessions by principal name.
protected static final String FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY =
"SELECT s FROM %1$s s WHERE s.principalName = $1";
protected static final String FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY = "SELECT s FROM %1$s s WHERE s.principalName = $1";
/**
* Constructs an instance of GemFireOperationsSessionRepository initialized with the required GemfireOperations
* object used to perform data access operations to manage Session state.
* Constructs an instance of GemFireOperationsSessionRepository initialized with the
* 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
*/
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.
* (e.g. {@link org.springframework.session.FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME}).
* @param indexValue value of the indexed Session attribute to search on (e.g. username).
* @param indexName name of the indexed Session attribute. (e.g.
* {@link org.springframework.session.FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME}
* ).
* @param indexValue value of the indexed Session attribute to search on (e.g.
* username).
* @return a mapping of Session ID to Session instances.
* @see org.springframework.session.ExpiringSession
* @see java.util.Map
* @see #prepareQuery(String)
*/
public Map<String, ExpiringSession> findByIndexNameAndIndexValue(String indexName, String indexValue) {
SelectResults<ExpiringSession> results = getTemplate().find(prepareQuery(indexName), indexValue);
public Map<String, ExpiringSession> findByIndexNameAndIndexValue(String indexName,
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()) {
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.
* @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) {
return (PRINCIPAL_NAME_INDEX_NAME.equals(indexName)
? String.format(FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY, getFullyQualifiedRegionName())
: String.format(FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY, getFullyQualifiedRegionName(), indexName));
? String.format(FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY,
getFullyQualifiedRegionName())
: String.format(FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY,
getFullyQualifiedRegionName(), indexName));
}
/**
* Constructs a new {@link ExpiringSession} instance 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 #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,
* then it is deleted.
* Gets a copy of an existing, non-expired {@link ExpiringSession} by ID. If the
* Session is expired, then it is deleted.
*
* @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.
@@ -140,15 +152,16 @@ public class GemFireOperationsSessionRepository extends AbstractGemFireOperation
}
/**
* Deletes (removes) any existing {@link ExpiringSession} from GemFire. This operation also results in
* a SessionDeletedEvent.
* Deletes (removes) any existing {@link ExpiringSession} from GemFire. This operation
* also results in a SessionDeletedEvent.
*
* @param sessionId a String indicating the ID of the Session to remove from GemFire.
* @see org.springframework.data.gemfire.GemfireOperations#remove(Object)
* @see #handleDeleted(String, ExpiringSession)
*/
public void delete(String sessionId) {
handleDeleted(sessionId, getTemplate().<Object, ExpiringSession>remove(sessionId));
handleDeleted(sessionId,
getTemplate().<Object, ExpiringSession>remove(sessionId));
}
}

View File

@@ -29,11 +29,13 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* Add this annotation to an {@code @Configuration} class to expose the SessionRepositoryFilter
* as a bean named "springSessionRepositoryFilter" and backed by Pivotal GemFire or Apache Geode.
* Add this annotation to an {@code @Configuration} class to expose the
* SessionRepositoryFilter as a bean named "springSessionRepositoryFilter" and backed by
* Pivotal GemFire or Apache Geode.
*
* In order to leverage the annotation, a single Pivotal GemFire/Apache Geode {@link com.gemstone.gemfire.cache.Cache}
* or {@link com.gemstone.gemfire.cache.client.ClientCache} instance must be provided.
* In order to leverage the annotation, a single Pivotal GemFire/Apache Geode
* {@link com.gemstone.gemfire.cache.Cache} or
* {@link com.gemstone.gemfire.cache.client.ClientCache} instance must be provided.
*
* For example:
*
@@ -61,12 +63,11 @@ import org.springframework.context.annotation.Import;
* return clientCacheFactoryBean;
* }
* }
* </code>
* </pre>
* </code> </pre>
*
* Alternatively, a Spring Session can be configured to use Pivotal GemFire (Apache Geode) as a client
* using a dedicated GemFire Server cluster and a {@link com.gemstone.gemfire.cache.client.ClientCache}.
* For example:
* Alternatively, a Spring Session can be configured to use Pivotal GemFire (Apache Geode)
* as a client using a dedicated GemFire Server cluster and a
* {@link com.gemstone.gemfire.cache.client.ClientCache}. For example:
*
* <code>
* {@literal @Configuration}
@@ -92,12 +93,14 @@ import org.springframework.context.annotation.Import;
* }
* </code>
*
* More advanced configurations can extend {@link GemFireHttpSessionConfiguration} instead.
* More advanced configurations can extend {@link GemFireHttpSessionConfiguration}
* instead.
*
* @author John Blum
* @see org.springframework.context.annotation.Configuration
* @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
* @since 1.1.0
*/
@@ -111,31 +114,35 @@ public @interface EnableGemFireHttpSession {
/**
* 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
*/
ClientRegionShortcut clientRegionShortcut() default ClientRegionShortcut.PROXY;
/**
* Identifies the Session attributes by name that should be indexed for query operations.
* For instance, find all Sessions in GemFire having attribute A defined with value X.
* Identifies the Session attributes by name that should be indexed for query
* 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.
*/
String[]indexableSessionAttributes() default {};
/**
* Defines the maximum interval in seconds that a Session can remain inactive before it is considered expired.
* Defaults to 1800 seconds, or 30 minutes.
* Defines the maximum interval in seconds that a Session can remain inactive before
* 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;
/**
* 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()
*/
String regionName() default "ClusteredSpringSessions";
@@ -143,7 +150,8 @@ public @interface EnableGemFireHttpSession {
/**
* 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
*/
RegionShortcut serverRegionShortcut() default RegionShortcut.PARTITION;

View File

@@ -49,8 +49,9 @@ import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
* The GemFireHttpSessionConfiguration class is a Spring @Configuration class used to configure and initialize
* Pivotal GemFire (or Apache Geode) as a clustered, replicated HttpSession provider implementation in Spring Session.
* The GemFireHttpSessionConfiguration class is a Spring @Configuration class used to
* configure and initialize Pivotal GemFire (or Apache Geode) as a clustered, replicated
* HttpSession provider implementation in Spring Session.
*
* @author John Blum
* @since 1.1.0
@@ -63,9 +64,11 @@ import org.springframework.util.StringUtils;
* @see org.springframework.data.gemfire.IndexFactoryBean
* @see org.springframework.data.gemfire.RegionAttributesFactoryBean
* @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.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.GemFireCache
* @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
* 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<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;
/**
* 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 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.
* @see java.lang.ClassLoader
@@ -142,10 +149,11 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
}
/**
* Sets the {@link ClientRegionShortcut} used to configure the GemFire ClientCache Region
* that will store Spring Sessions.
* Sets the {@link ClientRegionShortcut} used to configure the GemFire ClientCache
* 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
*/
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
* that will store Spring Sessions. Defaults to {@link ClientRegionShortcut#PROXY}.
* Gets the {@link ClientRegionShortcut} used to configure the GemFire ClientCache
* Region that will store Spring Sessions. Defaults to
* {@link ClientRegionShortcut#PROXY}.
*
* @return the ClientRegionShortcut used to configure the GemFire ClientCache Region.
* @see com.gemstone.gemfire.cache.client.ClientRegionShortcut
* @see EnableGemFireHttpSession#clientRegionShortcut()
*/
protected ClientRegionShortcut getClientRegionShortcut() {
return (this.clientRegionShortcut != null ? this.clientRegionShortcut : DEFAULT_CLIENT_REGION_SHORTCUT);
return (this.clientRegionShortcut != null ? this.clientRegionShortcut
: DEFAULT_CLIENT_REGION_SHORTCUT);
}
/**
* 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
* for which an Index will be created by GemFire.
* @param indexableSessionAttributes an array of Strings indicating the names of all
* Session attributes for which an Index will be created by GemFire.
*/
public void setIndexableSessionAttributes(String[] 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.
*
* @return an array of Strings indicating the names of all Session attributes for which an Index
* will be created by GemFire. Defaults to an empty String array if unspecified.
* @return an array of Strings indicating the names of all Session attributes for
* which an Index will be created by GemFire. Defaults to an empty String array if
* unspecified.
* @see EnableGemFireHttpSession#indexableSessionAttributes()
*/
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
* the Index expression of the Index definition.
* Gets the names of all Session attributes that will be indexed by GemFire as single
* 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
* as an Index definition expression. If the indexable Session attributes were not specified, then the
* wildcard ("*") is returned.
* @return a String composed of all the named Session attributes on which a GemFire
* Index will be created as an Index definition expression. If the indexable Session
* attributes were not specified, then the wildcard ("*") is returned.
* @see com.gemstone.gemfire.cache.query.Index#getIndexedExpression()
*/
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
* can remain inactive before it is considered expired.
* @param maxInactiveIntervalInSeconds an integer value specifying the maximum
* interval in seconds that a Session can remain inactive before it is considered
* expired.
*/
public void setMaxInactiveIntervalInSeconds(int 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
* before it is considered expired.
* @return an integer value specifying the maximum interval in seconds that a Session
* can remain inactive before it is considered expired.
* @see EnableGemFireHttpSession#maxInactiveIntervalInSeconds()
*/
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.
* @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.
* Defaults to {@link RegionShortcut#PARTITION}.
* Gets the {@link RegionShortcut} used to configure the GemFire Cache Region that
* will store Spring Sessions. Defaults to {@link RegionShortcut#PARTITION}.
*
* @return the RegionShortcut used to configure the GemFire Cache Region.
* @see com.gemstone.gemfire.cache.RegionShortcut
* @see EnableGemFireHttpSession#serverRegionShortcut()
*/
protected RegionShortcut getServerRegionShortcut() {
return (this.serverRegionShortcut != null ? this.serverRegionShortcut : DEFAULT_SERVER_REGION_SHORTCUT);
return (this.serverRegionShortcut != null ? this.serverRegionShortcut
: DEFAULT_SERVER_REGION_SHORTCUT);
}
/**
* 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
* used to store the Session.
* @param springSessionGemFireRegionName a String specifying the name of the GemFire
* (Client)Cache Region used to store the Session.
*/
public void setSpringSessionGemFireRegionName(String 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
* used to store the Session.
* @return a String specifying the name of the GemFire (Client)Cache Region used to
* store the Session.
* @see com.gemstone.gemfire.cache.Region#getName()
* @see EnableGemFireHttpSession#regionName()
*/
protected String getSpringSessionGemFireRegionName() {
return (StringUtils.hasText(this.springSessionGemFireRegionName) ? this.springSessionGemFireRegionName
return (StringUtils.hasText(this.springSessionGemFireRegionName)
? this.springSessionGemFireRegionName
: DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME);
}
/**
* Callback with the {@link AnnotationMetadata} of the class containing @Import annotation that imported
* this @Configuration class.
* Callback with the {@link AnnotationMetadata} of the class containing @Import
* annotation that imported this @Configuration class.
*
* @param importMetadata the AnnotationMetadata of the class importing this @Configuration class.
* @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession
* @param importMetadata the AnnotationMetadata of the class importing
* this @Configuration class.
* @see org.springframework.session.data.gemfire.config.annotation.web.http.
* EnableGemFireHttpSession
* @see org.springframework.core.type.AnnotationMetadata
*/
public void setImportMetadata(AnnotationMetadata importMetadata) {
AnnotationAttributes enableGemFireHttpSessionAnnotationAttributes = AnnotationAttributes.fromMap(
importMetadata.getAnnotationAttributes(EnableGemFireHttpSession.class.getName()));
AnnotationAttributes enableGemFireHttpSessionAnnotationAttributes = AnnotationAttributes
.fromMap(importMetadata.getAnnotationAttributes(
EnableGemFireHttpSession.class.getName()));
setClientRegionShortcut(ClientRegionShortcut.class.cast(enableGemFireHttpSessionAnnotationAttributes.getEnum(
"clientRegionShortcut")));
setClientRegionShortcut(ClientRegionShortcut.class
.cast(enableGemFireHttpSessionAnnotationAttributes
.getEnum("clientRegionShortcut")));
setIndexableSessionAttributes(enableGemFireHttpSessionAnnotationAttributes.getStringArray(
"indexableSessionAttributes"));
setIndexableSessionAttributes(enableGemFireHttpSessionAnnotationAttributes
.getStringArray("indexableSessionAttributes"));
setMaxInactiveIntervalInSeconds(enableGemFireHttpSessionAnnotationAttributes.getNumber(
"maxInactiveIntervalInSeconds").intValue());
setMaxInactiveIntervalInSeconds(enableGemFireHttpSessionAnnotationAttributes
.getNumber("maxInactiveIntervalInSeconds").intValue());
setServerRegionShortcut(RegionShortcut.class.cast(enableGemFireHttpSessionAnnotationAttributes.getEnum(
"serverRegionShortcut")));
setServerRegionShortcut(
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.
* @return a GemFireOperationsSessionRepository for managing (clustering/replicating) Sessions using GemFire.
* @param gemfireOperations an instance of {@link GemfireOperations} used to manage
* Spring Sessions in GemFire.
* @return a GemFireOperationsSessionRepository for managing (clustering/replicating)
* Sessions using GemFire.
* @see org.springframework.session.data.gemfire.GemFireOperationsSessionRepository
* @see org.springframework.data.gemfire.GemfireOperations
*/
@Bean
public GemFireOperationsSessionRepository sessionRepository(@Qualifier("sessionRegionTemplate")
GemfireOperations gemfireOperations) {
public GemFireOperationsSessionRepository sessionRepository(
@Qualifier("sessionRegionTemplate") GemfireOperations gemfireOperations) {
GemFireOperationsSessionRepository sessionRepository = new GemFireOperationsSessionRepository(gemfireOperations);
GemFireOperationsSessionRepository sessionRepository = new GemFireOperationsSessionRepository(
gemfireOperations);
sessionRepository.setMaxInactiveIntervalInSeconds(getMaxInactiveIntervalInSeconds());
sessionRepository
.setMaxInactiveIntervalInSeconds(getMaxInactiveIntervalInSeconds());
return sessionRepository;
}
/**
* Defines a Spring GemfireTemplate bean used to interact with GemFire's (Client)Cache {@link Region}
* storing Sessions.
* Defines a Spring GemfireTemplate bean used to interact with GemFire's (Client)Cache
* {@link Region} storing Sessions.
*
* @param gemFireCache reference to the single GemFire cache instance used by the {@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.
* @param gemFireCache reference to the single GemFire cache instance used by the
* {@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.
* @see org.springframework.data.gemfire.GemfireTemplate
* @see com.gemstone.gemfire.cache.Region
*/
@Bean
@DependsOn(DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME)
public GemfireTemplate sessionRegionTemplate(GemFireCache gemFireCache) {
return new GemfireTemplate(gemFireCache.getRegion(getSpringSessionGemFireRegionName()));
return new GemfireTemplate(
gemFireCache.getRegion(getSpringSessionGemFireRegionName()));
}
/**
* Defines a Spring GemFire {@link com.gemstone.gemfire.cache.Cache} {@link Region} bean used to store
* and manage Sessions using either a client-server or peer-to-peer (p2p) topology.
* Defines a Spring GemFire {@link com.gemstone.gemfire.cache.Cache} {@link Region}
* 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 sessionRegionAttributes the GemFire {@link RegionAttributes} used to configure the {@link Region}.
* @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
* @param gemfireCache a reference to the GemFire
* {@link com.gemstone.gemfire.cache.Cache}.
* @param sessionRegionAttributes the GemFire {@link RegionAttributes} used to
* configure the {@link Region}.
* @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.RegionAttributes
* @see #getClientRegionShortcut()
@@ -351,11 +387,11 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
* @see #getServerRegionShortcut()
*/
@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) {
GemFireCacheTypeAwareRegionFactoryBean<Object, ExpiringSession> serverRegion =
new GemFireCacheTypeAwareRegionFactoryBean<Object, ExpiringSession>();
GemFireCacheTypeAwareRegionFactoryBean<Object, ExpiringSession> serverRegion = new GemFireCacheTypeAwareRegionFactoryBean<Object, ExpiringSession>();
serverRegion.setGemfireCache(gemfireCache);
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
* {@link Region} storing Sessions. Expiration is also 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.
* Defines a Spring GemFire {@link RegionAttributes} bean used to configure and
* initialize the GemFire cache {@link Region} storing Sessions. Expiration is also
* 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.
* @return an instance of {@link RegionAttributes} used to configure and initialize the GemFire cache {@link Region}
* for storing and managing Sessions.
* @return an instance of {@link RegionAttributes} used to configure and initialize
* the GemFire cache {@link Region} for storing and managing Sessions.
* @see org.springframework.data.gemfire.RegionAttributesFactoryBean
* @see com.gemstone.gemfire.cache.GemFireCache
* @see com.gemstone.gemfire.cache.PartitionAttributes
@@ -381,44 +418,49 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
*/
@Bean
@SuppressWarnings({ "unchecked", "deprecation" })
public RegionAttributesFactoryBean sessionRegionAttributes(GemFireCache gemfireCache) {
public RegionAttributesFactoryBean sessionRegionAttributes(
GemFireCache gemfireCache) {
RegionAttributesFactoryBean regionAttributes = new RegionAttributesFactoryBean();
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)) {
regionAttributes.setStatisticsEnabled(true);
regionAttributes.setEntryIdleTimeout(new ExpirationAttributes(
Math.max(getMaxInactiveIntervalInSeconds(), 0), ExpirationAction.INVALIDATE));
Math.max(getMaxInactiveIntervalInSeconds(), 0),
ExpirationAction.INVALIDATE));
}
return regionAttributes;
}
/**
* Determines whether expiration configuration is allowed to be set on the GemFire cache {@link Region}
* used to store and manage Sessions.
* Determines whether expiration configuration is allowed to be set on the GemFire
* cache {@link Region} used to store and manage Sessions.
*
* @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#isProxy(ClientRegionShortcut)
* @see GemFireUtils#isProxy(RegionShortcut)
*/
boolean isExpirationAllowed(GemFireCache gemfireCache) {
return !(GemFireUtils.isClient(gemfireCache) ? GemFireUtils.isProxy(getClientRegionShortcut())
return !(GemFireUtils.isClient(gemfireCache)
? GemFireUtils.isProxy(getClientRegionShortcut())
: GemFireUtils.isProxy(getServerRegionShortcut()));
}
/**
* Defines a Spring GemFire Index bean on the GemFire cache {@link Region} storing and managing Sessions,
* specifically on the 'principalName' property for quick lookup and queries. This index will only be created
* on a server @{link Region}.
* Defines a Spring GemFire Index bean on the GemFire cache {@link Region} storing and
* managing Sessions, specifically on the 'principalName' property for quick lookup
* and queries. This index will only be created on a server @{link Region}.
*
* @param gemfireCache a reference to the GemFire cache.
* @return a IndexFactoryBean creating an GemFire Index on the 'principalName' property of Sessions stored
* in the GemFire cache {@link Region}.
* @return a IndexFactoryBean creating an GemFire Index on the 'principalName'
* property of Sessions stored in the GemFire cache {@link Region}.
* @see org.springframework.data.gemfire.IndexFactoryBean
* @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,
* specifically on Session attributes for quick lookup and queries on Session attribute names with a given value.
* This index will only be created on a server @{link Region}.
* Defines a Spring GemFire Index bean on the GemFire cache {@link Region} storing and
* managing Sessions, specifically on Session attributes for quick lookup and queries
* 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.
* @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 com.gemstone.gemfire.cache.GemFireCache
*/
@@ -460,7 +504,8 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
IndexFactoryBean index = new IndexFactoryBean() {
@Override
public void afterPropertiesSet() throws Exception {
if (GemFireUtils.isPeer(gemfireCache) && !ObjectUtils.isEmpty(getIndexableSessionAttributes())) {
if (GemFireUtils.isPeer(gemfireCache)
&& !ObjectUtils.isEmpty(getIndexableSessionAttributes())) {
super.afterPropertiesSet();
}
}
@@ -468,8 +513,10 @@ public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfigurat
index.setCache(gemfireCache);
index.setName("sessionAttributesIndex");
index.setExpression(String.format("s.attributes[%1$s]", getIndexableSessionAttributesAsGemFireIndexExpression()));
index.setFrom(String.format("%1$s s", GemFireUtils.toRegionPath(getSpringSessionGemFireRegionName())));
index.setExpression(String.format("s.attributes[%1$s]",
getIndexableSessionAttributesAsGemFireIndexExpression()));
index.setFrom(String.format("%1$s s",
GemFireUtils.toRegionPath(getSpringSessionGemFireRegionName())));
index.setOverride(true);
return index;

View File

@@ -34,8 +34,9 @@ import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* The GemFireCacheTypeAwareRegionFactoryBean class is a Spring {@link FactoryBean} used to construct, configure
* and initialize the GemFire cache {@link Region} used to store and manage Session state.
* The GemFireCacheTypeAwareRegionFactoryBean class is a Spring {@link FactoryBean} used
* to construct, configure and initialize the GemFire cache {@link Region} used to store
* and manage Session state.
*
* @param <K> the type of keys
* @param <V> the type of values
@@ -45,7 +46,8 @@ import org.springframework.util.StringUtils;
* @see org.springframework.beans.factory.InitializingBean
* @see org.springframework.data.gemfire.GenericRegionFactoryBean
* @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.InterestResultPolicy
* @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.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 =
GemFireHttpSessionConfiguration.DEFAULT_CLIENT_REGION_SHORTCUT;
protected static final ClientRegionShortcut DEFAULT_CLIENT_REGION_SHORTCUT = GemFireHttpSessionConfiguration.DEFAULT_CLIENT_REGION_SHORTCUT;
protected static final RegionShortcut DEFAULT_SERVER_REGION_SHORTCUT =
GemFireHttpSessionConfiguration.DEFAULT_SERVER_REGION_SHORTCUT;
protected static final RegionShortcut DEFAULT_SERVER_REGION_SHORTCUT = GemFireHttpSessionConfiguration.DEFAULT_SERVER_REGION_SHORTCUT;
protected static final String DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME =
GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME;
protected static final String DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME = GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME;
private ClientRegionShortcut clientRegionShortcut;
@@ -77,9 +77,10 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> implements FactoryBean
private String regionName;
/**
* Post-construction initialization callback to create, configure and initialize the GemFire cache {@link Region}
* used to store, replicate (distribute) and manage Session state. This method intelligently handles
* both client-server and peer-to-peer (p2p) GemFire supported distributed system topologies.
* Post-construction initialization callback to create, configure and initialize the
* GemFire cache {@link Region} used to store, replicate (distribute) and manage
* 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.
* @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
* and manage Session state in a GemFire server cluster accessible from a GemFire cache client.
* Constructs a GemFire cache {@link Region} using a peer-to-peer (p2p) GemFire
* 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}.
* @return a peer-to-peer-based GemFire cache {@link Region} to store and manage Session state.
* @throws Exception if the instantiation, configuration and initialization
* of the GemFire cache {@link Region} fails.
* @param gemfireCache a reference to the GemFire
* {@link com.gemstone.gemfire.cache.Cache}.
* @return a peer-to-peer-based GemFire cache {@link Region} to store and manage
* Session state.
* @throws Exception if the instantiation, configuration and initialization of the
* GemFire cache {@link Region} fails.
* @see org.springframework.data.gemfire.GenericRegionFactoryBean
* @see com.gemstone.gemfire.cache.GemFireCache
* @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
* and manage Session state in a GemFire server cluster accessible from a GemFire cache client.
* Constructs a GemFire cache {@link Region} using the client-server GemFire 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}.
* @return a client-server-based GemFire cache {@link Region} to store and manage Session state.
* @throws Exception if the instantiation, configuration and initialization
* of the GemFire cache {@link Region} fails.
* @param gemfireCache a reference to the GemFire
* {@link com.gemstone.gemfire.cache.Cache}.
* @return a client-server-based GemFire cache {@link Region} to store and manage
* 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 com.gemstone.gemfire.cache.GemFireCache
* @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.
*
* @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
*/
/**
* Decides whether interests will be registered for all keys. Interests is only registered on a client
* and typically only when the client is a (CACHING) PROXY to the server (i.e. non-LOCAL only).
* Decides whether interests will be registered for all keys. Interests is only
* registered on a client and typically only when the client is a (CACHING) PROXY to
* the server (i.e. non-LOCAL only).
*
* @param register a boolean value indicating whether interests should be registered.
* @return an array of Interests KEY/VALUE registrations.
@@ -168,13 +177,14 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> implements FactoryBean
*/
@SuppressWarnings("unchecked")
protected Interest<K>[] registerInterests(boolean register) {
return (!register ? new Interest[0] : new Interest[] {
new Interest<String>("ALL_KEYS", InterestResultPolicy.KEYS)
});
return (!register ? new Interest[0]
: 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.
* @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
* or Region.class when uninitialized.
* Returns the specific type of GemFire cache {@link Region} this factory creates when
* initialized or Region.class when uninitialized.
*
* @return the GemFire cache {@link Region} class type constructed by this factory.
* @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() {
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}
* data management policy.
* @param clientRegionShortcut a {@link ClientRegionShortcut} to specify the client
* {@link Region} data management policy.
* @see com.gemstone.gemfire.cache.client.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
* {@link ClientRegionShortcut#PROXY}.
* Returns the {@link Region} data policy used by the GemFire cache client to manage
* 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 com.gemstone.gemfire.cache.client.ClientRegionShortcut
*/
protected ClientRegionShortcut getClientRegionShortcut() {
return (this.clientRegionShortcut != null ? this.clientRegionShortcut : DEFAULT_CLIENT_REGION_SHORTCUT);
return (this.clientRegionShortcut != null ? this.clientRegionShortcut
: DEFAULT_CLIENT_REGION_SHORTCUT);
}
/**
* 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.
* @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.
* @throws IllegalStateException if the {@link GemFireCache} reference is null.
*/
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;
}
/**
* Sets the GemFire {@link RegionAttributes} used to configure the GemFire cache {@link Region} used to
* store and manage Session state.
* Sets the GemFire {@link RegionAttributes} used to configure the GemFire cache
* {@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
*/
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
* store and manage Session state.
* Returns the GemFire {@link RegionAttributes} used to configure the GemFire cache
* {@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
*/
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}.
*/
@@ -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.
* Defaults to "ClusteredSpringSessions"
* Returns the configured name of the GemFire cache {@link Region} use to store and
* manage Session state. Defaults to "ClusteredSpringSessions"
*
* @return a String specifying the name of the GemFire cache {@link Region}.
* @see com.gemstone.gemfire.cache.Region#getName()
*/
protected String getRegionName() {
return (StringUtils.hasText(this.regionName) ? this.regionName : DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME);
return (StringUtils.hasText(this.regionName) ? this.regionName
: DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME);
}
/**
* 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
*/
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
* {@link RegionShortcut#PARTITION}.
* Returns the {@link Region} data policy used by the GemFire peer cache to manage
* 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
*/
protected RegionShortcut getServerRegionShortcut() {
return (this.serverRegionShortcut != null ? this.serverRegionShortcut : DEFAULT_SERVER_REGION_SHORTCUT);
return (this.serverRegionShortcut != null ? this.serverRegionShortcut
: DEFAULT_SERVER_REGION_SHORTCUT);
}
}

View File

@@ -28,8 +28,8 @@ import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
/**
* GemFireUtils is an abstract, extensible utility class for working with GemFire types and functionality
* and is used by Spring Session's GemFire adapter support classes.
* GemFireUtils is an abstract, extensible utility class for working with GemFire types
* and functionality and is used by Spring Session's GemFire adapter support classes.
*
* @author John Blum
* @since 1.1.0
@@ -40,8 +40,8 @@ public abstract class GemFireUtils {
* Null-safe method to close the given {@link Closeable} object.
*
* @param obj the {@link Closeable} object to close.
* @return true if the {@link Closeable} object is not null and was successfully closed,
* otherwise return false.
* @return true if the {@link Closeable} object is not null and was successfully
* closed, otherwise return false.
* @see java.io.Closeable
*/
public static boolean close(Closeable obj) {
@@ -67,7 +67,8 @@ public abstract class GemFireUtils {
*/
public static boolean isClient(GemFireCache gemFireCache) {
boolean client = (gemFireCache instanceof ClientCache);
client &= (!(gemFireCache instanceof GemFireCacheImpl) || ((GemFireCacheImpl) gemFireCache).isClient());
client &= (!(gemFireCache instanceof GemFireCacheImpl)
|| ((GemFireCacheImpl) gemFireCache).isClient());
return client;
}
@@ -87,7 +88,8 @@ public abstract class GemFireUtils {
* Determines whether the given {@link ClientRegionShortcut} is local only.
*
* @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
*/
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.
* NOTE: "proxy"-based Regions keep no local state.
* Determines whether the client {@link ClientRegionShortcut} is a proxy-based
* shortcut. NOTE: "proxy"-based Regions keep no local state.
*
* @param shortcut the client {@link ClientRegionShortcut} to evaluate.
* @return a boolean value indicating whether the client {@link ClientRegionShortcut} refers to
* a proxy-based shortcut.
* @return a boolean value indicating whether the client {@link ClientRegionShortcut}
* refers to a proxy-based shortcut.
* @see com.gemstone.gemfire.cache.client.ClientRegionShortcut
*/
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
* keep no local state.
* Determines whether the peer {@link RegionShortcut} is a proxy-based shortcut. NOTE:
* "proxy"-based Regions keep no local state.
*
* @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
*/
public static boolean isProxy(RegionShortcut shortcut) {

View File

@@ -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;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.data.domain.Sort;
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.query.Query;
import java.util.List;
/**
* Base class for serializing and deserializing session objects.
* To create custom serializer you have to implement this interface
* and simply register your class as a bean.
* Base class for serializing and deserializing session objects. To create custom
* serializer you have to implement this interface and simply register your class as a
* bean.
*
* @author Jakub Kubrynski
* @since 1.2
@@ -26,7 +42,7 @@ public abstract class AbstractMongoSessionConverter implements GenericConverter
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 indexValue value to query against
* @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);
/**
* Method ensures that there is a TTL index on {@literal expireAt} field.
* It's has {@literal expireAfterSeconds} set to zero seconds, so the expiration
* time is controlled by the application.
* Method ensures that there is a TTL index on {@literal expireAt} field. It's has
* {@literal expireAfterSeconds} set to zero seconds, so the expiration time is
* controlled by the application.
*
* It can be extended in custom converters when there is a need for creating
* additional custom indexes.
* @param sessionCollectionIndexes {@link IndexOperations} to use
*/
protected void ensureIndexes(IndexOperations sessionCollectionIndexes) {
List<IndexInfo> indexInfo = sessionCollectionIndexes.getIndexInfo();
for (IndexInfo info : indexInfo) {
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;
}
}
LOG.info("Creating TTL index on field " + EXPIRE_AT_FIELD_NAME);
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));
}
}

View File

@@ -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;
import org.springframework.expression.Expression;
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
*/
class AuthenticationParser {
final class AuthenticationParser {
private static final String NAME_EXPRESSION = "authentication?.name";
private static final SpelExpressionParser PARSER = new SpelExpressionParser();
/**
* Extracts principal name from authentication
* Extracts principal name from authentication.
*
* @param authentication Authentication object
* @return principal name
@@ -27,4 +42,7 @@ class AuthenticationParser {
}
return null;
}
private AuthenticationParser() {
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -15,15 +15,6 @@
*/
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.ByteArrayOutputStream;
import java.io.IOException;
@@ -35,11 +26,20 @@ import java.util.HashMap;
import java.util.Map;
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
* using standard Java serialization
* {@code AbstractMongoSessionConverter} implementation transforming.
* {@code MongoExpiringSession} to/from a BSON object using standard Java serialization
*
* @author Jakub Kubrynski
* @since 1.2
@@ -57,25 +57,30 @@ class JdkMongoSessionConverter extends AbstractMongoSessionConverter {
private static final String PRINCIPAL_FIELD_NAME = "principal";
private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
@Override
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 null;
}
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) {
return null;
}
if (DBObject.class.isAssignableFrom(sourceType.getType())) {
return convert((DBObject) source);
} else {
}
else {
return convert((MongoExpiringSession) source);
}
}
@@ -103,24 +108,29 @@ class JdkMongoSessionConverter extends AbstractMongoSessionConverter {
outputStream.writeObject(attributes);
outputStream.flush();
return out.toByteArray();
} catch (IOException e) {
}
catch (IOException e) {
LOG.error("Exception during session serialization", e);
throw new IllegalStateException("Cannot serialize session", e);
}
}
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) {
return resolvedPrincipal;
} else {
return expiringSession.getAttribute(PRINCIPAL_NAME_INDEX_NAME);
}
else {
return expiringSession.getAttribute(
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME);
}
}
private MongoExpiringSession convert(DBObject sessionWrapper) {
MongoExpiringSession session =
new MongoExpiringSession((String) sessionWrapper.get(ID), (Integer) sessionWrapper.get(MAX_INTERVAL));
MongoExpiringSession session = new MongoExpiringSession(
(String) sessionWrapper.get(ID),
(Integer) sessionWrapper.get(MAX_INTERVAL));
session.setCreationTime((Long) sessionWrapper.get(CREATION_TIME));
session.setLastAccessedTime((Long) sessionWrapper.get(LAST_ACCESSED_TIME));
session.setExpireAt((Date) sessionWrapper.get(EXPIRE_AT_FIELD_NAME));
@@ -131,17 +141,21 @@ class JdkMongoSessionConverter extends AbstractMongoSessionConverter {
@SuppressWarnings("unchecked")
private void deserializeAttributes(DBObject sessionWrapper, Session session) {
try {
ByteArrayInputStream in = new ByteArrayInputStream((byte[]) sessionWrapper.get(ATTRIBUTES));
ByteArrayInputStream in = new ByteArrayInputStream(
(byte[]) sessionWrapper.get(ATTRIBUTES));
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()) {
session.setAttribute(entry.getKey(), entry.getValue());
}
objectInputStream.close();
} catch (IOException e) {
}
catch (IOException e) {
LOG.error("Exception during session deserialization", e);
throw new IllegalStateException("Cannot deserialize session", e);
} catch (ClassNotFoundException e) {
}
catch (ClassNotFoundException e) {
LOG.error("Exception during session deserialization", e);
throw new IllegalStateException("Cannot deserialize session", e);
}

Some files were not shown because too many files have changed in this diff Show More