Spring session with in memory store - spring

Why does not spring.session.store-type has in memory option. ?
Is there any way to use spring session with in memory option without writing my implementation of store ?
I would like to use spring session for rest api with token
#Bean
public HttpSessionIdResolver httpSessionIdResolver() {
return HeaderHttpSessionIdResolver.xAuthToken();
}

I found solution, there is a MapSessionRepository which can accept map.
here is a documentation EnableSpringHttpSession
#EnableSpringHttpSession
#Configuration
public class SpringHttpSessionConfig {
#Bean
public MapSessionRepository sessionRepository() {
return new MapSessionRepository(new ConcurrentHashMap<>());
}
}

Related

Changing the samesite session cookie attribute in a spring webflux application

I am trying to change the same site attribute of my springboot application using WebSessionIdResolver as described here : https://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot-webflux-custom-cookie.html
#Configuration
public class CookieConfiguration {
#Bean
public WebSessionIdResolver webSessionIdResolver() {
CookieWebSessionIdResolver resolver = new CookieWebSessionIdResolver();
resolver.addCookieInitializer(builder -> builder.sameSite("None"));
return resolver;
}
}
I don't understand what is going, when debugging I can see the bean being initialized,but on every http call a session cookie is written with the default sameSite attribute "Lax", and the default CookieWebSessionIdResolver.cookieInitializer being null.
I was able to solve this adding 'spring-session-core' dependency and using the following config :
#EnableSpringWebSession
#Configuration
public class CookieConfiguration {
#Bean
public WebSessionIdResolver webSessionIdResolver() {
CookieWebSessionIdResolver resolver = new CookieWebSessionIdResolver();
resolver.addCookieInitializer(builder -> builder.sameSite("None"));
return resolver;
}
#Bean
public ReactiveMapSessionRepository reactiveSessionRepository() {
return new ReactiveMapSessionRepository(new ConcurrentHashMap<>());
}
}

Spring - Choose repository implementation after bean creation

I'm developing Spring Boot application which persists data into MS SQL database. I'm tasked to add support for PostgreSQL, which uses same tables. So my goal is to add another repository layer implementation. But things gets little bit complicated.
It would be great if my repository layer could look like this:
public interface RecordRepository {
Record get(long id);
}
#Repository
#Conditional(MsSqlCondition.class)
public interface MsSqlRecordRepository {
public Record get(long id) {
// MS SQL implementation...
}
}
#Repository
#Conditional(PostgreSqlCondition.class)
public interface PostgreSqlRecordRepository {
public Record get(long id) {
// PostgreSql implementation...
}
}
However, it seems to not be possible in my case.
First of all, my application doesn't have database configuration in application.yaml file. It has to get these variables from remote HTTP server. My #Configuration file looks something like this:
#Configuration
public class MyAppConfiguration {
#Bean
public DatabaseConfiguration databaseConfiguration() {
// Make HTTP request to remote server
if (something) {
return new MsSqlServerConfiguration(...);
} else {
return new PostgreSqlServerConfiguration(...);
}
}
}
With this approach, I'm unable to use #Conditional annotation for my DataSource and repository beans, since #Conditional is evaluated while parsing #Configuration files. I need to choose right implementation AFTER DatabaseConfiguration bean is created.
I already considered this approach:
#Configuration
public class RepositoryConfiguration {
#Bean
public RecordRepository(DatabaseConfiguration configuration, JdbcTemplate jdbcTemplate) {
if (configuration.getType() == MS_SQL) {
return new MsSqlRecordRepository(jdbcTemplate);
} else {
return new PostgreSqlRecordRepository(jdbcTemplate);
}
}
}
But this seems that it is not working for me either, sice I'm using Spring AOP for my repository classes.
Does Spring Boot have some other mechanism, which allows me to choose right repository implementation after my DatabaseConfiguration bean is created?
Thanks

Spring session jdbc - How to add multiple HttpSessionIdResolver for a single application

