How to load spring config xml ${ } values from spring boot application properties - spring-boot

Camel Spring Boot application version 2.20.1
How to load the application.properties values to spring config xml parameter on start up ?
For eg: few parameters are defined as follows :-
eas.ssl.key-store-type = JKS
eas.ssl.key-store-password = *****
eas.ssl.key-store = filelocation
Now the same need to be configured in Spring Config XML on startup as follows :
<sec:keyStore type="${eas.ssl.key-store-type}" password="${eas.ssl.key-store-password}" file="${eas.ssl.key-store}" />
In logs,I could see the properties from application properties are detected as expected
PropertySourcesPropertyResolver : Found key 'eas.ssl.key-store-password'
However it looks like on the keys are not applied to config xml as values.
The errors log states:-
org.apache.cxf.transport.https.SSLUtils : The key store password has not
been set via a system property or through configuration, reading data from
the keystore will fail.

As mentioned in my latest comment my primary issue was related to SSL HandshakeException (No appropraite protocol found). And I was working with JDK 1.8.
Later I realized it was cipher filter "SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA256" was not supported with jdk 8. Once I changed to "TSL_ECDHE_RSA_WITH_AES_128_CBC_SHA256" all started working as expected.
A hint to solution got from this site :
http://www.ateam-oracle.com/tls-and-java/

Related

Spring boot 2.4.x cannot handle multi document yml files from config server

Java version: 8
Spring Boot version: 2.4.1
Spring Cloud version: 2020.0.0, specifically I use a Spring Cloud Config Server connected to GIT and our services are Spring Cloud Config Clients.
I have migrated away from using bootstrap.yml and started using spring.config.import and spring.config.activate.on-profile as mentioned in the documentation here and here
My configuration in my service, who is a client to the config server looks like this:
server.port: 9001
spring:
application.name: my-rest-service
config.import: configserver:http://localhost:8888
cloud.config.profile: ${spring.profiles.active}
My configuration in the config server looks like this:
application.yml (has two documents separated by the ---)
logging:
file.name: <omitted>
level:
root: INFO
---
spring:
config.activate.on-profile: dev
logging.level.root: DEBUG
my-rest-sercive.yml (has two documents separated by the ---)
spring:
datasource:
driver-class-name: <omitted>
username: <omitted>
password: <omitted>
---
spring:
config.activate.on-profile: dev
datasource.url: <omitted>
Because there is a profile "dev" active, I successfully get the following 4 configurations from config server:
application.yml: general logging level
application.yml: specific logging for dev
my-rest-sercive.yml: general datasource properties
my-rest-sercive.yml: specific datasource url for dev
I can see these 4 sources successfully being fetched when I use my browser or when I debug or in the logs when I lower the loglevel to trace:
o.s.b.c.config.ConfigDataEnvironment : Adding imported property source 'configserver:https://git.company.com/path.git/file:C:\configservergit\config\my-rest-service.yml'
o.s.b.c.config.ConfigDataEnvironment : Adding imported property source 'configserver:https://git.company.com/path.git/file:C:\configservergit\config\my-rest-service.yml'
o.s.b.c.config.ConfigDataEnvironment : Adding imported property source 'configserver:https://git.company.com/path.git/file:C:\configservergit\config\application.yml'
o.s.b.c.config.ConfigDataEnvironment : Adding imported property source 'configserver:https://git.company.com/path.git/file:C:\configservergit\config\application.yml'
However, notice that because I use multi document yml files, out of these 4 property sources only TWO unique names are used.
In a later step, when Spring creates the data source bean, he complains he cannot find the data source URL. If I debug the spring bean factory I can indeed see that out of the 4 property files returned by the config server, only two have remained (the ones that don't contain the dev profile specific configuration). I assume this is because they have an identical name and they overwrite each other. This is an effect of this piece of code in the MutablePropertySource.class:
public void addLast(PropertySource<?> propertySource) {
synchronized(this.propertySourceList) {
this.removeIfPresent(propertySource); <-- this is the culrprit!
this.propertySourceList.add(propertySource);
}
}
This is a breaking change from Spring 2.3/Spring Cloud Hoxton where it correctly collected all properties. I think spring cloud needs to change the config server so that every document within a yml has has a unique name when returned to Spring. This is exactly how Spring Boot handles multi document yml files, by appending the String (documenyt #1) to the property source name
I found an interesting note about profiles and multi document yml, basically saying it is not supported, but this doesn't apply to my use case because my yml files are not profiles based (there is no -{profileName} in the last part of the file name).
This is a known issue with the new release. We can track the issue here on the spring cloud config server github page.
The workaround seems to be stop using multi document yml files and use multiple distinct files with the profile name in the filename.

Custom application property to be supplied to spring boot app through cmd line

I was wondering if we can supply a custom attribute (a key to be in application.properties file), I know for sure that -Dserver.port=8080 works, and overrides the property value, but server.port is a spring boot's expected property value.
How about something other than that, for example a jdbc connection string or service name? does -Ddb.service.name=dbservice work?
Yes, any property can be set via system property. You can use -D or -- notation. There are also a variety of property sources Spring Boot uses:
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

Meaning of ${xxx:yyy} on Spring Boot application.properties

I see following in Spring Boot application.properties file. What is it doing here:
spring.datasource.password = ${DB_PASSWD:password}
It means try resolving DB_PASSWD property. If found, use it's value. If not, use the default provided value password. In short:
${property:defaultValue}
The property value is looked up from property sources registered in Spring context, see Environment.getProperty() and #PropertySource.

jasypt encryption not working in spring boot

I want to do encryption for some sensitive data in application.properties file of spring boot application.
for that I have used jasypt-spring-boot-starter plugin .
also used #EnableEncryptableProperties tag on spring application.
I have encrypted access key for my database and written its encrypted value in the property file.
com.test.SharedAccessKey=ENC(vfQQ9veC1G+RV8BC0VA==)
also provided in property file
jasypt.encryptor.password=secretpassword
jasypt.encryptor.algorithm=PBEWithMD5AndDES
I am accessing this property in spring boot application as followes
#Value("${com.test.SharedAccessKey}")
public String shareAcessKey;
But logger.info(shareAcessKey) print as it is ENC(vfQQ9veC1G+RV8BC0VA==)
what I am missing in above , can anyone help.
Issue was resolved . I have done some configuration in my spring Configuration class #Configuration related to property file.
as set property place holder configure to setIgnoreUnresolvablePlaceholders
after removing above code . Jasypt password is got picked up.

Set application.properties value from JNDI Environment value

I am building a spring boot application, that has RabbitMQ configuration like below.
spring.rabbitmq.host=host
spring.rabbitmq.port=5672
spring.rabbitmq.username=userName
spring.rabbitmq.password=password
I need to set environment specific configuration. But that configuration needs to be read from tomcat context.xml file.
I would need to pass the values for host, username, and password by reading from tomcat Environment tag set in context.xml.
How can I do this?
Spring docs says: 24.3 Application Property Files
If your application runs in a container, then JNDI properties (in java:comp/env) or servlet context initialization parameters can be used instead of, or as well as, environment variables or system properties.
can they be directly used like this:
spring.rabbitmq.host="${rabbitMQHost}"
spring.rabbitmq.port=5672
spring.rabbitmq.username=${rabbitMQUserName}
spring.rabbitmq.password=${rabbitMQPassword}

Resources