Custom session state management - spring

Can someone point me to example implementation for custom session state management ?
I am looking for following approach "keep all the session state in database and keep only the keys in HttpSession object. "
Can it be done using Spring ?
TIA
-Vin

Using a plain old java proxy for this (or cglib proxies) should be possible, you still need to handle saving/loading to/from your db. There's also the issue to see if a proxied object has been modified this would have to been handled additionally. Spring does not anything to this AFAIK.
Not sure what you're trying to achieve really, but perhaps also memcached-session-manager is interesting for you (shameless plug :-)).

Related

Spring boot 2.1.5, WebFlux, Reactor: How to deal properly with MDC

Spring boot 2.1.5
Project Reactor 3.2.9
I am setting up a bunch of rest reactive APIs using the above-mentioned frameworks and I am running into an annoying problem with MDC (mapped diagnostic context). My applications are in JAVA.
MDC relies on thread locals to store the current query's mapped context to put in the logs. That system, obviously, is not perfect and contradicts the reactive pattern since the different steps of your execution will be executed through different threads.
I have run into the same problem with the Play Reactive framework but found a workaround there by copying the mapped context transparently from one actor to another.
For spring and reactor, I could not find a satisfying solution yet.
Some random examples found on the internet:
First - It works but forces you to use a bunch of utility methods
Same thing
Second - It tries to copy the context during the onNext publisher event but seems to lose some features on the way of doing that. The signal context, for example, is lost.
I am in need of a proper solution to deal with this:
A library which would make the link between MDC and reactor?
A way to tweak reactor/spring to achieve it transparently?
Any advice?
"I could not find a satisfying solution yet."
Working with contexts is the only solution for the moment. Since as you said threadlocals goes against everything that has to do with reactive programming. Using thread local as a storage point during a request is a resource heavy way of solving things and in my opinion poor design. Unless logging frameworks themselves come up with a better solution to the problem we developers must pass the data through the context to accommodate for the logging frameworks blocking nature.
Reactive programming is a paradigm shift in the programming world. Other things like database drivers, that use threadlocal to rollback transactions are also in big trouble. the JDBC database driver spec is defined as blocking in nature, and atm. there has been attempts by spring and the R2DBC project to define a new JDBC driver spec that is inherently non/blocking. This means that all vendors must rewrite ther database driver implementations from scratch.
Reactive program is so new that lots of libraries need to rewrite entire codebases. The logging frameworks as we know it needs to be rewritten from the ground up which is a huge task. And the context in reactive is actually something that should not even be in reactive programming, it was implemented just to accommodate for MDC problems.
It's actually a lot of overhead needing to pass data from thread to thread.
So what can we do?
push on logging frameworks, and/or help logging frameworks to rewrite their codebase
Accept that there is no "tweak" that will magically fix this
use the context and the way suggested in the blogposts
Project reactor context

Spring session for session sharing(clustering) between servers

I'm trying to let two machines with the same base domain (subdomains differ) to share session.
spring-session-jdbc seems to be a solution I could use to achieve the goal.
When a user logs into server-a, session info is stored in SPRING_SESSION db.
What worries me is the fact that custom org.springframework.security.core.userdetails.UserDetails class is stored in that db as well.
When server-b tries to read session data from the db, it has to use the same custom subclass of the org.springframework.security.core.userdetails.UserDetails.
So I'm copying codes that relates to the UserDetails class from server-a to server-b.
I'm feeling a little awkward doing this, because server-a and server-b might want different UserDetails in general.
Is this really intended way of using spring-session-jdbc ?
Another question is, is it mandatory to use spring-security for both server-a and server-b?
Spring Session is meant to easily enable session clustering, i.e. have the multiple instances of the same app share the external session store therefore making it easier to scale your app.
For the problem you are trying to solve it might be a good idea to use an appropriate higher level protocol such as OAuth 2.0 and OpenID Connect and implement single sign-on without coupling you applications through the session store.
While the idea of sharing session store between different apps might seem convenient initially, such arrangement is usually very problematic, as you noted yourself with the UserDetails example.
In line with Vedran Pavic's answer it sounds like you should be using sso. That said there are instances where different code bases may want to share the same session such as in micro-service clusters. In this case you should simply put your UserDetails into a base jar/module that the other jar/module's are dependent upon. You can use a build automation tool to make this packaging easier to accomplish.
To answer your final question, if these two applications are regularly communicating with each other then I'd recommend either using spring security everywhere or nowhere.
Default mechanism to persist and load session is through the SecurityContextRepository (Spring Security) or SessionRepository (Spring Session).
If you use Redis for session sharing the repository implementation could be RedisSecurityContextRepository (spring-security-redis) or RedisIndexedSessionRepository (Spring Session).
The latter one for sure serialize UserDetails so you cannot share the session unless you use same Frameworks & user classes versions.
I would use custom SessionRepository and store shared user info in portable Json or XML, or whatever you like, not the Java object serialized ))

