Skip to content

Commit

Permalink
Support for TLS. Switched tests to use TLS.
Browse files Browse the repository at this point in the history
  • Loading branch information
spericas committed Feb 22, 2024
1 parent 32574a2 commit a882c5e
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@
import java.util.concurrent.TimeoutException;

import io.grpc.stub.StreamObserver;
import io.helidon.common.configurable.Resource;
import io.helidon.common.tls.Tls;
import io.helidon.examples.grpc.strings.StringServiceGrpc;
import io.helidon.examples.grpc.strings.Strings;
import io.helidon.webclient.api.WebClient;
import io.helidon.webclient.grpc.GrpcClient;
import io.helidon.webserver.WebServer;
import io.helidon.webserver.WebServerConfig;
import io.helidon.webserver.grpc.GrpcRouting;
import io.helidon.webserver.testing.junit5.ServerTest;
Expand All @@ -39,35 +42,57 @@
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

/**
* Tests gRPC client using stubs and TLS.
*/
@ServerTest
class GrpcStubTest {
private static final long TIMEOUT_SECONDS = 10;

private final WebClient webClient;

private GrpcStubTest(WebClient webClient) {
this.webClient = webClient;
private GrpcStubTest(WebServer server) {
Tls clientTls = Tls.builder()
.trust(trust -> trust
.keystore(store -> store
.passphrase("password")
.trustStore(true)
.keystore(Resource.create("client.p12"))))
.build();
this.webClient = WebClient.builder()
.tls(clientTls)
.baseUri("https://localhost:" + server.port())
.build();
}

@SetUpServer
public static void setup(WebServerConfig.Builder builder) {
builder.addRouting(GrpcRouting.builder()
.unary(Strings.getDescriptor(),
"StringService",
"Upper",
GrpcStubTest::upper)
.serverStream(Strings.getDescriptor(),
"StringService",
"Split",
GrpcStubTest::split)
.clientStream(Strings.getDescriptor(),
"StringService",
"Join",
GrpcStubTest::join)
.bidi(Strings.getDescriptor(),
"StringService",
"Echo",
GrpcStubTest::echo));
builder.tls(tls -> tls.privateKey(key -> key
.keystore(store -> store
.passphrase("password")
.keystore(Resource.create("server.p12"))))
.privateKeyCertChain(key -> key
.keystore(store -> store
.trustStore(true)
.passphrase("password")
.keystore(Resource.create("server.p12")))))
.addRouting(GrpcRouting.builder()
.unary(Strings.getDescriptor(),
"StringService",
"Upper",
GrpcStubTest::upper)
.serverStream(Strings.getDescriptor(),
"StringService",
"Split",
GrpcStubTest::split)
.clientStream(Strings.getDescriptor(),
"StringService",
"Join",
GrpcStubTest::join)
.bidi(Strings.getDescriptor(),
"StringService",
"Echo",
GrpcStubTest::echo));
}

// -- gRPC server methods --
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@

import com.google.protobuf.StringValue;
import io.grpc.stub.StreamObserver;
import io.helidon.common.configurable.Resource;
import io.helidon.common.tls.Tls;
import io.helidon.examples.grpc.strings.Strings;
import io.helidon.webclient.grpc.GrpcClient;
import io.helidon.webclient.grpc.GrpcClientMethodDescriptor;
import io.helidon.webclient.grpc.GrpcServiceDescriptor;
import io.helidon.webserver.WebServer;
import io.helidon.webserver.WebServerConfig;
import io.helidon.webserver.grpc.GrpcRouting;
import io.helidon.webserver.testing.junit5.ServerTest;
Expand All @@ -40,15 +43,29 @@
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

/**
* Tests gRPC client using low-level API and TLS, no stubs.
*/
@ServerTest
class GrpcTest {
private static final long TIMEOUT_SECONDS = 10;

private final GrpcClient grpcClient;
private final GrpcServiceDescriptor serviceDescriptor;

private GrpcTest(GrpcClient grpcClient) {
this.grpcClient = grpcClient;
private GrpcTest(WebServer server) {
Tls clientTls = Tls.builder()
.trust(trust -> trust
.keystore(store -> store
.passphrase("password")
.trustStore(true)
.keystore(Resource.create("client.p12"))))
.build();
this.grpcClient = GrpcClient.builder()
.tls(clientTls)
.baseUri("https://localhost:" + server.port())
.build();

this.serviceDescriptor = GrpcServiceDescriptor.builder()
.serviceName("StringService")
.putMethod("Upper",
Expand Down Expand Up @@ -76,23 +93,32 @@ private GrpcTest(GrpcClient grpcClient) {

@SetUpServer
public static void setup(WebServerConfig.Builder builder) {
builder.addRouting(GrpcRouting.builder()
.unary(Strings.getDescriptor(),
"StringService",
"Upper",
GrpcTest::upper)
.serverStream(Strings.getDescriptor(),
"StringService",
"Split",
GrpcTest::split)
.clientStream(Strings.getDescriptor(),
"StringService",
"Join",
GrpcTest::join)
.bidi(Strings.getDescriptor(),
"StringService",
"Echo",
GrpcTest::echo));
builder.tls(tls -> tls.privateKey(key -> key
.keystore(store -> store
.passphrase("password")
.keystore(Resource.create("server.p12"))))
.privateKeyCertChain(key -> key
.keystore(store -> store
.trustStore(true)
.passphrase("password")
.keystore(Resource.create("server.p12")))))
.addRouting(GrpcRouting.builder()
.unary(Strings.getDescriptor(),
"StringService",
"Upper",
GrpcTest::upper)
.serverStream(Strings.getDescriptor(),
"StringService",
"Split",
GrpcTest::split)
.clientStream(Strings.getDescriptor(),
"StringService",
"Join",
GrpcTest::join)
.bidi(Strings.getDescriptor(),
"StringService",
"Echo",
GrpcTest::echo));
}

// -- gRPC server methods --
Expand Down Expand Up @@ -187,7 +213,7 @@ void testUnaryUpperAsync() throws ExecutionException, InterruptedException, Time
void testServerStreamingSplit() {
Iterator<Strings.StringMessage> res = grpcClient.serviceClient(serviceDescriptor)
.serverStream("Split",
newStringMessage("hello world"));
newStringMessage("hello world"));
assertThat(res.next().getText(), is("hello"));
assertThat(res.next().getText(), is("world"));
assertThat(res.hasNext(), is(false));
Expand Down
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import java.util.logging.Logger;

import io.helidon.common.buffers.BufferData;
import io.helidon.common.tls.Tls;
import io.helidon.http.Header;
import io.helidon.http.HeaderNames;
import io.helidon.http.HeaderValues;
Expand Down Expand Up @@ -59,18 +58,20 @@

/**
* A gRPC client call handler. The typical order of calls will be:
*
* <p>
* start (request | sendMessage)* (halfClose | cancel)
*
* @param <ReqT>
* @param <ResT>
* @param <ReqT> request type
* @param <ResT> response type
*/
class GrpcClientCall<ReqT, ResT> extends ClientCall<ReqT, ResT> {
private static final Logger LOGGER = Logger.getLogger(GrpcClientCall.class.getName());

private static final Header GRPC_ACCEPT_ENCODING = HeaderValues.create(HeaderNames.ACCEPT_ENCODING, "gzip");
private static final Header GRPC_CONTENT_TYPE = HeaderValues.create(HeaderNames.CONTENT_TYPE, "application/grpc");

private static final int READ_TIMEOUT_SECONDS = 10;
private static final int BUFFER_SIZE_BYTES = 1024;
private static final int WAIT_TIME_MILLIS = 100;
private static final Duration WAIT_TIME_MILLIS_DURATION = Duration.ofMillis(WAIT_TIME_MILLIS);

Expand Down Expand Up @@ -135,7 +136,7 @@ public int priority() {

@Override
public Duration readTimeout() {
return grpcClient.prototype().readTimeout().orElse(Duration.ofSeconds(10));
return grpcClient.prototype().readTimeout().orElse(Duration.ofSeconds(READ_TIMEOUT_SECONDS));
}
},
null, // Http2ClientConfig
Expand Down Expand Up @@ -181,7 +182,7 @@ public void halfClose() {
@Override
public void sendMessage(ReqT message) {
LOGGER.finest("sendMessage called");
BufferData messageData = BufferData.growing(512);
BufferData messageData = BufferData.growing(BUFFER_SIZE_BYTES);
messageData.readFrom(requestMarshaller.stream(message));
BufferData headerData = BufferData.create(5);
headerData.writeInt8(0); // no compression
Expand Down Expand Up @@ -297,13 +298,12 @@ private ClientConnection clientConnection() {
ClientUri clientUri = clientConfig.baseUri().orElseThrow();
WebClient webClient = grpcClient.webClient();

Tls tls = Tls.builder().enabled(false).build();
ConnectionKey connectionKey = new ConnectionKey(
clientUri.scheme(),
clientUri.host(),
clientUri.port(),
clientConfig.readTimeout().orElse(Duration.ZERO),
tls,
clientConfig.tls(),
DefaultDnsResolver.create(),
DnsAddressLookup.defaultLookup(),
Proxy.noProxy());
Expand Down

0 comments on commit a882c5e

Please sign in to comment.