spring.session.timeout vs server.servlet.session.timeout - java

I'm looking to extend the user session in a Spring MVC app with Spring boot and Tomcat. Looking at the documentation there seems to be 2 relevant properties:
server.servlet.session.timeout
spring.session.timeout
Most examples out there seem to suggest to use server.servlet.session.timeout; what is the purpose of spring.session.timeout? Which one should be used to extend the user session?

spring.session.timeout is the property from a Spring sub-project called Spring Session. It will fallback to server.servlet.session.timeout if it is not set.
In short , Spring Session allows you to store HttpSession in RDBMS / Redis / Hazelcast Cluster / MongoDB rather than an internal map inside Tomcat .So the sessions is stored in the container agnostic way and make session clustering easier as you do not need to configure a Tomcat cluster.
So if you do not use Spring Session , you should use server.servlet.session.timeout

You should be able to set the server.session.timeout in your application.properties file to do the same
I think, If you add spring.session.timeout in application.properties the session timeout value mentioned using server.session.timeout will be overridden

Related

Is it possible to store session in two different stores using Spring Session and Spring Boot?

I am using redis for storing session in my Spring Boot app. I am also using Spring Session library to achieve this. I have two different redis instances namely US redis and EU redis. Once someone enters my app(after logging in of course), I want to store their sessions in both US redis and EU redis servers. Mind you that these both redis instances are masters and are not in any master-slave setup. This is what I have so far in my spring setup.
#EnableRedisHttpSession
#Configuration
public class RedisConfig{
}
Note: removed other security code for brevity.
According to #EnableRedisHttpSession docs, we need to add one RedisConnectionFactory instance, however Spring Boot by default does this.
So right now, once the user logs in, their session is stored in US redis(I added US redis related information in application.yml).
However whenever a session is stored in US redis, I want to replicate the same in EU redis server. How can I achieve this? Do I need to create another RedisConnectionFactory bean and manually save it? If manually save it, how to do so?
Note: This use case might not be following the best design practices(that is we are storing user session in multiple places). However I do understand this, but I do have a use case for this.
Replication is done by the underlying connection. For example, if you are using Lettuce with Spring Session Redis, then you would set it up with a Master Slave setup. In Spring you can refer to Connecting to Redis section of the documentation.
Spring Boot provides simple mechanism for setting up master/slave via properties. This article has a nice summary. In short, add the properties to application.yml
redis:
master:
host: localhost
port: 6379
slaves:
- host: localhost
port: 16379
- host: localhost
port: 26379
There is a built in solution for that, but you can always tweak the spring code or as you wrote sent an explicit set to the remote Redis.
You might want to consider using some Active-Active replication mechanism like CRDT

Spring Boot LDAP - pooled property for auto configuration

In Spring Boot I can pass properties which will be picked for auto configuration:
spring.ldap.url
spring.ldap.username
spring.ldap.password
Is there any spring.ldap.* property to set pooled=true to avoid using explicit LdapTemplate config?
LdapContextSource contextSource = new LdapContextSource();
contextSource.setPooled(true);
According to the Appendix that lists all of the Spring Boot properties, no. I also looked at the LdapProperties class which stores these values at runtime and didn't see anything in there that would help with pooling. I suspect you'll have to keep doing this manually.
Perhaps file a PR on them? They seem open to adding things if there is a need in the community.
You can set ldap pool properties with JVM parameters. You specify them when launching your application.
For example:
-Dcom.sun.jndi.ldap.connect.pool.maxsize=10
-Dcom.sun.jndi.ldap.connect.pool.prefsize=5
-Dcom.sun.jndi.ldap.connect.pool.timeout=300000
Everything that I have read on this recommends that configuration be done using the PoolingContextSource. The LDAP authentication process requires a two-stage process that is problematic. The below is from the blog of Mattias Hellborg Arthursson, a Spring LDAP guru.
Built-in JNDI Connection Pooling
The pooled property of ContextSource has previously defaulted to true,
enabling the built-in Java LDAP connection pooling by default. However
the built-in LDAP connection pooling suffers from several deficiencies
(most notable there is no way of doing connection validation and
configuration is cumbersome), which is why we decided to change the
default to false . If you require connection pooling we strongly
recommend using the Spring LDAP PoolingContextSource instead.
https://blog.jayway.com/2008/10/27/whats-new-in-spring-ldap-13/
https://docs.spring.io/spring-ldap/docs/1.3.2.RELEASE/reference/html/pooling.html