hibernate ejb3+Tomcat+Openejb or Spring+hibernate for an exsiting GWT2 project

I used GWT2+DAO pattern for my apps and it's work correctly. Now my BD as grown a lot and i want to manage it more easier. So I want to use an ORM.What i want to do is to keep my first DAO implementation and use hibernate for my new classes. But I read a lot on internet and I'm very confused about the way to deal with this.
which solution between hibernate ejb3+Tomcat+Openejb and Spring+hibernate could be better for me?
also which one could be the fastest?
Should I change all my dao to use hibernate methods or should I use the both?
NB: I'm just started to read spring doc, but I have already read hibernate doc.
thanks.
I think the change you need only affects the back-end, hence has nothing to do with the server or container you are using.
Rather in your DAO, when saving new pojos, use hibernateTemplate instead of what you were using.
It would be advisable to actually be consistent, if you are going to use hibernate, use hibernate for all your db manipulation.
Optimization is a whole chapter on itself, I think you should focus on getting your db changes for now, then worry about the speed when everything works.

Spring Context Event

I am currently studying Spring.
While reading a Spring book, I met a part regarding Event.
By using context.publishEvent(..), I could trigger the event.
But I don't know what It's exactly for.
I can use other Method instead of using complicated publishEvent.
Please, tell me. thank you.
Spring Events are used to implement publish-subscribe model (or observer pattern) where two not-related parts of code must be somehow connected.
Think of the analogy of web applications where servlet container creates http sessions and your code is informed about this using javax.servlet.http.HttpSessionListener.
Spring uses this mechanism internally. It's much more visible in Spring Security where several parts of the code are informed about e.g., successfull authentication.

RavenDB session per request with MVC3 and Ninject using repository model

I am looking for some advice on the correct mechanism to use for getting a RavenDB IDocumentSession into my repositories in a true session-pr-request behaviour.
This is a greenfield MVC3 application, and I've gotten Ninject / Ninject.MVC3 using NuGet. RavenDB is running on an external server (i.e. non-embedded).
I've set up the Ninject module to return the right repositories, and also a session per request for them.
However - is it true that MVC3 will instantiate the controller for each action method? In that case, I can just allow MVC3/Ninject to inject my repositories and the sessions they need, no problem.
However, if a controller is reused across several requests, this might not work, as the repository hanging around from a previous request might now employ a session that is old and discarded.
I have looked at a few ways to do this - the above is the basic one. I have also tried to do something like an ActionFilterAttribute that gets a new session from the IoC container at the start of each request - but in that case, where should I put it?
Should my repository have a Session property it uses that actually gets the current session from the container each time? This would add coupling between the repository implementation and the IoC container, but otherwise should work I guess.
What is the proper way to do this? How are the cool kids doing it? Any help would be highly appreciated!
Unless you are doing something really funny with your controller factory, each controller instance will be used for a single requests.
Controllers are not thread safe and will not usually survive beyond a single request.
I've written a comprehensive blog post about using Ninject's InRequestScope so that IDocumentSession is injected once per request. Ninject is great at managing scope for you.
http://www.dalsoft.co.uk/blog/index.php/2012/04/12/mvc-get-ravendb-up-and-running-in-5-minutes-using-ninject/
I think that you should avoid going on with Controllers.
It may help sometime:
If session state is disabled we should no longer try to use the Session Property on the Controller as it will be null. Turning off session state and using the Session Property will give you the dreaded “object reference not set to an instance of object” error.

Resources