Configuring Spring Eureka Client through environmental variables in CF - spring-boot

Trying to get a older version of Spring Boot running on Pivotal Web Services.
It needs to connect to a Eureka server. I have stood up a new Eureka server in the same space the Client App is running on in PWS.
As I don't have the code for the Client application (can't modify the application property/yml files), I need to configure the Client's Eureka client to connect to the new Eureka server using Environmental Variables.
Here is what I have tried:
In the Cloud Foundries 'manifest.yml' I currently have:
---
applications:
- name: <Client application name>
...
other non related settings
...
env:
EUREKA_INSTANCE_HOSTNAME: https://<pws route of eureka server>
This is not picked up.
It looks like that property is picked up like that:
https://jar-download.com/artifacts/org.springframework.cloud/spring-cloud-netflix-eureka-client/1.1.0.RELEASE/source-code/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java
I have tried a few variable names:
eureka.instance.hostname
EUREKA_CLIENT_SERVICEURL_DEFAULTZONE
eureka.client.serviceUrl.defaultZone
I also tried setting a SPRING_APPLICATION_JSON to contain these combinations in the same way in the manifest.yml.
None of them seem to get picked up.
Is there a different way that this can be done? Again, I don't have access to the code, only the Jar.

So its not pretty, but I was able to modify the application.properties files in the Jars using VIM to contain this setting:
eureka.client.serviceUrl.defaultZone=<pws route>/eureka/
Just made the Jar write-able, added that setting, saved and then cf push'd it up. Works. Not sure why the ENV did not work, but its not worth fixing. Everything in this Jar is ancient (Spring Cloud version 1.0). Its all going to get re-written anyway, just need the legacy version running somewhere stable while that work happens.

Related

Jhipster Registry cloud server config error for application property

So I want to override some settings for all my microservices, so I create a git repo and an application.yml file for that.
Download registry jar from jhipster.
run it with the following command.
java -jar jhipster-registry-5.0.2.jar --spring.profiles.active=prod --spring.security.user.password=xxx --jhipster.security.authentication.jwt.secret=abcde --spring.cloud.config.server.composite[0].type=git --spring.cloud.config.server.composite[0].uri=https://github.com/xxx --spring.cloud.config.server.composite[0].username=xxx --spring.cloud.config.server.composite[0].password=xxx
The services communicate through feign client which takes its data from the application.yml. The settings look like this:
application:
external:
services:
service-name:
base-url: local
But when I run the jhipster registry pointing to this repo. I get the following error.
Origin: ...
Reason: The elements [] are left unbound
I tried using all kinds of combos for the file name. application.yml, application-prod.yml, application-dev.yml, service-name.yml and also application.yml
There doesn't seem to be a problem for other properties, such as for database password and url. Or even arbitrary chains like abc.abc.abc.abc="data", these work. I even played around and simply messed up the spellings like mistyping external, services and application.
When I misspelled application like aaaaplication. It doesnt give an error. Only when I include "application:" in my yml file jhipster throws an error.
Please confirm if I am correct in assuming that jhipster won't allow application to be overriden. And if yes then how can I override this?
I don't think its optimal to change all the services for this. So is there a workaround for this?

Unable to link Spring boot application with Azure Application insight using application.properties, when logback.xml is used

I have created a spring-boot starter project and linked Azure Application insight to it. The properties like instrumentation- key is defined in "application.properties". On launching the application it is correctly linked to App Insight as can be verified by Live Metrics Stream.
However same application fails to connect to Azure App Insight if logback.xml is included in project (in resources), in this case to connect to App insight I have to include ApplicationInsights.xml as well.
But I do not want to use "ApplicationInsights.xml" in my application for 2 reasons. 1. I do not want multiple configuration files. 2. I am not able to inject key , i.e. not able to externalize key which might come as vm arguments or environment variable.
Defining InstrumentationKey and other configuration in application.properties works only when logback.xml is not present.
sample project (asset-register.zip) can be found at https://github.com/Microsoft/ApplicationInsights-Java/issues/710

Spring Cloud Config dual bootstrap files behavior

I have a setup where I am using the following:
Spring Boot 1.5.13 with Spring Cloud Version Edgware.S3
I have Spring Cloud Config Server and my Spring Boot apps are its clients
Each app carries a bootstrap.yml with the config server uri and some other properties.
Running containers on a Docker Swarm
I am currently passing Swarm secrets to the clients via a custom script which reads the files put into /run/secrets/ and creating a /config/bootstrap.properties file. It ends up looking like this:
spring.cloud.config.username=user
spring.cloud.config.password=password
My Docker image's default command is then this:
java -Djava.security.egd=file:/dev/./urandom -jar /${appName}.jar --spring.cloud.bootstrap.location=file:/config/bootstrap.properties"
Great. This is working without a problem. The app, seemingly, reads:
The external bootstrap.properties to read in the config server's credentials
The classpath bootstrap.yml to read in the rest of the config client props
Fetches and reads in the config server's application-appName.yml
Then reads the bundled application.yml from the classpath
Now. I'm moving the apps to Spring Boot 2.0.3 with Finchley.RELEASE and well, this breaks.
What is happening now is:
The external bootstrap.properties is read in to get the config server's credentials
The classpath bootstrap.yml is SKIPPED entirely (UNEXPECTED!)
Fetches and reads in the config server's application-appName.yml
Then reads the bundled application.yml from the classpath
The problem is that the properties that were set in the internal bootstrap.yml are now missing for the app so it blows up on start. I've been able to reproduce it outside the container environment by doing the same thing; point the app to an external bootstrap.properties. If I copy over the bootstrap.yml properties into the bootstrap.properties, then it works just fine. Also, if I don't provide an external properties file, then the internal bootstrap.yml kicks in without a problem. So it's either one or the other!
I'v also tried modifying the bootstrap location to include the default locations but no luck:
-- spring.cloud.bootstrap.location=file:/config/bootstrap.properties,classpath:,classpath:/config,file:,file:config/
Any ideas where to look next? Maybe there is a new spring.cloud.config property I'm missing? Or can anyone confirm which behavior is the correct behavior? Assuming they fixed a potential loophole in Finchley then I can just put this to rest and look for another solution. If it's 'broken' in Finchley, I guess an issue report is in order?
Well, some more digging showed that it looks like this is the new behavior:
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Migration-Guide
The behavior of the spring.config.location configuration has been fixed; it previously added a location to the list of default ones, now it replaces the default locations. If you were relying on the way it was handled previously, you should now use spring.config.additional-location instead.
It didn't look to be Spring Cloud specific but I had nothing to lose.
Changing my java command to use this new property did the trick:
--spring.config.additional-location=file:/config/bootstrap.properties
Thanks.

