Spring Add Profile at runtime - spring

I want to add a profile at runtime based on some environment variable, so I have -Dspring.profiles.active=local and in code I have
if(someCondition){
springApplication.additionalProfiles("mock-test");
}
If someCondition is true, was expecting active profiles to be "local", "mock-test" but its in reverse order?
INFO o.s.b.SpringApplication : The following 2 profiles are active: "mock-test", "local"
Anyway to make mock-test as last profile?

Related

AWS Secret Manager with Spring Boot Application

I tried to get secret manager value use this answer
How to integrate AWS Secret Manager with Spring Boot Application
But my application get secrets 2 times, first as I want with local profile, but second without any profile. Why application go to secret second time and how can I off this?
2021-08-19 11:40:01.214 INFO 9141 --- [ restartedMain] s.AwsSecretsManagerPropertySourceLocator : Loading secrets from AWS Secret Manager secret with name: secret/test_local, optional: false
2021-08-19 11:40:02.702 INFO 9141 --- [ restartedMain] s.AwsSecretsManagerPropertySourceLocator : Loading secrets from AWS Secret Manager secret with name: secret/test, optional: false
2021-08-19 11:40:02.956 ERROR 9141 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed
my config in bootstrap.yaml
aws:
secretsmanager:
prefix: secret
defaultContext: application
profileSeparator: _
name: test
start application with -Dspring.profiles.active=local
upd. If I create secret for secret/test I have the next one
s.AwsSecretsManagerPropertySourceLocator : Loading secrets from AWS Secret Manager secret with name: secret/application_local, optional: false
Currently there is no way to disable prefix/defaultContext look up.
If you take a look here you will see that prefix/ + defaultcontext of loading is always added and used.
You can check docs as well, to have more clear way what is being loaded and in what order.
My recommendation is to switch to spring.config.import since that will be the way we are going to take Secrets Manager importing. Big difference is that, it gives users a lot more control of which secrets they want to import since you can specify each key individually. spring.config.import can be found explained in docs or you can check the project sample .

GitLab CI CD runner not loading properties file for profile

When I run a command mvn clean test -Dspring.profiles.active=GITLAB-CI-TEST in the GitLab CI CD it not loading properties file application-gitlab-ci-test.properties. It is loading only application.properties.
As file application-gitlab-ci-test.properties contains the different value for spring.datasource.url the pipeline is failing in the remote runners with error
The last packet sent successfully to the server was 0 milliseconds ago.
The driver has not received any packets from the server.
Of course, this error is expected as properties file application.properties refers to the localhost database.
Code which loading application-gitlab-ci-test.properties:
#Profile("GITLAB-CI-TEST")
#PropertySource("classpath:application-gitlab-ci-test.properties")
#Configuration
public class GitLabCiTestProfile {
}
When I try to run the same command locally it's working as expected and in logs, I see the following records:
2020-03-30 19:23:00.609 DEBUG 604 --- [ main]
o.s.b.c.c.ConfigFileApplicationListener : Loaded config file
'file:/G:/****/****/****/****/target/classes/application.properties'
(classpath:/application.properties)
2020-03-30 19:23:00.609 DEBUG 604 --- [ main]
o.s.b.c.c.ConfigFileApplicationListener : Loaded config file
'file:/G:/****/****/****/****/target/classes/application-GITLAB-CI-TEST.properties' (classpath:/application-GITLAB-CI-TEST.properties) for profile
GITLAB-CI-TEST
I noticed that remote runners missing the second line. This one which loading application-GITLAB-CI-TEST.properties.
I also tried mvn clean test --batch-mode -PGITLAB-CI-TEST and this one too failing in the remote host but in local run working as expected.
I found the workaround for this issue by using the command
mvn clean test --batch-mode -Dspring.datasource.url=jdbc:mysql://mysql-db:3306/*******?useSSL=false&allowPublicKeyRetrieval=true
Can you please help me to solve this issue as this workaround is not satisfying me?
I found the solution to this issue.
I changed the name of the profile from the upper case (GITLAB-CI-TEST) to lower case (gitlab-ci-test), to match the lower case of profile name in properties file - application-gitlab-ci-test.properties.
Now in the remote runner, I'm using the following command:
mvn clean test -Dspring.profiles.active=gitlab-ci-test
Spring doc - link

am trying a Spring boot example but it is showing following error.. what should i do?

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-03-26 11:37:05.248 ERROR 9332 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
APPLICATION FAILED TO START
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location:
org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:175)
The following method did not exist:
org.apache.tomcat.util.modeler.Registry.disableRegistry()V
The method's class, org.apache.tomcat.util.modeler.Registry, is available from the following locations:
jar:file:/C:/Program%20Files/Java/jre1.8.0_77/lib/ext/tomcat-coyote.jar!/org/apache/tomcat/util/modeler/Registry.class
jar:file:/C:/Users/hp/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/9.0.31/tomcat-embed-core-9.0.31.jar!/org/apache/tomcat/util/modeler/Registry.class
It was loaded from the following location:
file:/C:/Program%20Files/Java/jre1.8.0_77/lib/ext/tomcat-coyote.jar
Action:
Correct the classpath of your application so that it contains a single, compatible version of org.apache.tomcat.util.modeler.Registry
please put some of your code snippet here, such as application.properties file, main and ... . or you can push your application to github and put your repository address here then i'll check it.

spring.profiles.include does not work from command line parameter

