Code Monkey home page Code Monkey logo

spring-session-data-mongodb's Introduction

Spring Session for MongoDB is part of the Spring Session umbrella.

icon?job=spring session data mongodb%2Fmaster&subject=Corn%20(master) icon?job=spring session data mongodb%2F2.1.x&subject=Bean%20(2.1 icon?job=spring session data mongodb%2F2.0.x&subject=Apple%20(2.0

Spring Session MongoDB

Spring Session MongoDB provides a solution for Spring Session in a MongoDB data store.

  • Accessing a session from any environment (i.e. web, messaging infrastructure, etc)

  • In a web environment

    • Support for clustering in a vendor neutral way

    • Pluggable strategy for determining the session id

    • Easily keep the HttpSession alive when a WebSocket is active

Project Status

We go to great lengths to ensure smooth upgrades. We also seek to make your upgrade on major versions of Java can be as smooth as possible.

Important
  • Spring Session for MongoDB 2.2.x runs on Spring Framework 5.2.

  • Spring Session for MongoDB 2.1.x runs on Spring Framework 5.1.

Both of these have support for JDK 11.

Spring Session for MongoDB 2.0 runs on Spring Framework 5.0 and is NOT supported on JDK 11 despite our pipelines testing against it. The extra tests are designed to give you a smooth upgrade path. If you are going into production on JDK 11, you should be using at least Spring Session for MongoDB 2.1.

Important
JDK 13 is Java’s latest version and is unstable. We are testing against it to catch issues early on, but don’t support it directly on any version of Spring Session for MongoDB.

Building Spring Session MongoDB

  1. Run ./mvnw clean package

This will generate the artifact.

You can also import the project into your IDE.

Making a release

  1. Create a new release (on the main branch).

    % ci/create-release.sh <release version> <next snapshot version>
  2. With the release tagged, push the tagged version to the release branch.

    % git checkout -b release
    % git reset --hard <tag>
    % git push -f origin release
Note
You can chain the previous set of commands together using &&.

The pipeline will build and release the "release" branch. It will also build a new a new snapshot and stage it on artifactory.

The pipeline will pick up the next tag and release it. It will also build a new snapshot and stage it on artifactory.

Running CI tasks locally

Since the pipeline uses Docker, it’s easy to:

  • Debug what went wrong on your local machine.

  • Test out a a tweak to your test.sh script before sending it out.

  • Experiment against a new image before submitting your pull request.

All of these use cases are great reasons to essentially run what Jenkins does on your local machine.

Important
To do this you must have Docker installed on your machine.
  1. docker run -it --mount type=bind,source="$(pwd)",target=/spring-session-data-mongodb-github adoptopenjdk/openjdk8:latest /bin/bash

    This will launch the Docker image and mount your source code at spring-session-data-mongodb-github.

  2. cd spring-session-data-mongodb-github

    Next, run the test.sh script from inside the container:

  3. PROFILE=none ci/test.sh

Since the container is binding to your source, you can make edits from your IDE and continue to run build jobs.

If you need to test the build.sh script, then do this:

  1. docker run -it --mount type=bind,source="$(pwd)",target=/spring-session-data-mongodb-github --mount type=bind,source="/tmp/spring-session-data-mongodb-artifactory",target=/spring-session-data-mongodb-artifactory adoptopenjdk/openjdk8:latest /bin/bash

    This will launch the Docker image and mount your source code at spring-session-data-mongodb-github and the temporary artifactory output directory at spring-session-data-mongodb-artifactory.

    Next, run the build.sh script from inside the container:

  2. ci/build.sh

Important
build.sh will attempt to push to Artifactory. If you don’t supply credentials, it will fail.
Note
Docker containers can eat up disk space fast! From time to time, run docker system prune to clean out old images.

Code of Conduct

This project adheres to the Contributor Covenant code of conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to [email protected].

Spring Session Project Site

You can find the documentation, issue management, support, samples, and guides for using Spring Session MongoDB at https://projects.spring.io/spring-session-data-mongodb/

License

Spring Session is Open Source software released under the Apache 2.0 license.

spring-session-data-mongodb's People

Contributors

atreides322 avatar brixtonasias avatar domdorn avatar eddumelendez avatar ggtucker avatar gregturn avatar izeye avatar jitendra-bisht avatar jkubrynski avatar jkuipers avatar jvalkeal avatar jxblum avatar lowzj avatar manderson23 avatar marcoblos avatar maseev avatar mp911de avatar panchenko avatar pasali avatar patrickgotthard avatar rstoyanchev avatar rwinch avatar shakuzen avatar slavisaavramovic avatar spring-builds avatar stevestorey avatar sylvermining avatar tsachev avatar tyutyutyu avatar vpavic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spring-session-data-mongodb's Issues

2.0.0.RC2: Session invalidation fails

In 2.0.0.M3 it was possible to invalidate a HTTP session even if the session has not been stored in the 'sessions' collection. E.g. request.getSession(false)?.invalidate()
In 2.0.0.RC2 MongoOperationsSessionRepository.deleteById does not check if the find method returns an existing session before it calls the remove operation of MongoOperations.
The remove operation in MongoTemplate does not accept null as an input object.
See also HttpSessionWrapper.invalidate which calls sessionRepository.deleteById(getId()).

Consider adding support for writing delta of changes

Generally, session repository implementations should track changes to session and write only delta in order to reduce the probability of lost updates due to race conditions.

Additionally, if this is implemented also consider supporting SaveMode to allow flexibility.

All session repositories in Spring Session core modules support this and could be used for inspiration.

Mongo Sharding issues using Spring-session-data-mongodb

Currently spring-session-data-mongodb doesn't have an option to use a custom query to findById(). If we have a sharded mongoDB, we should be able to pass in the shard key. The current implementation doesn't support pass in a shard key during a query.

Add expiration to MongoSession to autodelete

Provide ability to automatically delete MongoSession documents.

Per Christoph: "You’d use Index#expire(long, TimeUnit) when creating the index manually via IndexOperations#ensureIndex(IndexDefinition."

the session timeout is always 1800s

Object maxInterval = sessionWrapper.getOrDefault(MAX_INTERVAL, this.maxInactiveInterval);

I found that the session timeout is always 1800s. Maybe it refers

Old session is not deleted when using JacksonMongoSessionConverter

Hi @gregturn!
After you fix #116 I tried this with JacksonMongoSessionConverter instead of JdkMongoSessionConverter. After that the old session ceased to be deleted.

Expected behavior

After logging out current SESSION cookie should be deleted when using JacksonMongoSessionConverter.

Actual behavior

After logging out current SESSION still exist and accessible in DB when using JacksonMongoSessionConverter. And oridinalSessionId the same for all cookies.

Steps to reproduce

Please check this example - https://github.com/finke-ba/webflux-logout-not-delete-session-example.
There is one assumption what could be causing an error - CustomJacksonMongoSessionConverter line 62. But when using this fix part of test http request stop working.

Reactor Netty version

4.2.42.Final

JVM version (e.g. java -version)

1.8.0_212, x86_64: "AdoptOpenJDK 8"

OS version (e.g. uname -a)

Mac OS, Darwin Kernel Version 18.7.0

Unable to extend or modify ObjectMapper

I am trying to use JacksonMongoSessionConverter (in Spring Session MongoDB version 2.0.2.RELEASE) to serialize my sessions.

However, I keep getting the following exception:

Caused by: java.lang.IllegalArgumentException: The class with java.util.LinkedHashMap and name of java.util.LinkedHashMap is not whitelisted. If you believe this class is safe to deserialize, please provide an explicit mapping using Jackson annotations or by providing a Mixin. If the serialization is only done by a trusted source, you can also enable default typing. See spring-projects/spring-security#4370 for details

Unfortunately, despite the fact that the exception indicates that I should provide a mixin, the implementation of JacksonMongoSessionConverter prevents me from doing so due to the fact that the ObjectMapper is inaccessible. The property is private, and the method to build it is also private.

Expected behavior

Provide a mechanism for adding a mixin to the ObjectMapper or enable Default typing on the ObjectMapper.

I suggest making either the buildObjectMapper() protected so it can be overridden, or the objectMapper property be made protected, or provide a constructor where an external objectMapper can be provided.

Thanks.

Exception on the first app request

I'm using Spring Boot 2.0.0.M5 and spring-session-data-mongodb 2.0.0.M4, trying to add session persistence through @EnableMongoHttpSession on my main application class. At the very first request this exception is thrown:

java.lang.NullPointerException: null
	at org.springframework.session.data.mongo.JdkMongoSessionConverter.convert(JdkMongoSessionConverter.java:107) ~[spring-session-data-mongodb-2.0.0.M4.jar:na]
	at org.springframework.session.data.mongo.AbstractMongoSessionConverter.convert(AbstractMongoSessionConverter.java:113) ~[spring-session-data-mongodb-2.0.0.M4.jar:na]
	at org.springframework.session.data.mongo.MongoSessionUtils.convertToSession(MongoSessionUtils.java:38) ~[spring-session-data-mongodb-2.0.0.M4.jar:na]
	at org.springframework.session.data.mongo.MongoOperationsSessionRepository.findById(MongoOperationsSessionRepository.java:101) ~[spring-session-data-mongodb-2.0.0.M4.jar:na]

Anyone knows what cause this?

How to configure additional Datasource for Spring Session

I'm trying to route all session information to a dedicated datasource for session information. What I notice is that all the collections get written to the primary datasource even though there is a dedicated secondary datasource.

https://github.com/visweshwar/spring-session-multiple-mongo

Expected behavior

Collections should go to the second data source

Actual behavior

Spring session always goes to primary data source

Steps to reproduce

Run the application and you'll see the session collection getting created under first database.

Reactor Netty version

JVM version (e.g. java -version)

java version "1.8.0_101"
Java(TM) SE Runtime Environment (build 1.8.0_101-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)

OS version (e.g. uname -a)

Darwin-MacBook-Pro.local 18.5.0 Darwin Kernel Version 18.5.0: Mon Mar 11 20:40:32 PDT 2019; root:xnu-4903.251.3~3/RELEASE_X86_64 x86_64

Annotation for Default Value

during the creation of the schema, there is no notation that says "in the case of a null field or not present to assign them a default"
example:
when I define a mongo scheme

new Schema({ 
    count: { type: Number, default: 0 }
});

I also want that when I don't pass the field the value of default appears in the object.

Expected behavior

@DefaultValue(0)
int count;

Actual behavior

every time I send the object I initialize the field to let me add in mongo.

@Field 
int count = 0;

I also accept changes or suggestions.

Blocking operation restriction for Reactor Netty threads

Hello,

in version 0.7.6 of reactor-netty they added a restriction for blocking Reactor Netty threads that causes in my application the following exception:

java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-client-epoll-8
	at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:77) ~[reactor-core-3.1.9.RELEASE.jar!/:3.1.9.RELEASE]
	at reactor.core.publisher.Mono.block(Mono.java:1183) ~[reactor-core-3.1.9.RELEASE.jar!/:3.1.9.RELEASE]
	at org.springframework.data.mongodb.core.index.IndexOperationsAdapter$1.ensureIndex(IndexOperationsAdapter.java:45) ~[spring-data-mongodb-2.0.10.RELEASE.jar!/:2.0.10.RELEASE]
	at org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator.createIndex(MongoPersistentEntityIndexCreator.java:145) ~[spring-data-mongodb-2.0.10.RELEASE.jar!/:2.0.10.RELEASE]
	at org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator.checkForAndCreateIndexes(MongoPersistentEntityIndexCreator.java:135) ~[spring-data-mongodb-2.0.10.RELEASE.jar!/:2.0.10.RELEASE]
	at org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator.checkForIndexes(MongoPersistentEntityIndexCreator.java:127) ~[spring-data-mongodb-2.0.10.RELEASE.jar!/:2.0.10.RELEASE]
	at org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator.onApplicationEvent(MongoPersistentEntityIndexCreator.java:111) ~[spring-data-mongodb-2.0.10.RELEASE.jar!/:2.0.10.RELEASE]
	at org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator.onApplicationEvent(MongoPersistentEntityIndexCreator.java:54) ~[spring-data-mongodb-2.0.10.RELEASE.jar!/:2.0.10.RELEASE]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-5.0.9.RELEASE.jar!/:5.0.9.RELEASE]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-5.0.9.RELEASE.jar!/:5.0.9.RELEASE]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-5.0.9.RELEASE.jar!/:5.0.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:400) ~[spring-context-5.0.9.RELEASE.jar!/:5.0.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:354) ~[spring-context-5.0.9.RELEASE.jar!/:5.0.9.RELEASE]
	at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:420) ~[spring-data-commons-2.0.10.RELEASE.jar!/:2.0.10.RELEASE]
	at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:229) ~[spring-data-commons-2.0.10.RELEASE.jar!/:2.0.10.RELEASE]
	at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:172) ~[spring-data-commons-2.0.10.RELEASE.jar!/:2.0.10.RELEASE]
	at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:85) ~[spring-data-commons-2.0.10.RELEASE.jar!/:2.0.10.RELEASE]
	at org.springframework.data.mapping.context.MappingContext.getRequiredPersistentEntity(MappingContext.java:70) ~[spring-data-commons-2.0.10.RELEASE.jar!/:2.0.10.RELEASE]
	at org.springframework.data.mongodb.core.ReactiveMongoTemplate.determineCollectionName(ReactiveMongoTemplate.java:2247) ~[spring-data-mongodb-2.0.10.RELEASE.jar!/:2.0.10.RELEASE]
	at org.springframework.data.mongodb.core.ReactiveMongoTemplate.findOne(ReactiveMongoTemplate.java:579) ~[spring-data-mongodb-2.0.10.RELEASE.jar!/:2.0.10.RELEASE]
	...

