From 0e909a64d787c799218ef28a2c4f44ca9b07711b Mon Sep 17 00:00:00 2001 From: Jan Martiska Date: Mon, 14 Oct 2024 11:16:30 +0200 Subject: [PATCH] Docs and formatting fixes --- .../main/asciidoc/tls-registry-reference.adoc | 13 ++++-- .../SmallRyeGraphQLClientProcessor.java | 42 ++++++++++++------ .../deployment/ssl/SSLTestingTools.java | 3 +- ...raphQLClientReloadKeystoreDefaultTest.java | 44 ++++++++++--------- ...pesafeGraphQLClientReloadKeystoreTest.java | 10 +++-- ...LClientCertificateUpdateEventListener.java | 15 ++++--- .../SmallRyeGraphQLClientRecorder.java | 8 ++-- 7 files changed, 82 insertions(+), 53 deletions(-) diff --git a/docs/src/main/asciidoc/tls-registry-reference.adoc b/docs/src/main/asciidoc/tls-registry-reference.adoc index b566976b92ced..17747b3996676 100644 --- a/docs/src/main/asciidoc/tls-registry-reference.adoc +++ b/docs/src/main/asciidoc/tls-registry-reference.adoc @@ -26,7 +26,7 @@ ifndef::no-reactive-routes[] , or Reactive Routes endif::no-reactive-routes[] . -The TLS Registry extension is automatically included in your project when you use compatible extensions, such as Quarkus REST, gRPC, SmallRye GraphQL Client, or Reactive Routes. + As a result, applications that use the TLS Registry can be ready to handle secure communications out of the box. TLS Registry also provides features like automatic certificate reloading, Let's Encrypt (ACME) integration, Kubernetes Cert-Manager support, and compatibility with various keystore formats, such as PKCS12, PEM, and JKS. @@ -155,9 +155,14 @@ quarkus.grpc.clients.hello.tls-configuration-name=MY_TLS_CONFIGURATION ---- quarkus.smallrye-graphql-client.my-client.tls-configuration-name=MY_TLS_CONFIGURATION ---- -> [NOTE] -> When using the Typesafe GraphQL client with a certificate reloading mechanism (see <>), it is essential to override the bean's scope to `RequestScoped` (or another similar scope). By default, the Typesafe client is an application-scoped bean. -> This guarantees that each new instance of the bean created after a certificate reload will be configured with the latest certificate. + +[NOTE] +==== +When using the Typesafe GraphQL client with a certificate reloading mechanism (see <>), +it is essential to override the bean's scope to `RequestScoped` (or another similar scope). By default, the +Typesafe client is an application-scoped bean. This guarantees that each new instance of the bean created +after a certificate reload will be configured with the latest certificate. +==== == Configuring TLS diff --git a/extensions/smallrye-graphql-client/deployment/src/main/java/io/quarkus/smallrye/graphql/client/deployment/SmallRyeGraphQLClientProcessor.java b/extensions/smallrye-graphql-client/deployment/src/main/java/io/quarkus/smallrye/graphql/client/deployment/SmallRyeGraphQLClientProcessor.java index 012944bdad91f..59f6cc99488eb 100644 --- a/extensions/smallrye-graphql-client/deployment/src/main/java/io/quarkus/smallrye/graphql/client/deployment/SmallRyeGraphQLClientProcessor.java +++ b/extensions/smallrye-graphql-client/deployment/src/main/java/io/quarkus/smallrye/graphql/client/deployment/SmallRyeGraphQLClientProcessor.java @@ -74,23 +74,37 @@ void setupServiceProviders(BuildProducer services) { .allProvidersFromClassPath("io.smallrye.graphql.client.typesafe.api.TypesafeGraphQLClientBuilder")); services.produce(ServiceProviderBuildItem .allProvidersFromClassPath("io.smallrye.graphql.client.dynamic.api.DynamicGraphQLClientBuilder")); - services.produce(ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.ArgumentFactory")); - services.produce(ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.DirectiveFactory")); services.produce( - ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.DirectiveArgumentFactory")); - services.produce(ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.DocumentFactory")); - services.produce(ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.EnumFactory")); - services.produce(ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.FieldFactory")); - services.produce(ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.FragmentFactory")); + ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.ArgumentFactory")); services.produce( - ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.FragmentReferenceFactory")); - services.produce(ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.InlineFragmentFactory")); - services.produce(ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.InputObjectFactory")); + ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.DirectiveFactory")); services.produce( - ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.InputObjectFieldFactory")); - services.produce(ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.OperationFactory")); - services.produce(ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.VariableFactory")); - services.produce(ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.VariableTypeFactory")); + ServiceProviderBuildItem + .allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.DirectiveArgumentFactory")); + services.produce( + ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.DocumentFactory")); + services.produce( + ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.EnumFactory")); + services.produce( + ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.FieldFactory")); + services.produce( + ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.FragmentFactory")); + services.produce( + ServiceProviderBuildItem + .allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.FragmentReferenceFactory")); + services.produce(ServiceProviderBuildItem + .allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.InlineFragmentFactory")); + services.produce(ServiceProviderBuildItem + .allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.InputObjectFactory")); + services.produce( + ServiceProviderBuildItem + .allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.InputObjectFieldFactory")); + services.produce( + ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.OperationFactory")); + services.produce( + ServiceProviderBuildItem.allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.VariableFactory")); + services.produce(ServiceProviderBuildItem + .allProvidersFromClassPath("io.smallrye.graphql.client.core.factory.VariableTypeFactory")); } @BuildStep diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/ssl/SSLTestingTools.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/ssl/SSLTestingTools.java index 99dac5dfeeb36..90f391bdec326 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/ssl/SSLTestingTools.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/ssl/SSLTestingTools.java @@ -10,7 +10,6 @@ import io.vertx.core.http.ClientAuth; import io.vertx.core.http.HttpServer; import io.vertx.core.http.HttpServerOptions; -import io.vertx.core.net.JksOptions; import io.vertx.core.net.PfxOptions; public class SSLTestingTools { @@ -54,6 +53,6 @@ public HttpServer runServer(String keystorePath, String keystorePassword, } public void close() { - vertx.close(); + vertx.close().toCompletionStage().toCompletableFuture().join(); } } diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/ssl/TypesafeGraphQLClientReloadKeystoreDefaultTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/ssl/TypesafeGraphQLClientReloadKeystoreDefaultTest.java index e92806f8a3d8a..9e99fe37772f8 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/ssl/TypesafeGraphQLClientReloadKeystoreDefaultTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/ssl/TypesafeGraphQLClientReloadKeystoreDefaultTest.java @@ -1,20 +1,16 @@ package io.quarkus.smallrye.graphql.client.deployment.ssl; -import io.quarkus.arc.Arc; -import io.quarkus.test.QuarkusUnitTest; -import io.quarkus.tls.CertificateUpdatedEvent; -import io.quarkus.tls.TlsConfiguration; -import io.quarkus.tls.TlsConfigurationRegistry; -import io.smallrye.certs.Format; -import io.smallrye.certs.junit5.Certificate; -import io.smallrye.certs.junit5.Certificates; -import io.smallrye.graphql.client.impl.GraphQLClientsConfiguration; -import io.smallrye.graphql.client.typesafe.api.GraphQLClientApi; -import io.vertx.core.http.HttpServer; -import io.vertx.core.net.KeyCertOptions; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.UUID; + import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.event.Event; import jakarta.inject.Inject; + import org.assertj.core.api.Assertions; import org.eclipse.microprofile.config.inject.ConfigProperty; import org.eclipse.microprofile.graphql.Query; @@ -26,12 +22,18 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.util.UUID; - -import static org.assertj.core.api.Assertions.assertThat; +import io.quarkus.arc.Arc; +import io.quarkus.test.QuarkusUnitTest; +import io.quarkus.tls.CertificateUpdatedEvent; +import io.quarkus.tls.TlsConfiguration; +import io.quarkus.tls.TlsConfigurationRegistry; +import io.smallrye.certs.Format; +import io.smallrye.certs.junit5.Certificate; +import io.smallrye.certs.junit5.Certificates; +import io.smallrye.graphql.client.impl.GraphQLClientsConfiguration; +import io.smallrye.graphql.client.typesafe.api.GraphQLClientApi; +import io.vertx.core.http.HttpServer; +import io.vertx.core.net.KeyCertOptions; @Certificates(baseDir = "target/certs", certificates = { @Certificate(name = "wrong-test-reload", password = "password", formats = Format.PKCS12, client = true), @@ -99,7 +101,8 @@ static void setupServer() throws Exception { @Test void testReloading() throws IOException { TlsConfiguration def = registry.getDefault().orElseThrow(); - KeyCertOptions keystoreOptionsBefore = (KeyCertOptions) GraphQLClientsConfiguration.getInstance().getClient("my-client").getTlsKeyStoreOptions(); + KeyCertOptions keystoreOptionsBefore = (KeyCertOptions) GraphQLClientsConfiguration.getInstance().getClient("my-client") + .getTlsKeyStoreOptions(); Arc.container().requestContext().activate(); try { myApi.getResult(); @@ -116,7 +119,8 @@ void testReloading() throws IOException { event.fire(new CertificateUpdatedEvent("", def)); Arc.container().requestContext().activate(); try { - assertThat(GraphQLClientsConfiguration.getInstance().getClient("my-client").getTlsKeyStoreOptions()).isNotEqualTo(keystoreOptionsBefore); + assertThat(GraphQLClientsConfiguration.getInstance().getClient("my-client").getTlsKeyStoreOptions()) + .isNotEqualTo(keystoreOptionsBefore); assertThat(myApi.getResult()).isEqualTo(EXPECTED_RESPONSE); } finally { Arc.container().requestContext().terminate(); diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/ssl/TypesafeGraphQLClientReloadKeystoreTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/ssl/TypesafeGraphQLClientReloadKeystoreTest.java index b64b69fac0a40..1ad3e82416b30 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/ssl/TypesafeGraphQLClientReloadKeystoreTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/ssl/TypesafeGraphQLClientReloadKeystoreTest.java @@ -7,8 +7,6 @@ import java.nio.file.Files; import java.util.UUID; -import io.smallrye.graphql.client.impl.GraphQLClientsConfiguration; -import io.vertx.core.net.KeyCertOptions; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.event.Event; import jakarta.inject.Inject; @@ -32,8 +30,10 @@ import io.smallrye.certs.Format; import io.smallrye.certs.junit5.Certificate; import io.smallrye.certs.junit5.Certificates; +import io.smallrye.graphql.client.impl.GraphQLClientsConfiguration; import io.smallrye.graphql.client.typesafe.api.GraphQLClientApi; import io.vertx.core.http.HttpServer; +import io.vertx.core.net.KeyCertOptions; @Certificates(baseDir = "target/certs", certificates = { @Certificate(name = "wrong-test-reload", password = "password", formats = Format.PKCS12, client = true), @@ -102,7 +102,8 @@ static void setupServer() throws Exception { @Test void testReloading() throws IOException { TlsConfiguration tlsClient = registry.get("my-tls-client").orElseThrow(); - KeyCertOptions keystoreOptionsBefore = (KeyCertOptions) GraphQLClientsConfiguration.getInstance().getClient("my-client").getTlsKeyStoreOptions(); + KeyCertOptions keystoreOptionsBefore = (KeyCertOptions) GraphQLClientsConfiguration.getInstance().getClient("my-client") + .getTlsKeyStoreOptions(); Arc.container().requestContext().activate(); try { myApi.getResult(); @@ -119,7 +120,8 @@ void testReloading() throws IOException { event.fire(new CertificateUpdatedEvent("my-tls-client", tlsClient)); Arc.container().requestContext().activate(); try { - assertThat(GraphQLClientsConfiguration.getInstance().getClient("my-client").getTlsKeyStoreOptions()).isNotEqualTo(keystoreOptionsBefore); + assertThat(GraphQLClientsConfiguration.getInstance().getClient("my-client").getTlsKeyStoreOptions()) + .isNotEqualTo(keystoreOptionsBefore); assertThat(myApi.getResult()).isEqualTo(EXPECTED_RESPONSE); } finally { Arc.container().requestContext().terminate(); diff --git a/extensions/smallrye-graphql-client/runtime/src/main/java/io/quarkus/smallrye/graphql/client/runtime/GraphQLClientCertificateUpdateEventListener.java b/extensions/smallrye-graphql-client/runtime/src/main/java/io/quarkus/smallrye/graphql/client/runtime/GraphQLClientCertificateUpdateEventListener.java index 201d56054af22..5d0b5b0aeff43 100644 --- a/extensions/smallrye-graphql-client/runtime/src/main/java/io/quarkus/smallrye/graphql/client/runtime/GraphQLClientCertificateUpdateEventListener.java +++ b/extensions/smallrye-graphql-client/runtime/src/main/java/io/quarkus/smallrye/graphql/client/runtime/GraphQLClientCertificateUpdateEventListener.java @@ -1,6 +1,7 @@ package io.quarkus.smallrye.graphql.client.runtime; -import io.smallrye.graphql.client.impl.GraphQLClientConfiguration; +import static io.quarkus.tls.runtime.config.TlsConfig.DEFAULT_NAME; + import jakarta.enterprise.event.Observes; import jakarta.inject.Inject; import jakarta.inject.Singleton; @@ -9,10 +10,9 @@ import io.quarkus.tls.CertificateUpdatedEvent; import io.quarkus.tls.TlsConfiguration; +import io.smallrye.graphql.client.impl.GraphQLClientConfiguration; import io.smallrye.graphql.client.impl.GraphQLClientsConfiguration; -import static io.quarkus.tls.runtime.config.TlsConfig.DEFAULT_NAME; - @Singleton public class GraphQLClientCertificateUpdateEventListener { @@ -26,10 +26,12 @@ public void onCertificateUpdate(@Observes CertificateUpdatedEvent event) { TlsConfiguration updatedTlsConfiguration = event.tlsConfiguration(); graphQLClientsConfig.clients .forEach((configKey, clientConfig) -> { - GraphQLClientConfiguration graphQLClientConfiguration = GraphQLClientsConfiguration.getInstance().getClient(configKey); + GraphQLClientConfiguration graphQLClientConfiguration = GraphQLClientsConfiguration.getInstance() + .getClient(configKey); clientConfig.tlsConfigurationName.ifPresentOrElse(tlsConfigurationName -> { if (tlsConfigurationName.equals(updatedTlsConfigurationName)) { - updateConfiguration(updatedTlsConfigurationName, updatedTlsConfiguration, graphQLClientConfiguration, configKey); + updateConfiguration(updatedTlsConfigurationName, updatedTlsConfiguration, + graphQLClientConfiguration, configKey); } }, () -> { if (DEFAULT_NAME.equals(updatedTlsConfigurationName)) { @@ -39,7 +41,8 @@ public void onCertificateUpdate(@Observes CertificateUpdatedEvent event) { }); } - private void updateConfiguration(String tlsBucketName, TlsConfiguration updatedTlsConfiguration, GraphQLClientConfiguration graphQLClientConfiguration, String configKey) { + private void updateConfiguration(String tlsBucketName, TlsConfiguration updatedTlsConfiguration, + GraphQLClientConfiguration graphQLClientConfiguration, String configKey) { LOG.infof("Certificate reloaded for the client '%s' using the TLS configuration (bucket) name '%s'", configKey, tlsBucketName); graphQLClientConfiguration diff --git a/extensions/smallrye-graphql-client/runtime/src/main/java/io/quarkus/smallrye/graphql/client/runtime/SmallRyeGraphQLClientRecorder.java b/extensions/smallrye-graphql-client/runtime/src/main/java/io/quarkus/smallrye/graphql/client/runtime/SmallRyeGraphQLClientRecorder.java index f4c1294f7fba1..91f3a9aff73c6 100644 --- a/extensions/smallrye-graphql-client/runtime/src/main/java/io/quarkus/smallrye/graphql/client/runtime/SmallRyeGraphQLClientRecorder.java +++ b/extensions/smallrye-graphql-client/runtime/src/main/java/io/quarkus/smallrye/graphql/client/runtime/SmallRyeGraphQLClientRecorder.java @@ -127,7 +127,8 @@ private GraphQLClientConfiguration toSmallRyeNativeConfiguration(GraphQLClientCo transformed.setTlsKeyStoreOptions(tlsConfiguration.getKeyStoreOptions()); transformed.setTlsTrustStoreOptions(tlsConfiguration.getTrustStoreOptions()); transformed.setSslOptions(tlsConfiguration.getSSLOptions()); - tlsConfiguration.getHostnameVerificationAlgorithm().ifPresent(transformed::setHostnameVerificationAlgorithm); + tlsConfiguration.getHostnameVerificationAlgorithm() + .ifPresent(transformed::setHostnameVerificationAlgorithm); transformed.setUsesSni(Boolean.valueOf(tlsConfiguration.usesSni())); }, () -> { // DEPRECATED @@ -166,8 +167,9 @@ private Optional resolveTlsConfigurationForRegistry(GraphQLCli if (Arc.container() != null) { TlsConfigurationRegistry tlsConfigurationRegistry = Arc.container().select(TlsConfigurationRegistry.class).orNull(); if (tlsConfigurationRegistry != null) { - if (tlsConfigurationRegistry.getDefault().isPresent() && (tlsConfigurationRegistry.getDefault().get().getTrustStoreOptions() != null - || tlsConfigurationRegistry.getDefault().get().isTrustAll())) { + if (tlsConfigurationRegistry.getDefault().isPresent() + && (tlsConfigurationRegistry.getDefault().get().getTrustStoreOptions() != null + || tlsConfigurationRegistry.getDefault().get().isTrustAll())) { return tlsConfigurationRegistry.getDefault(); } return TlsConfiguration.from(tlsConfigurationRegistry, quarkusConfig.tlsConfigurationName);