Variables in yaml configuration not substituted - spring

I'm trying to set up some microservices with Spring Boot and Eureka. I'm using YAML configuration and when I start up the services, they are registered with the Eureka service. The problem I have is that the environment variables in my configuration files are not substituted but are interpreted as a string (see instanceId).
Example application.yml:
server:
port: 0
eureka:
instance:
leaseRenewalIntervalSeconds: 10
instanceId: ${vcap.application.instance_id:${spring.application.name}:${spring.application.instance_id:${random.value}}
client:
registryFetchIntervalSeconds: 5
What I see on the Eureka app:
I've Googled the problem but I can't seem to find a solution. Does anybody known why this might happen or where I could start looking for solutions? I'm fairly new to this and I don't have a clue. Thanks.

Related

Spring Cloud Gateway in CloudFoundry

I've been trying to get my apps to run after deploing them to a CloudFoundry instance. The instance I'm using will not allow to perform requests using http (they will simply timeout) so I have to route all requests to https.
The components/versions I am using are:
Java 10
Spring Boot 2.0.4.RELEASE/Spring Cloud Finchley.SR1
spring-cloud-gateway
spring-cloud-config-server
spring-cloud-starter-netflix-eureka
The failing config
EurekaClient Config (in gateway and the backend where the gw should route to)
eureka:
client:
serviceUrl:
defaultZone: ${DISCOVERY_SERVICE_URL:http://localhost:8061}/eureka/
instance:
hostname: ${vcap.application.uris[0]:localhost}
nonSecurePortEnabled: false
securePortEnabled: true
securePort: ${server.port}
statusPageUrl: https://${eureka.instance.hostname}/actuator/info
healthCheckUrl: https://${eureka.instance.hostname}/actuator/health
homePageUrl: https://${eureka.instance.hostname}/
secure-virtual-host-name: https://${vcap.application.application_uris[0]}
Gateway Config
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/user/**
filters:
- RewritePath=/user/(?<segment>.*), /$\{segment}
Things I have already tried:
Using lb:https://user-service like described in docs -> Will have no effect as far as I can see
Use real urls to the apps (uri: https://user-service.cf-instance.io) -> Routing works as expected.
But I do not want to define the urls in my config, they should returned by eureka and build up correctly by the gateway.
Thanks in advance
Edit:
Here is the output of /eureka/apps
https://pastebin.com/WP3b6PQG
I am currently working to get the current code into GitHub I will edit this post when I've found the time to get a clear state.
Edit 2:
You can find the full example (With SpringCloudGateway, Eureka, ...) at my GitHub
This is an running example, the applied config will not use the Eureka. To use Eureka the gateway-service-cloud.yml in config service has to be adopted.
- id: user-service
uri: lb://user-service
Please ignore the documentation service, this will not work yet, I first need to rewrite the path.
Ok, I found out the solution during fixing the "routing" problem with my documentation-service.
My problem was setting the property eureka.instance.securePort to ${server.port}. This property has to be set to 443 (the default 443 is not applied when nothing is set). When adding this to my configurations everything works as expected after pushing my application.

JHipster micro-services unable to register properly to Eureka on AWS

I have a Spring Cloud application working well on AWS.
I decided to add JHipster generated micro-services (the JHipster gateway and UAA).
Both of these services register to an existing Eureka Server, like all the previous ones.
Things work fine on a local machine, or running in Docker containers deployed on a EC2 instance on AWS.
However, when deploying on different EC2 instances, the JHipster generated services are not registering correctly. The Eureka UI displays :
Application AMIs Availability Zones Status
HELLO-SERVICE ami-809f84e6 (2) eu-west-1b (1), eu-west-1a (1) UP (2) - i-02eg07053a672ea37 , i-083c2f2204d01f4ba
UAA n/a (2) (2) UP (2) - 97b39345fb59:uaa:9999 , ga6831e52701:uaa:9999
"HELLO-SERVICE" is a simple spring boot app. Eureka displays AWS information, and links it to a private ip/port which is working.
"UAA" is generated by Jhipster. Eureka is missing AWS information for this service, and links it to a 172.17.x.x.x address which is not working.
What bothers me is that both services share the same eureka configuration files :
eureka:
datacenter: cloud
instance:
preferIpAddress: true
client:
healthcheck:
enabled: true
registerWithEureka: true
fetchRegistry: true
region: eu-west-1
preferedSameZone: true
availabilityZones:
eu-west-1: eu-west-1a,eu-west-1b
serviceUrl:
eu-west-1a: http://[eurekainstance]:8761/eureka/
eu-west-1b: http://[eurekainstance]:8761/eureka/
Why would a JHipster generated app and a simple Spring Boot app behave differently while sharing the same configuration ?
I have run out of ideas, any help would be much appreciated!
I'll anwser my own question in case it's useful to someone.
The issue had nothing to do with JHipster or AWS, but with Docker.
Adding an EurekaInstanceConfigBean solved it:
public EurekaInstanceConfigBean eurekaInstanceConfig(InetUtils inet) {
EurekaInstanceConfigBean config = new EurekaInstanceConfigBean(inet);
AmazonInfo info = AmazonInfo.Builder.newBuilder().autoBuild("eureka");
config.setDataCenterInfo(info);
info.getMetadata().put(AmazonInfo.MetaDataKey.localHostname.getName(), info.get(AmazonInfo.MetaDataKey.localIpv4));
config.setHostname(info.get(AmazonInfo.MetaDataKey.localHostname));
config.setIpAddress(info.get(AmazonInfo.MetaDataKey.localIpv4));
config.setNonSecurePort(port);
return config;
}
See the documentation for more information.

Can Spring set datasource from service discovery?

Before I start trying to programmatically set datasource configuration in my app using service discovery, I would like to be sure this functionality is not already managed by Spring.
In my case I am using Consul as the discovery service. So I read http://cloud.spring.io/spring-cloud-consul/1.0.x/index.html but don't really find something to answer my question (prolly because of my flawed knowledge of Spring configuration itself).
Basically I would configure the discovery system in a bootstrap.yml file
spring:
cloud:
consul:
host: localhost
port: 8500
then in the application.yml I would set something like:
spring:
datasource:
url: jdbc:${consul.service.datasource}
Is this possible "natively". If not, what do I miss in the concepts involved?

Reading key value from consul in springboot application

I want to read my external configs like database host and port from consul.
I want to access it in my Springboot application.
So I have created a springboot application and have added cloud config for consul configuration.
I have created an bootstrap.yml where I give my consul host and port and I am able to connect.
But I am not able to fetch any key-value pair from consul.
I have posted my bootstrap.yml below asd well.
Can somebody guide me how to do that
spring:
cloud:
consul:
host: localhost
port: 8500
config:
enabled: true
data-key: config/application/datakey
TIA
You can make use of ConsulClient and then use getKVValue method to read the kv configs you have set in consul.

Disabling Eureka Client when running Zuul Server

I am trying to use Zuul as reverse proxy without discovery server. Things seem to work. One thing that bothers me is that the discovery client keeps looking for a discovery server. How do I disable this behavior?
Solution is as simple as adding this to application.yml:
eureka:
client:
enabled: false
As suggested by #spencergibb below, excluding the eureka dependencies also disables the discovery client. I ended up choosing this latter approach as it inherently simplifies my build.

Resources