Detecting Session Creation and Destroy with Spring Session JDBC - spring

I am using Spring Session JDBC to persist sessions in my application. I am aware that this implementation does not support HTTP event publishing. However, I have a requirement to log session creation, expiration, and destruction. If I get some sort of notification that the session was destroyed, I already know how to determine if it was a logout or timeout.
I realize that the obvious answer is "don't use JDBC". However, I do not have the option to stand up Redis or Hazelcast due to strong port-management policies of my organization. If I want to open the Redis or Hazelcast ports, management has to get involved.
I'm asking if anyone has figured out how to "fake it", and determine if a sesson is created or destroyed in the absence of an HttpSessionEventPublisher. I have one idea which is the equivalent of a very large hammer approach, so I'm wondering if anyone else has done this in the past.

Related

Spring Session Redis web session expiration notifications not delayed until application is up again?

Currently using Spring Session Redis in a Spring Boot 2.5 web application.
The application correctly receives web session expiration notifications from Redis, but AFAIK only if the application is up and running at that time. It seems that if the backend is stopped at that time (crash, planned maintenance, ...), the notifications are not "kept" or "delayed" until the backend is up again, they are simply lost.
In https://redis.io/topics/notifications from "if your Pub/Sub client disconnects, and reconnects later, all the events delivered during the time the client was disconnected are lost" I understand that this is the standard Redis behavior.
Is this indeed the current Spring Session Redis behavior ?
Are there recommended solutions to "delay" the notifications ?
As you mentioned, this is the standard behavior of Redis Keyspace notifications.
If a key expires while the application is down, the expiry event cannot be processed, there is no way to delay the notification.
In the context of session expiration in Spring Session Data Redis, this means that the SessionExpiredEvent/SessionDeletedEvent will not fire if the application is down (crashed etc) when the Redis Keyspace notification is sent.
This will cause problems if you have a task dependent on these events.
It also means that resources may not get cleaned up properly.
However, from a security standpoint, the session will still expire correctly and the user will not be able to continue using the expired session.
If an application is performing a critical task on expiry, a different data store may be a better fit, given the "fire and forget" nature of Redis Pub/Sub.
Alternatively, having multiple nodes will make it unlikely that they will all be down at the time of receiving a notification.

Stateless with cookie vs stateful

I found sth like this:
"stateful – keep track of the previously stored information which is used for current transaction.
stateless – every transaction is performed as if it were being done for the very first time. There is no previously stored information used for the current transaction.
In a purely stateless environment you wouldn’t need this session id. Each request would contain all the information the server would need to process. But many applications need to maintain state to keep track of whether or not a session is authenticated to view certain content or to keep track of what a user is doing. You wouldn’t want to send user credentials over the wire for each request."
I'm quite confuse. So if stateless session with cookie maintain the state so it's mean that:
stateless session with cookie= session stateful?
Another think. I found information that session stateless is client side session and stateful is server side session. How we can discuss about client side session if stateless session does not maintain session?
In a purely stateless environment you really don't need sessions or cookies.
Both sessions and cookies are used to maintain state. The only question is where. Cookies maintain the state on the client while sessions maintain state on the server.
From Wikipedia: Representational state transfer
The session state can be transferred by the server to another service such as a database to maintain a persistent state for a period and allow authentication.
So typically in a stateless design, yes there is no state between client requests.
Every client request will have sufficient info to perform the requested action.
However, you still need authentication and/or authorization so who the client is identified from request headers (typically).

Queue an async web request in Spring with credentials

I'm relatively new to Spring, and trying to queue up a set of web reqeusts on the server (in order to warm memcached). It's unclear to me how I can transfer on the current request's credentials to be used in the future web request I'm putting in the queue. I've seen a handful of scheduling solutions (TaskExecutor, ApplicationEventMultitasker, etc) but was unclear if/how they handle credentials, as that seems to be the most complicated portion of this task.
It's not possible directly. Security credentials are stored in ThreadLocal which means once the request is forwarded to another thread, credentials are lost. All you can do (which might actually be beneficial to your design) is to pass credentials directly, by wrapping them inside Callable/Runnable or whatever mechanism you use.

How does Spring-JPA EntityManager handle "broken" connections?

I have an application that uses a Spring-EntityManager (JPA) and I wonder what happens if the database happens to be unavailable during the lifetime of my aforesaid application.
I expect in that situation it will throw an exception the first time to do anything on the database, right?
But, say I wait 10 minutes and try again then and the DB happens to be back. Will it recover? Can I arrange it so it does?
Thanks
Actually, neither Spring nor JPA have anything to do with it. Internally all persistence frameworks simply call DataSource.getConnection() and expect to receive (probably pooled) JDBC connection. Once they're done, they close() the connection effectively returning it to the pool.
Now when the DataSource is asked to give a connection but database is unaivalable it will throw an exception. That exception will propagate up and will be somehow handled by whatever framework you use.
Now to answer your question - typically DataSource implementation (like dbcp, c3p0, etc.) will discard connection known to be broken and replace it with a fresh one. It really depends on the provider, but you can safely assume that once the database is available again, the DataSource will gradually get rid of sick connections and replace them with healthy ones.
Also many DataSource implementors provide ways of testing the connection periodically and before it is returned to the client. This is important in pooled environemnts where the DataSource contains a pool of connections and when the database becomes unavailable it has no way to discover that. So some DataSources test connection (by calling SELECT 1 or similar) before giving it back to the client and do the same once in a while to get rid of broken connections, e.g. due to broken underlying TCP connection.
TL;DR
Yes, you will get an exception and yes the system will work normally once the database is back. BTW you can easily test this!

Toplink client session

Is there any way i can access the object of one client session from another client session?
Unless you have isolated your Entities to the client Session (ClassDescriptor.setIsIsolated) then the ClientSession does not actually hold any entity instances. So unless you have caching disabled all queries against a ClientSession will return the same entity instances.
If you have isolated Entities or are actually using a UnitOfWork then you will have to get the value from the holding UnitOfWork/IsolatedClientSession. It is not advisable to access a UnitOfWork or ClientSession concurrently with multiple threads.
I'm not sure to get what you're trying to achieve but, according to Server and Client Sessions from the TopLink Developer Guide, you're not supposed to share client session accross multiple threads:
Although client sessions are thread-safe, do not use them to write across multiple threads. Multithread write operations from the same client session can result in errors and a loss of data. For more information, see "Concurrency".
Could you clarify why you would need this?

Resources