diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/client/runtime/RedisClientUtil.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/client/runtime/RedisClientUtil.java index b376fb6d2200f8..4f58b86ee6a878 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/client/runtime/RedisClientUtil.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/client/runtime/RedisClientUtil.java @@ -1,5 +1,12 @@ package io.quarkus.redis.client.runtime; +import static io.quarkus.vertx.core.runtime.SSLConfigHelper.configureJksKeyCertOptions; +import static io.quarkus.vertx.core.runtime.SSLConfigHelper.configureJksTrustOptions; +import static io.quarkus.vertx.core.runtime.SSLConfigHelper.configurePemKeyCertOptions; +import static io.quarkus.vertx.core.runtime.SSLConfigHelper.configurePemTrustOptions; +import static io.quarkus.vertx.core.runtime.SSLConfigHelper.configurePfxKeyCertOptions; +import static io.quarkus.vertx.core.runtime.SSLConfigHelper.configurePfxTrustOptions; + import java.net.URI; import java.util.Collections; import java.util.Set; @@ -9,6 +16,7 @@ import io.quarkus.redis.client.RedisHostsProvider; import io.quarkus.redis.client.runtime.RedisConfig.RedisConfiguration; import io.quarkus.runtime.configuration.ConfigurationException; +import io.vertx.core.net.NetClientOptions; import io.vertx.redis.client.RedisClientType; import io.vertx.redis.client.RedisOptions; @@ -59,9 +67,51 @@ public static RedisOptions buildOptions(RedisConfiguration redisConfig) { options.setUseReplicas(redisConfig.replicas.get()); } + if (redisConfig.password.isPresent()) { + options.setPassword(redisConfig.password.get()); + } + + options.setNetClientOptions(toNetClientOptions(redisConfig)); + return options; } + private static NetClientOptions toNetClientOptions(RedisConfiguration redisConfig) { + NetClientOptions netClientOptions = new NetClientOptions() + .setTcpKeepAlive(true) + .setTcpNoDelay(true); + + if (redisConfig.ssl.isPresent()) { + SslConfig sslConfig = redisConfig.ssl.get(); + + netClientOptions + .setSsl(sslConfig.enabled) + .setTrustAll(sslConfig.trustAll); + + configurePemTrustOptions(netClientOptions, sslConfig.trustCertificatePem); + configureJksTrustOptions(netClientOptions, sslConfig.trustCertificateJks); + configurePfxTrustOptions(netClientOptions, sslConfig.trustCertificatePfx); + + configurePemKeyCertOptions(netClientOptions, sslConfig.keyCertificatePem); + configureJksKeyCertOptions(netClientOptions, sslConfig.keyCertificateJks); + configurePfxKeyCertOptions(netClientOptions, sslConfig.keyCertificatePfx); + + netClientOptions.setReconnectAttempts(redisConfig.reconnectAttempts); + netClientOptions.setReconnectInterval(redisConfig.reconnectInterval.toMillis()); + + if (redisConfig.idleTimeout.isPresent()) { + netClientOptions.setIdleTimeout(redisConfig.idleTimeout.get()); + } + + if (sslConfig.hostnameVerificationAlgorithm.isPresent()) { + netClientOptions.setHostnameVerificationAlgorithm( + sslConfig.hostnameVerificationAlgorithm.get()); + } + } + + return netClientOptions; + } + public static boolean isDefault(String clientName) { return DEFAULT_CLIENT.equals(clientName); } diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/client/runtime/RedisConfig.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/client/runtime/RedisConfig.java index f2fc4e834ba1ec..8b5aac8cdd4e22 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/client/runtime/RedisConfig.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/client/runtime/RedisConfig.java @@ -110,6 +110,14 @@ public static class RedisConfiguration { @ConfigItem(defaultValueDocumentation = "never") public Optional replicas; + /** + * The default password for cluster/sentinel connections. + *

+ * If not set it will try to extract the value from the current default endpoint. + */ + @ConfigItem + public Optional password = Optional.empty(); + /** * The maximum size of the connection pool. When working with cluster or sentinel. *

@@ -150,5 +158,30 @@ public static class RedisConfiguration { */ @ConfigItem(defaultValue = "32") public int maxNestedArrays; + + /** + * The number of reconnection attempts when a pooled connection cannot be established on first try. + */ + @ConfigItem(defaultValue = "0") + public int reconnectAttempts = 0; + + /** + * The interval between reconnection attempts when a pooled connection cannot be established on first try. + */ + @ConfigItem(defaultValue = "PT1S") + public Duration reconnectInterval = Duration.ofSeconds(1L); + + /** + * The maximum time a connection remains unused in the pool before it is closed. + */ + @ConfigItem(defaultValueDocumentation = "no timeout") + public Optional idleTimeout = Optional.empty(); + + /** + * SSL/TLS config. + */ + @ConfigItem + public Optional ssl = Optional.empty(); + } } diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/client/runtime/SslConfig.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/client/runtime/SslConfig.java new file mode 100644 index 00000000000000..4c08d11052c54a --- /dev/null +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/client/runtime/SslConfig.java @@ -0,0 +1,82 @@ +package io.quarkus.redis.client.runtime; + +import java.util.Optional; + +import io.quarkus.runtime.annotations.ConfigGroup; +import io.quarkus.runtime.annotations.ConfigItem; +import io.quarkus.vertx.core.runtime.config.JksConfiguration; +import io.quarkus.vertx.core.runtime.config.PemKeyCertConfiguration; +import io.quarkus.vertx.core.runtime.config.PemTrustCertConfiguration; +import io.quarkus.vertx.core.runtime.config.PfxConfiguration; + +@ConfigGroup +public class SslConfig { + + /** + * Whether SSL/TLS is enabled. + */ + @ConfigItem(defaultValue = "false") + public boolean enabled; + + /** + * Enable trusting all certificates. Disable by default. + */ + @ConfigItem(defaultValue = "false") + public boolean trustAll; + + /** + * Trust configuration in the PEM format. + *

+ * When enabled, {@code #trust-certificate-jks} and {@code #trust-certificate-pfx} must be disabled. + */ + @ConfigItem + public PemTrustCertConfiguration trustCertificatePem = new PemTrustCertConfiguration(); + + /** + * Trust configuration in the JKS format. + *

+ * When enabled, {@code #trust-certificate-pem} and {@code #trust-certificate-pfx} must be disabled. + */ + @ConfigItem + public JksConfiguration trustCertificateJks = new JksConfiguration(); + + /** + * Trust configuration in the PFX format. + *

+ * When enabled, {@code #trust-certificate-jks} and {@code #trust-certificate-pem} must be disabled. + */ + @ConfigItem + public PfxConfiguration trustCertificatePfx = new PfxConfiguration(); + + /** + * Key/cert configuration in the PEM format. + *

+ * When enabled, {@code key-certificate-jks} and {@code #key-certificate-pfx} must be disabled. + */ + @ConfigItem + public PemKeyCertConfiguration keyCertificatePem = new PemKeyCertConfiguration(); + + /** + * Key/cert configuration in the JKS format. + *

+ * When enabled, {@code #key-certificate-pem} and {@code #key-certificate-pfx} must be disabled. + */ + @ConfigItem + public JksConfiguration keyCertificateJks = new JksConfiguration(); + + /** + * Key/cert configuration in the PFX format. + *

+ * When enabled, {@code key-certificate-jks} and {@code #key-certificate-pem} must be disabled. + */ + @ConfigItem + public PfxConfiguration keyCertificatePfx = new PfxConfiguration(); + + /** + * The hostname verification algorithm to use in case the server's identity should be checked. + * Should be HTTPS, LDAPS or an empty string. + */ + @ConfigItem + public Optional hostnameVerificationAlgorithm = Optional.empty(); + +}