diff --git a/docs/src/test/java/docs/IndexDocTests.java b/docs/src/test/java/docs/IndexDocTests.java index 355e29f8..c4326600 100644 --- a/docs/src/test/java/docs/IndexDocTests.java +++ b/docs/src/test/java/docs/IndexDocTests.java @@ -22,7 +22,6 @@ import java.util.concurrent.ConcurrentHashMap; import com.hazelcast.config.Config; import com.hazelcast.core.Hazelcast; import com.hazelcast.core.HazelcastInstance; -import com.hazelcast.core.IMap; import org.junit.Test; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; @@ -155,11 +154,8 @@ public class IndexDocTests { HazelcastInstance hazelcastInstance = Hazelcast.newHazelcastInstance(config); - IMap sessions = hazelcastInstance - .getMap("spring:session:sessions"); - HazelcastSessionRepository repository = - new HazelcastSessionRepository(sessions); + new HazelcastSessionRepository(hazelcastInstance); // end::new-hazelcastsessionrepository[] } diff --git a/docs/src/test/java/docs/http/HazelcastHttpSessionConfig.java b/docs/src/test/java/docs/http/HazelcastHttpSessionConfig.java index 2075bd6d..c41ec021 100644 --- a/docs/src/test/java/docs/http/HazelcastHttpSessionConfig.java +++ b/docs/src/test/java/docs/http/HazelcastHttpSessionConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,7 +41,7 @@ public class HazelcastHttpSessionConfig { Config config = new Config(); - config.getMapConfig("spring:session:sessions") // <2> + config.getMapConfig(HazelcastSessionRepository.DEFAULT_SESSION_MAP_NAME) // <2> .addMapAttributeConfig(attributeConfig) .addMapIndexConfig(new MapIndexConfig( HazelcastSessionRepository.PRINCIPAL_NAME_ATTRIBUTE, false)); diff --git a/samples/javaconfig/hazelcast/src/main/java/sample/SessionConfig.java b/samples/javaconfig/hazelcast/src/main/java/sample/SessionConfig.java index 1451d09f..ab6a1845 100644 --- a/samples/javaconfig/hazelcast/src/main/java/sample/SessionConfig.java +++ b/samples/javaconfig/hazelcast/src/main/java/sample/SessionConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,7 +57,7 @@ public class SessionConfig { .setName(HazelcastSessionRepository.PRINCIPAL_NAME_ATTRIBUTE) .setExtractor(PrincipalNameExtractor.class.getName()); - config.getMapConfig("spring:session:sessions") + config.getMapConfig(HazelcastSessionRepository.DEFAULT_SESSION_MAP_NAME) .addMapAttributeConfig(attributeConfig) .addMapIndexConfig(new MapIndexConfig( HazelcastSessionRepository.PRINCIPAL_NAME_ATTRIBUTE, false)); diff --git a/spring-session-hazelcast/src/integration-test/java/org/springframework/session/hazelcast/AbstractHazelcastRepositoryITests.java b/spring-session-hazelcast/src/integration-test/java/org/springframework/session/hazelcast/AbstractHazelcastRepositoryITests.java index 0207dd58..1a8419be 100644 --- a/spring-session-hazelcast/src/integration-test/java/org/springframework/session/hazelcast/AbstractHazelcastRepositoryITests.java +++ b/spring-session-hazelcast/src/integration-test/java/org/springframework/session/hazelcast/AbstractHazelcastRepositoryITests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,8 +45,8 @@ public abstract class AbstractHazelcastRepositoryITests { HazelcastSession sessionToSave = this.repository.createSession(); String sessionId = sessionToSave.getId(); - IMap hazelcastMap = this.hazelcast.getMap( - "spring:session:sessions"); + IMap hazelcastMap = this.hazelcast + .getMap(HazelcastSessionRepository.DEFAULT_SESSION_MAP_NAME); assertThat(hazelcastMap.size()).isEqualTo(0); @@ -80,9 +80,11 @@ public abstract class AbstractHazelcastRepositoryITests { assertThat(this.repository.findById(originalFindById)).isNull(); - HazelcastSession findByChangeSessionId = this.repository.findById(changeSessionId); + HazelcastSession findByChangeSessionId = this.repository + .findById(changeSessionId); - assertThat(findByChangeSessionId.getAttribute(attrName)).isEqualTo(attrValue); + assertThat(findByChangeSessionId.getAttribute(attrName)) + .isEqualTo(attrValue); this.repository.deleteById(changeSessionId); } @@ -126,9 +128,11 @@ public abstract class AbstractHazelcastRepositoryITests { assertThat(this.repository.findById(originalFindById)).isNull(); - HazelcastSession findByChangeSessionId = this.repository.findById(changeSessionId); + HazelcastSession findByChangeSessionId = this.repository + .findById(changeSessionId); - assertThat(findByChangeSessionId.getAttribute(attrName)).isEqualTo(attrValue); + assertThat(findByChangeSessionId.getAttribute(attrName)) + .isEqualTo(attrValue); this.repository.deleteById(changeSessionId); } diff --git a/spring-session-hazelcast/src/integration-test/java/org/springframework/session/hazelcast/HazelcastITestUtils.java b/spring-session-hazelcast/src/integration-test/java/org/springframework/session/hazelcast/HazelcastITestUtils.java index 119232cd..e7297022 100644 --- a/spring-session-hazelcast/src/integration-test/java/org/springframework/session/hazelcast/HazelcastITestUtils.java +++ b/spring-session-hazelcast/src/integration-test/java/org/springframework/session/hazelcast/HazelcastITestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,7 +49,7 @@ public final class HazelcastITestUtils { config.getNetworkConfig() .setPort(port); - config.getMapConfig("spring:session:sessions") + config.getMapConfig(HazelcastSessionRepository.DEFAULT_SESSION_MAP_NAME) .addMapAttributeConfig(attributeConfig) .addMapIndexConfig(new MapIndexConfig( HazelcastSessionRepository.PRINCIPAL_NAME_ATTRIBUTE, false)); diff --git a/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/HazelcastSessionRepository.java b/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/HazelcastSessionRepository.java index 0078657a..78b418c6 100644 --- a/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/HazelcastSessionRepository.java +++ b/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/HazelcastSessionRepository.java @@ -29,6 +29,7 @@ import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import com.hazelcast.core.EntryEvent; +import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.IMap; import com.hazelcast.map.AbstractEntryProcessor; import com.hazelcast.map.EntryProcessor; @@ -64,11 +65,8 @@ import org.springframework.util.Assert; * * HazelcastInstance hazelcastInstance = Hazelcast.newHazelcastInstance(config); * - * IMap{@code } sessions = hazelcastInstance - * .getMap("spring:session:sessions"); - * * HazelcastSessionRepository sessionRepository = - * new HazelcastSessionRepository(sessions); + * new HazelcastSessionRepository(hazelcastInstance); * * * In order to support finding sessions by principal name using @@ -85,7 +83,7 @@ import org.springframework.util.Assert; * * Config config = new Config(); * - * config.getMapConfig("spring:session:sessions") + * config.getMapConfig(HazelcastSessionRepository.DEFAULT_SESSION_MAP_NAME) * .addMapAttributeConfig(attributeConfig) * .addMapIndexConfig(new MapIndexConfig( * HazelcastSessionRepository.PRINCIPAL_NAME_ATTRIBUTE, false)); @@ -111,10 +109,14 @@ import org.springframework.util.Assert; */ public class HazelcastSessionRepository implements FindByIndexNameSessionRepository, - EntryAddedListener, - EntryEvictedListener, + EntryAddedListener, EntryEvictedListener, EntryRemovedListener { + /** + * The default name of map used by Spring Session to store sessions. + */ + public static final String DEFAULT_SESSION_MAP_NAME = "spring:session:sessions"; + /** * The principal name custom attribute name. */ @@ -122,9 +124,7 @@ public class HazelcastSessionRepository implements private static final Log logger = LogFactory.getLog(HazelcastSessionRepository.class); - private final IMap sessions; - - private HazelcastFlushMode hazelcastFlushMode = HazelcastFlushMode.ON_SAVE; + private final HazelcastInstance hazelcastInstance; private ApplicationEventPublisher eventPublisher = new ApplicationEventPublisher() { @@ -144,20 +144,27 @@ public class HazelcastSessionRepository implements */ private Integer defaultMaxInactiveInterval; + private String sessionMapName = DEFAULT_SESSION_MAP_NAME; + + private HazelcastFlushMode hazelcastFlushMode = HazelcastFlushMode.ON_SAVE; + + private IMap sessions; + private String sessionListenerId; - public HazelcastSessionRepository(IMap sessions) { - Assert.notNull(sessions, "Sessions IMap must not be null"); - this.sessions = sessions; + public HazelcastSessionRepository(HazelcastInstance hazelcastInstance) { + Assert.notNull(hazelcastInstance, "HazelcastInstance must not be null"); + this.hazelcastInstance = hazelcastInstance; } @PostConstruct - private void init() { + public void init() { + this.sessions = this.hazelcastInstance.getMap(this.sessionMapName); this.sessionListenerId = this.sessions.addEntryListener(this, true); } @PreDestroy - private void close() { + public void close() { this.sessions.removeEntryListener(this.sessionListenerId); } @@ -186,6 +193,15 @@ public class HazelcastSessionRepository implements this.defaultMaxInactiveInterval = defaultMaxInactiveInterval; } + /** + * Set the name of map used to store sessions. + * @param sessionMapName the session map name + */ + public void setSessionMapName(String sessionMapName) { + Assert.hasText(sessionMapName, "Map name must not be empty"); + this.sessionMapName = sessionMapName; + } + /** * Sets the Hazelcast flush mode. Default flush mode is * {@link HazelcastFlushMode#ON_SAVE}. @@ -217,8 +233,8 @@ public class HazelcastSessionRepository implements session.getMaxInactiveInterval().getSeconds(), TimeUnit.SECONDS); } else if (session.changed) { - this.sessions.executeOnKey(session.getId(), - new SessionUpdateEntryProcessor(session.getDelegate(), session.delta)); + this.sessions.executeOnKey(session.getId(), new SessionUpdateEntryProcessor( + session.getDelegate(), session.delta)); } session.clearFlags(); } @@ -242,15 +258,14 @@ public class HazelcastSessionRepository implements } @Override - public Map findByIndexNameAndIndexValue( - String indexName, String indexValue) { + public Map findByIndexNameAndIndexValue(String indexName, + String indexValue) { if (!PRINCIPAL_NAME_INDEX_NAME.equals(indexName)) { return Collections.emptyMap(); } - Collection sessions = this.sessions.values( - Predicates.equal(PRINCIPAL_NAME_ATTRIBUTE, indexValue)); - Map sessionMap = new HashMap<>( - sessions.size()); + Collection sessions = this.sessions + .values(Predicates.equal(PRINCIPAL_NAME_ATTRIBUTE, indexValue)); + Map sessionMap = new HashMap<>(sessions.size()); for (MapSession session : sessions) { sessionMap.put(session.getId(), new HazelcastSession(session)); } diff --git a/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/config/annotation/web/http/EnableHazelcastHttpSession.java b/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/config/annotation/web/http/EnableHazelcastHttpSession.java index 9914163a..a05fd076 100644 --- a/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/config/annotation/web/http/EnableHazelcastHttpSession.java +++ b/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/config/annotation/web/http/EnableHazelcastHttpSession.java @@ -31,6 +31,7 @@ import org.springframework.session.Session; import org.springframework.session.SessionRepository; import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession; import org.springframework.session.hazelcast.HazelcastFlushMode; +import org.springframework.session.hazelcast.HazelcastSessionRepository; import org.springframework.session.web.http.SessionRepositoryFilter; /** @@ -58,6 +59,7 @@ import org.springframework.session.web.http.SessionRepositoryFilter; * * @author Tommy Ludwig * @author Aleksandar Stojsavljevic + * @author Vedran Pavic * @since 1.1 * @see EnableSpringHttpSession */ @@ -78,10 +80,10 @@ public @interface EnableHazelcastHttpSession { /** * This is the name of the Map that will be used in Hazelcast to store the session * data. Default is - * {@link HazelcastHttpSessionConfiguration#DEFAULT_SESSION_MAP_NAME}. + * {@link HazelcastSessionRepository#DEFAULT_SESSION_MAP_NAME}. * @return the name of the Map to store the sessions in Hazelcast */ - String sessionMapName() default HazelcastHttpSessionConfiguration.DEFAULT_SESSION_MAP_NAME; + String sessionMapName() default HazelcastSessionRepository.DEFAULT_SESSION_MAP_NAME; /** * Flush mode for the Hazelcast sessions. The default is {@code ON_SAVE} which only diff --git a/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/config/annotation/web/http/HazelcastHttpSessionConfiguration.java b/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/config/annotation/web/http/HazelcastHttpSessionConfiguration.java index e4acc554..dc9c5da7 100644 --- a/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/config/annotation/web/http/HazelcastHttpSessionConfiguration.java +++ b/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/config/annotation/web/http/HazelcastHttpSessionConfiguration.java @@ -19,7 +19,6 @@ package org.springframework.session.hazelcast.config.annotation.web.http; import java.util.Map; import com.hazelcast.core.HazelcastInstance; -import com.hazelcast.core.IMap; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Autowired; @@ -51,11 +50,9 @@ import org.springframework.util.StringUtils; public class HazelcastHttpSessionConfiguration extends SpringHttpSessionConfiguration implements ImportAware { - static final String DEFAULT_SESSION_MAP_NAME = "spring:session:sessions"; + private Integer maxInactiveIntervalInSeconds = MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS; - private Integer maxInactiveIntervalInSeconds; - - private String sessionMapName = DEFAULT_SESSION_MAP_NAME; + private String sessionMapName = HazelcastSessionRepository.DEFAULT_SESSION_MAP_NAME; private HazelcastFlushMode hazelcastFlushMode = HazelcastFlushMode.ON_SAVE; @@ -65,11 +62,12 @@ public class HazelcastHttpSessionConfiguration extends SpringHttpSessionConfigur @Bean public HazelcastSessionRepository sessionRepository() { - IMap sessions = this.hazelcastInstance - .getMap(this.sessionMapName); HazelcastSessionRepository sessionRepository = new HazelcastSessionRepository( - sessions); + this.hazelcastInstance); sessionRepository.setApplicationEventPublisher(this.applicationEventPublisher); + if (StringUtils.hasText(this.sessionMapName)) { + sessionRepository.setSessionMapName(this.sessionMapName); + } sessionRepository .setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds); sessionRepository.setHazelcastFlushMode(this.hazelcastFlushMode); diff --git a/spring-session-hazelcast/src/test/java/org/springframework/session/hazelcast/HazelcastSessionRepositoryTests.java b/spring-session-hazelcast/src/test/java/org/springframework/session/hazelcast/HazelcastSessionRepositoryTests.java index 28e97909..7d413d2b 100644 --- a/spring-session-hazelcast/src/test/java/org/springframework/session/hazelcast/HazelcastSessionRepositoryTests.java +++ b/spring-session-hazelcast/src/test/java/org/springframework/session/hazelcast/HazelcastSessionRepositoryTests.java @@ -23,8 +23,10 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; +import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.IMap; import com.hazelcast.map.EntryProcessor; +import com.hazelcast.map.listener.MapListener; import com.hazelcast.query.impl.predicates.EqualPredicate; import org.junit.Before; import org.junit.Rule; @@ -43,6 +45,8 @@ import org.springframework.session.hazelcast.HazelcastSessionRepository.Hazelcas import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isA; import static org.mockito.BDDMockito.given; @@ -64,6 +68,9 @@ public class HazelcastSessionRepositoryTests { @Rule public ExpectedException thrown = ExpectedException.none(); + @Mock + private HazelcastInstance hazelcastInstance; + @Mock private IMap sessions; @@ -71,19 +78,25 @@ public class HazelcastSessionRepositoryTests { @Before public void setUp() { - this.repository = new HazelcastSessionRepository(this.sessions); + given(this.hazelcastInstance.getMap(anyString())) + .willReturn(this.sessions); + this.repository = new HazelcastSessionRepository(this.hazelcastInstance); + this.repository.init(); } @Test public void constructorNullHazelcastInstance() { this.thrown.expect(IllegalArgumentException.class); - this.thrown.expectMessage("Sessions IMap must not be null"); + this.thrown.expectMessage("HazelcastInstance must not be null"); new HazelcastSessionRepository(null); } @Test public void createSessionDefaultMaxInactiveInterval() throws Exception { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + HazelcastSession session = this.repository.createSession(); assertThat(session.getMaxInactiveInterval()) @@ -93,6 +106,9 @@ public class HazelcastSessionRepositoryTests { @Test public void createSessionCustomMaxInactiveInterval() throws Exception { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + int interval = 1; this.repository.setDefaultMaxInactiveInterval(interval); @@ -105,42 +121,57 @@ public class HazelcastSessionRepositoryTests { @Test public void saveNewFlushModeOnSave() { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + HazelcastSession session = this.repository.createSession(); verifyZeroInteractions(this.sessions); this.repository.save(session); - verify(this.sessions, times(1)).set(eq(session.getId()), eq(session.getDelegate()), - isA(Long.class), eq(TimeUnit.SECONDS)); + verify(this.sessions, times(1)).set(eq(session.getId()), + eq(session.getDelegate()), isA(Long.class), eq(TimeUnit.SECONDS)); + verifyZeroInteractions(this.sessions); } @Test public void saveNewFlushModeImmediate() { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + this.repository.setHazelcastFlushMode(HazelcastFlushMode.IMMEDIATE); HazelcastSession session = this.repository.createSession(); - verify(this.sessions, times(1)).set(eq(session.getId()), eq(session.getDelegate()), - isA(Long.class), eq(TimeUnit.SECONDS)); + verify(this.sessions, times(1)).set(eq(session.getId()), + eq(session.getDelegate()), isA(Long.class), eq(TimeUnit.SECONDS)); + verifyZeroInteractions(this.sessions); } @Test public void saveUpdatedAttributeFlushModeOnSave() { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + HazelcastSession session = this.repository.createSession(); session.setAttribute("testName", "testValue"); verifyZeroInteractions(this.sessions); this.repository.save(session); - verify(this.sessions, times(1)).set(eq(session.getId()), eq(session.getDelegate()), - isA(Long.class), eq(TimeUnit.SECONDS)); + verify(this.sessions, times(1)).set(eq(session.getId()), + eq(session.getDelegate()), isA(Long.class), eq(TimeUnit.SECONDS)); + verifyZeroInteractions(this.sessions); } @Test public void saveUpdatedAttributeFlushModeImmediate() { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + this.repository.setHazelcastFlushMode(HazelcastFlushMode.IMMEDIATE); HazelcastSession session = this.repository.createSession(); session.setAttribute("testName", "testValue"); - verify(this.sessions, times(1)).set(eq(session.getId()), eq(session.getDelegate()), - isA(Long.class), eq(TimeUnit.SECONDS)); + verify(this.sessions, times(1)).set(eq(session.getId()), + eq(session.getDelegate()), isA(Long.class), eq(TimeUnit.SECONDS)); verify(this.sessions, times(1)).executeOnKey(eq(session.getId()), any(EntryProcessor.class)); @@ -150,23 +181,30 @@ public class HazelcastSessionRepositoryTests { @Test public void removeAttributeFlushModeOnSave() { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + HazelcastSession session = this.repository.createSession(); session.removeAttribute("testName"); verifyZeroInteractions(this.sessions); this.repository.save(session); - verify(this.sessions, times(1)).set(eq(session.getId()), eq(session.getDelegate()), - isA(Long.class), eq(TimeUnit.SECONDS)); + verify(this.sessions, times(1)).set(eq(session.getId()), + eq(session.getDelegate()), isA(Long.class), eq(TimeUnit.SECONDS)); + verifyZeroInteractions(this.sessions); } @Test public void removeAttributeFlushModeImmediate() { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + this.repository.setHazelcastFlushMode(HazelcastFlushMode.IMMEDIATE); HazelcastSession session = this.repository.createSession(); session.removeAttribute("testName"); - verify(this.sessions, times(1)).set(eq(session.getId()), eq(session.getDelegate()), - isA(Long.class), eq(TimeUnit.SECONDS)); + verify(this.sessions, times(1)).set(eq(session.getId()), + eq(session.getDelegate()), isA(Long.class), eq(TimeUnit.SECONDS)); verify(this.sessions, times(1)).executeOnKey(eq(session.getId()), any(EntryProcessor.class)); @@ -176,23 +214,30 @@ public class HazelcastSessionRepositoryTests { @Test public void saveUpdatedLastAccessedTimeFlushModeOnSave() { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + HazelcastSession session = this.repository.createSession(); session.setLastAccessedTime(Instant.now()); verifyZeroInteractions(this.sessions); this.repository.save(session); - verify(this.sessions, times(1)).set(eq(session.getId()), eq(session.getDelegate()), - isA(Long.class), eq(TimeUnit.SECONDS)); + verify(this.sessions, times(1)).set(eq(session.getId()), + eq(session.getDelegate()), isA(Long.class), eq(TimeUnit.SECONDS)); + verifyZeroInteractions(this.sessions); } @Test public void saveUpdatedLastAccessedTimeFlushModeImmediate() { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + this.repository.setHazelcastFlushMode(HazelcastFlushMode.IMMEDIATE); HazelcastSession session = this.repository.createSession(); session.setLastAccessedTime(Instant.now()); - verify(this.sessions, times(1)).set(eq(session.getId()), eq(session.getDelegate()), - isA(Long.class), eq(TimeUnit.SECONDS)); + verify(this.sessions, times(1)).set(eq(session.getId()), + eq(session.getDelegate()), isA(Long.class), eq(TimeUnit.SECONDS)); verify(this.sessions, times(1)).executeOnKey(eq(session.getId()), any(EntryProcessor.class)); @@ -202,23 +247,30 @@ public class HazelcastSessionRepositoryTests { @Test public void saveUpdatedMaxInactiveIntervalInSecondsFlushModeOnSave() { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + HazelcastSession session = this.repository.createSession(); session.setMaxInactiveInterval(Duration.ofSeconds(1)); verifyZeroInteractions(this.sessions); this.repository.save(session); - verify(this.sessions, times(1)).set(eq(session.getId()), eq(session.getDelegate()), - isA(Long.class), eq(TimeUnit.SECONDS)); + verify(this.sessions, times(1)).set(eq(session.getId()), + eq(session.getDelegate()), isA(Long.class), eq(TimeUnit.SECONDS)); + verifyZeroInteractions(this.sessions); } @Test public void saveUpdatedMaxInactiveIntervalInSecondsFlushModeImmediate() { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + this.repository.setHazelcastFlushMode(HazelcastFlushMode.IMMEDIATE); HazelcastSession session = this.repository.createSession(); session.setMaxInactiveInterval(Duration.ofSeconds(1)); - verify(this.sessions, times(1)).set(eq(session.getId()), eq(session.getDelegate()), - isA(Long.class), eq(TimeUnit.SECONDS)); + verify(this.sessions, times(1)).set(eq(session.getId()), + eq(session.getDelegate()), isA(Long.class), eq(TimeUnit.SECONDS)); verify(this.sessions, times(1)).executeOnKey(eq(session.getId()), any(EntryProcessor.class)); @@ -228,10 +280,13 @@ public class HazelcastSessionRepositoryTests { @Test public void saveUnchangedFlushModeOnSave() { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + HazelcastSession session = this.repository.createSession(); this.repository.save(session); - verify(this.sessions, times(1)).set(eq(session.getId()), eq(session.getDelegate()), - isA(Long.class), eq(TimeUnit.SECONDS)); + verify(this.sessions, times(1)).set(eq(session.getId()), + eq(session.getDelegate()), isA(Long.class), eq(TimeUnit.SECONDS)); this.repository.save(session); verifyZeroInteractions(this.sessions); @@ -239,11 +294,14 @@ public class HazelcastSessionRepositoryTests { @Test public void saveUnchangedFlushModeImmediate() { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + this.repository.setHazelcastFlushMode(HazelcastFlushMode.IMMEDIATE); HazelcastSession session = this.repository.createSession(); - verify(this.sessions, times(1)).set(eq(session.getId()), eq(session.getDelegate()), - isA(Long.class), eq(TimeUnit.SECONDS)); + verify(this.sessions, times(1)).set(eq(session.getId()), + eq(session.getDelegate()), isA(Long.class), eq(TimeUnit.SECONDS)); this.repository.save(session); verifyZeroInteractions(this.sessions); @@ -251,19 +309,26 @@ public class HazelcastSessionRepositoryTests { @Test public void getSessionNotFound() { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + String sessionId = "testSessionId"; HazelcastSession session = this.repository.findById(sessionId); assertThat(session).isNull(); verify(this.sessions, times(1)).get(eq(sessionId)); + verifyZeroInteractions(this.sessions); } @Test public void getSessionExpired() { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + MapSession expired = new MapSession(); - expired.setLastAccessedTime(Instant.now().minusSeconds( - MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS + 1)); + expired.setLastAccessedTime(Instant.now() + .minusSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS + 1)); given(this.sessions.get(eq(expired.getId()))).willReturn(expired); HazelcastSession session = this.repository.findById(expired.getId()); @@ -271,10 +336,14 @@ public class HazelcastSessionRepositoryTests { assertThat(session).isNull(); verify(this.sessions, times(1)).get(eq(expired.getId())); verify(this.sessions, times(1)).remove(eq(expired.getId())); + verifyZeroInteractions(this.sessions); } @Test public void getSessionFound() { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + MapSession saved = new MapSession(); saved.setAttribute("savedName", "savedValue"); given(this.sessions.get(eq(saved.getId()))).willReturn(saved); @@ -284,23 +353,31 @@ public class HazelcastSessionRepositoryTests { assertThat(session.getId()).isEqualTo(saved.getId()); assertThat(session.getAttribute("savedName")).isEqualTo("savedValue"); verify(this.sessions, times(1)).get(eq(saved.getId())); + verifyZeroInteractions(this.sessions); } @Test public void delete() { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + String sessionId = "testSessionId"; this.repository.deleteById(sessionId); verify(this.sessions, times(1)).remove(eq(sessionId)); + verifyZeroInteractions(this.sessions); } @Test public void findByIndexNameAndIndexValueUnknownIndexName() { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + String indexValue = "testIndexValue"; - Map sessions = this.repository.findByIndexNameAndIndexValue( - "testIndexName", indexValue); + Map sessions = this.repository + .findByIndexNameAndIndexValue("testIndexName", indexValue); assertThat(sessions).isEmpty(); verifyZeroInteractions(this.sessions); @@ -308,17 +385,26 @@ public class HazelcastSessionRepositoryTests { @Test public void findByIndexNameAndIndexValuePrincipalIndexNameNotFound() { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + String principal = "username"; - Map sessions = this.repository.findByIndexNameAndIndexValue( - FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, principal); + Map sessions = this.repository + .findByIndexNameAndIndexValue( + FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, + principal); assertThat(sessions).isEmpty(); verify(this.sessions, times(1)).values(isA(EqualPredicate.class)); + verifyZeroInteractions(this.sessions); } @Test public void findByIndexNameAndIndexValuePrincipalIndexNameFound() { + verify(this.sessions, times(1)).addEntryListener(any(MapListener.class), + anyBoolean()); + String principal = "username"; Authentication authentication = new UsernamePasswordAuthenticationToken(principal, "notused", AuthorityUtils.createAuthorityList("ROLE_USER")); @@ -331,11 +417,14 @@ public class HazelcastSessionRepositoryTests { saved.add(saved2); given(this.sessions.values(isA(EqualPredicate.class))).willReturn(saved); - Map sessions = this.repository.findByIndexNameAndIndexValue( - FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, principal); + Map sessions = this.repository + .findByIndexNameAndIndexValue( + FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, + principal); assertThat(sessions).hasSize(2); verify(this.sessions, times(1)).values(isA(EqualPredicate.class)); + verifyZeroInteractions(this.sessions); } }