Spring Boot: Configuring subdomain, hostname and port through app properties

My Spring Boot app will have 4 different environments:
Local; running locally on my machine
Dev
UAT
Prod
When a new user registers for my app, the backend sends them an email to verify their address/account. In this email there will be a link; the user clicks the link which verifies them in the database and allows them to now login and use the app.
These links of course have to have the environment built into them:
Locally, the link might be http://localhost:9200/v1/data/accounts/verify?vt=12345
In dev the link might be: http://dev.myapp.example.com/v1/data/accounts/verify?vt=12345
In UAT the link might be: http://uat.myapp.example.com/v1/data/accounts/verify?vt=12345
In Prod the link might be: http://myapp.example.com/v1/data/accounts/verify?vt=12345
In all three environments, the hostname + port are different. Locally I specify localhost:9200 (both localhost + port). Non-locally I don't need to specify port because the app will be running on nodes behind a load balancer. In production I don't need an environment-specific subdomain like dev or uat.
In order for my emails to work correctly in all 4 environments, I need to set an environment variable that is then used by my email generator to generate links correctly.
I could use something homegrown, such as a custom property in application.properties like emailDomain, and set the property different in each environment's properties file.
But I feel like the smart folks that make up the Spring Boot community have probably already solved this problem for me...have they? Is there already a Spring Boot app property I can set that will take care of all this for me?
In the comments, I read that your main concern is being able to update the property without having to modify your .JAR/.WAR or changing some code.
This is possible since you can externalize your Spring boot configuration. If you check the Externalized Configuration docs, you can see that it looks for properties within:
OS environment variables.
...
Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants)
Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants)
Application properties outside of your packaged jar
(application.properties and YAML variants).
Application properties packaged inside your jar (application.properties and YAML variants).
So, ideally, you can put an application.properties file next to your JAR, and update the properties in that file depending on the environment you run on.

Spring Cloud Config Server Shared Properties Across Applications

I currently have a number of deployable applications that work in a distributed fashion to solve a business problem. We are currently using a number of property configuration files to provide changing configuration per environment based off a system environment variable. All these deployable application share common configuration for database and messaging. This is currently achieved by picking up property files from the class path and having both deployed apps share a common jar for each connection (db, jms) containing property files.
I am looking to start using Spring Config Server to externalize this configuration if possible. I have a question about how to share this common config.
Currently it looks something like this:-
Web1
- database
- jms
Messaging1
- database
- jms
In this situation both deployed apps share the same connections and these connections change per environment (lab, prf, prd, etc). How can I achieve the same with the Spring Configuration Server where I have app config for each deployable app?
Application.yml
Web1.yml
Web1-dev.yml
Messaging1.yml
Messaging1-dev.yml
If a connection property changed for an environment I would need to make the change to each deployable app configuration rather than making it just once.
Is there currently anyway to achieve this? Am I just missing a simple point?
I found working solution here https://cloud.spring.io/spring-cloud-config/single/spring-cloud-config.html, paragraph "2.1.5 Sharing Configuration With All Applications". It says:
With file-based (i.e. git, svn and native) repositories, resources
with file names in application* are shared between all client
applications (so application.properties, application.yml,
application-*.properties etc.). You can use resources with these file
names to configure global defaults and have them overridden by
application-specific files as necessary.
You should create application.properties or application.yml at the top level of configuration repository (if it is git or svn based). Don't forget to commit the changes.
This is how I have configured for my setup.
1 All Common properties across all services and environments will be in root->application.properties files
2 All Common properties across all environments specific to service will be root->service-X.properties files
3: Similarly, to have common properties across specific environment use env->application.properties file
server:
port: 8888
spring:
cloud:
config:
server:
git:
uri:[git repo]
search-paths: /,/{profile}/
Finally found a solution. It's buried in the issues at github ...
https://github.com/spring-cloud/spring-cloud-config/issues/32
It worked liked described. I only noticed, that you need to put the files in a /config folder to make it work. If you put it in the root the file ist used by the configserver itself and is not included in the config requests.
application.properties/application.yml will be shared across all applications.
application-DEV.properties/application-DEV.yml will be shared across all DEV environment applications. You can replace DEV with any spring profile.
{applicationName}.properties/{applicationName}.yml will be shared across the give application.

Resources