Search code examples
spring-bootspring-boot-actuatorspring-cloud-gateway

Spring Cloud Gateway : actuator refresh does not reload properties


I am actually working on a project with Spring Cloud Gateway.

I have a Configuration class which gets its Properties from a custom PropretySourceFactory. I want to make a hot reload of the properties so I call actuator/refresh (curl localhost:8080/actuator/refresh -d {}H "Content-Type: application/json") but it does not reload my configuration properties. No error or exceptions.

Here is the Configuration class:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;


@Configuration
@ConfigurationProperties
@PropertySource(value="", factory=NatsPropertySourceFactory.class)
public class NatsConfiguration {
    private String apiKey;
    private String apiKeyConsumer;
    private String apiKeyValidity;
    private String apiKeyCreation;
    private int ratelimitMaxTokens;
    private int ratelimitReplenishFrequency;
    private int ratelimitReplenishRate;

    // Getters and setter
    //...
}

value is empty on PropertySource because I will not get my configuration from a file but from a message queue.

and the NatsPropertySourceFactory:

public class NatsPropertySourceFactory implements PropertySourceFactory{

    final private NatsConfigurationService natsConfigurationService = new NatsConfigurationServiceImpl();

    @Override
    public PropertySource<?> createPropertySource(String arg0, EncodedResource arg1) throws IOException {
        MapPropertySource result = null;
        Logger log = LoggerFactory.getLogger(this.getClass());
        try {
            result = new MapPropertySource("nats", natsConfigurationService.getConfiguration());

        } catch (ConfigurationException e) {
            log.error("RECUPERATION DE CONFIGURATION DEPUIS NATS EN ERREUR", e);
            System.exit(1);
        }
        return result;
    }
    
}

My properties are not used with @Value, so I should not need @RefreshScope. When I call /actuator/refresh the NatsConfiguration class is not recreated.

For information I use webflux with SpringSecurity (actuator urls are permitAll: pathMatchers("/actuator/**").permitAll())

@EnableWebFluxSecurity
@EnableWebFlux
public class SecurityConfiguration implements WebFluxConfigurer {

Where am I wrong?


Solution

  • By the way, I found the exact behaviour of /actuator/refresh: it reinstanciates the @Configuration class but does nothing for the PropertySourceFactory.

    I have found a workaround: I created a REST Controler which calls the createPropertySource method of the PropertySourceFactory and then calls the /actuator/refresh url. It does exactly what I wanted: the @Configuration class is up to date with the new properties given by the PropertySourceFactory.