Skip to content

Commit

Permalink
Add support for the TLS registry to the Redis client extension
Browse files Browse the repository at this point in the history
It is now possible to use the TLS registry to configure Redis client extension. Note that it's recommended to use a named configuration in this case, to avoid conflicts.
  • Loading branch information
cescoffier committed Jun 6, 2024
1 parent f81ef4f commit 0c3abe3
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 16 deletions.
14 changes: 13 additions & 1 deletion docs/src/main/asciidoc/redis-reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -247,11 +247,23 @@ quarkus.redis.password=<the password>

To use TLS, you need to:

Check warning on line 248 in docs/src/main/asciidoc/redis-reference.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.HeadingPunctuation] Do not use end punctuation in headings. Raw Output: {"message": "[Quarkus.HeadingPunctuation] Do not use end punctuation in headings.", "location": {"path": "docs/src/main/asciidoc/redis-reference.adoc", "range": {"start": {"line": 248, "column": 16}}}, "severity": "INFO"}

Check warning on line 248 in docs/src/main/asciidoc/redis-reference.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Fluff] Depending on the context, consider using 'Rewrite the sentence, or use 'must', instead of' rather than 'need to'. Raw Output: {"message": "[Quarkus.Fluff] Depending on the context, consider using 'Rewrite the sentence, or use 'must', instead of' rather than 'need to'.", "location": {"path": "docs/src/main/asciidoc/redis-reference.adoc", "range": {"start": {"line": 248, "column": 17}}}, "severity": "INFO"}

1. Set the `quarkus.redis.tls.enabled=true` property
1. Set the `quarkus.redis.tls.enabled=true` property or use the xref:./tls-registry-reference.adoc[TLS registry] (recommended)

Check warning on line 250 in docs/src/main/asciidoc/redis-reference.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.HeadingPunctuation] Do not use end punctuation in headings. Raw Output: {"message": "[Quarkus.HeadingPunctuation] Do not use end punctuation in headings.", "location": {"path": "docs/src/main/asciidoc/redis-reference.adoc", "range": {"start": {"line": 250, "column": 118}}}, "severity": "INFO"}
2. Make sure that your URL starts with `rediss://` (with two `s`)

Check warning on line 251 in docs/src/main/asciidoc/redis-reference.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsWarnings] Consider using 'verify' rather than 'Make sure' unless updating existing content that uses the term. Raw Output: {"message": "[Quarkus.TermsWarnings] Consider using 'verify' rather than 'Make sure' unless updating existing content that uses the term.", "location": {"path": "docs/src/main/asciidoc/redis-reference.adoc", "range": {"start": {"line": 251, "column": 4}}}, "severity": "WARNING"}


When using the TLS registry, we recommend using a named configuration to avoid conflicts:

Check warning on line 254 in docs/src/main/asciidoc/redis-reference.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using 'by using' or 'that uses' rather than 'using'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using 'by using' or 'that uses' rather than 'using'.", "location": {"path": "docs/src/main/asciidoc/redis-reference.adoc", "range": {"start": {"line": 254, "column": 5}}}, "severity": "INFO"}

Check warning on line 254 in docs/src/main/asciidoc/redis-reference.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Fluff] Depending on the context, consider using 'using more direct instructions' rather than 'recommend'. Raw Output: {"message": "[Quarkus.Fluff] Depending on the context, consider using 'using more direct instructions' rather than 'recommend'.", "location": {"path": "docs/src/main/asciidoc/redis-reference.adoc", "range": {"start": {"line": 254, "column": 33}}}, "severity": "INFO"}

Check warning on line 254 in docs/src/main/asciidoc/redis-reference.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using 'by using' or 'that uses' rather than 'using'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using 'by using' or 'that uses' rather than 'using'.", "location": {"path": "docs/src/main/asciidoc/redis-reference.adoc", "range": {"start": {"line": 254, "column": 42}}}, "severity": "INFO"}

[source,properties]
----
quarkus.tls.redis.trust-store.p12.path=client.p12
quarkus.tls.redis.trust-store.p12.password=secret
quarkus.redis.tls-configuration-name=redis # Reference the named configuration
----

IMPORTANT: The default hostname verifier is set to `NONE`, meaning it does not verify the host name. You can change this behavior by setting the `quarkus.redis.tls.hostname-verification-algorithm` property, to `HTTPS` for example.

Check warning on line 264 in docs/src/main/asciidoc/redis-reference.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsWarnings] Consider using 'hostname' rather than 'host name' unless updating existing content that uses the term. Raw Output: {"message": "[Quarkus.TermsWarnings] Consider using 'hostname' rather than 'host name' unless updating existing content that uses the term.", "location": {"path": "docs/src/main/asciidoc/redis-reference.adoc", "range": {"start": {"line": 264, "column": 91}}}, "severity": "WARNING"}


