Spring Boot: How to create 3 profiles and implement in spring boot - java

I want to create 3 profiles to access the database based on the enviroment
Instead of writing all the properties in a single file. I want the properties has to be split into 3 based on enviroment (Qlty,Prod,Dev). That is
1.application_prod.properties --should contain all production related details
2.application_qlty.properties --should contain all qlty related details
3.application_dev.properties --should contain all dev related details
How to implment the above 3 profiles in spring boot and how to select the profile based on the type of enviroment. what is the best practice to implement the above in an easy manner

you just add profile on run options
java -jar app.jar --spring.profiles.active=dev
or with maven
mvn spring-boot:run -Dspring-boot.run.arguments="--spring.profiles.active=dev"
One remark. profile on property file writes with "-"
application-dev.properties

Related

How to use environment variables on a Spring Boot and Gradle application?

I explain my problem;
I have a web app developed using Vue.js and Spring Boot, this application working a PDF sheet and saves the file that is generated by Java, I use two lines of code to separate my development part from the production part (I leave you the 2 lines of code like this you understand the concept well)
FileReader leggoFile = new FileReader(System.getProperty("user.dir") + "/temp/webapps/foolder/foolder/file.pdf");
// FileReader leggoFile = new FileReader(System.getProperty("catalina.base") + "/temp/webapps/foolder/foolder/file.pdf");
This whole application is built using the "bootWar gradle plugin" which returns me a .war which I will then upload to a Tomcat server;
My goal is this:
I would like to set a single environment variable so that if I want to build the project I don't have to comment/uncomment that line for example:
FileReader leggoFile = new FileReader({{variableEnvironment}} + "/temp/webapps/foolder/foolder/file.pdf")
my question is this:
How dp Gradle and Spring Boot handle environments? Is there a way to separate environments? Is this possible or should I start thinking differently?
I tried to search on something but unfortunately I was tied to the problem that I don't understand how the .war file is generated through the BootWar Gradle plugin, also searching on the internet I understood that environment Gradle and environment Spring are two separate things but in general even if I know the line of code is wrong in the beginning my question is always the same:
How are environment variables handled in Spring and Gradle?
With Spring Boot, you can add properties to your application by adding an file named application.yaml to your resources folder (src/resources/). In addition you can add properties through application-{profile}.yaml to add properties only for given Spring profiles. For instance application-test.yaml would only be read if "test" is an active profile. When booting up the application, Spring will first read application.yaml, then any profile-specific YAML-files, such that any overlapping properties are replaced.
There are several approaches to injecting the property. A simple solution is to add a field to your component annotated with #Value("${PATH}) and replace PATH with the property's path in the YAML.

Flyway - Different Migrations for certain envioronments - Spring Boot

