Support configuring maximum number of sessions for reactive server

Signed-off-by: John Niang <johnniang@foxmail.com>

See gh-38703
This commit is contained in:
John Niang 2023-12-10 00:19:26 +08:00 committed by Moritz Halbritter
parent d2a3c8703a
commit 49c6bacd44
3 changed files with 44 additions and 1 deletions

View File

@ -329,6 +329,11 @@ public class ServerProperties {
@DurationUnit(ChronoUnit.SECONDS)
private Duration timeout = Duration.ofMinutes(30);
/**
* The maximum number of sessions that can be stored.
*/
private int maxSessions = 10_000;
@NestedConfigurationProperty
private final Cookie cookie = new Cookie();
@ -340,6 +345,14 @@ public class ServerProperties {
this.timeout = timeout;
}
public int getMaxSessions() {
return this.maxSessions;
}
public void setMaxSessions(int maxSessions) {
this.maxSessions = maxSessions;
}
public Cookie getCookie() {
return this.cookie;
}

View File

@ -332,7 +332,10 @@ public class WebFluxAutoConfiguration {
public WebSessionManager webSessionManager(ObjectProvider<WebSessionIdResolver> webSessionIdResolver) {
DefaultWebSessionManager webSessionManager = new DefaultWebSessionManager();
Duration timeout = this.serverProperties.getReactive().getSession().getTimeout();
webSessionManager.setSessionStore(new MaxIdleTimeInMemoryWebSessionStore(timeout));
int maxSessions = this.serverProperties.getReactive().getSession().getMaxSessions();
MaxIdleTimeInMemoryWebSessionStore sessionStore = new MaxIdleTimeInMemoryWebSessionStore(timeout);
sessionStore.setMaxSessions(maxSessions);
webSessionManager.setSessionStore(sessionStore);
webSessionIdResolver.ifAvailable(webSessionManager::setSessionIdResolver);
return webSessionManager;
}

View File

@ -109,8 +109,11 @@ import org.springframework.web.server.i18n.AcceptHeaderLocaleContextResolver;
import org.springframework.web.server.i18n.FixedLocaleContextResolver;
import org.springframework.web.server.i18n.LocaleContextResolver;
import org.springframework.web.server.session.CookieWebSessionIdResolver;
import org.springframework.web.server.session.DefaultWebSessionManager;
import org.springframework.web.server.session.InMemoryWebSessionStore;
import org.springframework.web.server.session.WebSessionIdResolver;
import org.springframework.web.server.session.WebSessionManager;
import org.springframework.web.server.session.WebSessionStore;
import org.springframework.web.util.pattern.PathPattern;
import static org.assertj.core.api.Assertions.assertThat;
@ -622,6 +625,20 @@ class WebFluxAutoConfigurationTests {
})));
}
@Test
void customSessionMaxSessionsConfigurationShouldBeApplied() {
this.contextRunner.withPropertyValues("server.reactive.session.max-sessions:123")
.run((context) -> assertMaxSessionsWithWebSession(123));
}
@Test
void defaultSessionMaxSessionsConfigurationShouldBeInSync() {
this.contextRunner.run((context) -> {
int defaultMaxSessions = new InMemoryWebSessionStore().getMaxSessions();
assertMaxSessionsWithWebSession(defaultMaxSessions);
});
}
@Test
void customSessionCookieConfigurationShouldBeApplied() {
this.contextRunner.withPropertyValues("server.reactive.session.cookie.name:JSESSIONID",
@ -753,6 +770,16 @@ class WebFluxAutoConfigurationTests {
};
}
private ContextConsumer<ReactiveWebApplicationContext> assertMaxSessionsWithWebSession(int maxSessions) {
return (context) -> {
WebSessionManager sessionManager = context.getBean(WebSessionManager.class);
assertThat(sessionManager).isInstanceOf(DefaultWebSessionManager.class);
WebSessionStore sessionStore = ((DefaultWebSessionManager) sessionManager).getSessionStore();
assertThat(sessionStore).isInstanceOf(InMemoryWebSessionStore.class);
assertThat(((InMemoryWebSessionStore) sessionStore).getMaxSessions()).isEqualTo(maxSessions);
};
}
private Map<PathPattern, Object> getHandlerMap(ApplicationContext context) {
HandlerMapping mapping = context.getBean("resourceHandlerMapping", HandlerMapping.class);
if (mapping instanceof SimpleUrlHandlerMapping simpleMapping) {