At present, Actuator sessions endpoint is supported only on a Servlet stack and also requires an indexed session repository. With Spring Session moving to non-indexed session repositories as a default for some session stores, this means that sessions endpoint won't be available unless users opt into a (non-default) indexed session repository.
This commit updates SessionEndpoint so that it is able to work with a non-indexed session repository. In such setup, it exposes operations for fetching session by id and deleting the session.
Additionally, this also adds support for reactive stack by introducing ReactiveSessionEndpoint and its auto-configuration support.
Closes gh-10827
Comment From: vpavic
This is now ready for review.
Note @wilkinsona that :spring-boot-project:spring-boot-docs:asciidoctor* tasks are failing due a problem that seems related with the two different @Endpoints having the same id (as discussed in https://github.com/spring-projects/spring-boot/issues/10827#issuecomment-1209664435). You should see this failure in the CI as well:
> Task :spring-boot-project:spring-boot-docs:asciidoctor
2022-08-12T18:45:28.138+02:00 [main] WARN FilenoUtil : Native subprocess control requires open access to the JDK IO subsystem
Pass '--add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED' to enable.
Exception in thread "main" java.lang.IllegalStateException: Duplicate key management.endpoint.sessions.enabled (attempted merging values io.spring.asciidoctor.springboot.ConfigurationProperty@272f5373 and io.spring.asciidoctor.springboot.ConfigurationProperty@799557c8)
at java.base/java.util.stream.Collectors.duplicateKeyException(Collectors.java:135)
at java.base/java.util.stream.Collectors.lambda$uniqKeysMapAccumulator$1(Collectors.java:182)
at java.base/java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
at io.spring.asciidoctor.springboot.ConfigurationProperties.<init>(ConfigurationProperties.java:49)
at io.spring.asciidoctor.springboot.ConfigurationProperties.fromClasspath(ConfigurationProperties.java:98)
at io.spring.asciidoctor.springboot.ConfigurationPropertyValidator.<init>(ConfigurationPropertyValidator.java:39)
at io.spring.asciidoctor.springboot.ConfigurationPropertyInlineMacroProcessor.<init>(ConfigurationPropertyInlineMacroProcessor.java:37)
at io.spring.asciidoctor.springboot.SpringBootExtensionRegistry.register(SpringBootExtensionRegistry.java:37)
at org.asciidoctor.jruby.extension.internal.ExtensionRegistryExecutor.registerAllExtensions(ExtensionRegistryExecutor.java:21)
at org.asciidoctor.jruby.internal.JRubyAsciidoctor.registerExtensions(JRubyAsciidoctor.java:104)
at org.asciidoctor.jruby.internal.JRubyAsciidoctor.processRegistrations(JRubyAsciidoctor.java:89)
at org.asciidoctor.jruby.internal.JRubyAsciidoctor.create(JRubyAsciidoctor.java:69)
at org.asciidoctor.jruby.internal.JRubyAsciidoctor.create(JRubyAsciidoctor.java:65)
at org.asciidoctor.jruby.AsciidoctorJRuby$Factory.create(AsciidoctorJRuby.java:29)
at org.asciidoctor.gradle.remote.AsciidoctorJavaExec.getAsciidoctorInstance(AsciidoctorJavaExec.groovy:101)
at org.asciidoctor.gradle.remote.AsciidoctorJavaExec.run(AsciidoctorJavaExec.groovy:59)
at org.asciidoctor.gradle.remote.AsciidoctorJavaExec.main(AsciidoctorJavaExec.groovy:49)
Comment From: wilkinsona
As part of merging this, we'll need to figure out what to do about the two endpoints with the same ID. This may require some changes in the configuration properties annotation processor.
Comment From: vpavic
FWIW, I think sessions endpoint won't be the only endpoint that needs two different implementations which share the same id. https://github.com/spring-projects/spring-boot/issues/32024 has not been triaged yet, but I don't see any other way around the limitation expressed there outside of doing something similar like with sessions endpoint.
Also, is it safe to assume that https://github.com/spring-projects/spring-boot/issues/32054 solution outlined in that issue (and included in this PR) stays as it is?
Comment From: vpavic
Any updates on this?
Status quo means that the default session repository for the most popular session data store (Redis) does not have actuator endpoint capability.
Comment From: mhalbritter
I've updated the PR, it's now using the ReactiveFindByIndexNameSessionRepository: https://github.com/mhalbritter/spring-boot/tree/pr/32046
I'll take a look at the problem with the two endpoint ids which are the same.
Comment From: mhalbritter
~~PR for ignoring the duplicate property: https://github.com/spring-io/spring-asciidoctor-extensions/pull/95~~
Edit: There's a better approach, which i've integrated into my branch.
Comment From: mhalbritter
Thanks @vpavic!