Allow setting trusted certs for OTLP Trace exporter (#2429)

This commit is contained in:
Anuraag Agrawal 2021-01-07 08:53:20 +09:00 committed by GitHub
parent 015708b7a7
commit 045dd0c1a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 516 additions and 96 deletions

View File

@ -1,4 +1,5 @@
import nebula.plugin.release.git.opinion.Strategies
import ru.vyarus.gradle.plugin.animalsniffer.AnimalSniffer
plugins {
id "com.diffplug.spotless"
@ -377,8 +378,10 @@ subprojects {
}
plugins.withId("ru.vyarus.animalsniffer") {
animalsnifferTest {
enabled = false
tasks.withType(AnimalSniffer) {
if (name.startsWith('animalsnifferTest')) {
enabled = false
}
}
// If JMH enabled ignore animalsniffer.
plugins.withId("me.champeau.gradle.jmh") {

View File

@ -3,15 +3,25 @@ plugins {
id "maven-publish"
id "me.champeau.gradle.jmh"
id "org.unbroken-dome.test-sets"
id "ru.vyarus.animalsniffer"
}
description = 'OpenTelemetry Protocol Trace Exporter'
ext.moduleName = "io.opentelemetry.exporter.otlp.trace"
testSets {
testGrpcNetty
testGrpcNettyShaded
testGrpcOkhttp
}
dependencies {
api project(':sdk:trace')
compileOnly "io.grpc:grpc-netty"
compileOnly "io.grpc:grpc-netty-shaded"
implementation project(':sdk-extensions:otproto'),
libraries.grpc_api,
libraries.grpc_protobuf,
@ -19,11 +29,25 @@ dependencies {
libraries.protobuf
testImplementation project(':sdk:testing'),
'com.linecorp.armeria:armeria-grpc',
'com.linecorp.armeria:armeria-junit5',
"io.grpc:grpc-testing:${grpcVersion}"
testRuntime "io.grpc:grpc-netty-shaded:${grpcVersion}"
testGrpcNettyImplementation 'com.linecorp.armeria:armeria-grpc',
'com.linecorp.armeria:armeria-junit5'
testGrpcNettyShadedImplementation 'com.linecorp.armeria:armeria-grpc',
'com.linecorp.armeria:armeria-junit5'
testGrpcOkhttpImplementation 'com.linecorp.armeria:armeria-grpc',
'com.linecorp.armeria:armeria-junit5'
testGrpcNettyRuntimeOnly "io.grpc:grpc-netty:${grpcVersion}",
libraries.slf4jsimple
testGrpcNettyShadedRuntimeOnly "io.grpc:grpc-netty-shaded:${grpcVersion}",
libraries.slf4jsimple
testGrpcOkhttpRuntimeOnly "io.grpc:grpc-okhttp:${grpcVersion}",
libraries.slf4jsimple
jmh project(':sdk:testing')

View File

@ -11,12 +11,16 @@ import com.google.common.base.Splitter;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.Metadata;
import io.grpc.netty.GrpcSslContexts;
import io.grpc.netty.NettyChannelBuilder;
import io.grpc.stub.MetadataUtils;
import io.opentelemetry.sdk.common.export.ConfigBuilder;
import io.opentelemetry.sdk.extension.otproto.CommonProperties;
import java.io.ByteArrayInputStream;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import javax.net.ssl.SSLException;
/** Builder utility for this exporter. */
public final class OtlpGrpcSpanExporterBuilder extends ConfigBuilder<OtlpGrpcSpanExporterBuilder> {
@ -31,6 +35,7 @@ public final class OtlpGrpcSpanExporterBuilder extends ConfigBuilder<OtlpGrpcSpa
private String endpoint = OtlpGrpcSpanExporter.DEFAULT_ENDPOINT;
private boolean useTls = false;
@Nullable private Metadata metadata;
@Nullable private byte[] trustedCertificatesPem;
/**
* Sets the managed chanel to use when communicating with the backend. Takes precedence over
@ -78,6 +83,16 @@ public final class OtlpGrpcSpanExporterBuilder extends ConfigBuilder<OtlpGrpcSpa
return this;
}
/**
* Sets the certificate chain to use for verifying servers when TLS is enabled. The {@code byte[]}
* should contain an X.509 certificate collection in PEM format. If not set, TLS connections will
* use the system default trusted certificates.
*/
public OtlpGrpcSpanExporterBuilder setTrustedCertificates(byte[] trustedCertificatesPem) {
this.trustedCertificatesPem = trustedCertificatesPem;
return this;
}
/**
* Add header to request. Optional. Applicable only if {@link
* OtlpGrpcSpanExporterBuilder#endpoint} is set to build channel.
@ -114,6 +129,51 @@ public final class OtlpGrpcSpanExporterBuilder extends ConfigBuilder<OtlpGrpcSpa
managedChannelBuilder.intercept(MetadataUtils.newAttachHeadersInterceptor(metadata));
}
if (trustedCertificatesPem != null) {
// gRPC does not abstract TLS configuration so we need to check the implementation and act
// accordingly.
if (managedChannelBuilder
.getClass()
.getName()
.equals("io.grpc.netty.NettyChannelBuilder")) {
NettyChannelBuilder nettyBuilder = (NettyChannelBuilder) managedChannelBuilder;
try {
nettyBuilder.sslContext(
GrpcSslContexts.forClient()
.trustManager(new ByteArrayInputStream(trustedCertificatesPem))
.build());
} catch (IllegalArgumentException | SSLException e) {
throw new IllegalStateException(
"Could not set trusted certificates for gRPC TLS connection, are they valid "
+ "X.509 in PEM format?",
e);
}
} else if (managedChannelBuilder
.getClass()
.getName()
.equals("io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder")) {
io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder nettyBuilder =
(io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder) managedChannelBuilder;
try {
nettyBuilder.sslContext(
io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts.forClient()
.trustManager(new ByteArrayInputStream(trustedCertificatesPem))
.build());
} catch (IllegalArgumentException | SSLException e) {
throw new IllegalStateException(
"Could not set trusted certificates for gRPC TLS connection, are they valid "
+ "X.509 in PEM format?",
e);
}
} else {
throw new IllegalStateException(
"TLS cerificate configuration only supported with Netty. "
+ "If you need to configure a certificate, switch to grpc-netty or "
+ "grpc-netty-shaded.");
}
// TODO(anuraaga): Support okhttp.
}
channel = managedChannelBuilder.build();
}
return new OtlpGrpcSpanExporter(channel, deadlineMs);

View File

@ -5,17 +5,10 @@
package io.opentelemetry.exporter.otlp.trace;
import static com.google.common.base.Charsets.US_ASCII;
import static io.grpc.Metadata.ASCII_STRING_MARSHALLER;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
import com.google.common.io.Closer;
import com.linecorp.armeria.common.RequestHeaders;
import com.linecorp.armeria.server.ServerBuilder;
import com.linecorp.armeria.server.ServiceRequestContext;
import com.linecorp.armeria.server.grpc.GrpcService;
import com.linecorp.armeria.testing.junit5.server.ServerExtension;
import io.grpc.ManagedChannel;
import io.grpc.Server;
import io.grpc.Status;
@ -24,8 +17,6 @@ import io.grpc.inprocess.InProcessChannelBuilder;
import io.grpc.inprocess.InProcessServerBuilder;
import io.grpc.stub.StreamObserver;
import io.opentelemetry.api.trace.Span.Kind;
import io.opentelemetry.api.trace.SpanId;
import io.opentelemetry.api.trace.TraceId;
import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest;
import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse;
import io.opentelemetry.proto.collector.trace.v1.TraceServiceGrpc;
@ -36,50 +27,15 @@ import io.opentelemetry.sdk.testing.trace.TestSpanData;
import io.opentelemetry.sdk.trace.data.SpanData;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
class OtlpGrpcSpanExporterTest {
@RegisterExtension
public static ServerExtension server =
new ServerExtension() {
@Override
protected void configure(ServerBuilder sb) throws Exception {
sb.service(
GrpcService.builder()
.addService(
new TraceServiceGrpc.TraceServiceImplBase() {
@Override
public void export(
ExportTraceServiceRequest request,
StreamObserver<ExportTraceServiceResponse> responseObserver) {
RequestHeaders headers =
ServiceRequestContext.current().request().headers();
if (headers.get("key").equals("value")
&& headers.get("key2").equals("value2=")
&& headers.get("key3").equals("val=ue3")
&& headers.get("key4").equals("value4")
&& !headers.contains("key5")) {
responseObserver.onNext(
ExportTraceServiceResponse.getDefaultInstance());
responseObserver.onCompleted();
} else {
responseObserver.onError(new AssertionError("Invalid metadata"));
}
}
})
.build());
}
};
private static final String TRACE_ID = "00000000000000000000000000abc123";
private static final String SPAN_ID = "0000000000def456";
@ -90,53 +46,6 @@ class OtlpGrpcSpanExporterTest {
private final Closer closer = Closer.create();
@Test
void configTest() {
Properties options = new Properties();
String endpoint = "localhost:" + server.httpPort();
options.put("otel.exporter.otlp.span.timeout", "5124");
options.put("otel.exporter.otlp.span.endpoint", endpoint);
options.put("otel.exporter.otlp.span.insecure", "true");
options.put(
"otel.exporter.otlp.span.headers",
"key=value,key2=value2=,key3=val=ue3, key4 = value4 ,key5= ");
OtlpGrpcSpanExporterBuilder builder = OtlpGrpcSpanExporter.builder().readProperties(options);
assertThat(builder)
.extracting("metadata")
.extracting("namesAndValues")
.isEqualTo(
new Object[] {
"key".getBytes(US_ASCII),
ASCII_STRING_MARSHALLER.toAsciiString("value").getBytes(US_ASCII),
"key2".getBytes(US_ASCII),
ASCII_STRING_MARSHALLER.toAsciiString("value2=").getBytes(US_ASCII),
"key3".getBytes(US_ASCII),
ASCII_STRING_MARSHALLER.toAsciiString("val=ue3").getBytes(US_ASCII),
"key4".getBytes(US_ASCII),
ASCII_STRING_MARSHALLER.toAsciiString("value4").getBytes(US_ASCII)
});
OtlpGrpcSpanExporter exporter = builder.build();
assertThat(exporter.getDeadlineMs()).isEqualTo(5124);
assertThat(
exporter
.export(
Arrays.asList(
TestSpanData.builder()
.setTraceId(TraceId.getInvalid())
.setSpanId(SpanId.getInvalid())
.setName("name")
.setKind(Kind.CLIENT)
.setStartEpochNanos(1)
.setEndEpochNanos(2)
.setStatus(SpanData.Status.ok())
.setHasEnded(true)
.build()))
.join(10, TimeUnit.SECONDS)
.isSuccess())
.isTrue();
}
@BeforeEach
public void setup() throws IOException {
Server server =

View File

@ -0,0 +1,112 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.exporter.otlp.trace;
import static com.google.common.base.Charsets.US_ASCII;
import static io.grpc.Metadata.ASCII_STRING_MARSHALLER;
import static org.assertj.core.api.Assertions.assertThat;
import com.linecorp.armeria.common.RequestHeaders;
import com.linecorp.armeria.server.ServerBuilder;
import com.linecorp.armeria.server.ServiceRequestContext;
import com.linecorp.armeria.server.grpc.GrpcService;
import com.linecorp.armeria.testing.junit5.server.ServerExtension;
import io.grpc.stub.StreamObserver;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanId;
import io.opentelemetry.api.trace.TraceId;
import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest;
import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse;
import io.opentelemetry.proto.collector.trace.v1.TraceServiceGrpc;
import io.opentelemetry.sdk.testing.trace.TestSpanData;
import io.opentelemetry.sdk.trace.data.SpanData;
import java.util.Arrays;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
class OtlpGrpcSpanExporterTest {
@RegisterExtension
public static ServerExtension server =
new ServerExtension() {
@Override
protected void configure(ServerBuilder sb) throws Exception {
sb.service(
GrpcService.builder()
.addService(
new TraceServiceGrpc.TraceServiceImplBase() {
@Override
public void export(
ExportTraceServiceRequest request,
StreamObserver<ExportTraceServiceResponse> responseObserver) {
RequestHeaders headers =
ServiceRequestContext.current().request().headers();
if (headers.get("key").equals("value")
&& headers.get("key2").equals("value2=")
&& headers.get("key3").equals("val=ue3")
&& headers.get("key4").equals("value4")
&& !headers.contains("key5")) {
responseObserver.onNext(
ExportTraceServiceResponse.getDefaultInstance());
responseObserver.onCompleted();
} else {
responseObserver.onError(new AssertionError("Invalid metadata"));
}
}
})
.build());
}
};
@Test
void configTest() {
Properties options = new Properties();
String endpoint = "localhost:" + server.httpPort();
options.put("otel.exporter.otlp.span.timeout", "5124");
options.put("otel.exporter.otlp.span.endpoint", endpoint);
options.put("otel.exporter.otlp.span.insecure", "true");
options.put(
"otel.exporter.otlp.span.headers",
"key=value,key2=value2=,key3=val=ue3, key4 = value4 ,key5= ");
OtlpGrpcSpanExporterBuilder builder = OtlpGrpcSpanExporter.builder().readProperties(options);
assertThat(builder)
.extracting("metadata")
.extracting("namesAndValues")
.isEqualTo(
new Object[] {
"key".getBytes(US_ASCII),
ASCII_STRING_MARSHALLER.toAsciiString("value").getBytes(US_ASCII),
"key2".getBytes(US_ASCII),
ASCII_STRING_MARSHALLER.toAsciiString("value2=").getBytes(US_ASCII),
"key3".getBytes(US_ASCII),
ASCII_STRING_MARSHALLER.toAsciiString("val=ue3").getBytes(US_ASCII),
"key4".getBytes(US_ASCII),
ASCII_STRING_MARSHALLER.toAsciiString("value4").getBytes(US_ASCII)
});
OtlpGrpcSpanExporter exporter = builder.build();
assertThat(exporter.getDeadlineMs()).isEqualTo(5124);
assertThat(
exporter
.export(
Arrays.asList(
TestSpanData.builder()
.setTraceId(TraceId.getInvalid())
.setSpanId(SpanId.getInvalid())
.setName("name")
.setKind(Span.Kind.CLIENT)
.setStartEpochNanos(1)
.setEndEpochNanos(2)
.setStatus(SpanData.Status.ok())
.setHasEnded(true)
.build()))
.join(10, TimeUnit.SECONDS)
.isSuccess())
.isTrue();
}
}

View File

@ -0,0 +1,124 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.exporter.otlp.trace;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import com.linecorp.armeria.server.ServerBuilder;
import com.linecorp.armeria.server.grpc.GrpcService;
import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension;
import com.linecorp.armeria.testing.junit5.server.ServerExtension;
import io.grpc.stub.StreamObserver;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanId;
import io.opentelemetry.api.trace.TraceId;
import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest;
import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse;
import io.opentelemetry.proto.collector.trace.v1.TraceServiceGrpc;
import io.opentelemetry.sdk.testing.trace.TestSpanData;
import io.opentelemetry.sdk.trace.data.SpanData;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
class TlsExportTest {
@RegisterExtension
@Order(1)
public static SelfSignedCertificateExtension certificate = new SelfSignedCertificateExtension();
@RegisterExtension
@Order(2)
public static ServerExtension server =
new ServerExtension() {
@Override
protected void configure(ServerBuilder sb) {
sb.service(
GrpcService.builder()
.addService(
new TraceServiceGrpc.TraceServiceImplBase() {
@Override
public void export(
ExportTraceServiceRequest request,
StreamObserver<ExportTraceServiceResponse> responseObserver) {
responseObserver.onNext(ExportTraceServiceResponse.getDefaultInstance());
responseObserver.onCompleted();
}
})
.build());
sb.tls(certificate.certificateFile(), certificate.privateKeyFile());
}
};
@Test
void testTlsExport() throws Exception {
OtlpGrpcSpanExporter exporter =
OtlpGrpcSpanExporter.builder()
.setEndpoint("localhost:" + server.httpsPort())
.setUseTls(true)
.setTrustedCertificates(Files.readAllBytes(certificate.certificateFile().toPath()))
.build();
assertThat(
exporter
.export(
Arrays.asList(
TestSpanData.builder()
.setTraceId(TraceId.getInvalid())
.setSpanId(SpanId.getInvalid())
.setName("name")
.setKind(Span.Kind.CLIENT)
.setStartEpochNanos(1)
.setEndEpochNanos(2)
.setStatus(SpanData.Status.ok())
.setHasEnded(true)
.build()))
.join(10, TimeUnit.SECONDS)
.isSuccess())
.isTrue();
}
@Test
void testTlsExport_untrusted() throws Exception {
OtlpGrpcSpanExporter exporter =
OtlpGrpcSpanExporter.builder()
.setEndpoint("localhost:" + server.httpsPort())
.setUseTls(true)
.build();
assertThat(
exporter
.export(
Arrays.asList(
TestSpanData.builder()
.setTraceId(TraceId.getInvalid())
.setSpanId(SpanId.getInvalid())
.setName("name")
.setKind(Span.Kind.CLIENT)
.setStartEpochNanos(1)
.setEndEpochNanos(2)
.setStatus(SpanData.Status.ok())
.setHasEnded(true)
.build()))
.join(10, TimeUnit.SECONDS)
.isSuccess())
.isFalse();
}
@Test
void tlsBadCert() {
assertThatThrownBy(
() ->
OtlpGrpcSpanExporter.builder()
.setTrustedCertificates("foobar".getBytes(StandardCharsets.UTF_8))
.build())
.isInstanceOf(IllegalStateException.class)
.hasMessageContaining("Could not set trusted certificates");
}
}

View File

@ -0,0 +1,124 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.exporter.otlp.trace;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import com.linecorp.armeria.server.ServerBuilder;
import com.linecorp.armeria.server.grpc.GrpcService;
import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension;
import com.linecorp.armeria.testing.junit5.server.ServerExtension;
import io.grpc.stub.StreamObserver;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanId;
import io.opentelemetry.api.trace.TraceId;
import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest;
import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse;
import io.opentelemetry.proto.collector.trace.v1.TraceServiceGrpc;
import io.opentelemetry.sdk.testing.trace.TestSpanData;
import io.opentelemetry.sdk.trace.data.SpanData;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
class TlsExportTest {
@RegisterExtension
@Order(1)
public static SelfSignedCertificateExtension certificate = new SelfSignedCertificateExtension();
@RegisterExtension
@Order(2)
public static ServerExtension server =
new ServerExtension() {
@Override
protected void configure(ServerBuilder sb) {
sb.service(
GrpcService.builder()
.addService(
new TraceServiceGrpc.TraceServiceImplBase() {
@Override
public void export(
ExportTraceServiceRequest request,
StreamObserver<ExportTraceServiceResponse> responseObserver) {
responseObserver.onNext(ExportTraceServiceResponse.getDefaultInstance());
responseObserver.onCompleted();
}
})
.build());
sb.tls(certificate.certificateFile(), certificate.privateKeyFile());
}
};
@Test
void testTlsExport() throws Exception {
OtlpGrpcSpanExporter exporter =
OtlpGrpcSpanExporter.builder()
.setEndpoint("localhost:" + server.httpsPort())
.setUseTls(true)
.setTrustedCertificates(Files.readAllBytes(certificate.certificateFile().toPath()))
.build();
assertThat(
exporter
.export(
Arrays.asList(
TestSpanData.builder()
.setTraceId(TraceId.getInvalid())
.setSpanId(SpanId.getInvalid())
.setName("name")
.setKind(Span.Kind.CLIENT)
.setStartEpochNanos(1)
.setEndEpochNanos(2)
.setStatus(SpanData.Status.ok())
.setHasEnded(true)
.build()))
.join(10, TimeUnit.SECONDS)
.isSuccess())
.isTrue();
}
@Test
void testTlsExport_untrusted() throws Exception {
OtlpGrpcSpanExporter exporter =
OtlpGrpcSpanExporter.builder()
.setEndpoint("localhost:" + server.httpsPort())
.setUseTls(true)
.build();
assertThat(
exporter
.export(
Arrays.asList(
TestSpanData.builder()
.setTraceId(TraceId.getInvalid())
.setSpanId(SpanId.getInvalid())
.setName("name")
.setKind(Span.Kind.CLIENT)
.setStartEpochNanos(1)
.setEndEpochNanos(2)
.setStatus(SpanData.Status.ok())
.setHasEnded(true)
.build()))
.join(10, TimeUnit.SECONDS)
.isSuccess())
.isFalse();
}
@Test
void tlsBadCert() {
assertThatThrownBy(
() ->
OtlpGrpcSpanExporter.builder()
.setTrustedCertificates("foobar".getBytes(StandardCharsets.UTF_8))
.build())
.isInstanceOf(IllegalStateException.class)
.hasMessageContaining("Could not set trusted certificates");
}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.exporter.otlp.trace;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import com.linecorp.armeria.server.ServerBuilder;
import com.linecorp.armeria.server.grpc.GrpcService;
import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension;
import com.linecorp.armeria.testing.junit5.server.ServerExtension;
import io.grpc.stub.StreamObserver;
import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest;
import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse;
import io.opentelemetry.proto.collector.trace.v1.TraceServiceGrpc;
import java.nio.file.Files;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
class TlsExportTest {
@RegisterExtension
@Order(1)
public static SelfSignedCertificateExtension certificate = new SelfSignedCertificateExtension();
@RegisterExtension
@Order(2)
public static ServerExtension server =
new ServerExtension() {
@Override
protected void configure(ServerBuilder sb) {
sb.service(
GrpcService.builder()
.addService(
new TraceServiceGrpc.TraceServiceImplBase() {
@Override
public void export(
ExportTraceServiceRequest request,
StreamObserver<ExportTraceServiceResponse> responseObserver) {
responseObserver.onNext(ExportTraceServiceResponse.getDefaultInstance());
responseObserver.onCompleted();
}
})
.build());
sb.tls(certificate.certificateFile(), certificate.privateKeyFile());
}
};
@Test
void testTlsExport() {
// Currently not supported.
assertThatThrownBy(
() ->
OtlpGrpcSpanExporter.builder()
.setTrustedCertificates(
Files.readAllBytes(certificate.certificateFile().toPath()))
.build())
.isInstanceOf(IllegalStateException.class)
.hasMessageContaining("TLS cerificate configuration only supported with Netty.");
}
}