I think that there is an issue when using these two dependencies in the same projet. I'm talking about spring-cloud-starter
and spring-cloud-starter-kubernetes-fabric8-config
.
I'm using
- Spring Boot : 2.7.7
- Spring Cloud : 2021.0.5
What i'm trying to build is a spring boot application on kubernetes. Each time a configmap or a sercret get changed, the app context should be updated with the new values. To achieve this, i'm using the spring cloud watcher.
For the configmap part, everything works fine but when i tried to use a secret i noticed a strange behavior. The spring watcher calls my pods on the /actuator/refresh endpoint but nothing get updated. Actually, even on my local machine, the /refresh endpoint returns 200_OK but nothing is updated. Here's the code snippet :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-fabric8-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
@Configuration
@ConfigurationProperties(prefix = "metadata")
@PropertySource(value = "classpath:acl-default.yaml", factory = YamlPropertySourceFactory.class)
@PropertySource(value = "file:${user.home}/acls/acl.yaml", factory = YamlPropertySourceFactory.class, ignoreResourceNotFound = true)
@Slf4j
@Getter
@Setter
public class ACLConfig implements InitializingBean {
private List<User> users;
The ACLConfig class will load our users credentials let's say based on a file from the files system under ${user.home}/acls/acl.yaml
otherwise it will get loaded from the classpath.
The content of ${user.home}/acls/acl.yaml
is :
metadata:
users:
- name: Richard
password: kjqsd78jkdq-local
- name: Richard
password: jqsd98ds78-local
- name: Richard
password: kSkjqf887qsd-local
bootstrap.properties
server.port=8080
spring.application.name=demo
spring.cloud.kubernetes.config.sources[0].name=${spring.application.name}
spring.cloud.kubernetes.config.sources[0].namespace=spring-cloud-watcher
application.properties
logging.level.root=INFO
logging.level.com.example.demo=DEBUG
management.endpoints.web.exposure.include=info,health,refresh
spring.config.import=optional:file:${user.home}/acls/acl.yaml
So as i said, this example does not work (the acl file update will not trigger the spring context refresh).
To make it work, you have to :
- delete the
spring-cloud-starter-kubernetes-fabric8-config
dependency frompom.xml
, - change the content of
${user.home}/acls/acl.yaml
, - call the
/actuator/refresh
, - check the logs : you'll see that ACLConfig -> users List will be updated
You can find the example on my repo : https://github.com/mamdouni/spring-watcher-example
Delete the fabric8 dependency is not an option for me because i need to run this on kubernetes but i don't understand why it blocks the context refresh !!!
Any help will be appreciated.
As mentioned by @Eugene in the first comment, it was an incompatibility issue between spring boot 2 and spring cloud. It worked fine after upgrading to spring boot 3.