I have a problem in injecting multiple HttpSessionIdResolver for a single spring application.
For normal web application I would like to use CookieHttpSessionIdResolver
For Rest API I would go for HeaderHttpSessionIdResolver and Rest API url will be like "/api/**"
Internally spring sets a bean and uses that bean for all request(In this case HeaderHttpSessionIdResolver
and my web stopped working because i dont set X-Auth-Token header for every request) but i would like to override it.
Could any one please help me.
Thank you.
#EnableJdbcHttpSession(maxInactiveIntervalInSeconds = 3600)
public class SessionConfig extends AbstractHttpSessionApplicationInitializer{
#Autowired
#Qualifier("userDatabase")
private DataSource dataSource;
#Bean
public DataSource dataSource() {
return dataSource;
}
#Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
#Bean(value = "httpSessionIdResolver")
public HttpSessionIdResolver httpSessionIdResolver() {
return HeaderHttpSessionIdResolver.xAuthToken();
}
#Bean(value = "cookieHttpSessionIdResolver")
public HttpSessionIdResolver cookieHttpSessionIdResolver() {
return new CookieHttpSessionIdResolver();
}
}
I overridden spring session to enable both cookie and header based session.
Now it's working fine.
Currently I'm checking for URL that contains /api/* and if it contains i'm using header based other wise cookie based session.

Register Caffeine Cache in Spring Actuator (CacheManager)

We're using Spring Boot 2 and Spring Actuator. When creating a cache like the following:
#Bean
public CaffeineCache someCache() {
return new CaffeineCache("my-cache",
Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.SECONDS)
.build());
}
it is registered into Spring Actuator and can be accessed and handle via endpoints:
❯ http GET localhost:8080/actuator/caches
{
"cacheManagers": {
"cacheManager": {
"caches": {
"my-cache": {
"target": "com.github.benmanes.caffeine.cache.BoundedLocalCache$BoundedLocalManualCache"
}
}
}
}
}
However, this is valid when using the annotation #Cacheable - but I would like to create a cache and use it as a map.
Therefore, I can create:
#Bean
public com.github.benmanes.caffeine.cache.Cache<String, MyObject> customCache(QueryServiceProperties config) {
return Caffeine.newBuilder()
.maximumSize(10)
.expireAfterAccess(10, TimeUnit.SECONDS)
.build();
}
And it works but it cannot be discovered by Spring Actuator. Is there any way to register this kind of cache?
Addapted from this Answer I did the following:
#Autowired
private CacheMetricsRegistrar cacheMetricsRegistrar;
private LoadingCache<Key, MyObject> cache;
#PostConstruct
public void init() {
cache = Caffeine.newBuilder()
.maximumSize(10_000)
.refreshAfterWrite(cacheDuration)
.recordStats()
.build(this::loadMyObject);
// trick the compiler
Cache tmp = cache;
cacheMetricsRegistrar.bindCacheToRegistry(new CaffeineCache(CACHE_NAME, tmp), Tag.of("name", CACHE_NAME));
}
The Cache should now show up in the cache actuator endpoints, e.g. "http://localhost:8080/metrics/cache.gets"
use CacheManager
add your custom cache into CacheManager, inject CacheManager and get that cache out for your usage.
see https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-caching.html for some further details

Togglz with Spring #Configuration bean

I'm trying to implement Togglz & Spring using #Configuration beans rather than XML. I'm not sure how to configure the return type of the Configuration bean. For example:
#Configuration
public class SystemClockConfig {
#Bean
public SystemClock plainSystemClock() {
return new PlainSystemClock();
}
#Bean
public SystemClock awesomeSystemClock() {
return new AwesomeSystemClock();
}
#Bean
public FeatureProxyFactoryBean systemClock() {
FeatureProxyFactoryBean proxyFactoryBean = new FeatureProxyFactoryBean();
proxyFactoryBean.setActive(awesomeSystemClock());
proxyFactoryBean.setInactive(plainSystemClock());
proxyFactoryBean.setFeature(Features.AWESOME_SYSTEM_CLOCK.name());
proxyFactoryBean.setProxyType(SystemClock.class);
return proxyFactoryBean;
}
}
The systemClock method returns a FeatureProxyFactoryBean but the clients of this bean require a SystemClock. Of course, the compiler freaks over this.
I imagine it just works when XML config is used. How should I approach it when using a configuration bean?
I'm not an expert for the Java Config configuration style of Spring, but I guess your systemClock() method should return a proxy created with the FeatureProxyFactoryBean. Something like this:
#Bean
public SystemClock systemClock() {
FeatureProxyFactoryBean proxyFactoryBean = new FeatureProxyFactoryBean();
proxyFactoryBean.setActive(awesomeSystemClock());
proxyFactoryBean.setInactive(plainSystemClock());
proxyFactoryBean.setFeature(Features.AWESOME_SYSTEM_CLOCK.name());
proxyFactoryBean.setProxyType(SystemClock.class);
return (SystemClock) proxyFactoryBean.getObject();
}
But I'm not sure if this is the common way to use FactoryBeans with Spring Java Config.

Resources