=== Configure the authentication

Check warning on line 267 in docs/src/main/asciidoc/redis-reference.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.HeadingPunctuation] Do not use end punctuation in headings. Raw Output: {"message": "[Quarkus.HeadingPunctuation] Do not use end punctuation in headings.", "location": {"path": "docs/src/main/asciidoc/redis-reference.adoc", "range": {"start": {"line": 267, "column": 1}}}, "severity": "INFO"}

The Redis password can be set in the `redis://` URL or with the `quarkus.redis.password` property.

Check warning on line 269 in docs/src/main/asciidoc/redis-reference.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Fluff] Depending on the context, consider using 'using more direct instructions' rather than 'recommend'. Raw Output: {"message": "[Quarkus.Fluff] Depending on the context, consider using 'using more direct instructions' rather than 'recommend'.", "location": {"path": "docs/src/main/asciidoc/redis-reference.adoc", "range": {"start": {"line": 269, "column": 92}}}, "severity": "INFO"}
Expand Down
4 changes: 4 additions & 0 deletions extensions/redis-client/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-devservices-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-tls-registry-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-redis-client</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import io.quarkus.runtime.LaunchMode;
import io.quarkus.runtime.configuration.ConfigurationException;
import io.quarkus.smallrye.health.deployment.spi.HealthBuildItem;
import io.quarkus.tls.TlsRegistryBuildItem;
import io.quarkus.vertx.deployment.VertxBuildItem;
import io.vertx.redis.client.impl.types.BulkType;