I am using spring-boot version 2.0.5.RELEASE that comes with the following dependencies:

  • Spring mongodb 2.0.10
  • Reactor netty 0.7.9
  • Reactor core 3.1.9

Regards
Mario

java.lang.ClassCastException: org.springframework.session.data.mongo.MongoSession cannot be cast to org.springframework.session.ExpiringSession

Hi,

I'm using spring-session-core in version 2.2.0.M1 and spring-session-data-mongodb in version 2.2.0.M2, after trying to create new session I'm getting the following exception:

java.lang.ClassCastException: org.springframework.session.data.mongo.MongoSession cannot be cast to org.springframework.session.ExpiringSession
	at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:372) ~[spring-session-2.0.0.M1.jar:na]
	at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:217) ~[spring-session-2.0.0.M1.jar:na]
	at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:241) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:241) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:241) ~[tomcat-embed-core-9.0.16.jar:9.0.16]

What can I do about it?

Many thanks in advance for any response.

lombok should be `compile/provided` scope

Expected behavior

package which depend spring-session-data-mongodb has no lombok dependency

Actual behavior

lombok will be packaged into module which depend spring-session-data-mongodb

maybe we should add scope compile for lombok?

Error in Docs

expireAt not serialized properly

Actual behavior

Currently MongoSession is serialized inorrectly. The problem is in the expireAt field, which is serialized as "expireAt" : [ "java.util.Date" , 1547418146965]. It looks like it's due to SecurityJackson2Modules.createWhitelistedDefaultTyping invocation. In fact TTL index is not working as it cannot operate on array.

