Skip to content

Commit

Permalink
Allow configuring the gRPC client using the TLS registry
Browse files Browse the repository at this point in the history
This commit transitions the configuration of the Quarkus (Vert.x based) gRPC client from `quarkus.grpc.clients.<name>.tls....` to `quarkus.tls.keystore/truststore/...`. This change provides a more streamlined and intuitive configuration process. The previous approach is still supported.

Additionally, the update introduces support for named configurations, which can be selected using the `quarkus.grpc.clients.<name>.tls-configuration-name` property.

Note that this change only updates the Quarkus (Vert.x based) gRPC client. The plain gRPC client (using grpc-java) do not use the TLS registry.
  • Loading branch information
cescoffier committed May 7, 2024
1 parent e9a090a commit 9ffba64
Show file tree
Hide file tree
Showing 16 changed files with 799 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package io.quarkus.grpc.client.tls;

import static org.assertj.core.api.Assertions.assertThat;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.grpc.examples.helloworld.GreeterGrpc;
import io.grpc.examples.helloworld.HelloReply;
import io.grpc.examples.helloworld.HelloRequest;
import io.quarkus.grpc.GrpcClient;
import io.quarkus.test.QuarkusUnitTest;
import me.escoffier.certs.Format;
import me.escoffier.certs.junit5.Certificate;
import me.escoffier.certs.junit5.Certificates;

