Spring Cloud; CloudFoundry; spring.jpa properties - java

I am using spring cloud to bind services to a spring boot application deployed to CloudFoundry. When running locally, I can pass Java options to the application as follows:
-Dspring.jpa.hibernate.ddl-auto=create-drop
Now I would like to do the same thing when running the application on CloudFoundry. What's the usual way to do this?

An alternative to setting a system property or environment variable is to set this as a Spring property in src/main/resources/application.properties or src/main/resources/application.yml.
application.properties:
spring.jpa.hibernate.ddl-auto=create-drop
application.yml
spring:
jpa:
hibernate:
ddl-auto: create-drop
With this approach, the configuration will be applied regardless of now the app is deployed - locally, on CF, or on another platform.

You can put an env entry in your manifest.yml file like so:
env:
spring.jpa.hibernate.ddl-auto: create-drop
See more information here:
http://docs.cloudfoundry.org/devguide/deploy-apps/manifest.html#env-block

Related

Why couldn't I use #Scheduled with an externalized Spring Cloud properties file?

When I was working on a Spring Boot application that used scheduling and acted as a config client, I was unable to pull the crontab expression from the application-cloud.yml file.
This:
#Scheduled(cron = "${cron.expression}")
did not work.
Putting the cron.expression in the jar's internal application.yml was not an option. As a workaround, I changed the source of that property to the appropriate environment variable, CRON_EXPRESSION.
Does anyone know why I had to do that? Why was Spring Scheduled unable to resolve an externalized configuration property?
Edit:
Here is the bootstrap.yml that the project was setup with:
spring:
profiles: cloud
application:
name: application-name
cloud:
config:
uri: https://config-server.com
fail-fast: false

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 autoconfiguration based on env variables

In my understanding in a spring-boot application when having spring-boot-starter-data-jpa on your classpath and also mysql-connector
spring-boot will still try to use in memory h2 (as per default), if no db related properties are defined.
But if you have properties like the following:
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_example
spring.datasource.username=springuser
spring.datasource.password=ThePassword
It will use mysql database.
My question is:
what happens if you have those properties only declared as environmental variables ?
Is this behaviour still valid ?
thanks!
I tried using the following dependencies together: "web", "mysql", "jpa". A simple run without any configuration shows the following error:
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).
And if you use the environment route instead of "application.properties" as long as you set them correctly it should act the same as a fully configured "application.properties" file.

Environment Specific Eureka properties is not loading

I have created a Eureka Client and Server project using spring Cloud 1.5.17 version. Both the project is working fine but the issue is that based on environment I want certain eureka properties to be loaded at run-time for the client project. For that what I have done is that I have created environment specific property file for eureka like as shown below.
I have tried all the below three properties in application.yml but none of them seems not picking the eureka-client-test.properties properties
spring:
profiles:
active: test
eureka:
instance:
environment: test
eureka:
instance:
environment:
active-profiles:
- test
Can anyone please help me on this
Full source code is committed and is available under the below bitbucket repository
https://bitbucket.org/resh32/eureka
Override this property eureka.client.props with your property file name without .properties suffix.
So lets say you specify your spring active env using spring.profiles.active & then in corresponding application-env.properties file you can set eureka.client.props to eureka-client-env.

How to resolve placeholder in properties file with values from another properties file in spring boot application

My spring boot application has below properties files.
src/main/resources/config/DEV/env.properties
mail.server=dev.mail.domain
src/main/resources/config/QA/env.properties
mail.server=qa.mail.domain
src/main/resources/config/common/env.properties
mail.url=${mail.server}/endpoint
Is it possible to load "common/env.properties" so that it's placeholders will be resolved using the given environment specific properties file. For DEV environment, we want the placeholders in "common/env.properties" to be resolved using values from "DEV/env.properties".
There are answers about how to load multiple properties files and profile based loading but could not find an answer for this particular use case.
Thanks in advance.
2 Options :
Generate the common/application.properties using configuration-maven-plugin and filter files for each environment. It is outdated now.
Use application-<env>.properties for each environment and pass the -Dspring.profiles.active=<env> as VM option in application start up. Spring will automatically take the property from correct file.
In option 2, you will be overwriting whatever is present in application.properties with application-.properties. So you dont have to add only the properties which you need to change per environment.
for eg:
Your application.properties can have
logging.level.root=WARN
logging.level.org.apache=WARN
logging.level.org.springframework=WARN
Your application-dev.properties can have
logging.level.org.springframework=DEBUG
which means, when you are starting application using dev profile, spring takes
logging.level.root=WARN
logging.level.org.apache=WARN
logging.level.org.springframework=DEBUG
edit :
Also, you can try something like below on your class. (Spring will overwrite value in config.properties with values from config-dev.properties). ignoreResourceNotFound will make sure, application will still start with default values even if the corresponding file is not found.
#Configuration
#PropertySource("classpath:config.properties")
#PropertySource(value = "classpath:config-${spring.profiles.active}.properties", ignoreResourceNotFound = true)
You can add resources/application.yml file where you can have multiple profiles in one File.
MultiProfile Yaml
e.g.here are two different profiles 'dev' and 'qa' with different applicationNames 'DEV' and 'QA' and one defaultName 'Default'
spring:
application:
name: Default
profiles:
active: qa
---
spring:
profiles: dev
application:
name: DEV
---
spring:
profiles: qa
application:
name: QA
You can achieve this by declaring a property source on a class configuration and setting up an environment variable in the path :
#PropertySource({ "classpath:config/${env}/env.properties" })
#Configuration
public class config{}
And then you launch the spring boot app with the command line variable -env=dev
UPDATE
You can use #PropertySources annotation to load several properties.
#PropertySources({
#PropertySource("classpath:config/${env}/env.properties"),
#PropertySource("classpath:config/common/env.properties")
})
public class config{}

Categories