Spring boot, how to organize multiple profile specific datasources - java

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?

Related

Multi tenant configuration spring boot

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.

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.

Can I selectively disable Spring Data repositories for testing?

I'm writing a module-level integration test for a system using Spring Integration. I need the integration plan up and running but at this level am still using MockMvc and a mocked repository interface to ensure that I have all of my mappings, conversions, and message routing correct.
Right now, my module-level Enable configuration is meta-annotated with #EnableMongoRepositories, and the Spring test runner aborts because it doesn't have a live mongoTemplate to create the repositories from; the mock repository doesn't prevent the attempt to create real ones.
I know that I can conditionalize the inclusion of #EnableMongoRepositories, but is there simpler way to tell Spring Data not to create repository proxies if I'm already supplying mocks for them?
Basaically if I understand correctly you have two kinds of set up for your MongoDB repositories, mock and live. So you want to run integration tests and control the repository that is being used. I would suggest using "Spring Profiles".
create an simple interface say MongodbCofig
crate two configuration classes for mock and live. Make sure these classes implement MongodbConfig. Set the profiles (#Profiles) in both the classes.
Later activate the required profile before running the tests
For detailed understanding of profiles you can refer here

Categories