Steps to reproduce

new JacksonMongoSessionConverter().convert(new MongoSession));

NPE thrown when cannot deserialize session

spring-session-data-mongodb 2.0.2.RELEASE

Currently it's possible that the converters (extending AbstractMongoSessionConverter) can return null. However the first operation after returning the session is the session.isExpired() which causes NPE:

java.lang.NullPointerException: null at org.springframework.session.data.mongo.MongoOperationsSessionRepository.findById(MongoOperationsSessionRepository.java:117) at org.springframework.session.data.mongo.MongoOperationsSessionRepository.findById(MongoOperationsSessionRepository.java:58)

How to expire user sessions properly?

Hello, I'm using

  • Spring Boot 2.1.0.M4
  • Spring Session Data Mongodb 2.1.0.BUILD-SNAPSHOT

I'm trying to expire sessions for current user:

@GetMapping("kill_my_sessions")
    public ResponseEntity<?> killMySessions() {
        final var currentUserId = currentUserService.getId().toString();

        // All user sessions
        var sessions = mongoOperationsSessionRepository
                .findByIndexNameAndIndexValue(
                        FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
                        currentUserId);

        // Expiring all user sessions
        sessions.forEach((id, session) -> {
            session.isExpired(); // false
            session.setExpireAt(new Date());
            session.isExpired(); // true
            mongoOperationsSessionRepository.save(session); // ok
        });

        return ResponseEntity.ok().build();
    }