@Certificates(baseDir = "target/certs", certificates = {
@Certificate(name = "grpc", password = "password", formats = { Format.JKS, Format.PEM, Format.PKCS12 }, client = true)
})
class MtlsWithJKSTrustStoreWithHttpServerWithTlsRegistryTest {

private static final String configuration = """
quarkus.tls.key-store.jks.path=target/certs/grpc-keystore.jks
quarkus.tls.key-store.jks.password=password
quarkus.tls.trust-store.jks.path=target/certs/grpc-server-truststore.jks
quarkus.tls.trust-store.jks.password=password
quarkus.tls.my-client.trust-store.jks.path=target/certs/grpc-client-truststore.jks
quarkus.tls.my-client.trust-store.jks.password=password
quarkus.tls.my-client.key-store.jks.path=target/certs/grpc-client-keystore.jks
quarkus.tls.my-client.key-store.jks.password=password
quarkus.grpc.clients.hello.plain-text=false
quarkus.grpc.clients.hello.tls-configuration-name=my-client
quarkus.grpc.clients.hello.use-quarkus-grpc-client=true
quarkus.grpc.server.use-separate-server=false
quarkus.grpc.server.plain-text=false # Force the client to use TLS for the tests
quarkus.http.ssl.client-auth=REQUIRED
quarkus.http.insecure-requests=disabled
""";

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest().setArchiveProducer(
() -> ShrinkWrap.create(JavaArchive.class)
.addPackage(HelloWorldTlsEndpoint.class.getPackage())
.addPackage(GreeterGrpc.class.getPackage())
.add(new StringAsset(configuration), "application.properties"));

@GrpcClient("hello")
GreeterGrpc.GreeterBlockingStub blockingHelloService;

@Test
void testClientTlsConfiguration() {
HelloReply reply = blockingHelloService.sayHello(HelloRequest.newBuilder().setName("neo").build());
assertThat(reply.getMessage()).isEqualTo("Hello neo");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package io.quarkus.grpc.client.tls;

import static org.assertj.core.api.Assertions.assertThat;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.grpc.examples.helloworld.GreeterGrpc;
import io.grpc.examples.helloworld.HelloReply;
import io.grpc.examples.helloworld.HelloRequest;
import io.quarkus.grpc.GrpcClient;
import io.quarkus.test.QuarkusUnitTest;
import me.escoffier.certs.Format;
import me.escoffier.certs.junit5.Certificate;
import me.escoffier.certs.junit5.Certificates;

@Certificates(baseDir = "target/certs", certificates = {
@Certificate(name = "grpc", password = "password", formats = { Format.JKS, Format.PEM, Format.PKCS12 }, client = true)
})
class MtlsWithP12TrustStoreWithHttpServerWithTlsRegistryTest {

private static final String configuration = """
quarkus.tls.key-store.p12.path=target/certs/grpc-keystore.p12
quarkus.tls.key-store.p12.password=password
quarkus.tls.trust-store.p12.path=target/certs/grpc-server-truststore.p12
quarkus.tls.trust-store.p12.password=password
quarkus.tls.my-client.trust-store.p12.path=target/certs/grpc-client-truststore.p12
quarkus.tls.my-client.trust-store.p12.password=password
quarkus.tls.my-client.key-store.p12.path=target/certs/grpc-client-keystore.p12
quarkus.tls.my-client.key-store.p12.password=password
quarkus.grpc.clients.hello.plain-text=false
quarkus.grpc.clients.hello.tls-configuration-name=my-client
quarkus.grpc.clients.hello.use-quarkus-grpc-client=true
quarkus.grpc.server.use-separate-server=false
quarkus.grpc.server.plain-text=false # Force the client to use TLS for the tests
quarkus.http.ssl.client-auth=REQUIRED
quarkus.http.insecure-requests=disabled
""";

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest().setArchiveProducer(
() -> ShrinkWrap.create(JavaArchive.class)
.addPackage(HelloWorldTlsEndpoint.class.getPackage())
.addPackage(GreeterGrpc.class.getPackage())
.add(new StringAsset(configuration), "application.properties"));

@GrpcClient("hello")
GreeterGrpc.GreeterBlockingStub blockingHelloService;

@Test
void testClientTlsConfiguration() {
HelloReply reply = blockingHelloService.sayHello(HelloRequest.newBuilder().setName("neo").build());
assertThat(reply.getMessage()).isEqualTo("Hello neo");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package io.quarkus.grpc.client.tls;

import static org.assertj.core.api.Assertions.assertThat;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.grpc.examples.helloworld.GreeterGrpc;
import io.grpc.examples.helloworld.HelloReply;
import io.grpc.examples.helloworld.HelloRequest;
import io.quarkus.grpc.GrpcClient;
import io.quarkus.test.QuarkusUnitTest;
import me.escoffier.certs.Format;
import me.escoffier.certs.junit5.Certificate;
import me.escoffier.certs.junit5.Certificates;

@Certificates(baseDir = "target/certs", certificates = {
@Certificate(name = "grpc", password = "password", formats = { Format.JKS, Format.PEM, Format.PKCS12 }, client = true)
})
class MtlsWithPemTrustStoreWithHttpServerWithTlsRegistryTest {

private static final String configuration = """
quarkus.tls.key-store.jks.path=target/certs/grpc-keystore.jks
quarkus.tls.key-store.jks.password=password
quarkus.tls.trust-store.jks.path=target/certs/grpc-server-truststore.jks
quarkus.tls.trust-store.jks.password=password
quarkus.tls.my-client.trust-store.pem.certs=target/certs/grpc-client-ca.crt
quarkus.tls.my-client.key-store.pem.0.cert=target/certs/grpc-client.crt
quarkus.tls.my-client.key-store.pem.0.key=target/certs/grpc-client.key
quarkus.grpc.clients.hello.plain-text=false
quarkus.grpc.clients.hello.tls-configuration-name=my-client
quarkus.grpc.clients.hello.use-quarkus-grpc-client=true
quarkus.grpc.server.use-separate-server=false
quarkus.grpc.server.plain-text=false # Force the client to use TLS for the tests
quarkus.http.ssl.client-auth=REQUIRED
quarkus.http.insecure-requests=disabled
""";

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest().setArchiveProducer(
() -> ShrinkWrap.create(JavaArchive.class)
.addPackage(HelloWorldTlsEndpoint.class.getPackage())
.addPackage(GreeterGrpc.class.getPackage())
.add(new StringAsset(configuration), "application.properties"));

@GrpcClient("hello")
GreeterGrpc.GreeterBlockingStub blockingHelloService;

@Test
void testClientTlsConfiguration() {
HelloReply reply = blockingHelloService.sayHello(HelloRequest.newBuilder().setName("neo").build());
assertThat(reply.getMessage()).isEqualTo("Hello neo");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package io.quarkus.grpc.client.tls;

import static io.restassured.RestAssured.get;
import static org.assertj.core.api.Assertions.assertThat;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
import me.escoffier.certs.Format;
import me.escoffier.certs.junit5.Certificate;
import me.escoffier.certs.junit5.Certificates;

@Certificates(baseDir = "target/certs", certificates = {
@Certificate(name = "grpc", password = "password", formats = { Format.JKS, Format.PEM, Format.PKCS12 }, client = true)
})
class TlsWithJKSTrustStoreAndTlsRegistryTest {

private static final String configuration = """
quarkus.tls.trust-store.jks.path=target/certs/grpc-client-truststore.jks
quarkus.tls.trust-store.jks.password=password
quarkus.grpc.clients.hello.host=localhost
quarkus.grpc.clients.hello.port=9001
quarkus.grpc.clients.hello.plain-text=false
quarkus.grpc.clients.hello.use-quarkus-grpc-client=true
# Legacy server
quarkus.grpc.server.ssl.certificate=target/certs/grpc.crt
quarkus.grpc.server.ssl.key=target/certs/grpc.key
""";

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest().setArchiveProducer(
() -> ShrinkWrap.create(JavaArchive.class)
.addPackage(HelloWorldTlsEndpoint.class.getPackage())
.addPackage(io.grpc.examples.helloworld.GreeterGrpc.class.getPackage())
.add(new StringAsset(configuration), "application.properties"));

@Test
void testClientTlsConfiguration() {
String response = get("/hello/blocking/neo").asString();
assertThat(response).isEqualTo("Hello neo");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package io.quarkus.grpc.client.tls;

import static org.assertj.core.api.Assertions.assertThat;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.grpc.examples.helloworld.GreeterGrpc;
import io.grpc.examples.helloworld.HelloReply;
import io.grpc.examples.helloworld.HelloRequest;
import io.quarkus.grpc.GrpcClient;
import io.quarkus.test.QuarkusUnitTest;
import me.escoffier.certs.Format;
import me.escoffier.certs.junit5.Certificate;
import me.escoffier.certs.junit5.Certificates;

@Certificates(baseDir = "target/certs", certificates = {
@Certificate(name = "grpc", password = "password", formats = { Format.JKS, Format.PEM, Format.PKCS12 }, client = true)
})
class TlsWithJKSTrustStoreWithHttpServerAndTlsRegistryTest {

private static final String configuration = """
quarkus.tls.my-client.trust-store.jks.path=target/certs/grpc-client-truststore.jks
quarkus.tls.my-client.trust-store.jks.password=password
quarkus.grpc.clients.hello.plain-text=false
quarkus.grpc.clients.hello.tls-configuration-name=my-client
quarkus.grpc.clients.hello.use-quarkus-grpc-client=true
quarkus.grpc.server.use-separate-server=false
quarkus.grpc.server.plain-text=false # Force the client to use TLS for the tests
quarkus.tls.key-store.jks.path=target/certs/grpc-keystore.jks
quarkus.tls.key-store.jks.password=password
quarkus.http.insecure-requests=disabled
""";

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest().setArchiveProducer(
() -> ShrinkWrap.create(JavaArchive.class)
.addPackage(HelloWorldTlsEndpoint.class.getPackage())
.addPackage(GreeterGrpc.class.getPackage())
.add(new StringAsset(configuration), "application.properties"));

@GrpcClient("hello")
GreeterGrpc.GreeterBlockingStub blockingHelloService;

@Test
void testClientTlsConfiguration() {
HelloReply reply = blockingHelloService.sayHello(HelloRequest.newBuilder().setName("neo").build());
assertThat(reply.getMessage()).isEqualTo("Hello neo");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package io.quarkus.grpc.client.tls;

import static io.restassured.RestAssured.get;
import static org.assertj.core.api.Assertions.assertThat;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
import me.escoffier.certs.Format;
import me.escoffier.certs.junit5.Certificate;
import me.escoffier.certs.junit5.Certificates;

@Certificates(baseDir = "target/certs", certificates = {
@Certificate(name = "grpc", password = "password", formats = { Format.JKS, Format.PEM, Format.PKCS12 }, client = true)
})
class TlsWithP12TrustStoreAndTlsRegistryTest {

private static final String configuration = """
quarkus.tls.trust-store.p12.path=target/certs/grpc-client-truststore.p12
quarkus.tls.trust-store.p12.password=password
quarkus.grpc.clients.hello.host=localhost
quarkus.grpc.clients.hello.port=9001
quarkus.grpc.clients.hello.plain-text=false
quarkus.grpc.clients.hello.use-quarkus-grpc-client=true
# Legacy server
quarkus.grpc.server.ssl.certificate=target/certs/grpc.crt
quarkus.grpc.server.ssl.key=target/certs/grpc.key
""";

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest().setArchiveProducer(
() -> ShrinkWrap.create(JavaArchive.class)
.addPackage(HelloWorldTlsEndpoint.class.getPackage())
.addPackage(io.grpc.examples.helloworld.GreeterGrpc.class.getPackage())
.add(new StringAsset(configuration), "application.properties"));

@Test
void testClientTlsConfiguration() {
String response = get("/hello/blocking/neo").asString();
assertThat(response).isEqualTo("Hello neo");
}
}
Loading

0 comments on commit 9ffba64

Please sign in to comment.