I'm using Config Server from spring-cloud. I wish to refresh app's configuration without have to restart it.
This is my scenario:
1) Single configuration in application.yml, stored in git
job:
demo:
testMessage: 'My ID is 123'
2) Actuator in the client and annotation @RefreshScope in the controller.
@RefreshScope
@Component
@RestController
public class DemoController {
@Value("${job.demo.testMessage}")
String testMessage;
@RequestMapping(value = "/", produces = "application/json")
public List<String> index() {
List<String> env = Arrays.asList(
"config 1 is: " + testMessage
);
return env;
}
}
3) One flow with Spring Integration:
@RefreshScope
@Slf4j
@Setter
@Component
@ConfigurationProperties(prefix = "job.demo")
public class DemoFlow {
private String testMessage;
@Bean
public IntegrationFlow putDemoModelFlow() {
return IntegrationFlows.from(Http.inboundChannelAdapter("/demoFlow"))
.handle(new DemoHandler())
.handle(m -> log.info("[LOGGING DEMO] {}" , m.getPayload()))
.get();
}
private class DemoHandler implements GenericHandler {
@Override
public String handle(Object payload, Map headers) {
return new StringBuilder().append(testMessage)
.append(" ").toString();
}
}
}
4) I update the configuration and push to git
job:
demo:
testMessage: 'My ID is 789'
5) Run the refresh
curl -d{} http://localhost:8002/refresh
In the rest call to controller, everything worked fine, the config was updated.
["config 1 is: My ID is 789"]
But in the rest call to integration flow, the config wasn't update:
[LOGGING DEMO] My ID is 123
There are some particular behavior of the bean that is preventing to refresh the configuration?
Thanks.
I don't believe that putting the @Configuration
class in @RefreshScope
will put the beans declared therein into that scope.
Further, the IntegrationFlow
@Bean
generates a number of beans internally and they certainly won't be put in that scope. You should not attempt to "refresh" an integration flow, it will likely cause runtime problems.
Instead, you should put the property in a separate class from the flow and inject that into your DemoHandler
@Bean
.