BUT some other thread executes save() method with old not-expired session and overwrites expired session in DB after all sessions were expired.


So, should save() do check for the session expiration in DB before save? Thank you.

How to config remote mongodb in the example spring-session-data-mongodb-examples?

I use following config in my spring boot project:

@Bean
    public MongoOperationsSessionRepository sessionRepository(@Autowired MongoTemplate mongoTemplate) {
        MongoOperationsSessionRepository mongoOperationsSessionRepository = new MongoOperationsSessionRepository(mongoTemplate);
        mongoOperationsSessionRepository.setMongoSessionConverter(new JacksonMongoSessionConverter());
        return mongoOperationsSessionRepository;
    }

and got error as following

Caused by: java.lang.NoSuchMethodError: org.springframework.data.mongodb.core.MongoOperations.indexOps(Ljava/lang/String;)Lorg/springframework/data/mongodb/core/index/IndexOperations;
	at org.springframework.session.data.mongo.MongoOperationsSessionRepository.ensureIndexesAreCreated(MongoOperationsSessionRepository.java:168) ~[spring-session-data-mongodb-2.0.0.RELEASE.jar:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_131]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_131]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_131]
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:311) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:134) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	... 40 common frames omitted

I checked org.springframework.data.mongodb.core.MongoOperations.indexOps,could be found in the classpath.I google a lot,did not get useful solution.

ReactiveMongoOperationsSessionRepository deleteById throws java.lang.NullPointerException when session is not found

Hi,

I am using spring-session-data-mongodb 2.1.3.RELEASE with spring boot 2.1.5.RELEASE and jdk 11 and I am facing an issue if I have a valid session cookie and for any reason the related session is missing in MongoDB. The deleteById method throws the exception below:

java.lang.NullPointerException: null
	at org.springframework.session.events.AbstractSessionEvent.<init>(AbstractSessionEvent.java:40) ~[spring-session-core-2.1.6.RELEASE.jar:2.1.6.RELEASE]
	at org.springframework.session.events.SessionDestroyedEvent.<init>(SessionDestroyedEvent.java:36) ~[spring-session-core-2.1.6.RELEASE.jar:2.1.6.RELEASE]
	at org.springframework.session.events.SessionDeletedEvent.<init>(SessionDeletedEvent.java:39) ~[spring-session-core-2.1.6.RELEASE.jar:2.1.6.RELEASE]
	at org.springframework.session.data.mongo.ReactiveMongoOperationsSessionRepository.lambda$deleteById$6(ReactiveMongoOperationsSessionRepository.java:142) ~[spring-session-data-mongodb-2.1.3.RELEASE.jar:na]

Looking at the code I think there is a mistake in using "doOnSuccess":

/**
 * Deletes the {@link MongoSession} with the given {@link MongoSession#getId()} or does nothing if the
 * {@link MongoSession} is not found.
 *
 * @param id the {@link MongoSession#getId()} to delete
 */
@Override
public Mono<Void> deleteById(String id) {

	return findSession(id)
			.flatMap(document -> this.mongoOperations.remove(document, this.collectionName).then(Mono.just(document)))
			.map(document -> convertToSession(this.mongoSessionConverter, document))
			.doOnSuccess(mongoSession -> publishEvent(new SessionDeletedEvent(this, mongoSession))) //
			.then();
}

"doOnSuccess" is called even if findSession completes without data, that means mongoSession is null. "doOnNext" should be used instead.

Regards
Mario

Error creating bean 'scopedTarget.accessTokenRequest' when using Spring Security OAuth and JacksonMongoSessionConverter