Multi tenancy with Spring boot

I'm planning to work on a multi-tenancy application and for now I'm just looking at different implementations on the web to understand the requirements needed to implement such task.
Hibernate + Spring boot are the technologies I'm planning to use.
From my readings, all the different tutorials are using the same approach which is to declare the data sources in a config file so that session factories are launched with the boot of the application, but I really want to have a higher level of the app, where I can add tenants dynamically and input their data sources informations.
This way the application can get the information of the new tenant without the need to touch the config files and re-boot the app.
I thought about having a separate database where I can store my tenants data source credentials or something like that. Can you give me another approach to solve this requirement or a link to an existing implementation that I can refer to.
Thanks
I got similar requirements in the past.
I implemented DataSource proxy class. The class has tenant resolver and a map of simple DataSources. All the places where we need a DataSource use the proxy.
On any method call e.g. getConnection() it resolves tenant, check whether the map contains already created DataSource (if not a new DataSource is created for the tenant and stored in the DB). Then the same method of real DataSource from the map is invoked.
Tenant resolver is ThreadLocal based where tenant value is stored in a filter (got tenant from request header) and used in the DataSource proxy.
What you need to do is using dynamic datasource routing of Spring Framweork via AbstractRoutingDataSource. This answer explains all for you.
In my question.I implements MultiTenantConnectionProvider and CurrentTenantIdentifierResolver.And use DataSourceLookup to choose datasource by tenant.This links is helpful to me.
Here is a full working example of a database-per-tenant multitenat app I built using Spring Boot 2, Spring JPA (Hibernate), Spring Security 5 running on MySQL.
I have explained how it all works and have shared the entire code too.
Take a look here.

Spring MVC Java Configuration session replication

I'm working on porting over an application into Spring MVC using Java Configuration so I don't have to use a web.xml file anymore.
For the most part it is working, except for session replication. The app currently runs on Tomcat and we use the distributable tag in the web.xml for session replication.
Does anyone know a way to make this work using Java configuration?
You could use Hazelcast for that. Please, see How to configure Hazelcast for session caching using spring while limiting it to a set of nodes? for how to configure it.

Using Spring, JPA with Hibernate to access multiple databases/datasources configured in Jboss

I have a requirement where i need to configure a Spring based application to work with two databases. We have two databases, one that we use to keep the live data and the other database is used as a datawarehouse and contains archived data (which has the exact structure as the Live db).
To keep it simple, assume that there is a request to search for a product. What the application should do is to search for the product details in the Live database and if not found it will check the archive database.
If i need to configure such a setup, do i still need to configure to datasources and would the search code have to use the first datasource to check the live database and if not found it will run another query using the archive database?
The above is probably doable but i am wondering whether there is a better way of doing this. For example, is it possible for the application to work on a single datasource even though behind the scenes it actually works with two databases?
The application is based on Spring, JPA/Hibernate, SOAP and Mysql database and Jboss 7 as the application server.
Any examples showing how this is configured using Spring and Jboss would be very useful.
Thanks
Spring has exactly what you want - the AbstractRoutingDataSource. See this blog post on how to use it. In your case, you need to switch the datasource during one request, so you'll need to have 2 transactions, switching the datasource between them by changing the datasource indicator on the ThreadLocal:
For these DAOs, demarcate the wrapping Service-layer either with distinct packages, class names, or method names
Indicate to Spring that the Service-layer method calls should run in their own transactional contexts by annotating with #Transactional(propogation=Propogation.REQUIRES_NEW)
Create an Aspect (using AspectJ annotation #Aspect) to fire around the service-layer method calls (using #Around) to set the ThreadLocal value before the method call, and to unset it afterwards
In the #Controller, simply call the Service-layer methods. The Aspect will take care of setting the values to indicate which datasource to use, and the AbstractRoutingDataSource will use that datasource in the context of each transaction.

Categories

Resources