Issue
My Goal:
Having the Spring Cloud Config Server import active and provide a way for developers to have an optional property file on their machine.
alt="wanted cfg prio diagram" />
My Config Server is up and running using org.springframework.cloud:spring-cloud-config-server:3.1.3
and @EnableConfigServer
on the main class. Http requests to the concrete endpoint yield the expected result. This server should provide important environment configurations for a developer for his/her local setup.
$ curl http://localhost:8888/test-application/dev
{"name":"test-application","profiles":["dev"],"label":null,"version":null,"state":null,"propertySources":[{"name":"classpath:/cfg/test-application/application-dev.yml","source":{"server.port":1111}},{"name":"classpath:/cfg/test-application/application.yml","source":{"server.port":8000}}]}
Where localhost:8888
is my Config Server and test-application
ist the name of the client application (defined via spring.application.name
). The provided dev
is the currently active profile on the client (The dev profile indicates a locally running software, there is no dev environment).
Clients configuration:
application.yml
spring:
application:
name: test-application
config:
import:
- configserver:http://localhost:8888 # <- pull the configuration from the configserver
- optional:file:/absolute/path/to/the/project/root/ # <- if there are any additional configuration files, use them
The client uses the following dependencies:
org.springframework.boot:spring-boot-starter-web:2.7.0
org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.3
org.springframework.cloud:spring-cloud-starter:3.1.3
org.springframework.cloud:spring-cloud-starter-config:3.1.3
As shown above, the "base" application.yml
configured server.port=8000
where the profile specific is set to server.port=1111
. When reading the documentation this behaviour is correct. But my local developer configuration contains server.port=2222
. This was ignored.
Here comes the problem:
When starting the client application, i can see the following log statements:
Fetching config from server at : http://localhost:8888
Located environment: name=test-application, profiles=[default], label=null, version=null, state=null
Located property source: [BootstrapPropertySource {name='bootstrapProperties-configClient'}, BootstrapPropertySource {name='bootstrapProperties-classpath:/cfg/test-application/application-dev.yml'}, BootstrapPropertySource {name='bootstrapProperties-classpath:/cfg/test-application/application.yml'}]
The following 1 profile is active: "dev"
Tomcat initialized with port(s): 1111 (http)
Initializing Spring embedded WebApplicationContext
Tomcat started on port(s): 1111 (http) with context path ''
Started TestApplicationKt in 2.234 seconds (JVM running for 2.762)
The configuration evaluation result from spring was to choose port 1111
instead of the wanted 2222
within the application-dev.yml
located in the project root (developer config).
Wrapped up:
Three config files:
- config server
application.yml
(port: 8000) - config server
application-dev.yml
(port: 1111) - project root developer config
application-dev.yml
(port: 2222) <- I want this file to have precedence over the other two.
When running the debugger, i see these found property sources within the injected Environment
bean. The wanted developer file is within this list and the property source content is correct (server.port=2222
).
Does anyone have an idea how to solve this problem?
I have created a project that reproduces this exact behaviour. Link to GitHub.
Thanks in advance!
Solution
Is the dev
profile active when application is running in dev environment or it's also active when running locally?
Ideally you should have 2 different profiles for dev and local and you can enable config server only when dev
profile is active.
You can rename your local property file as application-local.yml
and disable spring cloud config when profile local
is active.
You can put below code in bootstrap.yml
(create new file beside application.yml
) and remove config server configurations from application.yml
---
spring:
application:
name: test-application
config:
activate:
on-profile: dev
import:
- configserver:http://localhost:8888 # <- pull the configuration from the configserver
- optional:file:/absolute/path/to/the/project/root/ # <- if there are any additional configuration files, use them
---
spring:
application:
name: test-application
config:
activate:
on-profile: local
cloud:
config:
enabled: false
EDIT: Actual fix
Thanks for sharing reproducible example.
All you need to do is remove local application-dev.yml
location reference from client application.yml
and add it to configServer application.yml
as shown in belolow screenshots.
/client/src/main/resources/application.yml
And put it in configServer application.yml
at the end of search-locations. Order matters so please make sure you put overriding location/s at the end.
/configServer/src/main/resources/application.yml
Build and start both the applications and you will see client application server started on port 2222
Answered By - Shivaji Pote
Answer Checked By - Katrina (JavaFixing Volunteer)