I'm using

  • Spring Session Mongo 1.3.1.RELEASE
  • Spring Security OAuth 2.0.13.RELEASE

I have the issue only with JacksonMongoSessionConverter, not with JdkMongoSessionConverter.

I use the following Spring Session config :

@EnableMongoHttpSession
public class HttpSessionConfig {

    @Bean
    public AbstractMongoSessionConverter mongoSessionConverter() {
        return new JacksonMongoSessionConverter();
    }
}

For OAuth setup it's a Spring Boot OAuth2 Client setup similar to https://spring.io/guides/tutorials/spring-boot-oauth2/#_social_login_simple (adapted for my own OAuth Authorization Server)

When accessing the main page of my app I get a :

java.lang.IllegalStateException: Cannot convert MongoExpiringSession
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Error creating bean with name 'scopedTarget.accessTokenRequest': Scope 'request' is not active for the current thread...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.accessTokenRequest': Scope 'request' is not active for the current thread
Caused by: java.lang.IllegalStateException: No thread-bound request found

I thinks this issue is due because Spring Security OAuth relies on requestScoped or sessionScoped bean, and SessionRepositoryFilter is executed outside of RequestContextFilter, and JacksonMongoSessionConverter tries to access a session scoped bean but RequestContextHolder..currentRequestAttributes isn't anymore available.

Complete stack:

2017-06-01 15:14:56.513  WARN [iam-swagger-gateway,,,] 26065 --- [tp2027963364-91] org.eclipse.jetty.server.HttpChannel     : /swagger/login

java.lang.IllegalStateException: Cannot convert MongoExpiringSession
	at org.springframework.session.data.mongo.JacksonMongoSessionConverter.convert(JacksonMongoSessionConverter.java:92) ~[spring-session-1.3.1.RELEASE.jar:na]
	at org.springframework.session.data.mongo.AbstractMongoSessionConverter.convert(AbstractMongoSessionConverter.java:110) ~[spring-session-1.3.1.RELEASE.jar:na]
	at org.springframework.session.data.mongo.MongoOperationsSessionRepository.convertToDBObject(MongoOperationsSessionRepository.java:141) ~[spring-session-1.3.1.RELEASE.jar:na]
	at org.springframework.session.data.mongo.MongoOperationsSessionRepository.save(MongoOperationsSessionRepository.java:77) ~[spring-session-1.3.1.RELEASE.jar:na]
	at org.springframework.session.data.mongo.MongoOperationsSessionRepository.save(MongoOperationsSessionRepository.java:44) ~[spring-session-1.3.1.RELEASE.jar:na]
	at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:245) ~[spring-session-1.3.1.RELEASE.jar:na]
	at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access$100(SessionRepositoryFilter.java:217) ~[spring-session-1.3.1.RELEASE.jar:na]
	at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:170) ~[spring-session-1.3.1.RELEASE.jar:na]
	at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:80) ~[spring-session-1.3.1.RELEASE.jar:na]
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1621) ~[jetty-servlet-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.springframework.cloud.sleuth.instrument.web.TraceFilter.doFilter(TraceFilter.java:145) ~[spring-cloud-sleuth-core-1.1.3.RELEASE.jar:1.1.3.RELEASE]
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1621) ~[jetty-servlet-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1621) ~[jetty-servlet-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106) ~[spring-boot-actuator-1.5.2.RELEASE.jar:1.5.2.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1621) ~[jetty-servlet-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:541) ~[jetty-servlet-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) ~[jetty-server-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) ~[jetty-security-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) ~[jetty-server-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:190) ~[jetty-server-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1592) ~[jetty-server-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188) ~[jetty-server-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1239) ~[jetty-server-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168) ~[jetty-server-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:481) ~[jetty-servlet-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1561) ~[jetty-server-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166) ~[jetty-server-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1141) ~[jetty-server-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) ~[jetty-server-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) ~[jetty-server-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.server.Server.handle(Server.java:564) ~[jetty-server-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320) ~[jetty-server-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251) [jetty-server-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279) [jetty-io-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:110) [jetty-io-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124) [jetty-io-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:672) [jetty-util-9.4.2.v20170220.jar:9.4.2.v20170220]
	at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:590) [jetty-util-9.4.2.v20170220.jar:9.4.2.v20170220]
	at java.lang.Thread.run(Thread.java:745) [na:1.8.0_101]
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Error creating bean with name 'scopedTarget.accessTokenRequest': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request. (through reference chain: org.springframework.session.data.mongo.MongoExpiringSession["attrs"]->java.util.LinkedHashMap["scopedTargetoauth2ClientContext"]->org.springframework.security.oauth2.client.DefaultOAuth2ClientContext["accessTokenRequest"])
	at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:388) ~[jackson-databind-2.8.7.jar:2.8.7]
	at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:348) ~[jackson-databind-2.8.7.jar:2.8.7]
	at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:343) ~[jackson-databind-2.8.7.jar:2.8.7]
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:698) ~[jackson-databind-2.8.7.jar:2.8.7]
	at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.8.7.jar:2.8.7]
	at com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeFields(MapSerializer.java:633) ~[jackson-databind-2.8.7.jar:2.8.7]
	at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:536) ~[jackson-databind-2.8.7.jar:2.8.7]
	at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:30) ~[jackson-databind-2.8.7.jar:2.8.7]
	at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:704) ~[jackson-databind-2.8.7.jar:2.8.7]
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:690) ~[jackson-databind-2.8.7.jar:2.8.7]
	at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.8.7.jar:2.8.7]
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:292) ~[jackson-databind-2.8.7.jar:2.8.7]
	at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3681) ~[jackson-databind-2.8.7.jar:2.8.7]
	at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3057) ~[jackson-databind-2.8.7.jar:2.8.7]
	at org.springframework.session.data.mongo.JacksonMongoSessionConverter.convert(JacksonMongoSessionConverter.java:87) ~[spring-session-1.3.1.RELEASE.jar:na]
	... 41 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.accessTokenRequest': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:355) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35) ~[spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:192) ~[spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at com.sun.proxy.$Proxy116.isEmpty(Unknown Source) ~[na:na]
	at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:516) ~[jackson-databind-2.8.7.jar:2.8.7]
	at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:30) ~[jackson-databind-2.8.7.jar:2.8.7]
	at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:704) ~[jackson-databind-2.8.7.jar:2.8.7]
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:690) ~[jackson-databind-2.8.7.jar:2.8.7]
	... 52 common frames omitted
Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
	at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.springframework.web.context.request.AbstractRequestAttributesScope.get(AbstractRequestAttributesScope.java:41) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:340) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	... 60 common frames omitted

