Multi tenant configuration spring boot - java

I wonder if there is a good solution to manage different configurations for different tenants in runtime, the same instance should manage all the tenants.
Currently, the application gets all the properties using #Value but this inject the properties in the application runs, and the property is gonna be different depends on the tenant making the request.

Related

Spring - decide on profile based on database

We use a WebApplicationInitializer to decide the relevant Spring profile based on local properties
We want to decide on spring profile based on database table (one central place)
The issue is that not all beans are initialized, can it be done in a straight way?
Is it a good approach or anti-pattern/wrong to load spring profile from database ?
Note we already use #Order(1) in our classes
I found old related question but without any solution
In ApplicationContextInitializer I cannot use Spring beans because the application context is not yet fully initialized. Is low level access to the database my only option?
There's option to keep a cluster servers which will load database and then all servers will get profile using cluster, but it seems like a overhead

How to disable Spring/Hibernate/Hazelcast joint cache?

We use Hazelcast as our Hibernate 2nd level cache manager and we have some configurations for it in our Spring context files. Our code is also instrumented by Spring #Cacheable annotations (for business level cache) and we configured it to use Hazelcast. The problem is that in development environment we have multiple database instances and sometimes we should switch our application between them. Each time we switch to another database we should also restart the Hazelcast to be filled with new data and it is a REALY annoying work :(( This is more annoying when we need to have multiple instances of our application up on different databases! so we need also multiple instances of Hazelcast!!
As our code is tightly coupled with cache stuffs, it is so hard to remove cache configurations from the code for new instances. Is there any way to tell Hazelcast, Spring and Hibernate do not use/fill cache in presence of our configurations?
You should be able to turn off caching with the Spring and Hibernate configurations. In case of Spring Boot, you can do it by setting the following properties in your application-dev.properties:
spring.cache.type=NONE
spring.jpa.properties.hibernate.cache.use_second_level_cache=false

How to avoid putting #RefreshScope on multiple beans in my application

We are externalizing configuration of our microservices (spring boot based) using spring cloud.
As per my understanding on Spring Cloud, to enable the beans loading refreshed/updated values from Config server we need to do 2 things in Spring Cloud Client:
add #RefreshScope on the beans reading values from property files
using #Value
add spring actuator to provide /refresh endpoint to
refresh the context.
Scenario:
We have 100s of classes reading values from property file using #Value.
I have to mark all these beans refresh enabled using #RefreshScope annotation.
How can I avoid putting #RefreshScope annotation on all these classes.
Is there any shortcut or spring cloud feature to get around this situation.
You may want to look into Spring Boot feature called #ConfigurationProperties. It is designed to better organize several external configuration options.
According this Github issue, it should work for spring-cloud without #RefreshScope usage.
EDIT (reaction on comment): Maybe you are missing point of #ConfigurationProperties. With this annotation, you wouldn't use it in other configuration classes. You would have dedicated class (or few classes) only for reading and providing properties. Other configuration classes would inject this configuration holder bean.
You could encapsulate your #Values into one (or several) ConfigurationService bean which is #RefreshScoped and autowire this service into your classes instead. That way you only have a small amount of request scoped beans and your services can stay singletons.

Spring boot, how to organize multiple profile specific datasources

I'm lacking solid patterns and reference, how to organize profile specific security and persistence configurations in Spring Boot, where multiple profile specific DataSources may co-exists for different contexts.
Let's say I have three maven profiles: dev, qa, prod, each of which defines different properties for database connections, JPA configuration, logging etc.
With dev build, Spring should authenticate users against in-memory map, which is populated on startup. This is easy to implement using AuthenticationManagerBuilder interface.
However, with qa and prod builds, user should be authenticated against database. Now Spring should configure a DataSource with profile-specific connection parameters, and use this specific DataSource in UserDetailsService, retrieving the credentials for authentication mechanism. I know how to create necessary beans, but here is the problem:
One important fact is, the user DataSource is distinct from the actual business entity DataSource. How can I define profile specific DataSource in security configuration, and tie the scope of this particular DataSource to the security configuration, making User DAO (either Spring Data JPA repository or injected EntityManager) use this DataSource? Is this where concept called Persistence unit comes into play?
Also, is it a good idea to configure HttpSecurity in a base class, and extend Profile specific configurations from this class, where either AuthenticationManagerBuilder is utilized or DataSource beans are defined?
Another question is, how to enable the Spring profile based on the maven profile? I think using the common denominator for both is a bad idea, as maven profile activation by variable is one-to-one, where as spring.profiles.active may list multiple profiles. Is it a good idea in a first place to mix maven profiles and Spring profiles, or is there a better way to organize things?
I know it's a broad question, but it's a broad subject which I need to grasp. Is there some good examples targeting these problems?

Access properties dynamically with Spring

I have a Spring application with xml configuration (v4.0.8) where I need to access properties dynamically rather than using #Value annotation. I tried using tho methods for this, one of them is using #ConfigurationProperties with a Map which gives me all properties in a map, and the other way is using Environment.getProperty.
Both methods are getting the properties from the propertySources of the Environment. Unfortunately that contains 5 property sources including system properties, etc, but not my properties files. Therefore I cannot access my properties.
I'm adding my properties using EncryptablePropertySourcesPlaceholderConfigurer from jasypt which is a simple implementation of PropertySourcesPlaceholderConfigurer that decrypts encrypted property values. PropertySourcesPlaceholderConfigurer does not add properties to Environment.propertySources and I couldn't figure out how can I extend it myself rather than using jasypt implementation and add them to property sources manually.
Two notes:
#Value annotation works fine, because it's not using Environment but goes through configurers during bean creation. There's not problem with that.
I have a spring boot application where I cold achieve my goal appending to Environment.propertySources by listening to ApplicationEnvironmentPreparedEvent of spring boot and adding my properties to Environment rather than implementing PropertySourcesPlaceholderConfigurer. But this is only applicable to spring boot applications and my legacy application is not a spring boot app.

Categories