spring.config.import doesn't accept configserver option when in yaml - spring

I have a bunch of services and recently migrated to new Spring Boot/Cloud. All but one works ok. The one complains like this:
***************************
APPLICATION FAILED TO START
***************************
Description:
Config data location 'configserver:http://localhost:8888/' does not exist
Action:
Check that the value 'configserver:http://localhost:8888/' at class path resource [application.yaml] - 5:13 is correct, or prefix it with 'optional:'
Making it optional makes service to completely skip remote configuration. Other services tells
Fetching config from server at : http://localhost:8888/
but this one misses it completely.
I've checked dependencies, they looks ok, tried to use latest spring-cloud-starter-config 3.0.5 but didn't change anything.
application.yaml looks like this:
spring:
application:
name: some-service
config:
import: "configserver:http://localhost:8888/"
cloud:
config:
fail-fast: true
retry:
max-attempts: 5000
initial-interval: 1500
multiplier: 1.5
All services has exactly the same config, just different names.
I have also another service which had similar problem, and switching from application.yaml to application.properties has fixed the problem. I don't like this solution, that's why I'm asking for help here. I suppose I miss some dependency or it has different version. I've even found similar problem, but no solution is visible: https://github.com/spring-cloud/spring-cloud-config/issues/1933
Edit: I've switched from yaml to properties format and it's working ok. Why yaml is not working?

So the problem was excessive application.properties in one of attached library. After removing this properties everything is working as expected.
Probably something in Spring Boot doesn't like such additional properties.

Related

Spring Cloud Embedded Config Server with native repository

I have a working spring boot application and I am trying to remove some properties from application.yaml file and read them from an embedded config server in the same app. At the moment, I am trying to read properties from file system through "native" profile type, and I am planning to later replace this with S3. Also, I am trying to read the configuration directly from backend repository as explained here https://docs.spring.io/spring-cloud-config/docs/current/reference/html/#_embedding_the_config_server , rather than connecting through an endpoint.
If you want to read the configuration for an application directly from
the backend repository (instead of from the config server), you
basically want an embedded config server with no endpoints. You can
switch off the endpoints entirely by not using the #EnableConfigServer
annotation (set spring.cloud.config.server.bootstrap=true).
I have introduced following changes to my existing application to achieve this.
Added following dependencies to pom.xml
spring-cloud-starter-config
spring-cloud-config-server
spring-cloud-config-client
application-dev.yaml
spring:
could:
bootstrap:
enabled: true
bootstrap.yaml
spring:
profiles:
active: composite
cloud:
config:
server:
composite:
- type: native
search-locations: file:C:\\Users\\chamila\\config-test\\config
# bootstrap: true
The required properties are saved in a different application-dev.yaml file at the above file path. I have not used #EnableConfigServer annotation from my app class, as I want connect directly without the endpoint.
However, still my program is failing to read the properties from the config-server. I tried setting spring.cloud.config.server.bootstrap=true and spring.cloud.bootstrap.enabled=true from both application-dev.yaml and bootstrap.yaml, but it didn't work?
Any idea what I am missing? I note that I never specified how to connect to the config-server in my application-dev.yaml file also. Is that an issue?
Any help is highly appreciated.
I created a sample project of an embedded Configuration Server which uses a custom repository:
https://github.com/taxone/embedded-config-server
The initial problem was that the custom EnvironmentRepository was not available via bootstrap, as described in this issue.
I followed https://cloud.spring.io/spring-cloud-config/reference/html/#_embedding_the_config_server and achieved the expected result.
Add spring-cloud-starter-bootstrap to your dependencies as suggested in https://github.com/taxone/embedded-config-server.
Make sure that composite profile is active when you start the app.
Verify that your native configuration is added by finding a log message from NativeEnvironmentRepository during startup.
(Optional) Remove spring.cloud.bootstrap.enabled from application-dev.yaml.
(Optional) Remove spring-cloud-config-client dependency as it is included in both spring-cloud-starter-config and
spring-cloud-config-server.
(Further steps) Use #RefreshScope on a spring bean to achieve dynamic properties. Requires POST actuator/refresh.

How to override a property defined in profile-specific application-{profile}.yml for a single application?