Rework @Configuration class that users may subclass to indicate whether or not they require proxying

This is related to spring-projects/spring-session#1345.

It would be beneficial if @Configuration classes that are intended to be sub-classed by users could be annotated with @Configuration(proxyBeanMethods=false) to indicate that they do not require proxying. If there are configuration classes where proxying is required (due to inter-dependent @Bean methods) it would be beneficial if they were reworked so that proxying is no longer required.

Harmonize naming of session repositories

In Spring Session core modules we recently harmonized naming of session repositories - see spring-projects/spring-session#1455. This was triggered by addition of another Redis-backed SessionRepository implementation for 2.1 so we wanted that implementation name more closely reflect the concrete SessionRepository interface they implement.

To align with the above, Spring Session Data MongoDB should:

  • rename MongoOperationsSessionRepository to MongoIndexedSessionRepository
  • rename ReactiveMongoOperationsSessionRepository to ReactiveMongoSessionRepository

See spring-projects/spring-session@8cc8fbb for inspiration and strategy taken for preserving backwards compatibility.

Classloader issues with devtools

Following on #13, after declaring my session attribute Serializable, a class cast exception like this one occurs:

java.lang.ClassCastException: br.com.mercur.rel.model.Usuario cannot be cast to br.com.mercur.rel.model.Usuario

That doesn't maked any sense at first, class cast exception trying to cast to the same class. Searching a little bit, i got here: spring-projects/spring-boot#3805. From the issue description:

This means that the value restored from session has a class defined by the system ClassLoader. The application itself loads the same class from Spring Boot's RestartClassLoader. Since the two classes are loaded from different ClassLoaders they cannot be cast from one to the other.

The docs from spring boot devtools have a section on this: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#using-boot-devtools-known-restart-limitations

Looking at the code, the default constructor on JdkMongoSessionConverter uses the serializer/deserializer from Spring, wich seems to be the recommended one from the docs.

Removing spring-boot-dev-tools from the classpath solves the problem. Is there any possibility to keep using dev-tools? It's features are a much appreciated help at developing.

Release 2.1.0.RELEASE

Spring Session Bean is scheduled for release on Oct 25th. For spring-session-data-mongodb 2.1.0 to be included, we need a the GA release by Oct 24th. If it is not available, we will need to roll back to the previous GA of spring-session-data-monogodb in order to ensure Spring Session Bean gets in Spring Boot

Consider adding support for flush mode

Immediate FlushMode can be used as a strategy for dealing with race conditions, by writing changes to data store as they happen, vs traditionally on invocation of #save on session repository.

Note that this is an option only for Servlet-based implementations, as org.springframework.session.Session#setAttribute returns void (and not Mono<Void>).

All SessionRepository implementations in Spring Session core modules support this and could be used for inspiration.

Version spring session core gives a null pointer

Expected behavior

I would expect a 302 redirect, when I have an invalid session id.

Actual behavior

I get a 500 error due to a null pointer exception.

Steps to reproduce

Login into your app and invalidate the session, by dropping the collection. After a refresh of the app you would get a 500 error.

Reactor Netty version

reactor-core-3.2.12.RELEASE

JVM version (e.g. java -version)

openjdk 11.0.5 2019-10-15 LTS
OpenJDK Runtime Environment Zulu11.35+15-CA (build 11.0.5+10-LTS)
OpenJDK 64-Bit Server VM Zulu11.35+15-CA (build 11.0.5+10-LTS, mixed mode)

OS version (e.g. uname -a)

Linux lenovo 5.3.0-23-generic #25-Ubuntu SMP Tue Nov 12 09:22:33 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

