Search code examples
kotlinvert.x

vertx sync config retrieval behaves unexpectedly


In my multi-verticle application, I would like to load the config once and then inject the resulting JsonObject into each verticle using koin. The problem is that the ConfigRetriever doesn't really behave the way I would expect it to. Consider the following example:

class MainVerticle : AbstractVerticle() {
  override fun start() {
    val retriever = ConfigRetriever.create(vertx)
    val config = ConfigRetriever.getConfigAsFuture(retriever).result()
    println(config)
  }
}

Intuitively I would expect this to load the config file under /resources/conf/config.json and print all the key/value pairs. Instead of doing that, it prints null. However, if I change the third line to:

val retriever = ConfigRetriever.create(Vertx.vertx())

then the JsonObject gets populated with the properties of my config.json file.

The docs of Future#result state the following

The result of the operation. This will be null if the operation failed.

So the operation succeeds but no config is loaded?

I don't really understand why I have to create a new vertx instance for the config to be loaded properly. What am I missing here?


Solution

  • Found a solution: there is a method which returns a cached version of the config https://vertx.io/docs/vertx-config/java/#_retrieving_the_last_retrieved_configuration

    So all I had to do is to load the config once in @Provides method:

    @Provides
    @Singleton
    public ConfigRetriever config(Vertx vertx) {
        final ConfigRetriever retriever = ConfigRetriever.create(vertx);
    
        // Retrieving the config here is not just to print it,
        // but also to create a cached config which can be later used in Configuration
        try {
            final var cfg = retriever.getConfig().toCompletionStage().toCompletableFuture().get();
            cfg.stream()
                .filter(entry -> entry.getKey().startsWith("backend") && !entry.getKey().contains("pass"))
                .forEach(entry -> log.info("{} = {}", entry.getKey(), entry.getValue()));
    
            return retriever;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }