spring-boot icon indicating copy to clipboard operation
spring-boot copied to clipboard

Provide an Actuator endpoint for non-indexed session repositories

Open vpavic opened this issue 3 years ago • 3 comments

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

vpavic avatar Aug 09 '22 21:08 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)

vpavic avatar Aug 12 '22 16:08 vpavic

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.

wilkinsona avatar Sep 01 '22 19:09 wilkinsona

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?

vpavic avatar Sep 05 '22 07:09 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.

vpavic avatar Sep 25 '23 16:09 vpavic

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.

mhalbritter avatar Jan 18 '24 13:01 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.

mhalbritter avatar Jan 18 '24 14:01 mhalbritter

Thanks @vpavic!

mhalbritter avatar Jan 22 '24 13:01 mhalbritter