Example project: https://gitlab.com/jf-lab/investigate-spring-session

stacktrace

019-11-29 23:07:29.230 ERROR 7610 --- [ntLoopGroup-2-2] a.w.r.e.AbstractErrorWebExceptionHandler : [9a51e275] 500 Server Error for HTTP GET "/"

java.lang.NullPointerException: null
	at org.springframework.session.events.AbstractSessionEvent.<init>(AbstractSessionEvent.java:40) ~[spring-session-core-2.1.9.RELEASE.jar:2.1.9.RELEASE]
	at org.springframework.session.events.SessionDestroyedEvent.<init>(SessionDestroyedEvent.java:36) ~[spring-session-core-2.1.9.RELEASE.jar:2.1.9.RELEASE]
	at org.springframework.session.events.SessionDeletedEvent.<init>(SessionDeletedEvent.java:39) ~[spring-session-core-2.1.9.RELEASE.jar:2.1.9.RELEASE]
	at org.springframework.session.data.mongo.ReactiveMongoOperationsSessionRepository.lambda$deleteById$6(ReactiveMongoOperationsSessionRepository.java:142) ~[spring-session-data-mongodb-2.1.4.RELEASE.jar:na]
	at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onComplete(MonoPeekTerminal.java:311) ~[reactor-core-3.2.12.RELEASE.jar:3.2.12.RELEASE]
	at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onComplete(FluxMapFuseable.java:336) ~[reactor-core-3.2.12.RELEASE.jar:3.2.12.RELEASE]
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onComplete(MonoFlatMap.java:174) ~[reactor-core-3.2.12.RELEASE.jar:3.2.12.RELEASE]
	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:1743) ~[reactor-core-3.2.12.RELEASE.jar:3.2.12.RELEASE]
	at reactor.core.publisher.FluxHide$SuppressFuseableSubscriber.onComplete(FluxHide.java:137) ~[reactor-core-3.2.12.RELEASE.jar:3.2.12.RELEASE]
	at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) ~[reactor-core-3.2.12.RELEASE.jar:3.2.12.RELEASE]
	at reactor.core.publisher.MonoNext$NextSubscriber.onComplete(MonoNext.java:96) ~[reactor-core-3.2.12.RELEASE.jar:3.2.12.RELEASE]
	at com.mongodb.reactivestreams.client.internal.ObservableToPublisher$1.onComplete(ObservableToPublisher.java:78) ~[mongodb-driver-reactivestreams-1.9.2.jar:na]
	at com.mongodb.async.client.AbstractSubscription.onComplete(AbstractSubscription.java:145) ~[mongodb-driver-async-3.8.2.jar:na]
	at com.mongodb.async.client.AbstractSubscription.processResultsQueue(AbstractSubscription.java:211) ~[mongodb-driver-async-3.8.2.jar:na]
	at com.mongodb.async.client.AbstractSubscription.tryProcessResultsQueue(AbstractSubscription.java:159) ~[mongodb-driver-async-3.8.2.jar:na]
	at com.mongodb.async.client.SingleResultCallbackSubscription$1.onResult(SingleResultCallbackSubscription.java:48) ~[mongodb-driver-async-3.8.2.jar:na]
	at com.mongodb.async.client.FindIterableImpl$1$1.onResult(FindIterableImpl.java:211) ~[mongodb-driver-async-3.8.2.jar:na]
	at com.mongodb.async.client.FindIterableImpl$1$1.onResult(FindIterableImpl.java:204) ~[mongodb-driver-async-3.8.2.jar:na]
	at com.mongodb.operation.AsyncQueryBatchCursor.next(AsyncQueryBatchCursor.java:141) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.operation.AsyncQueryBatchCursor.next(AsyncQueryBatchCursor.java:100) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.async.client.FindIterableImpl$1.onResult(FindIterableImpl.java:204) ~[mongodb-driver-async-3.8.2.jar:na]
	at com.mongodb.async.client.FindIterableImpl$1.onResult(FindIterableImpl.java:198) ~[mongodb-driver-async-3.8.2.jar:na]
	at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:49) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.async.client.OperationExecutorImpl$1$1.onResult(OperationExecutorImpl.java:82) ~[mongodb-driver-async-3.8.2.jar:na]
	at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:49) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.operation.FindOperation$3.onResult(FindOperation.java:806) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.operation.OperationHelper$ReferenceCountedReleasingWrappedCallback.onResult(OperationHelper.java:364) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.operation.CommandOperationHelper$2.onResult(CommandOperationHelper.java:405) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:49) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.internal.connection.DefaultServer$DefaultServerProtocolExecutor$2.onResult(DefaultServer.java:227) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:49) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.internal.connection.CommandProtocolImpl$1.onResult(CommandProtocolImpl.java:85) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection$1.onResult(DefaultConnectionPool.java:461) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.internal.connection.UsageTrackingInternalConnection$2.onResult(UsageTrackingInternalConnection.java:111) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:49) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.internal.connection.InternalStreamConnection$2$1.onResult(InternalStreamConnection.java:379) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.internal.connection.InternalStreamConnection$2$1.onResult(InternalStreamConnection.java:356) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.internal.connection.InternalStreamConnection$MessageHeaderCallback$MessageCallback.onResult(InternalStreamConnection.java:651) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.internal.connection.InternalStreamConnection$MessageHeaderCallback$MessageCallback.onResult(InternalStreamConnection.java:618) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.internal.connection.InternalStreamConnection$5.completed(InternalStreamConnection.java:494) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.internal.connection.InternalStreamConnection$5.completed(InternalStreamConnection.java:491) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.connection.netty.NettyStream.readAsync(NettyStream.java:236) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.internal.connection.InternalStreamConnection.readAsync(InternalStreamConnection.java:491) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.internal.connection.InternalStreamConnection.access$1000(InternalStreamConnection.java:74) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.internal.connection.InternalStreamConnection$MessageHeaderCallback.onResult(InternalStreamConnection.java:608) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.internal.connection.InternalStreamConnection$MessageHeaderCallback.onResult(InternalStreamConnection.java:593) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.internal.connection.InternalStreamConnection$5.completed(InternalStreamConnection.java:494) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.internal.connection.InternalStreamConnection$5.completed(InternalStreamConnection.java:491) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.connection.netty.NettyStream.readAsync(NettyStream.java:236) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.connection.netty.NettyStream.handleReadResponse(NettyStream.java:266) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.connection.netty.NettyStream.access$600(NettyStream.java:66) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.connection.netty.NettyStream$InboundBufferHandler.channelRead0(NettyStream.java:325) ~[mongodb-driver-core-3.8.2.jar:na]
	at com.mongodb.connection.netty.NettyStream$InboundBufferHandler.channelRead0(NettyStream.java:322) ~[mongodb-driver-core-3.8.2.jar:na]
	at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) ~[netty-transport-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) ~[netty-transport-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) ~[netty-transport-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) ~[netty-transport-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1422) ~[netty-transport-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) ~[netty-transport-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) ~[netty-transport-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:931) ~[netty-transport-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) ~[netty-transport-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:700) ~[netty-transport-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:635) ~[netty-transport-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:552) ~[netty-transport-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:514) ~[netty-transport-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor$6.run(SingleThreadEventExecutor.java:1050) ~[netty-common-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.43.Final.jar:4.1.43.Final]
	at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]