We are configuraing/starting our flyway migrations in java in our Spring Boot App.
So we have both sql and java migration files.
In certain environments we want extra migrations to run. Basically in a QA env we want to prepare the DB with data for tests.
So I know you can configure multiple migration locations in java.
So I can do something like this
if(isQAenv == true)
{
Flyway.configure().locations("/db/migrations/","db/qaMigrations/")
else{
Flyway.configure().locations("/db/migrations/")
}
My issue is with the versioning and making sure stuff gets executed as intended in all envs.
Do I need to maintain the numbering system to be the correct order?
So lets say I have the following migration scripts that should run in all envs
db/migrations/V1__table1.sql
db/migrations/V2__table2.sql
db/migrations/V4__table2.sql
And this migration only runs in QA env
db/qaMigrations/V3__insert_statements.sql
Now in a non QA env, my beacon_history_table has migration for 1,2,4. Is there any way to avoid this and have something that looks cleaner in the history table?
You can easily do that using profiles, so suppose you have profiles i.e dev, prod, then you can easily define the spring.flyway.locations path in your properties file for that profile or in a section for that profile in application.yml file.
spring:
profiles: prod
flyway:
locations: classpath:/db/migration,classpath:/prod/db/migration
---
spring:
profiles: dev
flyway:
locations: classpath:/db/migration,classpath:/dev/db/migration
Or if you have properties file then you should have file i.e application-dev.properties and then
spring.flyway.locations=classpath:/db/migration,classpath:/dev/db/migration
All the paths, mentioned above should be present inside the resources folder.

Spring Boot - Profiles (application.properties) to define baseUrl for HTTP requests

The situation is that I have two api projects, API A does HTTP requests to API B. Both API's are deployed to a development and production environment.
What I want to achieve is the following: Build the project based on a specific profile (dev or prod) so that the code can use a particular baseurl to talk with the correct api on the correct environment.
So if I build API A based on prod flag, I want it to use the specific url to make http requests to API B that is deployed on it's own prod environment.
It looks like you're referring to profiles of maven, however you should probably check out spring profiles. The concept should change :
You're not supposed to build different artifacts for different environments.
Instead create a spring profile in service A:
application-dev.properties:
url.addr=dev-service-host:1234
application-prod.properties:
url.addr=prod-service-b-host:4321
Then run the application with --spring.profiles.active=dev (or prod) flag.
Spring boot will load the correct definitions automatically because the dev/prod matches the suffix of properties file
You can define Spring-Boot profile as:
spring.profiles.active=prod
You also should have profiled .properties files in resources:
in application-dev.properties you should have api.b.url={api_b_url_on_dev_environment}
in application-prod.properties you should have api.b.url={api_b_url_on_prod_environment}
Or if you don't want to recompile your application after changing properties you may use outside .properties files.
In order for them to be included during app's deployment do the following:
in some config directory add application-dev.properties and application-prod.properties
deploy you app with the following properties: --spring.profiles.active=dev and --spring.config.additional-location=config/application.properties
This way the outside profiled properties will be included in deployment process. These .properties files have the highest priority in Spring.

Can we use multiple yaml files in a single spring boot application?

I have one yaml file that reads all the environment profiles. I need another yaml file to create a feature switch that i can turn on/off during deployment. And how can we define the feature switch in properties file.
Yes, you can use multiple YAML files if you use spring profile. For example, if you start your JVM with the following flag:
-Dspring.profiles.active=deployed,cassandra
It will pick up the following application YAML files:
application.yml, application-deployed.yml, and application-cassandra.yml
Another way to do this, is by adding this key in the application.yml file like below
spring:
profiles:
include:
- student
- address
and you can name your yaml files, as
application-student.yml, application-address.yml

JAVA SPRING - Using Maven, steps to create 2 war file (quality & production)

Can anyone please help me to create 2 war files using maven, java spring?
Requirement: Need 4 war file
For that 1st create 2 war file
(make another 2 copy from this with different name for oauth)
database name only diff between staging & production war
staging (http://10.19:3006/imdesk_imapi_staging)-sql datasource- for staging
1)war - api
2)oauth staging war - copy
production (http://10.19:3006/imdesk_imapi_production)-sql datasource for ****production****
1)api - war
2)oauth war - copy
work with maven profiles
http://maven.apache.org/guides/introduction/introduction-to-profiles.html
so you can create different artifacts for different stages
I see two paths you could take to solve the issue:
1. Use maven profiles.
http://maven.apache.org/guides/introduction/introduction-to-profiles.html
How can a profile be triggered? How does this vary according to the type of profile being used?
A profile can be triggered/activated in several ways:
Explicitly
Through Maven settings
Based on environment variables
OS settings
Present or missing files
Details on profile activation
Profiles can be explicitly specified using the -P CLI option.
This option takes an argument that is a comma-delimited list of profile-ids to use. When this option is specified, the profile(s) specified in the option argument will be activated in addition to any profiles which are activated by their activation configuration or the section in settings.xml.
mvn groupId:artifactId:goal -P profile-1,profile-2
2. Use Spring profiles.
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-profiles.html
Spring Profiles provide a way to segregate parts of your application configuration and make it only available in certain environments. Any #Component or #Configuration can be marked with #Profile to limit when it is loaded:
`#Configuration
#Profile("production")
public class ProductionConfiguration {
// ...
}
In the normal Spring way, you can use a spring.profiles.active Environment property to specify which profiles are active. You can specify the property in any of the usual ways, for example you could include it in your application.properties:
spring.profiles.active=dev,hsqldb
or specify on the command line using the switch --spring.profiles.active=dev,hsqldb

Categories