I have a spring-cloud-config server set up to serve YML files from a git repository. The server is using Spring Cloud 2020.0.3. There are several spring-cloud-config clients consuming config files from the server. The client applications consuming the config are using Spring Boot 2.4.6 and the new config parsing implementation.
The config repository contains an application-db.yml file and myapp.yml file. The application-db.yml file has several common properties set that all applications will use for the db profile. myapp.yml has properties for a specific application. Prior to using Spring Boot 2.4.6, I was able to override properties from application-db.yml in myapp.yml. In effect, the application-db.yml properties were the default values that individual applications could override.
For example application-db.yml might have (property key is not relevant):
spring:
datasource:
hikari:
maximum-pool-size: 5
to set the connection pool size to 5 for most applications and myapp.yml could set
spring:
datasource:
hikari:
maximum-pool-size: 10
for a one-off connection pool size of 10.
In Spring Cloud 2020.0.3 (Spring Cloud Config 3.0.4) and Spring Boot 2.4.6, the behavior is that the property in application-db.yml cannot be overridden in myapp.yml and the connection pool size property always has value 5.
I have tried setting the following properties in the application.yml and still have the same results.
spring:
cloud:
config:
allowOverride: true
overrideNone: true
overrideSystemProperties: false
According to Config file processing in Spring Boot 2.4 overriding property values is allowed in the config processing, but it is dependent on document order.
Is the overriding behavior still supported by Spring Boot using Spring Cloud Config? If so, does it depend on the order the cloud config server serves the documents? Is there a way to control the order?
edit note: I originally posted about overriding properties in the application.yml file. After more investigation, that does allowing overriding. It is in the profile specific files like application-db.yml that I cannot override values. I'm starting to think this might be a bug.
The overriding behavior you are looking for is supported in the latest release documented here and should be the default behavior without needing to add additional properties to enable override. You will need to include the application name with the spring.application.name property for the config server to recognize the overriding file.The overriding file also needs to have the same name you give in the client application (in this case,for example, my config repo has files application.properties and myapp.properties.
Client application.properties
spring.application.name=myapp
spring.config.import=optional:configserver:http://localhost:8888
...
Server application.properties
spring.application.name=configserver
spring.cloud.config.server.git.uri=https://github.com/...
server.port=8888
...
Within config repo
application.properties
spring:
datasource:
hikari:
maximum-pool-size: 5
myapp.properties
spring:
datasource:
hikari:
maximum-pool-size: 10
If the client application cannot fetch the overriding file (in this case the myapp file) from the config server application, it will fall back to its local application.properties file. However, the application will probably fail if all of the properties your application needs are not present there as well, so it's a good practice to copy all properties from your overriding file to the client application.properties file in case fetch fails.
If this didn't fix your problem I would check out this section on property overrides.

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?

Integration tests in spring boot application with spring cloud

I have an spring-boot application that uses config server.
In project I have a bootstrap.yml:
spring:
cloud:
config:
uri: ${CLOUD_CONFIG_URI:http://localhost:8888}
failFast: true
enabled: ??
and I can pass actual config for server location through parameter. That's ok.
With this configuration I don't know how to disable this in integration tests. My tests load this configuration and want to communicate with config server. I know that I can pass spring.cloud.config.enabled=false but it's not a solution (I want to right click in IDE and run test without additional configuration per each test method).
Any idea?
This is a late answer but for the people that join from any search engines here is my solution:
The #Profile("test") annotation above your integration test class is correct. To get this really working is adding two extra configuration files to your normal resources folder, not the test resources folder.
Add "application-test.yml"
Add "bootstrap-test.yml"
In your bootstrap-test.yml add the following:
spring:
cloud:
config:
enabled: false
With this configuration you can put all of your needed configuration options in the application-test.yml and the bootstrap-test.yml will disabled spring cloud config.

Spring Cloud Client Config with placeholders

I have a Spring Boot application.yml with this config for Cloud Config:
spring:
cloud:
config:
uri: http://localhost:8080/config
name: ${cluster.name}
profile: ${cluster.idx}
I read cluster.name and cluster.idx from a custom PropertySouce that loads a JSON file. But Spring Boot is not capable of resolve the placeholder yet.
13:04:37,370 ERROR [main] org.springframework.boot.SpringApplication(SpringApplication.java:839) : Application startup failed
java.lang.IllegalArgumentException: Could not resolve placeholder 'cluster.idx' in string value "${cluster.idx}"
How do I tell Spring Boot to load my PropertySource before trying to resolve the placeholders? Thanks in advance.
I'm using Sp Boot 1.4.3 and Sp Cloud Config 1.2.2.
You won't be able to use the property sources as they are not yet available, and will not be at the time that this file is read. You have a couple of options, though. First, you can place these properties into the bootstrap.properties (or bootstrap.yml if you prefer). I suspect that you are trying to do something that's profile driven though and should use the appropriate properties for the profile. In this case, you can create bootstrap-{profile}.yml. So, if you are running with -Dspring.profiles.active=dev, you would have a bootstrap-dev.yml file that would contain the values for this profile.
The second and simpler approach would be to pass these to the VM as arguments. -Dcluster.name=foo -Dcluster.idx=bar

Resources