See pom:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.10.RELEASE</version>
    </parent>
    <groupId>nl.ftoc.spring.problem</groupId>
    <artifactId>mongo-session</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mongo-session</name>
    <description>Demo project do demonstrate problem in spring session mongo, when using session ids not known by spring
        session
    </description>

    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>-->
<!--        </dependency>-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-mongodb</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.5.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Unable to use JacksonMongoSessionConverter with Spring WebFlux

Hello! I'm trying to save WebSession in Mongo with reactive driver in Spring WebFlux project.
It works with default JdkMongoSessionConverter but failed with JacksonMongoSessionConverter. I have an exception:
Caused by: java.lang.ClassNotFoundException: javax.servlet.http.Cookie

Problem in WebJackson2Module class, it uses javax.servlet.http.Cookie:

@Override
public void setupModule(SetupContext context) {
	SecurityJackson2Modules.enableDefaultTyping((ObjectMapper) context.getOwner());
	context.setMixInAnnotations(Cookie.class, CookieMixin.class);
...

And I have no javax.servlet dependencies and I can't have it in Spring WebFlux.

Expected behavior

I could use JacksonMongoSessionConverter for Spring Session Data Mongodb with Spring WebFlux.

Actual behavior

I have an exception:

Caused by: java.lang.NoClassDefFoundError: javax/servlet/http/Cookie
...
Caused by: java.lang.ClassNotFoundException: javax.servlet.http.Cookie

Steps to reproduce

  1. Create Spring WebFlux project
  2. Configure Spring Security
  3. Add dependencies spring-boot-starter-data-mongodb-reactive and spring-session-data-mongodb
  4. Configure Spring Session (spring.session.store-type=mongodb)
  5. Add JacksonMongoSessionConverter bean:
@Bean
public AbstractMongoSessionConverter mongoSessionConverter() {
   return new JacksonMongoSessionConverter();
}

Reactor Netty version

I'm using SpringBoot 2.0.4.RELEASE with spring-boot-starter-webflux.
So version of Reactor Netty is 0.7.8.RELEASE.

JVM version (e.g. java -version)

Java 10

OS version (e.g. uname -a)

MacOS High Sierra 10.13.6

Session change doesn't remove old session

After logging out, Spring creates a new SESSION cookie, but doesn't delete the current one and we can use previous session even after logging out.
Please check comments from this issue - spring-projects/spring-session#1519.

Expected behavior

After logging out current SESSION cookie should be deleted or invalidated.

Actual behavior

After logging out current SESSION still exist and accessible in DB.

Steps to reproduce

Please check this example - https://github.com/finke-ba/webflux-logout-not-delete-session-example. You will find steps to reproduce in readme file.

Reactor Netty version

4.1.39.Final

JVM version (e.g. java -version)

1.8.0_212, x86_64: "AdoptOpenJDK 8"

OS version (e.g. uname -a)

Mac OS, Darwin Kernel Version 18.7.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.