Spring Boot read environment variables inside application-properties - java

So I have been trying to figure out how to use environment-variables in either application.properties or application.yaml. Since this works in countless frameworks (such as Laravel for example), I assumed this would also work in Spring Boot. Now as I have found out, this is not the case.
I saw a post about Spring Environment API, that started that the environment-variable SPRING_DATASOURCE_URL would be equivalent to setting spring.datasource.url inside my application. However, this also didn't work for me.
Is there any quick way that allows using variables that are declared inside a .env file?
I'd like to use it like this inside the application.properties if possible.
spring.datasource.url=jdbc:postgresql://${DB_HOST}:${DB_PORT}/${DB_NAME}

.env is way of Python. If you use spring cloud, you can read env variable from configServer then inject them into application.properties.
add some dependency into pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
define a yml to locate config-server. for example, called myBootstrap.yml
spring:
cloud:
config:
fail-fast: true
uri: http://[config-server-git]
name: cc
profile: config
label: maste
define a file named cc-config.properties and push it into config-server git. The env variables are written in this properties.
use below way to run application jar
java -jar [your-application-jar] --spring.cloud.bootstrap.location=myBootstrap.yml

Related

How does spring boot know which property file to use based on environment

I have 4 files in my project:
application.properties
application-dev.properties
application-qa.properties
application-prod.properties
application.properties has a property spring.profiles.active = #active.profile#
When running on local, it uses application-dev.properties file. But in UAT and Prod, it uses respective property files. My question is how does spring boot know to use dev when im running in local and and qa in uat and prod in prod?
What does #active.profile# mean?
This is decided by the "profiles" variable. This is a Set<String>.
The exact way spring detect the profiles depends on the way you run your application.
The most common way is through the System Parameter: -Dspring.profiles.active=dev. So I assume somwhere in your production enviroment this variable gets set.
Alternativelly, if you run your spring app via a builder, you can define the profiles explicitly (code is in kotlin):
SpringApplicationBuilder(MyApp::class.java)
.profiles(*profiles)
.run(*args)
Check this article for more info: https://www.baeldung.com/spring-profiles

How to autoselect springprofile when running tests

I am looking for a solution to automatically add the environment variable SPRING_PROFILES_ACTIVE="test" when running unit-tests. The solution should fulfill the following criteria :
Ideally it should be configured via maven pom.xml
If 1 is not possible configuration should be done for IntelliJ via configuration file in the project not via UI setting
The particular environment variable should only be set when running unit tests not when generally launching the app.
Any idea on how to approach this goal is appreciated.
Best
Andy
The SPRING_PROFILES_ACTIVE is a property value that should be set in a file like application-test.properties or application-test.yml
In a yml file it would look like,
spring:
profiles:
active: test
Additionally, there are specific annotations to help identify certain classes/methods as test specific such as #Profile("test") or #ActiveProfiles("test").

How to select profiles in spring-boot

I have application files according to my environment: application.yml and application-uat.yml. I'm running the application by providing the SPRING_PROFILES_ACTIVE as environment variable so that the correct file is selected. I have a problem with defining additional profiles inside application.
Suppose I have a bean with profile mock-rest that mocks the rest client and I have a bean with profile actual-rest.
I've tried two do it in those ways:
#inside application.yml
spring:
profiles:
include: mock-rest
And for UAT:
#inside application-uat.yml
spring:
profiles:
include: actual-rest
But the problem is that spring will include both profiles, because it takes the both files and only replaces the values from uat yml file.
If I try to use spring.profiles.active inside yml files Spring will ignore that as the SPRING_PROFILES_ACTIVE environment variable will have priority.
So, the question is what is the way to overcome described problem? Basically, I need to define profiles inside application.yml files and I want to only define environment as my SPRING_PROFILES_ACTIVE env variable. Is this possible? If not, what are my options to consider?
The application.yml file is read whatsoever. This is an indented behaviour. Usually, all values in application.yml would be overrided by other more specific application-*.yml.
But profiles are not a single values, you can have multiple one enabled at the same time, so i does not oeverride the profile, instead it cumulate both.
If you want to get rid of the mock-rest on prod environment you might want to remove the mock-rest profile from application.yml and move it to a new application-mock.yml that you can activate using an environment variable.
application.yml
# some default configuration
application-mock.yml
spring:
profiles:
include: actual-rest
application-uat.yml
spring:
profiles:
include: actual-rest

Global variables And Application Variables Defining in Spring boot project

I am trying to develop micro service by using spring and spring boot. In my project , I am converting monolithic to service oriented architecture. Project contain 20 Micro services.I these I need to set application variables and global variables. I have confusions related to this , And I am adding those confusions here,
Is possible to declare my global variables in application.properties file? If not possible where I can define my global variables?
If I am using spring config server for global configuration, How I can import those properties conditionally to client project?
Can I set different property files for different profiles in config server , and conditionally import into client project for different profiles? Here each profile representing different regions in my case.
After My Exploration I find out Solution for this problem for loading global variables and application variables including database configuration. The best way we can use that is - spring cloud config server externalized configuration.
We can create a microservice for spring cloud config server. In config server we can create our variables and configuration in two ways.
Configurations from GIT Link reference
Using local file system / Environment variables.
Links To refer
https://cloud.spring.io/spring-cloud-config/single/spring-cloud-config.html
https://cloud.spring.io/spring-cloud-static/spring-cloud-config/1.3.3.RELEASE/multi/multi__spring_cloud_config_server.html
https://github.com/spring-cloud/spring-cloud-config
Here I followed using local file system.
Need to create Config folder under src/main/resources. And create different profiles by following naming convention,
db,properties , db-test.properties , db-prod.properties , db-dev.properties.
I created for example for different development environment. Like we can create any profiles for variables and configuration.
And add following in application.properties for config server
server.port=8888
spring.profiles.active=native
Add config server dependency in pom.xml file of config server,
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
Add the following into main application run class,
#SpringBootApplication
#EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
And also create client microservice project by adding pom.xml dependency,
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
Add following line in application.properties file for setting client to receive configuration from server,
server.port=8080
spring.application.name=db
spring.cloud.config.uri=localhost:8888
Finally run your client project by specifying profile ,
java -jar -Dsping.profiles.active=<profile> <jar_name>.jar
Thanks In advance

Spring Datasources based on Environment

I am trying to configure my Spring Boot application to use specific datasources when certain environmental variables exist. For example, if the MY_PROD_DATASOURCE environmental variable exists, I would like to use my production datasource; otherwise, I would like to use my local datasource (of the same type).
I have found something in the Spring reference that explains how a single datasource could be declared in my application.properties. Specifically, a MySQL datasource could look like:
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driverClassName=com.mysql.jdbc.Driver
However, I do not see how I could change the datasource properties conditionally in this file. Is there another way to do it?
In Spring Boot you can:
Externalize application.properties from your jar and provide file per environment by adding path as a startup parameter:
java -jar your-app.jar --spring.config.location=/path/to/app.properties
Use Spring profiles. Create application-${profile}.properties for each profile, in each one different datasource properties
Use Spring profiles and instead of application.properties, put your properties to application.yaml where you can put properties for all environments using convention as below:
spring:
profiles: development
server:
port: 9001
---
spring:
profiles: production
server:
port: 0
Use environment variables and set SPRING_DATASOURCE_URL, SPRING_DATASOURCE_USERNAME, SPRING_DATASOURCE_PASSWORD, and (optionally) SPRING_DATASOURCE_DRIVER_CLASS_NAME.
Learn more in the Spring Boot reference section on How to change configuration depending on the environment and External Configuration.

Categories

Resources