Expand Down Expand Up @@ -127,7 +128,8 @@ public void init(
VertxBuildItem vertxBuildItem,
ApplicationArchivesBuildItem applicationArchivesBuildItem, LaunchModeBuildItem launchMode,
BuildProducer<NativeImageResourceBuildItem> nativeImageResources,
BuildProducer<HotDeploymentWatchedFileBuildItem> hotDeploymentWatchedFiles) {
BuildProducer<HotDeploymentWatchedFileBuildItem> hotDeploymentWatchedFiles,
TlsRegistryBuildItem tlsRegistryBuildItem) {

// Collect the used redis clients, the unused clients will not be instantiated.
Set<String> names = new HashSet<>();
Expand Down Expand Up @@ -156,7 +158,7 @@ public void init(
.ifPresent(x -> names.addAll(configuredClientNames(buildTimeConfig, ConfigProvider.getConfig())));

// Inject the creation of the client when the application starts.
recorder.initialize(vertxBuildItem.getVertx(), names);
recorder.initialize(vertxBuildItem.getVertx(), names, tlsRegistryBuildItem.registry());

// Create the supplier and define the beans.
for (String name : names) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import io.quarkus.redis.datasource.RedisDataSource;
import io.quarkus.redis.datasource.codecs.Codec;
import io.quarkus.redis.runtime.client.RedisClientRecorder;
import io.quarkus.tls.TlsRegistryBuildItem;
import io.quarkus.vertx.deployment.VertxBuildItem;

public class RedisDatasourceProcessor {
Expand Down Expand Up @@ -84,7 +85,8 @@ public void init(RedisClientRecorder recorder,
List<RequestedRedisClientBuildItem> clients,
ShutdownContextBuildItem shutdown,
BuildProducer<SyntheticBeanBuildItem> syntheticBeans,
VertxBuildItem vertxBuildItem) {
VertxBuildItem vertxBuildItem,
TlsRegistryBuildItem tlsRegistryBuildItem) {

if (clients.isEmpty()) {
return;
Expand All @@ -94,7 +96,7 @@ public void init(RedisClientRecorder recorder,
names.add(client.name);
}
// Inject the creation of the client when the application starts.
recorder.initialize(vertxBuildItem.getVertx(), names);
recorder.initialize(vertxBuildItem.getVertx(), names, tlsRegistryBuildItem.registry());

// Create the supplier and define the beans.
for (String name : names) {
Expand Down
4 changes: 4 additions & 0 deletions extensions/redis-client/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-tls-registry</artifactId>
</dependency>
<dependency>
<groupId>io.smallrye.reactive</groupId>
<artifactId>smallrye-mutiny-vertx-redis-client</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import io.quarkus.runtime.ShutdownContext;
import io.quarkus.runtime.annotations.Recorder;
import io.quarkus.runtime.configuration.ConfigurationException;
import io.quarkus.tls.TlsConfigurationRegistry;
import io.vertx.mutiny.core.Vertx;
import io.vertx.mutiny.redis.client.Command;
import io.vertx.mutiny.redis.client.Redis;
Expand All @@ -48,7 +49,8 @@ public RedisClientRecorder(RedisConfig rc) {
this.config = rc;
}

public void initialize(RuntimeValue<io.vertx.core.Vertx> vertx, Set<String> names) {
public void initialize(RuntimeValue<io.vertx.core.Vertx> vertx, Set<String> names,
Supplier<TlsConfigurationRegistry> registry) {
Instance<ObservableRedisMetrics> instance = CDI.current().select(ObservableRedisMetrics.class);
if (instance.isResolvable()) {
this.metrics = instance.get();
Expand All @@ -58,9 +60,11 @@ public void initialize(RuntimeValue<io.vertx.core.Vertx> vertx, Set<String> name

this.vertx = Vertx.newInstance(vertx.getValue());

TlsConfigurationRegistry tlsRegistry = registry.get();

_registerCodecs();

_initialize(vertx.getValue(), names);
_initialize(vertx.getValue(), names, tlsRegistry);
}

private static void _registerCodecs() {
Expand All @@ -69,7 +73,7 @@ private static void _registerCodecs() {
Codecs.register(codecs.stream());
}

public void _initialize(io.vertx.core.Vertx vertx, Set<String> names) {
public void _initialize(io.vertx.core.Vertx vertx, Set<String> names, TlsConfigurationRegistry tlsRegistry) {
for (String name : names) {
// Search if we have an associated config:
// - if default -> Default
Expand All @@ -89,11 +93,12 @@ public ConfigurationException get() {
}
});
clients.computeIfAbsent(name,
x -> new RedisClientAndApi(name, VertxRedisClientFactory.create(name, vertx, actualConfig), metrics));
x -> new RedisClientAndApi(name, VertxRedisClientFactory.create(name, vertx, actualConfig, tlsRegistry),
metrics));
} else if (DEFAULT_CLIENT_NAME.equalsIgnoreCase(name) && maybe.isPresent()) {
clients.computeIfAbsent(name,
x -> new RedisClientAndApi(name,
VertxRedisClientFactory.create(DEFAULT_CLIENT_NAME, vertx, maybe.get()), metrics));
VertxRedisClientFactory.create(DEFAULT_CLIENT_NAME, vertx, maybe.get(), tlsRegistry), metrics));
}
// Do not throw an error. We would need to check if the default redis client is used.
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ private VertxRedisClientFactory() {
// Avoid direct instantiation.
}

public static Redis create(String name, Vertx vertx, RedisClientConfig config) {
public static Redis create(String name, Vertx vertx, RedisClientConfig config, TlsConfigurationRegistry tlsRegistry) {
RedisOptions options = new RedisOptions();

configureTLS(name, config, tlsRegistry, options.getNetClientOptions());

List<URI> hosts = new ArrayList<>();
if (config.hosts().isPresent()) {
hosts.addAll(config.hosts().get());
Expand Down Expand Up @@ -118,8 +120,6 @@ private static NetClientOptions toNetClientOptions(RedisClientConfig config) {
TlsConfig tls = config.tls();
NetClientOptions net = new NetClientOptions();



tcp.applicationLayerProtocols().ifPresent(net::setApplicationLayerProtocols);
tcp.connectionTimeout().ifPresent(d -> net.setConnectTimeout((int) d.toMillis()));
tcp.idleTimeout().ifPresent(d -> net.setIdleTimeout((int) d.toSeconds()));
Expand Down Expand Up @@ -178,7 +178,8 @@ public static RedisHostsProvider findProvider(String name) {
return providers.get();
}

private void configureTLS(String name, RedisClientConfig config, TlsConfigurationRegistry tlsRegistry, NetClientOptions net) {
private static void configureTLS(String name, RedisClientConfig config, TlsConfigurationRegistry tlsRegistry,
NetClientOptions net) {
TlsConfiguration configuration = null;

// Check if we have a named TLS configuration or a default configuration:
Expand All @@ -189,7 +190,8 @@ private void configureTLS(String name, RedisClientConfig config, TlsConfiguratio
+ config.tlsConfigurationName().get() + " for the Redis client " + name + ".");
}
configuration = maybeConfiguration.get();
} else if (tlsRegistry.getDefault().isPresent() && tlsRegistry.getDefault().get().isTlsEnabled()) {
} else if (tlsRegistry.getDefault().isPresent() && (tlsRegistry.getDefault().get().isTrustAll()
|| tlsRegistry.getDefault().get().getTrustStore() != null)) {
configuration = tlsRegistry.getDefault().get();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import io.quarkus.runtime.annotations.ConfigDocDefault;
import io.quarkus.runtime.annotations.ConfigDocSection;
import io.quarkus.runtime.annotations.ConfigGroup;
import io.quarkus.runtime.annotations.ConfigItem;
import io.smallrye.config.WithDefault;
import io.vertx.redis.client.ProtocolVersion;
import io.vertx.redis.client.RedisClientType;
Expand Down

0 comments on commit 0c3abe3

Please sign in to comment.