quarkiverse / quarkus-vault

Quarkus HashiCorp Vault extension
Apache License 2.0
19 stars 24 forks source link

Vault Config Source fetch secrets retry does not handle timeouts #233

Closed vsevel closed 6 months ago

vsevel commented 7 months ago

we trap VaultIOException

        for (int i = 0; i < vaultRuntimeConfig.mpConfigInitialAttempts(); i++) {
            try {
                if (i > 0) {
                    log.debug("retrying to fetch secrets");
                }
                fetchSecrets(properties);
                log.debug("loaded " + properties.size() + " properties from vault");
                return;
            } catch (VaultIOException e) {
                log.debug("attempt " + (i + 1) + " to fetch secrets from vault failed with: " + e);
                last = e;
            }
        }

but if we get the Uni to timeout, then we get a CompletionException caused by TimeoutException:


ERROR: Failed to start application (with profile [prod])
java.lang.RuntimeException: Failed to start quarkus
    at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)
    at io.quarkus.runtime.Application.start(Application.java:101)
    at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:111)
    at io.quarkus.runtime.Quarkus.run(Quarkus.java:71)
    at io.quarkus.runtime.Quarkus.run(Quarkus.java:44)
    at io.quarkus.runner.GeneratedMain.main(Unknown Source)
Caused by: java.util.concurrent.CompletionException: java.util.concurrent.TimeoutException
    at io.smallrye.mutiny.operators.uni.UniBlockingAwait.await(UniBlockingAwait.java:79)
    at io.smallrye.mutiny.groups.UniAwait.atMost(UniAwait.java:65)
    at io.smallrye.mutiny.groups.UniAwait.indefinitely(UniAwait.java:46)
    at io.quarkus.vault.runtime.config.VaultConfigSource.fetchSecrets(VaultConfigSource.java:132)
    at io.quarkus.vault.runtime.config.VaultConfigSource.lambda$fetchSecrets$2(VaultConfigSource.java:128)
    at java.base@17.0.10/java.util.ArrayList.forEach(ArrayList.java:1511)
    at io.quarkus.vault.runtime.config.VaultConfigSource.fetchSecrets(VaultConfigSource.java:128)
    at io.quarkus.vault.runtime.config.VaultConfigSource.lambda$fetchSecrets$1(VaultConfigSource.java:124)
    at java.base@17.0.10/java.util.HashMap.forEach(HashMap.java:1421)
    at io.quarkus.vault.runtime.config.VaultConfigSource.fetchSecrets(VaultConfigSource.java:124)
    at io.quarkus.vault.runtime.config.VaultConfigSource.fetchSecretsFirstTime(VaultConfigSource.java:104)
    at io.quarkus.vault.runtime.config.VaultConfigSource.getSecretConfig(VaultConfigSource.java:82)
    at io.quarkus.vault.runtime.config.VaultConfigSource.getValue(VaultConfigSource.java:63)
    at io.smallrye.config.ConfigValueConfigSourceWrapper.getConfigValue(ConfigValueConfigSourceWrapper.java:20)
    at io.smallrye.config.SmallRyeConfigSources.getValue(SmallRyeConfigSources.java:29)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.SecretKeysConfigSourceInterceptor.getValue(SecretKeysConfigSourceInterceptor.java:24)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.RelocateConfigSourceInterceptor.getValue(RelocateConfigSourceInterceptor.java:25)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.RelocateConfigSourceInterceptor.getValue(RelocateConfigSourceInterceptor.java:25)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.RelocateConfigSourceInterceptor.getValue(RelocateConfigSourceInterceptor.java:25)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.ProfileConfigSourceInterceptor.getProfileValue(ProfileConfigSourceInterceptor.java:56)
    at io.smallrye.config.ProfileConfigSourceInterceptor.getValue(ProfileConfigSourceInterceptor.java:37)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.RelocateConfigSourceInterceptor.getValue(RelocateConfigSourceInterceptor.java:25)
    at io.quarkus.smallrye.openapi.runtime.OpenApiConfigMapping.getValue(OpenApiConfigMapping.java:30)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.ExpressionConfigSourceInterceptor.getValue(ExpressionConfigSourceInterceptor.java:43)
    at io.smallrye.config.ExpressionConfigSourceInterceptor.getValue(ExpressionConfigSourceInterceptor.java:35)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.quarkus.opentelemetry.runtime.config.OTelFallbackConfigSourceInterceptor.iterateNames(OTelFallbackConfigSourceInterceptor.java:60)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.iterateNames(SmallRyeConfigSourceInterceptorContext.java:25)
    at io.smallrye.config.ConfigSourceInterceptor.iterateNames(ConfigSourceInterceptor.java:55)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.iterateNames(SmallRyeConfigSourceInterceptorContext.java:25)
    at io.smallrye.config.AbstractMappingConfigSourceInterceptor.iterateNames(AbstractMappingConfigSourceInterceptor.java:30)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.iterateNames(SmallRyeConfigSourceInterceptorContext.java:25)
    at io.quarkus.restclient.config.RestClientFallbackConfigSourceInterceptor.iterateNames(RestClientFallbackConfigSourceInterceptor.java:70)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.iterateNames(SmallRyeConfigSourceInterceptorContext.java:25)
    at io.smallrye.config.PropertyNamesConfigSourceInterceptor.iterateNames(PropertyNamesConfigSourceInterceptor.java:23)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.iterateNames(SmallRyeConfigSourceInterceptorContext.java:25)
    at io.smallrye.config.SmallRyeConfig$ConfigSources.generateDottedProperties(SmallRyeConfig.java:738)
    at io.smallrye.config.SmallRyeConfig$ConfigSources.<init>(SmallRyeConfig.java:570)
    at io.smallrye.config.SmallRyeConfig.<init>(SmallRyeConfig.java:69)
    at io.smallrye.config.SmallRyeConfigBuilder.build(SmallRyeConfigBuilder.java:629)
    at io.quarkus.runtime.generated.Config.readConfig(Unknown Source)
    at io.quarkus.deployment.steps.RuntimeConfigSetup.deploy(Unknown Source)
    ... 6 more
Caused by: java.util.concurrent.TimeoutException
    at io.smallrye.mutiny.operators.uni.UniFailOnTimeout$UniFailOnTimeoutProcessor.doTimeout(UniFailOnTimeout.java:102)
    at java.base@17.0.10/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
    at java.base@17.0.10/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base@17.0.10/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
    at java.base@17.0.10/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.base@17.0.10/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base@17.0.10/java.lang.Thread.run(Thread.java:840)
    at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:807)
    at org.graalvm.nativeimage.builder/com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:210)