How can I load properties in spring boot from a custom source? - spring

I have a spring boot application. I do not want to store sensitive properties (e.g. DB password) in my application yaml or system environment variables. How can I load properties from a custom source before the startup of the context?
Meaning of custom property source: I want to write the code which reads these properties, because they are not stored in files or on classpath.
Update:
I want to store my properties in AWS SSM Parameter Store.

Related

How do I load AWS region specific properties from Spring Boot application properties?

My java microservice (developed in Spring boot) loads S3 bucket from an application properties file. S3 bucket names for 4 different AWS regions are different (bucker-east-1, bucker-west-2 etc) hence how do I load AWS region-specific properties from application properties? For example, for us-west-2 region, bucker-us-west-2 property should be loaded, etc. is there any existing support for this type of feature in SPring boot?
There's at least a couple of ways you could handle this.
Use environment variables: Using env variable in Spring Boot's application.properties
Feasibly you could structure the names to be something like bucket.name=<bucket-prefix>-${AWS_REGION}
Use Spring profiles. You can create separate properties files for each region.
For example, you'd have application-us_east_1.properties, application-us_east_2.properties. You then can add the appropriate spring profile upon deployment by passing in the JVM parameter, -Dspring.profiles.active=us_east_1 to activate us_east_1. Alternatively, you can use the SPRING_PROFILES_ACTIVE environment variable similarly.

Fetch any service's properties from spring config server

Using spring cloud config properties can be defined for different services and different environments, e.g. using a native profile we could have the following tree in the server:
resources
config
service-a
service-a-local.properties
service-a-test.properties
service-b
service-b-local.properties
service-b-test.properties
and have client services bootstrapped with configuration from the server, using one of the available options, such as #Value annotations etc. This however will only see the properties slice from the config server for the calling service (or whatever spring.application.name is used).
How can service-a access properties of service-b (or any other service) dynamically? The default property source locator uses a "/{name}/{profile}" path for fetch requests. I suppose one could restructure the entire configuration and put all services' properties in one file per environment, using some appropriate naming convention for the properties (e.g. using the service name as the prefix), and then explicitly prefix the calling-site property references with that prefix, but is there another/more elegant option, before using a discovery/mesh alternative?

application.properties configuration for distributed database pattern

I am trying to develop a microservice by using sprin and spring boot with postgresql database. I am here using distributted datbase. So for particular region I am using one DB, and for other region I am using different DB. Currently I only tried with one database. I added datasource name , username and password in application.properties.
Here my doubt is that, if I am using multiple distributed database, how cam mention different DB source URL in configuration (application.properties)? I am using following structure to use one database currently,
spring.datasource.url=jdbc:postgresql://localhost/milleTech_users
spring.datasource.username=postgres
spring.datasource.password=postgresql
spring.jpa.generate-ddl=true
Like above.
So if I am using multiple DB for multiple region How I can give configuration conditionally here? I am new to microservice world and distributed database design pattern.
Multiple Database details cannot be managed within a single application.properties.
Consider using Spring Cloud Config where in you can create multiple application.properties with different profile names for every application.
In your case, the profile names could reflect the region. When you deploy to a particular region, launch the app with that profile name so that the required config would be loaded and appropriate database connection would be used
Edit :
Also in your case, if you can set environment variables, you can explore on the following option mentioned in this thread

No plain text passwords in Spring Boot’s application.properties

Having something like
security.user.password = plainTextPassword
inside Spring Boot’s application.properties is obviously an anti-pattern as it prevents the code from being pushed to a public SCM. In my non-Spring Boot projects I use
security.user.password = ${myPasswordFromMavenSettingsXML}
and put a corresponding <properties/> reference inside my pom.xml.
Using Maven’s resource filter plugin the passwords are replaced at build time so the application have access to actual plain text passwords after it has been build and deployed.
For some reason Maven’s resource filter plugin does not work in this case. Is there a way to not commit plain text passwords to an SCM and let Spring Boot to insert them at build time?
Spring boot has multiple mechanisms to provided externalized configuration. Some examples are command line arguments, environment variables and also application properties outside of your packaged JAR.
What I usually do:
Locally we configured several environment variables. Most (if not all) IDE's allow you to configure environment variables from within the run configuration.
For example if you don't want to expose the spring.datasource.password property you could set an environment variable called SPRING_DATASOURCE_PASSWORD.
When we deploy on another environment, we usually choose to add another application.properties or application.yml file within the same folder as the application JAR/WAR, since Spring boot picks that up as well.
Another solution is to use Spring cloud since it has a config service which can be used as a microservice to provide configuration. The configuration can be versioned using SCM as well, but you can put it on a separate system that is not connected to your source code.

Spring Property place holder / multiple applications within the same tomcat/jvm

Is there a way to use Spring 3 property place holder to load application specific properties without conflicting with other applications within the same tomcat/jvm ?
All of your application specific properties are residing inside your jar and tomcat will only make them available to your application.
Just put them under webapps/${app_war}/WEB-INF/classes/app.properties and your spring config will pick them up from classpath.
System properties via -D startup parameters are shared, but not application specific.

Resources