I made trivial Spring Boot application and packaged it as JAR.
When I call
java -jar target/boot-active-include-0.0.1-SNAPSHOT.jar
I got
No active profile set, falling back to default profiles: default
When I call
echo spring.profiles.include=B > application.properties
java -jar target/boot-active-include-0.0.1-SNAPSHOT.jar
I got
The following profiles are active: B
When I call
rm application.properties
java -Dspring.profiles.include=B -jar target/boot-active-include-0.0.1-SNAPSHOT.jar
I got
No active profile set, falling back to default profiles: default
But I expect The following profiles are active: B
Can I include Spring profile from command line?
Version: 1.5.1.RELEASE
PS. spring.profiles.active works as expected. But I don't want replace active profiles.
I see what's happening now, and I think it's arguably something I missed when making this change.
Prior to that change, spring.profiles.include was only considered when it was used in a configuration file. Following that change, spring.profiles.include is now considered from any source (System properties, command line arguments, etc) as long as spring.profiles.active is also set.
You can see this by running your sample with both properties set:
java -Dspring.profiles.include=alpha -Dspring.profiles.active=bravo -jar target/boot-active-include-0.0.1-SNAPSHOT.jar
Both the alpha and bravo profiles are active:
2017-02-09 11:30:49.467 INFO 40409 --- [ main] my.Example : The following profiles are active: alpha,bravo
I've opened an issue so that we can straighten this out.

grails database migration plugin problems after upgrade to grails 3

I was using a previous version grails-database-migration plugin for a while and never had any big issues with it. However, lately I upgraded the whole project to grails 3.0.9 and did some additional development, the behavior as follows:
Imported the current prod DB structure into local machine (that DB copy is without the latest changes and new entities)
Execute: grails -Dgrails.env=staging dbm-gorm-diff changlog.xml
What I expected at this point is new changlog.xml file with all changes of existing entities and new ones.
What I get:
Newly defined entities automatically got added into the DB.
The changes in changlog.xml only included the changes of already existing tables, such as:
also, If I try running grails -Dgrails.env=staging run-app
ERROR grails.boot.GrailsApp - Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springLiquibase_dataSource': Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: liquibase.integration.spring.SpringLiquibase.createDatabase(Ljava/sql/Connection;Lliquibase/resource/ResourceAccessor;)Lliquibase/database/Database;
FAILURE: Build failed with an exception.
What went wrong: Execution failed for task ':bootRun'.
Process 'command '/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/bin/java''
finished with non-zero exit value 1
...
...
Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. | Error Failed to start server (Use --stacktrace to see the full trace)
Here is the portion of my application.yml
dataSource:
pooled: true
url: jdbc:mysql://127.0.0.1:3306/triz?useUnicode=yes&characterEncoding=UTF-8
driverClassName: "com.mysql.jdbc.Driver"
jmxExport: true
username: root
password: password
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
properties:
jmxEnabled: true
initialSize: 5
maxActive: 50
minIdle: 5
maxIdle: 25
maxWait: 10000
maxAge: 600000
timeBetweenEvictionRunsMillis: 5000
minEvictableIdleTimeMillis: 60000
validationQuery: SELECT 1
validationQueryTimeout: 3
validationInterval: 15000
testOnBorrow: true
testWhileIdle: true
testOnReturn: false
jdbcInterceptors: ConnectionState
defaultTransactionIsolation: 2
environments:
development:
dataSource:
dbCreate: create
# url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
test:
dataSource:
dbCreate: update
url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
staging:
dataSource:
url: jdbc:mysql://127.0.0.1:3306/triz_staging?useUnicode=yes&characterEncoding=UTF-8
and gradle.build
buildscript {
ext {
grailsVersion = project.grailsVersion
}
repositories {
mavenCentral()
mavenLocal()
maven { url "https://repo.grails.org/grails/core" }
}
dependencies {
classpath "org.grails:grails-gradle-plugin:$grailsVersion"
classpath 'com.bertramlabs.plugins:asset-pipeline-gradle:2.5.0'
// classpath 'com.bertramlabs.plugins:less-asset-pipeline:2.6.7'
classpath "org.grails.plugins:hibernate:4.3.10.5"
classpath 'org.grails.plugins:database-migration:2.0.0.RC4'
}
}
...
...
dependencies {
...
compile 'org.liquibase:liquibase-core:3.3.2'
runtime 'org.grails.plugins:database-migration:2.0.0.RC4'
}
UPDATE
I have another way to approach this problem:
My plan was to generate a changelog based on my current prod DB and then generate a diff for the changes I made. Sounds simple and straightforward; however, it didn't work out as expected. Here is what I did:
Dumped prod DB
Removed liquibase tables
Run: grails dbm-generate-changelog changelog-init.xml --add
At this point, I expected changelog-init.xml to contain the current state of DB. But, instead it applied the changes based on my models first, and then tried generating the diff. Eventually, I ended up with a changelog including my entire existing DB with changes applied from gorm.
What am I doing wrong here?
Additional Observations
It looks like, whenever I try to run ANY migration related commands, grails applies all the changes before that, even through my config says:
staging:
dataSource:
dbCreate: ~
url: jdbc:mysql://127.0.0.1:3306/triz_staging?useUnicode=yes&characterEncoding=UTF-8
properties:
jmxEnabled: true
Also tried completely removing dbCreate. Didn't change anything...
I am done, have no idea where to move next!!!
Well, here is a deal...
I am not sure if that was the real reason, but all I did is moved datasource config from application.yml to application.groovy and everything got back to normal.
I would be happy to hear thoughts.
Thanks.

Resources