Skip to content

Commit f00a1b9

Browse files
committed
Fix HazelcastSessionRepository to update TTL when maxInactiveInterval is changed
Resolves: #1300
1 parent 39cecb0 commit f00a1b9

File tree

3 files changed

+42
-5
lines changed

3 files changed

+42
-5
lines changed

spring-session-hazelcast/src/integration-test/java/org/springframework/session/hazelcast/config/annotation/web/http/EnableHazelcastHttpSessionEventsTests.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2018 the original author or authors.
2+
* Copyright 2014-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -181,6 +181,28 @@ public void changeSessionIdNoEventTest() throws InterruptedException {
181181
assertThat(this.registry.receivedEvent(sessionToSave.getId())).isFalse();
182182
}
183183

184+
@Test // gh-1300
185+
public void updateMaxInactiveIntervalTest() throws InterruptedException {
186+
S sessionToSave = this.repository.createSession();
187+
sessionToSave.setMaxInactiveInterval(Duration.ofMinutes(30));
188+
this.repository.save(sessionToSave);
189+
190+
assertThat(this.registry.receivedEvent(sessionToSave.getId())).isTrue();
191+
assertThat(this.registry.<SessionCreatedEvent>getEvent(sessionToSave.getId()))
192+
.isInstanceOf(SessionCreatedEvent.class);
193+
this.registry.clear();
194+
195+
S sessionToUpdate = this.repository.findById(sessionToSave.getId());
196+
sessionToUpdate.setLastAccessedTime(Instant.now());
197+
sessionToUpdate.setMaxInactiveInterval(Duration.ofSeconds(1));
198+
this.repository.save(sessionToUpdate);
199+
200+
assertThat(this.registry.receivedEvent(sessionToUpdate.getId())).isTrue();
201+
assertThat(this.registry.<SessionExpiredEvent>getEvent(sessionToUpdate.getId()))
202+
.isInstanceOf(SessionExpiredEvent.class);
203+
assertThat(this.repository.findById(sessionToUpdate.getId())).isNull();
204+
}
205+
184206
@Configuration
185207
@EnableHazelcastHttpSession(maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
186208
static class HazelcastSessionConfig {

spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/HazelcastSessionRepository.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2018 the original author or authors.
2+
* Copyright 2014-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -48,6 +48,7 @@
4848
import org.springframework.session.events.SessionDeletedEvent;
4949
import org.springframework.session.events.SessionExpiredEvent;
5050
import org.springframework.util.Assert;
51+
import org.springframework.util.ClassUtils;
5152

5253
/**
5354
* A {@link org.springframework.session.SessionRepository} implementation that stores
@@ -120,6 +121,9 @@ public class HazelcastSessionRepository implements
120121
*/
121122
public static final String PRINCIPAL_NAME_ATTRIBUTE = "principalName";
122123

124+
private static final boolean SUPPORTS_SET_TTL = ClassUtils
125+
.hasAtLeastOneMethodWithName(IMap.class, "setTtl");
126+
123127
private static final Log logger = LogFactory.getLog(HazelcastSessionRepository.class);
124128

125129
private final HazelcastInstance hazelcastInstance;
@@ -238,6 +242,9 @@ else if (session.hasChanges()) {
238242
entryProcessor.setLastAccessedTime(session.getLastAccessedTime());
239243
}
240244
if (session.maxInactiveIntervalChanged) {
245+
if (SUPPORTS_SET_TTL) {
246+
updateTtl(session);
247+
}
241248
entryProcessor.setMaxInactiveInterval(session.getMaxInactiveInterval());
242249
}
243250
if (!session.delta.isEmpty()) {
@@ -248,6 +255,11 @@ else if (session.hasChanges()) {
248255
session.clearChangeFlags();
249256
}
250257

258+
private void updateTtl(HazelcastSession session) {
259+
this.sessions.setTtl(session.getId(),
260+
session.getMaxInactiveInterval().getSeconds(), TimeUnit.SECONDS);
261+
}
262+
251263
@Override
252264
public HazelcastSession findById(String id) {
253265
MapSession saved = this.sessions.get(id);

spring-session-hazelcast/src/test/java/org/springframework/session/hazelcast/HazelcastSessionRepositoryTests.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2018 the original author or authors.
2+
* Copyright 2014-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -42,6 +42,7 @@
4242
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
4343
import static org.mockito.ArgumentMatchers.any;
4444
import static org.mockito.ArgumentMatchers.anyBoolean;
45+
import static org.mockito.ArgumentMatchers.anyLong;
4546
import static org.mockito.ArgumentMatchers.anyString;
4647
import static org.mockito.ArgumentMatchers.eq;
4748
import static org.mockito.ArgumentMatchers.isA;
@@ -259,10 +260,12 @@ public void saveUpdatedMaxInactiveIntervalInSecondsFlushModeImmediate() {
259260
this.repository.setHazelcastFlushMode(HazelcastFlushMode.IMMEDIATE);
260261

261262
HazelcastSession session = this.repository.createSession();
263+
String sessionId = session.getId();
262264
session.setMaxInactiveInterval(Duration.ofSeconds(1));
263-
verify(this.sessions, times(1)).set(eq(session.getId()),
265+
verify(this.sessions, times(1)).set(eq(sessionId),
264266
eq(session.getDelegate()), isA(Long.class), eq(TimeUnit.SECONDS));
265-
verify(this.sessions, times(1)).executeOnKey(eq(session.getId()),
267+
verify(this.sessions).setTtl(eq(sessionId), anyLong(), any());
268+
verify(this.sessions, times(1)).executeOnKey(eq(sessionId),
266269
any(EntryProcessor.class));
267270

268271
this.repository.save(session);

0 commit comments

Comments
 (0)