From b4ef76418431c84c419957784827a976a0a3f3c2 Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Wed, 22 Oct 2025 15:12:05 -0500 Subject: [PATCH] Refactor http, grpc senders and promote to public API --- .../opentelemetry-exporter-common.txt | 120 +++++++- .../Compressor.java | 5 +- .../compressor/CompressorProvider.java | 13 + .../exporter/grpc/GrpcMessageWriter.java | 19 ++ .../exporter/grpc/GrpcResponse.java | 30 ++ .../exporter/grpc/GrpcSender.java | 40 +++ .../exporter/grpc/GrpcSenderConfig.java | 93 ++++++ .../grpc/GrpcSenderProvider.java | 9 +- .../exporter/grpc/GrpcStatusCode.java | 53 ++++ .../exporter/http/HttpRequestBodyWriter.java | 19 ++ .../exporter/http/HttpResponse.java | 27 ++ .../exporter/http/HttpSender.java | 40 +++ .../exporter/http/HttpSenderConfig.java | 89 ++++++ .../http/HttpSenderProvider.java | 5 +- .../internal/FailedExportException.java | 12 +- .../exporter/internal/RetryUtil.java | 16 +- .../compression/CompressorProvider.java | 18 -- .../internal/compression/CompressorUtil.java | 2 + .../internal/compression/GzipCompressor.java | 1 + .../grpc/ExtendedGrpcSenderConfig.java | 21 ++ .../exporter/internal/grpc/GrpcExporter.java | 39 +-- .../internal/grpc/GrpcExporterBuilder.java | 104 ++++--- .../internal/grpc/GrpcExporterUtil.java | 10 - .../exporter/internal/grpc/GrpcResponse.java | 30 -- .../exporter/internal/grpc/GrpcSender.java | 24 -- .../internal/grpc/GrpcSenderConfig.java | 91 ------ .../internal/grpc/ImmutableGrpcResponse.java | 26 ++ .../grpc/ImmutableGrpcSenderConfig.java | 51 ++++ .../internal/grpc/MarshalerInputStream.java | 22 +- .../internal/grpc/MarshalerServiceStub.java | 28 -- .../exporter/internal/http/HttpExporter.java | 28 +- .../internal/http/HttpExporterBuilder.java | 83 +++--- .../exporter/internal/http/HttpSender.java | 61 ---- ...ig.java => ImmutableHttpSenderConfig.java} | 54 +--- .../exporter/internal/marshal/Marshaler.java | 34 +++ .../metrics/ExporterInstrumentation.java | 42 ++- .../grpc/GrpcExporterBuilderTest.java | 7 +- .../internal/grpc/GrpcExporterTest.java | 29 +- .../http/HttpExporterBuilderTest.java | 7 +- .../internal/http/HttpExporterTest.java | 33 ++- .../metrics/ExporterInstrumentationTest.java | 33 +-- .../internal/grpc/GrpcExporterTest.java | 80 ++---- .../internal/http/HttpExporterTest.java | 20 +- exporters/otlp/all/build.gradle.kts | 8 +- .../otlp/trace/OltpExporterBenchmark.java | 29 +- .../http/logs/OtlpHttpLogRecordExporter.java | 9 +- .../OtlpHttpLogRecordExporterBuilder.java | 9 +- .../http/metrics/OtlpHttpMetricExporter.java | 9 +- .../OtlpHttpMetricExporterBuilder.java | 9 +- .../otlp/http/trace/OtlpHttpSpanExporter.java | 10 +- .../trace/OtlpHttpSpanExporterBuilder.java | 9 +- .../otlp/logs/MarshalerLogsServiceGrpc.java | 86 ------ .../otlp/logs/OtlpGrpcLogRecordExporter.java | 9 +- .../OtlpGrpcLogRecordExporterBuilder.java | 16 +- .../metrics/MarshalerMetricsServiceGrpc.java | 90 ------ .../otlp/metrics/OtlpGrpcMetricExporter.java | 9 +- .../OtlpGrpcMetricExporterBuilder.java | 16 +- .../otlp/trace/MarshalerTraceServiceGrpc.java | 85 ------ .../otlp/trace/OtlpGrpcSpanExporter.java | 10 +- .../trace/OtlpGrpcSpanExporterBuilder.java | 16 +- ... OtlpGrpcOkHttpLogRecordExporterTest.java} | 4 +- .../otlp/MarshalerInputStreamBenchmarks.java | 6 +- .../MarshalerProfilesServiceGrpc.java | 90 ------ .../profiles/OtlpGrpcProfileExporter.java | 8 +- .../OtlpGrpcProfilesExporterBuilder.java | 19 +- .../profiles/OtlpGrpcProfileExporterTest.java | 3 +- .../otlp/testing-internal/build.gradle.kts | 1 + .../AbstractGrpcTelemetryExporterTest.java | 267 +++++++++++------- .../AbstractHttpTelemetryExporterTest.java | 16 +- .../internal/compressor/Base64Compressor.java | 2 +- .../compressor/Base64CompressorProvider.java | 4 +- ...ry.exporter.compressor.CompressorProvider} | 0 .../internal/UpstreamGrpcSender.java | 129 +++++++-- .../internal/UpstreamGrpcSenderProvider.java | 83 ++---- ...elemetry.exporter.grpc.GrpcSenderProvider} | 0 .../sender/jdk/internal/JdkHttpSender.java | 68 ++--- .../jdk/internal/JdkHttpSenderProvider.java | 9 +- ...elemetry.exporter.http.HttpSenderProvider} | 0 .../jdk/internal/JdkHttpSenderTest.java | 37 ++- .../okhttp/internal/GrpcRequestBody.java | 15 +- .../okhttp/internal/OkHttpGrpcSender.java | 82 ++++-- .../internal/OkHttpGrpcSenderProvider.java | 16 +- .../okhttp/internal/OkHttpHttpSender.java | 103 +++---- .../internal/OkHttpHttpSenderProvider.java | 9 +- ...elemetry.exporter.grpc.GrpcSenderProvider} | 0 ...elemetry.exporter.http.HttpSenderProvider} | 0 .../okhttp/internal/OkHttpGrpcSenderTest.java | 4 +- .../internal/OkHttpGrpcSuppressionTest.java | 38 +-- .../internal/OkHttpHttpSuppressionTest.java | 26 +- .../exporter/zipkin/ZipkinSpanExporter.java | 3 +- .../sampler/JaegerRemoteSamplerBuilder.java | 2 +- .../MarshallerRemoteSamplerServiceGrpc.java | 36 +-- .../jaeger/sampler/OkHttpGrpcService.java | 9 +- .../jaeger/sampler/UpstreamGrpcService.java | 30 +- 94 files changed, 1552 insertions(+), 1564 deletions(-) rename exporters/common/src/main/java/io/opentelemetry/exporter/{internal/compression => compressor}/Compressor.java (82%) create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/compressor/CompressorProvider.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcMessageWriter.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcResponse.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcSender.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcSenderConfig.java rename exporters/common/src/main/java/io/opentelemetry/exporter/{internal => }/grpc/GrpcSenderProvider.java (50%) create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcStatusCode.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/http/HttpRequestBodyWriter.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/http/HttpResponse.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/http/HttpSender.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/http/HttpSenderConfig.java rename exporters/common/src/main/java/io/opentelemetry/exporter/{internal => }/http/HttpSenderProvider.java (70%) delete mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorProvider.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/ExtendedGrpcSenderConfig.java delete mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcResponse.java delete mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSender.java delete mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderConfig.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/ImmutableGrpcResponse.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/ImmutableGrpcSenderConfig.java delete mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/MarshalerServiceStub.java delete mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSender.java rename exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/{HttpSenderConfig.java => ImmutableHttpSenderConfig.java} (52%) delete mode 100644 exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/MarshalerLogsServiceGrpc.java delete mode 100644 exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/MarshalerMetricsServiceGrpc.java delete mode 100644 exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/MarshalerTraceServiceGrpc.java rename exporters/otlp/all/src/testGrpcOkhttp/java/io/opentelemetry/exporter/otlp/logs/{OtlpGrpcNettyOkHttpLogRecordExporterTest.java => OtlpGrpcOkHttpLogRecordExporterTest.java} (96%) delete mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/MarshalerProfilesServiceGrpc.java rename exporters/otlp/testing-internal/src/main/resources/META-INF/services/{io.opentelemetry.exporter.internal.compression.CompressorProvider => io.opentelemetry.exporter.compressor.CompressorProvider} (100%) rename exporters/sender/grpc-managed-channel/src/main/resources/META-INF/services/{io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider => io.opentelemetry.exporter.grpc.GrpcSenderProvider} (100%) rename exporters/sender/jdk/src/main/resources/META-INF/services/{io.opentelemetry.exporter.internal.http.HttpSenderProvider => io.opentelemetry.exporter.http.HttpSenderProvider} (100%) rename exporters/sender/okhttp/src/main/resources/META-INF/services/{io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider => io.opentelemetry.exporter.grpc.GrpcSenderProvider} (100%) rename exporters/sender/okhttp/src/main/resources/META-INF/services/{io.opentelemetry.exporter.internal.http.HttpSenderProvider => io.opentelemetry.exporter.http.HttpSenderProvider} (100%) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt index 1eb8f8c1c0b..a026f218651 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt @@ -1,2 +1,120 @@ Comparing source compatibility of opentelemetry-exporter-common-1.56.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.55.0.jar -No changes. \ No newline at end of file ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.exporter.compressor.Compressor (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.io.OutputStream compress(java.io.OutputStream) + +++ NEW EXCEPTION: java.io.IOException + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String getEncoding() ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.exporter.compressor.CompressorProvider (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.exporter.compressor.Compressor getInstance() ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.exporter.grpc.GrpcMessageWriter (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) int contentLength() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void writeMessage(java.io.OutputStream) + +++ NEW EXCEPTION: java.io.IOException ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.exporter.grpc.GrpcResponse (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) byte[] getResponseMessage() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.exporter.grpc.GrpcStatusCode getStatusCode() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String getStatusDescription() + +++ NEW ANNOTATION: javax.annotation.Nullable ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.exporter.grpc.GrpcSender (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void send(io.opentelemetry.exporter.grpc.GrpcMessageWriter, java.util.function.Consumer, java.util.function.Consumer) + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.common.CompletableResultCode shutdown() ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.exporter.grpc.GrpcSenderConfig (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.exporter.compressor.Compressor getCompressor() + +++ NEW ANNOTATION: javax.annotation.Nullable + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) long getConnectTimeoutNanos() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.net.URI getEndpoint() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.concurrent.ExecutorService getExecutorService() + +++ NEW ANNOTATION: javax.annotation.Nullable + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String getFullServiceName() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.function.Supplier>> getHeadersSupplier() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String getMethodName() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.common.export.RetryPolicy getRetryPolicy() + +++ NEW ANNOTATION: javax.annotation.Nullable + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) javax.net.ssl.SSLContext getSslContext() + +++ NEW ANNOTATION: javax.annotation.Nullable + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) long getTimeoutNanos() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) javax.net.ssl.X509TrustManager getTrustManager() + +++ NEW ANNOTATION: javax.annotation.Nullable ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.exporter.grpc.GrpcSenderProvider (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.exporter.grpc.GrpcSender createSender(io.opentelemetry.exporter.grpc.GrpcSenderConfig) ++++ NEW ENUM: PUBLIC(+) FINAL(+) io.opentelemetry.exporter.grpc.GrpcStatusCode (compatible) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW INTERFACE: java.lang.constant.Constable + +++ NEW INTERFACE: java.lang.Comparable + +++ NEW INTERFACE: java.io.Serializable + +++ NEW SUPERCLASS: java.lang.Enum + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.exporter.grpc.GrpcStatusCode RESOURCE_EXHAUSTED + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.exporter.grpc.GrpcStatusCode ALREADY_EXISTS + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.exporter.grpc.GrpcStatusCode UNIMPLEMENTED + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.exporter.grpc.GrpcStatusCode FAILED_PRECONDITION + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.exporter.grpc.GrpcStatusCode NOT_FOUND + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.exporter.grpc.GrpcStatusCode DEADLINE_EXCEEDED + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.exporter.grpc.GrpcStatusCode OUT_OF_RANGE + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.exporter.grpc.GrpcStatusCode UNAUTHENTICATED + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.exporter.grpc.GrpcStatusCode CANCELLED + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.exporter.grpc.GrpcStatusCode DATA_LOSS + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.exporter.grpc.GrpcStatusCode INTERNAL + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.exporter.grpc.GrpcStatusCode UNAVAILABLE + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.exporter.grpc.GrpcStatusCode UNKNOWN + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.exporter.grpc.GrpcStatusCode ABORTED + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.exporter.grpc.GrpcStatusCode OK + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.exporter.grpc.GrpcStatusCode INVALID_ARGUMENT + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.exporter.grpc.GrpcStatusCode PERMISSION_DENIED + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.exporter.grpc.GrpcStatusCode fromValue(int) + +++ NEW METHOD: PUBLIC(+) int getValue() + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.exporter.grpc.GrpcStatusCode valueOf(java.lang.String) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.exporter.grpc.GrpcStatusCode[] values() ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.exporter.http.HttpRequestBodyWriter (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) int contentLength() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void writeRequestBody(java.io.OutputStream) + +++ NEW EXCEPTION: java.io.IOException ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.exporter.http.HttpResponse (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) byte[] getResponseBody() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) int getStatusCode() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String getStatusMessage() ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.exporter.http.HttpSender (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void send(io.opentelemetry.exporter.http.HttpRequestBodyWriter, java.util.function.Consumer, java.util.function.Consumer) + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.common.CompletableResultCode shutdown() ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.exporter.http.HttpSenderConfig (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.exporter.compressor.Compressor getCompressor() + +++ NEW ANNOTATION: javax.annotation.Nullable + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) long getConnectTimeoutNanos() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String getContentType() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.net.URI getEndpoint() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.concurrent.ExecutorService getExecutorService() + +++ NEW ANNOTATION: javax.annotation.Nullable + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.function.Supplier>> getHeadersSupplier() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.common.export.ProxyOptions getProxyOptions() + +++ NEW ANNOTATION: javax.annotation.Nullable + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.common.export.RetryPolicy getRetryPolicy() + +++ NEW ANNOTATION: javax.annotation.Nullable + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) javax.net.ssl.SSLContext getSslContext() + +++ NEW ANNOTATION: javax.annotation.Nullable + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) long getTimeoutNanos() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) javax.net.ssl.X509TrustManager getTrustManager() + +++ NEW ANNOTATION: javax.annotation.Nullable ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.exporter.http.HttpSenderProvider (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.exporter.http.HttpSender createSender(io.opentelemetry.exporter.http.HttpSenderConfig) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/Compressor.java b/exporters/common/src/main/java/io/opentelemetry/exporter/compressor/Compressor.java similarity index 82% rename from exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/Compressor.java rename to exporters/common/src/main/java/io/opentelemetry/exporter/compressor/Compressor.java index 71894cc9d4a..297efb61375 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/Compressor.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/compressor/Compressor.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.exporter.internal.compression; +package io.opentelemetry.exporter.compressor; import java.io.IOException; import java.io.OutputStream; @@ -13,8 +13,7 @@ * An abstraction for compressing messages. Implementation MUST be thread safe as the same instance * is expected to be used many times and concurrently. Instances are usually singletons. * - *

This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. + * @see CompressorProvider */ @ThreadSafe public interface Compressor { diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/compressor/CompressorProvider.java b/exporters/common/src/main/java/io/opentelemetry/exporter/compressor/CompressorProvider.java new file mode 100644 index 00000000000..443b0fd4f18 --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/compressor/CompressorProvider.java @@ -0,0 +1,13 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.compressor; + +/** A service provider interface (SPI) for providing {@link Compressor}s. */ +public interface CompressorProvider { + + /** Return the {@link Compressor}. */ + Compressor getInstance(); +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcMessageWriter.java b/exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcMessageWriter.java new file mode 100644 index 00000000000..c79a8f25df4 --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcMessageWriter.java @@ -0,0 +1,19 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.grpc; + +import java.io.IOException; +import java.io.OutputStream; + +/** Writes gRPC messages to an {@link OutputStream}. */ +public interface GrpcMessageWriter { + + /** Write the gRPC message bytes to the {@link OutputStream}. */ + void writeMessage(OutputStream output) throws IOException; + + /** Returns the message length in bytes. */ + int contentLength(); +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcResponse.java b/exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcResponse.java new file mode 100644 index 00000000000..ed697d58731 --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcResponse.java @@ -0,0 +1,30 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.grpc; + +import java.util.function.Consumer; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; + +/** + * A gRPC response. + * + * @see GrpcSender#send(GrpcMessageWriter, Consumer, Consumer) + */ +@Immutable +public interface GrpcResponse { + + /** The response gRPC status code. */ + GrpcStatusCode getStatusCode(); + + /** A string description of the status. */ + @Nullable + String getStatusDescription(); + + /** The gRPC response message bytes. */ + @SuppressWarnings("mutable") + byte[] getResponseMessage(); +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcSender.java b/exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcSender.java new file mode 100644 index 00000000000..51509e6dbb6 --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcSender.java @@ -0,0 +1,40 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.grpc; + +import io.opentelemetry.sdk.common.CompletableResultCode; +import java.util.function.Consumer; + +/** + * An abstraction for executing gRPC calls, allowing for implementations backed by different client + * libraries. + * + *

While this interface is public, implementing a custom sender is generally not recommended. The + * {@code opentelemetry-java} project provides built-in implementations that cover virtually all + * cases. + * + * @see GrpcSenderProvider + */ +public interface GrpcSender { + + /** + * Execute a gRPC unary call, including any retry attempts. {@code onResponse} is called with the + * gRPC response, either a success response or an error response after retries. {@code onError} is + * called when the call could not be executed due to cancellation, connectivity problems, or + * timeout. + * + * @param messageWriter the message writer + * @param onResponse the callback to invoke with the gRPC response + * @param onError the callback to invoke when the gRPC call could not be executed + */ + void send( + GrpcMessageWriter messageWriter, + Consumer onResponse, + Consumer onError); + + /** Shutdown the sender. */ + CompletableResultCode shutdown(); +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcSenderConfig.java b/exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcSenderConfig.java new file mode 100644 index 00000000000..d6c5218eef8 --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcSenderConfig.java @@ -0,0 +1,93 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.grpc; + +import io.opentelemetry.exporter.compressor.Compressor; +import io.opentelemetry.sdk.common.export.RetryPolicy; +import java.io.OutputStream; +import java.net.URI; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.function.Consumer; +import java.util.function.Supplier; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; +import javax.net.ssl.SSLContext; +import javax.net.ssl.X509TrustManager; + +/** + * Configuration for {@link GrpcSender} implementations, provided via {@link + * GrpcSenderProvider#createSender(GrpcSenderConfig)}. + */ +@Immutable +public interface GrpcSenderConfig { + + /** + * The gRPC endpoint to send to, including scheme. Omits path, which must be constructed from + * {@link #getFullServiceName()} and {@link #getMethodName()}. + */ + URI getEndpoint(); + + /** + * The fully qualified gRPC service name, e.g. {@code + * opentelemetry.proto.collector.trace.v1.TraceService}. + */ + String getFullServiceName(); + + /** The gRPC method name, e.g. {@code Export}. */ + String getMethodName(); + + /** + * The compressor, or {@code null} if no compression is used. If present, {@link + * Compressor#compress(OutputStream)} must be applied to {@link + * GrpcMessageWriter#writeMessage(OutputStream)} when {@link GrpcSender#send(GrpcMessageWriter, + * Consumer, Consumer)} is called and {@link Compressor#getEncoding()} must be set as the {@code + * grpc-encoding}. + */ + @Nullable + Compressor getCompressor(); + + /** + * The max time in nanoseconds allowed to send a request, including resolving DNS, connecting, + * writing the request, reading the response, and any retries via {@link #getRetryPolicy()}. + */ + long getTimeoutNanos(); + + /** The max time in nanoseconds allowed to connect to a target host. */ + long getConnectTimeoutNanos(); + + /** + * Additional headers that must be appended to every request. The resulting {@link Supplier} must + * be invoked for each request. + */ + Supplier>> getHeadersSupplier(); + + /** The retry policy, or {@code null} if retry is disabled. */ + @Nullable + RetryPolicy getRetryPolicy(); + + /** + * The SSL context to use, or {@code null} if the system default is used. If non-null, {@link + * #getTrustManager()} will also be non-null. + */ + @Nullable + SSLContext getSslContext(); + + /** + * The trust manager to use, or {@code null} if the system default is used. If non-null, {@link + * #getSslContext()} will also be non-null. + */ + @Nullable + X509TrustManager getTrustManager(); + + /** + * The executor service used to execute any asynchronous processing, or {@code null} if the sender + * default executor service should be used. + */ + @Nullable + ExecutorService getExecutorService(); +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderProvider.java b/exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcSenderProvider.java similarity index 50% rename from exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderProvider.java rename to exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcSenderProvider.java index 5b2883cf066..697f78773d7 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderProvider.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcSenderProvider.java @@ -3,19 +3,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.exporter.internal.grpc; - -import io.opentelemetry.exporter.internal.marshal.Marshaler; +package io.opentelemetry.exporter.grpc; /** * A service provider interface (SPI) for providing {@link GrpcSender}s backed by different client * libraries. - * - *

This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. */ public interface GrpcSenderProvider { /** Returns a {@link GrpcSender} configured with the provided config. */ - GrpcSender createSender(GrpcSenderConfig grpcSenderConfig); + GrpcSender createSender(GrpcSenderConfig grpcSenderConfig); } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcStatusCode.java b/exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcStatusCode.java new file mode 100644 index 00000000000..ea300396de0 --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/grpc/GrpcStatusCode.java @@ -0,0 +1,53 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.grpc; + +/** + * gRPC status codes. See official grpc.io + * docs for usage. + */ +public enum GrpcStatusCode { + OK(0), + CANCELLED(1), + UNKNOWN(2), + INVALID_ARGUMENT(3), + DEADLINE_EXCEEDED(4), + NOT_FOUND(5), + ALREADY_EXISTS(6), + PERMISSION_DENIED(7), + RESOURCE_EXHAUSTED(8), + FAILED_PRECONDITION(9), + ABORTED(10), + OUT_OF_RANGE(11), + UNIMPLEMENTED(12), + INTERNAL(13), + UNAVAILABLE(14), + DATA_LOSS(15), + UNAUTHENTICATED(16); + + private final int value; + + GrpcStatusCode(int value) { + this.value = value; + } + + /** Returns the integer representation of the status code. */ + public int getValue() { + return value; + } + + /** + * Returns the {@link GrpcStatusCode} corresponding to the integer {@code value}, or {@link + * GrpcStatusCode#UNKNOWN} if the {@code value} is not recognized. + */ + public static GrpcStatusCode fromValue(int value) { + GrpcStatusCode[] values = GrpcStatusCode.values(); + if (value >= 0 && value < values.length) { + return values[value]; + } + return UNKNOWN; + } +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/http/HttpRequestBodyWriter.java b/exporters/common/src/main/java/io/opentelemetry/exporter/http/HttpRequestBodyWriter.java new file mode 100644 index 00000000000..d03df541637 --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/http/HttpRequestBodyWriter.java @@ -0,0 +1,19 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.http; + +import java.io.IOException; +import java.io.OutputStream; + +/** Writes HTTP request bodies to an {@link OutputStream}. */ +public interface HttpRequestBodyWriter { + + /** Write the gRPC message bytes to the {@link OutputStream}. */ + void writeRequestBody(OutputStream output) throws IOException; + + /** Return the request body length in bytes. */ + int contentLength(); +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/http/HttpResponse.java b/exporters/common/src/main/java/io/opentelemetry/exporter/http/HttpResponse.java new file mode 100644 index 00000000000..f6fa351c5ed --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/http/HttpResponse.java @@ -0,0 +1,27 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.http; + +import java.util.function.Consumer; +import javax.annotation.concurrent.Immutable; + +/** + * A HTTP response. + * + * @see HttpSender#send(HttpRequestBodyWriter, Consumer, Consumer) + */ +@Immutable +public interface HttpResponse { + + /** The HTTP status code. */ + int getStatusCode(); + + /** The HTTP status message. */ + String getStatusMessage(); + + /** The HTTP response body bytes. */ + byte[] getResponseBody(); +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/http/HttpSender.java b/exporters/common/src/main/java/io/opentelemetry/exporter/http/HttpSender.java new file mode 100644 index 00000000000..50406e30161 --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/http/HttpSender.java @@ -0,0 +1,40 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.http; + +import io.opentelemetry.sdk.common.CompletableResultCode; +import java.util.function.Consumer; + +/** + * An abstraction for executing HTTP requests, allowing for implementations backed by different + * client libraries. + * + *

While this interface is public, implementing a custom sender is generally not recommended. The + * {@code opentelemetry-java} project provides built-in implementations that cover virtually all + * cases. + * + * @see io.opentelemetry.exporter.http.HttpSenderProvider + */ +public interface HttpSender { + + /** + * Send an HTTP request, including any retry attempts. {@code onResponse} is called with the HTTP + * response, either a success response or an error response after retries. {@code onError} is + * called when the request could not be executed due to cancellation, connectivity problems, or + * timeout. + * + * @param requestBodyWriter the request body writer + * @param onResponse the callback to invoke with the HTTP response + * @param onError the callback to invoke when the HTTP request could not be executed + */ + void send( + HttpRequestBodyWriter requestBodyWriter, + Consumer onResponse, + Consumer onError); + + /** Shutdown the sender. */ + CompletableResultCode shutdown(); +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/http/HttpSenderConfig.java b/exporters/common/src/main/java/io/opentelemetry/exporter/http/HttpSenderConfig.java new file mode 100644 index 00000000000..978e3ac24fe --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/http/HttpSenderConfig.java @@ -0,0 +1,89 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.http; + +import io.opentelemetry.exporter.compressor.Compressor; +import io.opentelemetry.sdk.common.export.ProxyOptions; +import io.opentelemetry.sdk.common.export.RetryPolicy; +import java.io.OutputStream; +import java.net.URI; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.function.Consumer; +import java.util.function.Supplier; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; +import javax.net.ssl.SSLContext; +import javax.net.ssl.X509TrustManager; + +/** + * Configuration for {@link HttpSender} implementations, provided via {@link + * HttpSenderProvider#createSender(HttpSenderConfig)}. + */ +@Immutable +public interface HttpSenderConfig { + + /** The fully qualified endpoint to send to, including scheme and path. */ + URI getEndpoint(); + + /** The payload content type to set as the {@code Content-Type} header. */ + String getContentType(); + + /** + * The compressor, or {@code null} if no compression is used. If present, {@link + * Compressor#compress(OutputStream)} must be applied to {@link + * HttpRequestBodyWriter#writeRequestBody(OutputStream)} when {@link + * HttpSender#send(HttpRequestBodyWriter, Consumer, Consumer)} is called and {@link + * Compressor#getEncoding()} must be set as the {@code Content-Encoding} header. + */ + @Nullable + Compressor getCompressor(); + + /** + * The max time in nanoseconds allowed to send a request, including resolving DNS, connecting, + * writing the request, reading the response, and any retries via {@link #getRetryPolicy()}. + */ + long getTimeoutNanos(); + + /** The max time in nanoseconds allowed to connect to a target host. */ + long getConnectTimeoutNanos(); + + /** + * Additional headers that must be appended to every request. The resulting {@link Supplier} must + * be invoked for each request. + */ + Supplier>> getHeadersSupplier(); + + /** The proxy options, or {@code null} if no proxy is used. */ + @Nullable + ProxyOptions getProxyOptions(); + + /** The retry policy, or {@code null} if retry is disabled. */ + @Nullable + RetryPolicy getRetryPolicy(); + + /** + * The SSL context to use, or {@code null} if the system default is used. If non-null, {@link + * #getTrustManager()} will also be non-null. + */ + @Nullable + SSLContext getSslContext(); + + /** + * The trust manager to use, or {@code null} if the system default is used. If non-null, {@link + * #getSslContext()} will also be non-null. + */ + @Nullable + X509TrustManager getTrustManager(); + + /** + * The executor service used to execute any asynchronous processing, or {@code null} if the sender + * default executor service should be used. + */ + @Nullable + ExecutorService getExecutorService(); +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java b/exporters/common/src/main/java/io/opentelemetry/exporter/http/HttpSenderProvider.java similarity index 70% rename from exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java rename to exporters/common/src/main/java/io/opentelemetry/exporter/http/HttpSenderProvider.java index 10563f5a00d..05006e46e84 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/http/HttpSenderProvider.java @@ -3,14 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.exporter.internal.http; +package io.opentelemetry.exporter.http; /** * A service provider interface (SPI) for providing {@link HttpSender}s backed by different HTTP * client libraries. - * - *

This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. */ public interface HttpSenderProvider { diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/FailedExportException.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/FailedExportException.java index 3d229514108..63dfc184345 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/FailedExportException.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/FailedExportException.java @@ -5,8 +5,8 @@ package io.opentelemetry.exporter.internal; -import io.opentelemetry.exporter.internal.grpc.GrpcResponse; -import io.opentelemetry.exporter.internal.http.HttpSender; +import io.opentelemetry.exporter.grpc.GrpcResponse; +import io.opentelemetry.exporter.http.HttpResponse; import javax.annotation.Nullable; /** @@ -24,7 +24,7 @@ private FailedExportException(@Nullable Throwable cause) { } /** Indicates an HTTP export failed after receiving a response from the server. */ - public static HttpExportException httpFailedWithResponse(HttpSender.Response response) { + public static HttpExportException httpFailedWithResponse(HttpResponse response) { return new HttpExportException(response, null); } @@ -56,10 +56,10 @@ public static final class HttpExportException extends FailedExportException { private static final long serialVersionUID = -6787390183017184775L; - @Nullable private final HttpSender.Response response; + @Nullable private final HttpResponse response; @Nullable private final Throwable cause; - private HttpExportException(@Nullable HttpSender.Response response, @Nullable Throwable cause) { + private HttpExportException(@Nullable HttpResponse response, @Nullable Throwable cause) { super(cause); this.response = response; this.cause = cause; @@ -75,7 +75,7 @@ public boolean failedWithResponse() { * export failed exceptionally with no response. */ @Nullable - public HttpSender.Response getResponse() { + public HttpResponse getResponse() { return response; } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/RetryUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/RetryUtil.java index 3e3b66af8ac..015992994c3 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/RetryUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/RetryUtil.java @@ -5,7 +5,7 @@ package io.opentelemetry.exporter.internal; -import io.opentelemetry.exporter.internal.grpc.GrpcExporterUtil; +import io.opentelemetry.exporter.grpc.GrpcStatusCode; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; @@ -24,13 +24,13 @@ public final class RetryUtil { static { Set retryableGrpcStatusCodes = new HashSet<>(); - retryableGrpcStatusCodes.add(GrpcExporterUtil.GRPC_STATUS_CANCELLED); - retryableGrpcStatusCodes.add(GrpcExporterUtil.GRPC_STATUS_DEADLINE_EXCEEDED); - retryableGrpcStatusCodes.add(GrpcExporterUtil.GRPC_STATUS_RESOURCE_EXHAUSTED); - retryableGrpcStatusCodes.add(GrpcExporterUtil.GRPC_STATUS_ABORTED); - retryableGrpcStatusCodes.add(GrpcExporterUtil.GRPC_STATUS_OUT_OF_RANGE); - retryableGrpcStatusCodes.add(GrpcExporterUtil.GRPC_STATUS_UNAVAILABLE); - retryableGrpcStatusCodes.add(GrpcExporterUtil.GRPC_STATUS_DATA_LOSS); + retryableGrpcStatusCodes.add(GrpcStatusCode.CANCELLED.getValue()); + retryableGrpcStatusCodes.add(GrpcStatusCode.DEADLINE_EXCEEDED.getValue()); + retryableGrpcStatusCodes.add(GrpcStatusCode.RESOURCE_EXHAUSTED.getValue()); + retryableGrpcStatusCodes.add(GrpcStatusCode.ABORTED.getValue()); + retryableGrpcStatusCodes.add(GrpcStatusCode.OUT_OF_RANGE.getValue()); + retryableGrpcStatusCodes.add(GrpcStatusCode.UNAVAILABLE.getValue()); + retryableGrpcStatusCodes.add(GrpcStatusCode.DATA_LOSS.getValue()); RETRYABLE_GRPC_STATUS_CODES = Collections.unmodifiableSet( retryableGrpcStatusCodes.stream().map(Object::toString).collect(Collectors.toSet())); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorProvider.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorProvider.java deleted file mode 100644 index 6b4518f1ea0..00000000000 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorProvider.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.internal.compression; - -/** - * A service provider interface (SPI) for providing {@link Compressor}s. - * - *

This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. - */ -public interface CompressorProvider { - - /** Return the {@link Compressor}. */ - Compressor getInstance(); -} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorUtil.java index 92b7d2d9c60..01f1c5a33ee 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorUtil.java @@ -9,6 +9,8 @@ import static java.util.stream.Collectors.joining; import io.opentelemetry.common.ComponentLoader; +import io.opentelemetry.exporter.compressor.Compressor; +import io.opentelemetry.exporter.compressor.CompressorProvider; import java.util.HashMap; import java.util.Map; import java.util.Set; diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/GzipCompressor.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/GzipCompressor.java index 7395fdb41b1..7fdd6a7f63b 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/GzipCompressor.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/GzipCompressor.java @@ -5,6 +5,7 @@ package io.opentelemetry.exporter.internal.compression; +import io.opentelemetry.exporter.compressor.Compressor; import java.io.IOException; import java.io.OutputStream; import java.util.zip.GZIPOutputStream; diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/ExtendedGrpcSenderConfig.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/ExtendedGrpcSenderConfig.java new file mode 100644 index 00000000000..a08c0f9ffe6 --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/ExtendedGrpcSenderConfig.java @@ -0,0 +1,21 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.grpc; + +import io.opentelemetry.exporter.grpc.GrpcSenderConfig; +import javax.annotation.Nullable; + +/** + * Extended {@link GrpcSenderConfig} with internal / experimental APIs. + * + *

This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public interface ExtendedGrpcSenderConfig extends GrpcSenderConfig { + + @Nullable + Object getMangedChannel(); +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporter.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporter.java index 3c8de2f541c..acd752ebf32 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporter.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporter.java @@ -5,10 +5,10 @@ package io.opentelemetry.exporter.internal.grpc; -import static io.opentelemetry.exporter.internal.grpc.GrpcExporterUtil.GRPC_STATUS_UNAVAILABLE; -import static io.opentelemetry.exporter.internal.grpc.GrpcExporterUtil.GRPC_STATUS_UNIMPLEMENTED; - import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.exporter.grpc.GrpcResponse; +import io.opentelemetry.exporter.grpc.GrpcSender; +import io.opentelemetry.exporter.grpc.GrpcStatusCode; import io.opentelemetry.exporter.internal.FailedExportException; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.internal.metrics.ExporterInstrumentation; @@ -16,6 +16,7 @@ import io.opentelemetry.sdk.common.InternalTelemetryVersion; import io.opentelemetry.sdk.internal.StandardComponentId; import io.opentelemetry.sdk.internal.ThrottlingLogger; +import java.net.URI; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; import java.util.logging.Level; @@ -28,7 +29,7 @@ * at any time. */ @SuppressWarnings("checkstyle:JavadocMethod") -public final class GrpcExporter { +public final class GrpcExporter { private static final Logger internalLogger = Logger.getLogger(GrpcExporter.class.getName()); @@ -39,15 +40,15 @@ public final class GrpcExporter { private final AtomicBoolean isShutdown = new AtomicBoolean(); private final String type; - private final GrpcSender grpcSender; + private final GrpcSender grpcSender; private final ExporterInstrumentation exporterMetrics; public GrpcExporter( - GrpcSender grpcSender, + GrpcSender grpcSender, InternalTelemetryVersion internalTelemetryVersion, StandardComponentId componentId, Supplier meterProviderSupplier, - String endpoint) { + URI endpoint) { this.type = componentId.getStandardType().signal().logFriendlyName(); this.grpcSender = grpcSender; this.exporterMetrics = @@ -55,7 +56,7 @@ public GrpcExporter( internalTelemetryVersion, meterProviderSupplier, componentId, endpoint); } - public CompletableResultCode export(T exportRequest, int numItems) { + public CompletableResultCode export(Marshaler exportRequest, int numItems) { if (isShutdown.get()) { return CompletableResultCode.ofFailure(); } @@ -66,7 +67,7 @@ public CompletableResultCode export(T exportRequest, int numItems) { CompletableResultCode result = new CompletableResultCode(); grpcSender.send( - exportRequest, + exportRequest.toGrpcRequestBodyWriter(), grpcResponse -> onResponse(result, metricRecording, grpcResponse), throwable -> onError(result, metricRecording, throwable)); @@ -77,25 +78,25 @@ private void onResponse( CompletableResultCode result, ExporterInstrumentation.Recording metricRecording, GrpcResponse grpcResponse) { - int statusCode = grpcResponse.grpcStatusValue(); + GrpcStatusCode statusCode = grpcResponse.getStatusCode(); - metricRecording.setGrpcStatusCode(statusCode); + metricRecording.setGrpcStatusCode(statusCode.getValue()); - if (statusCode == 0) { + if (statusCode == GrpcStatusCode.OK) { metricRecording.finishSuccessful(); result.succeed(); return; } - metricRecording.finishFailed(String.valueOf(statusCode)); + metricRecording.finishFailed(String.valueOf(statusCode.getValue())); switch (statusCode) { - case GRPC_STATUS_UNIMPLEMENTED: + case UNIMPLEMENTED: if (loggedUnimplemented.compareAndSet(false, true)) { GrpcExporterUtil.logUnimplemented( - internalLogger, type, grpcResponse.grpcStatusDescription()); + internalLogger, type, grpcResponse.getStatusDescription()); } break; - case GRPC_STATUS_UNAVAILABLE: + case UNAVAILABLE: logger.log( Level.SEVERE, "Failed to export " @@ -103,7 +104,7 @@ private void onResponse( + "s. Server is UNAVAILABLE. " + "Make sure your collector is running and reachable from this network. " + "Full error message:" - + grpcResponse.grpcStatusDescription()); + + grpcResponse.getStatusDescription()); break; default: logger.log( @@ -111,9 +112,9 @@ private void onResponse( "Failed to export " + type + "s. Server responded with gRPC status code " - + statusCode + + statusCode.getValue() + ". Error message: " - + grpcResponse.grpcStatusDescription()); + + grpcResponse.getStatusDescription()); break; } result.failExceptionally(FailedExportException.grpcFailedWithResponse(grpcResponse)); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java index 499839d7a0b..1b10b47525e 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java @@ -5,18 +5,18 @@ package io.opentelemetry.exporter.internal.grpc; -import io.grpc.Channel; import io.grpc.ManagedChannel; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.internal.ConfigUtil; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.common.ComponentLoader; +import io.opentelemetry.exporter.compressor.Compressor; +import io.opentelemetry.exporter.compressor.CompressorProvider; +import io.opentelemetry.exporter.grpc.GrpcSender; +import io.opentelemetry.exporter.grpc.GrpcSenderProvider; import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.exporter.internal.TlsConfigHelper; -import io.opentelemetry.exporter.internal.compression.Compressor; -import io.opentelemetry.exporter.internal.compression.CompressorProvider; import io.opentelemetry.exporter.internal.compression.CompressorUtil; -import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.InternalTelemetryVersion; import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.internal.ComponentId; @@ -32,7 +32,6 @@ import java.util.StringJoiner; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; -import java.util.function.BiFunction; import java.util.function.Supplier; import java.util.logging.Level; import java.util.logging.Logger; @@ -47,16 +46,15 @@ * at any time. */ @SuppressWarnings("JavadocMethod") -public class GrpcExporterBuilder { +public class GrpcExporterBuilder { public static final long DEFAULT_CONNECT_TIMEOUT_SECS = 10; private static final Logger LOGGER = Logger.getLogger(GrpcExporterBuilder.class.getName()); private final StandardComponentId.ExporterType exporterType; - private final String grpcEndpointPath; - private final Supplier>> - grpcStubFactory; + private final String fullServiceName; + private final String methodName; private long timeoutNanos; private long connectTimeoutNanos = TimeUnit.SECONDS.toNanos(DEFAULT_CONNECT_TIMEOUT_SECS); @@ -80,40 +78,40 @@ public GrpcExporterBuilder( StandardComponentId.ExporterType exporterType, long defaultTimeoutSecs, URI defaultEndpoint, - Supplier>> grpcStubFactory, - String grpcEndpointPath) { + String fullServiceName, + String methodName) { this.exporterType = exporterType; - this.grpcEndpointPath = grpcEndpointPath; + this.fullServiceName = fullServiceName; + this.methodName = methodName; timeoutNanos = TimeUnit.SECONDS.toNanos(defaultTimeoutSecs); endpoint = defaultEndpoint; - this.grpcStubFactory = grpcStubFactory; } - public GrpcExporterBuilder setChannel(ManagedChannel channel) { + public GrpcExporterBuilder setChannel(ManagedChannel channel) { this.grpcChannel = channel; return this; } - public GrpcExporterBuilder setTimeout(long timeout, TimeUnit unit) { + public GrpcExporterBuilder setTimeout(long timeout, TimeUnit unit) { timeoutNanos = timeout == 0 ? Long.MAX_VALUE : unit.toNanos(timeout); return this; } - public GrpcExporterBuilder setTimeout(Duration timeout) { + public GrpcExporterBuilder setTimeout(Duration timeout) { return setTimeout(timeout.toNanos(), TimeUnit.NANOSECONDS); } - public GrpcExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { + public GrpcExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { connectTimeoutNanos = timeout == 0 ? Long.MAX_VALUE : unit.toNanos(timeout); return this; } - public GrpcExporterBuilder setEndpoint(String endpoint) { + public GrpcExporterBuilder setEndpoint(String endpoint) { this.endpoint = ExporterBuilderUtil.validateEndpoint(endpoint); return this; } - public GrpcExporterBuilder setCompression(@Nullable Compressor compressor) { + public GrpcExporterBuilder setCompression(@Nullable Compressor compressor) { this.compressor = compressor; return this; } @@ -123,74 +121,72 @@ public GrpcExporterBuilder setCompression(@Nullable Compressor compressor) { * method "gzip" and "none" are supported out of the box. Support for additional compression * methods is available by implementing {@link Compressor} and {@link CompressorProvider}. */ - public GrpcExporterBuilder setCompression(String compressionMethod) { + public GrpcExporterBuilder setCompression(String compressionMethod) { Compressor compressor = CompressorUtil.validateAndResolveCompressor(compressionMethod, componentLoader); return setCompression(compressor); } - public GrpcExporterBuilder setTrustManagerFromCerts(byte[] trustedCertificatesPem) { + public GrpcExporterBuilder setTrustManagerFromCerts(byte[] trustedCertificatesPem) { tlsConfigHelper.setTrustManagerFromCerts(trustedCertificatesPem); return this; } - public GrpcExporterBuilder setKeyManagerFromCerts( - byte[] privateKeyPem, byte[] certificatePem) { + public GrpcExporterBuilder setKeyManagerFromCerts(byte[] privateKeyPem, byte[] certificatePem) { tlsConfigHelper.setKeyManagerFromCerts(privateKeyPem, certificatePem); return this; } - public GrpcExporterBuilder setSslContext( - SSLContext sslContext, X509TrustManager trustManager) { + public GrpcExporterBuilder setSslContext(SSLContext sslContext, X509TrustManager trustManager) { tlsConfigHelper.setSslContext(sslContext, trustManager); return this; } - public GrpcExporterBuilder addConstantHeader(String key, String value) { + public GrpcExporterBuilder addConstantHeader(String key, String value) { constantHeaders.put(key, value); return this; } - public GrpcExporterBuilder setHeadersSupplier(Supplier> headerSupplier) { + public GrpcExporterBuilder setHeadersSupplier(Supplier> headerSupplier) { this.headerSupplier = headerSupplier; return this; } - public GrpcExporterBuilder setRetryPolicy(@Nullable RetryPolicy retryPolicy) { + public GrpcExporterBuilder setRetryPolicy(@Nullable RetryPolicy retryPolicy) { this.retryPolicy = retryPolicy; return this; } - public GrpcExporterBuilder setMeterProvider(Supplier meterProviderSupplier) { + public GrpcExporterBuilder setMeterProvider(Supplier meterProviderSupplier) { this.meterProviderSupplier = meterProviderSupplier; return this; } - public GrpcExporterBuilder setInternalTelemetryVersion( + public GrpcExporterBuilder setInternalTelemetryVersion( InternalTelemetryVersion internalTelemetryVersion) { this.internalTelemetryVersion = internalTelemetryVersion; return this; } - public GrpcExporterBuilder setComponentLoader(ComponentLoader componentLoader) { + public GrpcExporterBuilder setComponentLoader(ComponentLoader componentLoader) { this.componentLoader = componentLoader; return this; } - public GrpcExporterBuilder setExecutorService(ExecutorService executorService) { + public GrpcExporterBuilder setExecutorService(ExecutorService executorService) { this.executorService = executorService; return this; } @SuppressWarnings("BuilderReturnThis") - public GrpcExporterBuilder copy() { - GrpcExporterBuilder copy = - new GrpcExporterBuilder<>( + public GrpcExporterBuilder copy() { + GrpcExporterBuilder copy = + new GrpcExporterBuilder( exporterType, TimeUnit.NANOSECONDS.toSeconds(timeoutNanos), endpoint, - grpcStubFactory, - grpcEndpointPath); + fullServiceName, + methodName); copy.timeoutNanos = timeoutNanos; copy.connectTimeoutNanos = connectTimeoutNanos; @@ -209,7 +205,7 @@ public GrpcExporterBuilder copy() { return copy; } - public GrpcExporter build() { + public GrpcExporter build() { Supplier>> headerSupplier = () -> { Map> result = new HashMap<>(); @@ -233,29 +229,29 @@ public GrpcExporter build() { boolean isPlainHttp = "http".equals(endpoint.getScheme()); GrpcSenderProvider grpcSenderProvider = resolveGrpcSenderProvider(); - GrpcSender grpcSender = + GrpcSender grpcSender = grpcSenderProvider.createSender( - GrpcSenderConfig.create( + ImmutableGrpcSenderConfig.create( endpoint, - grpcEndpointPath, + fullServiceName, + methodName, compressor, timeoutNanos, connectTimeoutNanos, headerSupplier, - grpcChannel, - grpcStubFactory, retryPolicy, isPlainHttp ? null : tlsConfigHelper.getSslContext(), isPlainHttp ? null : tlsConfigHelper.getTrustManager(), - executorService)); + executorService, + grpcChannel)); LOGGER.log(Level.FINE, "Using GrpcSender: " + grpcSender.getClass().getName()); - return new GrpcExporter<>( + return new GrpcExporter( grpcSender, internalTelemetryVersion, ComponentId.generateLazy(exporterType), meterProviderSupplier, - endpoint.toString()); + endpoint); } public String toString(boolean includePrefixAndSuffix) { @@ -264,7 +260,8 @@ public String toString(boolean includePrefixAndSuffix) { ? new StringJoiner(", ", "GrpcExporterBuilder{", "}") : new StringJoiner(", "); joiner.add("endpoint=" + endpoint.toString()); - joiner.add("endpointPath=" + grpcEndpointPath); + joiner.add("fullServiceName=" + fullServiceName); + joiner.add("methodName=" + methodName); joiner.add("timeoutNanos=" + timeoutNanos); joiner.add("connectTimeoutNanos=" + connectTimeoutNanos); joiner.add( @@ -309,10 +306,9 @@ public String toString() { *

If multiple are available and.. * *

    - *
  • {@code io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider} is empty, use the - * first found. - *
  • {@code io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider} is set, use the - * matching provider. If none match, throw {@link IllegalStateException}. + *
  • {@code io.opentelemetry.exporter.grpc.GrpcSenderProvider} is empty, use the first found. + *
  • {@code io.opentelemetry.exporter.grpc.GrpcSenderProvider} is set, use the matching + * provider. If none match, throw {@link IllegalStateException}. *
*/ private GrpcSenderProvider resolveGrpcSenderProvider() { @@ -335,14 +331,14 @@ private GrpcSenderProvider resolveGrpcSenderProvider() { // If we've reached here, there are multiple GrpcSenderProviders String configuredSender = - ConfigUtil.getString("io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider", ""); + ConfigUtil.getString("io.opentelemetry.exporter.grpc.GrpcSenderProvider", ""); // Multiple providers but none configured, use first we find and log a warning if (configuredSender.isEmpty()) { LOGGER.log( Level.WARNING, "Multiple GrpcSenderProvider found. Please include only one, " - + "or specify preference setting io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider " + + "or specify preference setting io.opentelemetry.exporter.grpc.GrpcSenderProvider " + "to the FQCN of the preferred provider."); return grpcSenderProviders.values().stream().findFirst().get(); } @@ -354,7 +350,7 @@ private GrpcSenderProvider resolveGrpcSenderProvider() { // Multiple providers, configured does not match, throw throw new IllegalStateException( - "No GrpcSenderProvider matched configured io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider: " + "No GrpcSenderProvider matched configured io.opentelemetry.exporter.grpc.GrpcSenderProvider: " + configuredSender); } } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterUtil.java index 65eb34801fe..46c79fbbf94 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterUtil.java @@ -17,16 +17,6 @@ */ public final class GrpcExporterUtil { - public static final int GRPC_STATUS_CANCELLED = 1; - public static final int GRPC_STATUS_UNKNOWN = 2; - public static final int GRPC_STATUS_DEADLINE_EXCEEDED = 4; - public static final int GRPC_STATUS_RESOURCE_EXHAUSTED = 8; - public static final int GRPC_STATUS_ABORTED = 10; - public static final int GRPC_STATUS_OUT_OF_RANGE = 11; - public static final int GRPC_STATUS_UNIMPLEMENTED = 12; - public static final int GRPC_STATUS_UNAVAILABLE = 14; - public static final int GRPC_STATUS_DATA_LOSS = 15; - static void logUnimplemented(Logger logger, String type, @Nullable String fullErrorMessage) { // hopefully temporary special handling for profile signal as it evolves towards stability. diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcResponse.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcResponse.java deleted file mode 100644 index 4602cbc0ba7..00000000000 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcResponse.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.internal.grpc; - -import com.google.auto.value.AutoValue; -import javax.annotation.Nullable; - -/** - * This class is internal and is hence not for public use. Its APIs are unstable and can change at - * any time. - */ -@AutoValue -public abstract class GrpcResponse { - - GrpcResponse() {} - - public static GrpcResponse create(int grpcStatusValue, @Nullable String grpcStatusDescription) { - return new AutoValue_GrpcResponse(grpcStatusValue, grpcStatusDescription); - } - - public abstract int grpcStatusValue(); - - @Nullable - public abstract String grpcStatusDescription(); - - // TODO(jack-berg): add byte[] responseBody() throws IOException; -} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSender.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSender.java deleted file mode 100644 index ed85d630e42..00000000000 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSender.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.internal.grpc; - -import io.opentelemetry.exporter.internal.marshal.Marshaler; -import io.opentelemetry.sdk.common.CompletableResultCode; -import java.util.function.Consumer; - -/** - * An exporter of a messages encoded by {@link Marshaler} using the gRPC wire format. - * - *

This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. - */ -public interface GrpcSender { - - void send(T request, Consumer onResponse, Consumer onError); - - /** Shutdown the sender. */ - CompletableResultCode shutdown(); -} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderConfig.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderConfig.java deleted file mode 100644 index 8f4f546d6c4..00000000000 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderConfig.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.internal.grpc; - -import com.google.auto.value.AutoValue; -import io.grpc.Channel; -import io.opentelemetry.exporter.internal.compression.Compressor; -import io.opentelemetry.exporter.internal.marshal.Marshaler; -import io.opentelemetry.sdk.common.export.RetryPolicy; -import java.net.URI; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.function.BiFunction; -import java.util.function.Supplier; -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; -import javax.net.ssl.SSLContext; -import javax.net.ssl.X509TrustManager; - -/** - * This class is internal and is hence not for public use. Its APIs are unstable and can change at - * any time. - */ -@AutoValue -@Immutable -public abstract class GrpcSenderConfig { - - @SuppressWarnings("TooManyParameters") - public static GrpcSenderConfig create( - URI endpoint, - String endpointPath, - @Nullable Compressor compressor, - long timeoutNanos, - long connectTimeoutNanos, - Supplier>> headersSupplier, - @Nullable Object managedChannel, - Supplier>> stubFactory, - @Nullable RetryPolicy retryPolicy, - @Nullable SSLContext sslContext, - @Nullable X509TrustManager trustManager, - @Nullable ExecutorService executorService) { - return new AutoValue_GrpcSenderConfig<>( - endpoint, - endpointPath, - compressor, - timeoutNanos, - connectTimeoutNanos, - headersSupplier, - managedChannel, - stubFactory, - retryPolicy, - sslContext, - trustManager, - executorService); - } - - public abstract URI getEndpoint(); - - public abstract String getEndpointPath(); - - @Nullable - public abstract Compressor getCompressor(); - - public abstract long getTimeoutNanos(); - - public abstract long getConnectTimeoutNanos(); - - public abstract Supplier>> getHeadersSupplier(); - - @Nullable - public abstract Object getManagedChannel(); - - public abstract Supplier>> - getStubFactory(); - - @Nullable - public abstract RetryPolicy getRetryPolicy(); - - @Nullable - public abstract SSLContext getSslContext(); - - @Nullable - public abstract X509TrustManager getTrustManager(); - - @Nullable - public abstract ExecutorService getExecutorService(); -} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/ImmutableGrpcResponse.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/ImmutableGrpcResponse.java new file mode 100644 index 00000000000..b5b8a91cd9a --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/ImmutableGrpcResponse.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.grpc; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.exporter.grpc.GrpcResponse; +import io.opentelemetry.exporter.grpc.GrpcStatusCode; +import javax.annotation.Nullable; + +/** + * Auto value implementation of {@link GrpcResponse}. + * + *

This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +@AutoValue +public abstract class ImmutableGrpcResponse implements GrpcResponse { + + public static ImmutableGrpcResponse create( + GrpcStatusCode grpcStatusCode, @Nullable String grpcStatusDescription, byte[] responseBody) { + return new AutoValue_ImmutableGrpcResponse(grpcStatusCode, grpcStatusDescription, responseBody); + } +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/ImmutableGrpcSenderConfig.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/ImmutableGrpcSenderConfig.java new file mode 100644 index 00000000000..e24716bff39 --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/ImmutableGrpcSenderConfig.java @@ -0,0 +1,51 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.grpc; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.exporter.compressor.Compressor; +import io.opentelemetry.sdk.common.export.RetryPolicy; +import java.net.URI; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.function.Supplier; +import javax.annotation.Nullable; +import javax.net.ssl.SSLContext; +import javax.net.ssl.X509TrustManager; + +@AutoValue +abstract class ImmutableGrpcSenderConfig implements ExtendedGrpcSenderConfig { + + @SuppressWarnings("TooManyParameters") + static ImmutableGrpcSenderConfig create( + URI endpoint, + String fullServiceName, + String methodName, + @Nullable Compressor compressor, + long timeoutNanos, + long connectTimeoutNanos, + Supplier>> headersSupplier, + @Nullable RetryPolicy retryPolicy, + @Nullable SSLContext sslContext, + @Nullable X509TrustManager trustManager, + @Nullable ExecutorService executorService, + @Nullable Object managedChannel) { + return new AutoValue_ImmutableGrpcSenderConfig( + endpoint, + fullServiceName, + methodName, + compressor, + timeoutNanos, + connectTimeoutNanos, + headersSupplier, + retryPolicy, + sslContext, + trustManager, + executorService, + managedChannel); + } +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/MarshalerInputStream.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/MarshalerInputStream.java index 39c49c10245..9b36639798d 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/MarshalerInputStream.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/MarshalerInputStream.java @@ -25,7 +25,7 @@ import com.google.common.io.ByteStreams; import io.grpc.Drainable; import io.grpc.KnownLength; -import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.grpc.GrpcMessageWriter; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -34,7 +34,7 @@ import javax.annotation.Nullable; /** - * Adapter from {@link Marshaler} to gRPC types. + * Adapter from {@link GrpcMessageWriter} to gRPC types. * *

This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. @@ -43,11 +43,11 @@ // https://github.com/grpc/grpc-java/blob/2c2ebaebd5a93acec92fbd2708faac582db99371/protobuf-lite/src/main/java/io/grpc/protobuf/lite/ProtoInputStream.java public final class MarshalerInputStream extends InputStream implements Drainable, KnownLength { - @Nullable private Marshaler message; + @Nullable private GrpcMessageWriter message; @Nullable private ByteArrayInputStream partial; /** Creates a new {@link MarshalerInputStream}. */ - public MarshalerInputStream(Marshaler message) { + public MarshalerInputStream(GrpcMessageWriter message) { this.message = message; } @@ -55,8 +55,8 @@ public MarshalerInputStream(Marshaler message) { public int drainTo(OutputStream target) throws IOException { int written; if (message != null) { - written = message.getBinarySerializedSize(); - message.writeBinaryTo(target); + written = message.contentLength(); + message.writeMessage(target); message = null; } else if (partial != null) { written = (int) ByteStreams.copy(partial, target); @@ -82,7 +82,7 @@ public int read() throws IOException { @Override public int read(byte[] b, int off, int len) throws IOException { if (message != null) { - int size = message.getBinarySerializedSize(); + int size = message.contentLength(); if (size == 0) { message = null; partial = null; @@ -103,16 +103,16 @@ public int read(byte[] b, int off, int len) throws IOException { return -1; } - private static byte[] toByteArray(Marshaler message) throws IOException { - ByteArrayOutputStream bos = new ByteArrayOutputStream(message.getBinarySerializedSize()); - message.writeBinaryTo(bos); + private static byte[] toByteArray(GrpcMessageWriter message) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(message.contentLength()); + message.writeMessage(bos); return bos.toByteArray(); } @Override public int available() { if (message != null) { - return message.getBinarySerializedSize(); + return message.contentLength(); } else if (partial != null) { return partial.available(); } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/MarshalerServiceStub.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/MarshalerServiceStub.java deleted file mode 100644 index 2fe9e1685ad..00000000000 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/MarshalerServiceStub.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.internal.grpc; - -import com.google.common.util.concurrent.ListenableFuture; -import io.grpc.CallOptions; -import io.grpc.Channel; -import io.grpc.stub.AbstractFutureStub; -import io.opentelemetry.exporter.internal.marshal.Marshaler; - -/** - * A gRPC stub that uses a {@link Marshaler}. - * - *

This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. - */ -public abstract class MarshalerServiceStub< - T extends Marshaler, U, S extends MarshalerServiceStub> - extends AbstractFutureStub { - protected MarshalerServiceStub(Channel channel, CallOptions callOptions) { - super(channel, callOptions); - } - - public abstract ListenableFuture export(T request); -} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporter.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporter.java index 07533a95fea..31201fa13d5 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporter.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporter.java @@ -6,6 +6,8 @@ package io.opentelemetry.exporter.internal.http; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.exporter.http.HttpResponse; +import io.opentelemetry.exporter.http.HttpSender; import io.opentelemetry.exporter.internal.FailedExportException; import io.opentelemetry.exporter.internal.grpc.GrpcExporterUtil; import io.opentelemetry.exporter.internal.marshal.Marshaler; @@ -15,6 +17,7 @@ import io.opentelemetry.sdk.internal.StandardComponentId; import io.opentelemetry.sdk.internal.ThrottlingLogger; import java.io.IOException; +import java.net.URI; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; import java.util.logging.Level; @@ -28,7 +31,7 @@ * at any time. */ @SuppressWarnings("checkstyle:JavadocMethod") -public final class HttpExporter { +public final class HttpExporter { private static final Logger internalLogger = Logger.getLogger(HttpExporter.class.getName()); @@ -38,21 +41,24 @@ public final class HttpExporter { private final String type; private final HttpSender httpSender; private final ExporterInstrumentation exporterMetrics; + private final boolean exportAsJson; public HttpExporter( StandardComponentId componentId, HttpSender httpSender, Supplier meterProviderSupplier, InternalTelemetryVersion internalTelemetryVersion, - String endpoint) { + URI endpoint, + boolean exportAsJson) { this.type = componentId.getStandardType().signal().logFriendlyName(); this.httpSender = httpSender; this.exporterMetrics = new ExporterInstrumentation( internalTelemetryVersion, meterProviderSupplier, componentId, endpoint); + this.exportAsJson = exportAsJson; } - public CompletableResultCode export(T exportRequest, int numItems) { + public CompletableResultCode export(Marshaler exportRequest, int numItems) { if (isShutdown.get()) { return CompletableResultCode.ofFailure(); } @@ -63,8 +69,7 @@ public CompletableResultCode export(T exportRequest, int numItems) { CompletableResultCode result = new CompletableResultCode(); httpSender.send( - exportRequest, - exportRequest.getBinarySerializedSize(), + exportRequest.toHttpRequestBodyWriter(exportAsJson), httpResponse -> onResponse(result, metricRecording, httpResponse), throwable -> onError(result, metricRecording, throwable)); @@ -74,8 +79,8 @@ public CompletableResultCode export(T exportRequest, int numItems) { private void onResponse( CompletableResultCode result, ExporterInstrumentation.Recording metricRecording, - HttpSender.Response httpResponse) { - int statusCode = httpResponse.statusCode(); + HttpResponse httpResponse) { + int statusCode = httpResponse.getStatusCode(); metricRecording.setHttpStatusCode(statusCode); @@ -87,14 +92,9 @@ private void onResponse( metricRecording.finishFailed(String.valueOf(statusCode)); - byte[] body = null; - try { - body = httpResponse.responseBody(); - } catch (IOException ex) { - logger.log(Level.FINE, "Unable to obtain response body", ex); - } + byte[] body = httpResponse.getResponseBody(); - String status = extractErrorStatus(httpResponse.statusMessage(), body); + String status = extractErrorStatus(httpResponse.getStatusMessage(), body); logger.log( Level.WARNING, diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java index 3d9a6238e01..6f29bb8ea31 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java @@ -9,12 +9,13 @@ import io.opentelemetry.api.internal.ConfigUtil; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.common.ComponentLoader; +import io.opentelemetry.exporter.compressor.Compressor; +import io.opentelemetry.exporter.compressor.CompressorProvider; +import io.opentelemetry.exporter.http.HttpSender; +import io.opentelemetry.exporter.http.HttpSenderProvider; import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.exporter.internal.TlsConfigHelper; -import io.opentelemetry.exporter.internal.compression.Compressor; -import io.opentelemetry.exporter.internal.compression.CompressorProvider; import io.opentelemetry.exporter.internal.compression.CompressorUtil; -import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.InternalTelemetryVersion; import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; @@ -44,7 +45,7 @@ * at any time. */ @SuppressWarnings("checkstyle:JavadocMethod") -public final class HttpExporterBuilder { +public final class HttpExporterBuilder { public static final long DEFAULT_TIMEOUT_SECS = 10; public static final long DEFAULT_CONNECT_TIMEOUT_SECS = 10; @@ -52,7 +53,7 @@ public final class HttpExporterBuilder { private StandardComponentId.ExporterType exporterType; - private String endpoint; + private URI endpoint; private long timeoutNanos = TimeUnit.SECONDS.toNanos(DEFAULT_TIMEOUT_SECS); @Nullable private Compressor compressor; @@ -74,26 +75,25 @@ public HttpExporterBuilder( StandardComponentId.ExporterType exporterType, String defaultEndpoint) { this.exporterType = exporterType; - endpoint = defaultEndpoint; + endpoint = ExporterBuilderUtil.validateEndpoint(defaultEndpoint); } - public HttpExporterBuilder setTimeout(long timeout, TimeUnit unit) { + public HttpExporterBuilder setTimeout(long timeout, TimeUnit unit) { timeoutNanos = timeout == 0 ? Long.MAX_VALUE : unit.toNanos(timeout); return this; } - public HttpExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { + public HttpExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { connectTimeoutNanos = timeout == 0 ? Long.MAX_VALUE : unit.toNanos(timeout); return this; } - public HttpExporterBuilder setEndpoint(String endpoint) { - URI uri = ExporterBuilderUtil.validateEndpoint(endpoint); - this.endpoint = uri.toString(); + public HttpExporterBuilder setEndpoint(String endpoint) { + this.endpoint = ExporterBuilderUtil.validateEndpoint(endpoint); return this; } - public HttpExporterBuilder setCompression(@Nullable Compressor compressor) { + public HttpExporterBuilder setCompression(@Nullable Compressor compressor) { this.compressor = compressor; return this; } @@ -103,71 +103,69 @@ public HttpExporterBuilder setCompression(@Nullable Compressor compressor) { * method "gzip" and "none" are supported out of the box. Support for additional compression * methods is available by implementing {@link Compressor} and {@link CompressorProvider}. */ - public HttpExporterBuilder setCompression(String compressionMethod) { + public HttpExporterBuilder setCompression(String compressionMethod) { Compressor compressor = CompressorUtil.validateAndResolveCompressor(compressionMethod, componentLoader); return setCompression(compressor); } - public HttpExporterBuilder addConstantHeaders(String key, String value) { + public HttpExporterBuilder addConstantHeaders(String key, String value) { constantHeaders.put(key, value); return this; } - public HttpExporterBuilder setHeadersSupplier(Supplier> headerSupplier) { + public HttpExporterBuilder setHeadersSupplier(Supplier> headerSupplier) { this.headerSupplier = headerSupplier; return this; } - public HttpExporterBuilder setTrustManagerFromCerts(byte[] trustedCertificatesPem) { + public HttpExporterBuilder setTrustManagerFromCerts(byte[] trustedCertificatesPem) { tlsConfigHelper.setTrustManagerFromCerts(trustedCertificatesPem); return this; } - public HttpExporterBuilder setKeyManagerFromCerts( - byte[] privateKeyPem, byte[] certificatePem) { + public HttpExporterBuilder setKeyManagerFromCerts(byte[] privateKeyPem, byte[] certificatePem) { tlsConfigHelper.setKeyManagerFromCerts(privateKeyPem, certificatePem); return this; } - public HttpExporterBuilder setSslContext( - SSLContext sslContext, X509TrustManager trustManager) { + public HttpExporterBuilder setSslContext(SSLContext sslContext, X509TrustManager trustManager) { tlsConfigHelper.setSslContext(sslContext, trustManager); return this; } - public HttpExporterBuilder setMeterProvider(Supplier meterProviderSupplier) { + public HttpExporterBuilder setMeterProvider(Supplier meterProviderSupplier) { this.meterProviderSupplier = meterProviderSupplier; return this; } - public HttpExporterBuilder setInternalTelemetryVersion( + public HttpExporterBuilder setInternalTelemetryVersion( InternalTelemetryVersion internalTelemetryVersion) { this.internalTelemetryVersion = internalTelemetryVersion; return this; } - public HttpExporterBuilder setRetryPolicy(@Nullable RetryPolicy retryPolicy) { + public HttpExporterBuilder setRetryPolicy(@Nullable RetryPolicy retryPolicy) { this.retryPolicy = retryPolicy; return this; } - public HttpExporterBuilder setProxyOptions(ProxyOptions proxyOptions) { + public HttpExporterBuilder setProxyOptions(ProxyOptions proxyOptions) { this.proxyOptions = proxyOptions; return this; } - public HttpExporterBuilder setComponentLoader(ComponentLoader componentLoader) { + public HttpExporterBuilder setComponentLoader(ComponentLoader componentLoader) { this.componentLoader = componentLoader; return this; } - public HttpExporterBuilder setExecutorService(ExecutorService executorService) { + public HttpExporterBuilder setExecutorService(ExecutorService executorService) { this.executorService = executorService; return this; } - public HttpExporterBuilder exportAsJson() { + public HttpExporterBuilder exportAsJson() { this.exportAsJson = true; exporterType = mapToJsonTypeIfPossible(exporterType); return this; @@ -188,8 +186,8 @@ private static StandardComponentId.ExporterType mapToJsonTypeIfPossible( } @SuppressWarnings("BuilderReturnThis") - public HttpExporterBuilder copy() { - HttpExporterBuilder copy = new HttpExporterBuilder<>(exporterType, endpoint); + public HttpExporterBuilder copy() { + HttpExporterBuilder copy = new HttpExporterBuilder(exporterType, endpoint.toString()); copy.endpoint = endpoint; copy.timeoutNanos = timeoutNanos; copy.connectTimeoutNanos = connectTimeoutNanos; @@ -208,7 +206,7 @@ public HttpExporterBuilder copy() { return copy; } - public HttpExporter build() { + public HttpExporter build() { Supplier>> headerSupplier = () -> { Map> result = new HashMap<>(); @@ -230,15 +228,14 @@ public HttpExporter build() { return result; }; - boolean isPlainHttp = endpoint.startsWith("http://"); + boolean isPlainHttp = endpoint.toString().startsWith("http://"); HttpSenderProvider httpSenderProvider = resolveHttpSenderProvider(); HttpSender httpSender = httpSenderProvider.createSender( - HttpSenderConfig.create( + ImmutableHttpSenderConfig.create( endpoint, - compressor, - exportAsJson, exportAsJson ? "application/json" : "application/x-protobuf", + compressor, timeoutNanos, connectTimeoutNanos, headerSupplier, @@ -249,12 +246,13 @@ public HttpExporter build() { executorService)); LOGGER.log(Level.FINE, "Using HttpSender: " + httpSender.getClass().getName()); - return new HttpExporter<>( + return new HttpExporter( ComponentId.generateLazy(exporterType), httpSender, meterProviderSupplier, internalTelemetryVersion, - endpoint); + endpoint, + exportAsJson); } public String toString(boolean includePrefixAndSuffix) { @@ -306,10 +304,9 @@ public String toString() { *

If multiple are available and.. * *

    - *
  • {@code io.opentelemetry.exporter.internal.http.HttpSenderProvider} is empty, use the - * first found. - *
  • {@code io.opentelemetry.exporter.internal.http.HttpSenderProvider} is set, use the - * matching provider. If none match, throw {@link IllegalStateException}. + *
  • {@code io.opentelemetry.exporter.http.HttpSenderProvider} is empty, use the first found. + *
  • {@code io.opentelemetry.exporter.http.HttpSenderProvider} is set, use the matching + * provider. If none match, throw {@link IllegalStateException}. *
*/ private HttpSenderProvider resolveHttpSenderProvider() { @@ -332,14 +329,14 @@ private HttpSenderProvider resolveHttpSenderProvider() { // If we've reached here, there are multiple HttpSenderProviders String configuredSender = - ConfigUtil.getString("io.opentelemetry.exporter.internal.http.HttpSenderProvider", ""); + ConfigUtil.getString("io.opentelemetry.exporter.http.HttpSenderProvider", ""); // Multiple providers but none configured, use first we find and log a warning if (configuredSender.isEmpty()) { LOGGER.log( Level.WARNING, "Multiple HttpSenderProvider found. Please include only one, " - + "or specify preference setting io.opentelemetry.exporter.internal.http.HttpSenderProvider " + + "or specify preference setting io.opentelemetry.exporter.http.HttpSenderProvider " + "to the FQCN of the preferred provider."); return httpSenderProviders.values().stream().findFirst().get(); } @@ -351,7 +348,7 @@ private HttpSenderProvider resolveHttpSenderProvider() { // Multiple providers, configured does not match, throw throw new IllegalStateException( - "No HttpSenderProvider matched configured io.opentelemetry.exporter.internal.http.HttpSenderProvider: " + "No HttpSenderProvider matched configured io.opentelemetry.exporter.http.HttpSenderProvider: " + configuredSender); } } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSender.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSender.java deleted file mode 100644 index aec50288ebd..00000000000 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSender.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.internal.http; - -import io.opentelemetry.exporter.internal.marshal.Marshaler; -import io.opentelemetry.sdk.common.CompletableResultCode; -import java.io.IOException; -import java.util.function.Consumer; - -/** - * An abstraction for sending HTTP requests and handling responses. - * - *

This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. - * - * @see HttpExporter - * @see HttpExporterBuilder - */ -public interface HttpSender { - - /** - * Send an HTTP request, including any retry attempts. {@code onResponse} is called with the HTTP - * response, either a success response or a error response after retries. {@code onError} is - * called when the request could not be executed due to cancellation, connectivity problems, or - * timeout. - * - * @param marshaler the request body marshaler - * @param contentLength the request body content length - * @param onResponse the callback to invoke with the HTTP response - * @param onError the callback to invoke when the HTTP request could not be executed - */ - void send( - Marshaler marshaler, - int contentLength, - Consumer onResponse, - Consumer onError); - - /** Shutdown the sender. */ - CompletableResultCode shutdown(); - - /** - * The HTTP response. - * - *

This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. - */ - interface Response { - - /** The HTTP status code. */ - int statusCode(); - - /** The HTTP status message. */ - String statusMessage(); - - /** The HTTP response body. */ - byte[] responseBody() throws IOException; - } -} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderConfig.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/ImmutableHttpSenderConfig.java similarity index 52% rename from exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderConfig.java rename to exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/ImmutableHttpSenderConfig.java index 78b63afaf1d..ba9358c7d44 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderConfig.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/ImmutableHttpSenderConfig.java @@ -6,32 +6,27 @@ package io.opentelemetry.exporter.internal.http; import com.google.auto.value.AutoValue; -import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.compressor.Compressor; +import io.opentelemetry.exporter.http.HttpSenderConfig; import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; +import java.net.URI; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.function.Supplier; import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; -/** - * This class is internal and is hence not for public use. Its APIs are unstable and can change at - * any time. - */ @AutoValue -@Immutable -public abstract class HttpSenderConfig { +abstract class ImmutableHttpSenderConfig implements HttpSenderConfig { @SuppressWarnings("TooManyParameters") - public static HttpSenderConfig create( - String endpoint, - @Nullable Compressor compressor, - boolean exportAsJson, + static HttpSenderConfig create( + URI endpoint, String contentType, + @Nullable Compressor compressor, long timeoutNanos, long connectTimeoutNanos, Supplier>> headerSupplier, @@ -40,11 +35,10 @@ public static HttpSenderConfig create( @Nullable SSLContext sslContext, @Nullable X509TrustManager trustManager, @Nullable ExecutorService executorService) { - return new AutoValue_HttpSenderConfig( + return new AutoValue_ImmutableHttpSenderConfig( endpoint, - compressor, - exportAsJson, contentType, + compressor, timeoutNanos, connectTimeoutNanos, headerSupplier, @@ -54,34 +48,4 @@ public static HttpSenderConfig create( trustManager, executorService); } - - public abstract String getEndpoint(); - - @Nullable - public abstract Compressor getCompressor(); - - public abstract boolean getExportAsJson(); - - public abstract String getContentType(); - - public abstract long getTimeoutNanos(); - - public abstract long getConnectTimeoutNanos(); - - public abstract Supplier>> getHeadersSupplier(); - - @Nullable - public abstract ProxyOptions getProxyOptions(); - - @Nullable - public abstract RetryPolicy getRetryPolicy(); - - @Nullable - public abstract SSLContext getSslContext(); - - @Nullable - public abstract X509TrustManager getTrustManager(); - - @Nullable - public abstract ExecutorService getExecutorService(); } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Marshaler.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Marshaler.java index e942673da13..fed42069d7f 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Marshaler.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Marshaler.java @@ -6,6 +6,8 @@ package io.opentelemetry.exporter.internal.marshal; import com.fasterxml.jackson.core.JsonGenerator; +import io.opentelemetry.exporter.grpc.GrpcMessageWriter; +import io.opentelemetry.exporter.http.HttpRequestBodyWriter; import java.io.IOException; import java.io.OutputStream; @@ -53,4 +55,36 @@ public final void writeJsonWithNewline(JsonGenerator output) throws IOException public abstract int getBinarySerializedSize(); protected abstract void writeTo(Serializer output) throws IOException; + + public HttpRequestBodyWriter toHttpRequestBodyWriter(boolean exportAsJson) { + return new HttpRequestBodyWriter() { + @Override + public void writeRequestBody(OutputStream output) throws IOException { + if (exportAsJson) { + writeJsonTo(output); + } else { + writeBinaryTo(output); + } + } + + @Override + public int contentLength() { + return exportAsJson ? -1 : getBinarySerializedSize(); + } + }; + } + + public GrpcMessageWriter toGrpcRequestBodyWriter() { + return new GrpcMessageWriter() { + @Override + public void writeMessage(OutputStream output) throws IOException { + writeBinaryTo(output); + } + + @Override + public int contentLength() { + return getBinarySerializedSize(); + } + }; + } } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/metrics/ExporterInstrumentation.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/metrics/ExporterInstrumentation.java index a6ae53481a9..2fcbdaec8da 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/metrics/ExporterInstrumentation.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/metrics/ExporterInstrumentation.java @@ -13,7 +13,6 @@ import io.opentelemetry.sdk.internal.Signal; import io.opentelemetry.sdk.internal.StandardComponentId; import java.net.URI; -import java.net.URISyntaxException; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -29,7 +28,7 @@ public ExporterInstrumentation( InternalTelemetryVersion schema, Supplier meterProviderSupplier, StandardComponentId componentId, - String endpoint) { + URI endpoint) { Signal signal = componentId.getStandardType().signal(); switch (schema) { @@ -52,30 +51,25 @@ public ExporterInstrumentation( } // visible for testing - static Attributes extractServerAttributes(String httpEndpoint) { - try { - URI parsed = new URI(httpEndpoint); - AttributesBuilder builder = Attributes.builder(); - String host = parsed.getHost(); - if (host != null) { - builder.put(SemConvAttributes.SERVER_ADDRESS, host); - } - int port = parsed.getPort(); - if (port == -1) { - String scheme = parsed.getScheme(); - if ("https".equals(scheme)) { - port = 443; - } else if ("http".equals(scheme)) { - port = 80; - } - } - if (port != -1) { - builder.put(SemConvAttributes.SERVER_PORT, port); + static Attributes extractServerAttributes(URI httpEndpoint) { + AttributesBuilder builder = Attributes.builder(); + String host = httpEndpoint.getHost(); + if (host != null) { + builder.put(SemConvAttributes.SERVER_ADDRESS, host); + } + int port = httpEndpoint.getPort(); + if (port == -1) { + String scheme = httpEndpoint.getScheme(); + if ("https".equals(scheme)) { + port = 443; + } else if ("http".equals(scheme)) { + port = 80; } - return builder.build(); - } catch (URISyntaxException e) { - return Attributes.empty(); } + if (port != -1) { + builder.put(SemConvAttributes.SERVER_PORT, port); + } + return builder.build(); } public Recording startRecordingExport(int itemCount) { diff --git a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilderTest.java b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilderTest.java index b17f3cdb595..b78d16017a1 100644 --- a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilderTest.java +++ b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilderTest.java @@ -9,9 +9,8 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.opentelemetry.common.ComponentLoader; -import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.compressor.Compressor; import io.opentelemetry.exporter.internal.compression.GzipCompressor; -import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.internal.StandardComponentId; import java.net.URI; import java.net.URL; @@ -21,12 +20,12 @@ class GrpcExporterBuilderTest { - private GrpcExporterBuilder builder; + private GrpcExporterBuilder builder; @BeforeEach void setUp() { builder = - new GrpcExporterBuilder<>( + new GrpcExporterBuilder( StandardComponentId.ExporterType.OTLP_GRPC_SPAN_EXPORTER, 0, URI.create("http://localhost:4317"), diff --git a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterTest.java b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterTest.java index 0ea1fa4a10e..a5d3edf35a3 100644 --- a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterTest.java +++ b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterTest.java @@ -5,12 +5,16 @@ package io.opentelemetry.exporter.internal.grpc; +import static io.opentelemetry.exporter.grpc.GrpcStatusCode.UNAVAILABLE; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.exporter.grpc.GrpcResponse; +import io.opentelemetry.exporter.grpc.GrpcSender; +import io.opentelemetry.exporter.grpc.GrpcStatusCode; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InternalTelemetryVersion; @@ -34,7 +38,7 @@ class GrpcExporterTest { void build_NoGrpcSenderProvider() { assertThatThrownBy( () -> - new GrpcExporterBuilder<>( + new GrpcExporterBuilder( StandardComponentId.ExporterType.OTLP_GRPC_SPAN_EXPORTER, 10, new URI("http://localhost"), @@ -49,7 +53,6 @@ void build_NoGrpcSenderProvider() { @ParameterizedTest @EnumSource - @SuppressWarnings("unchecked") @SuppressLogger(GrpcExporter.class) void testInternalTelemetry(StandardComponentId.ExporterType exporterType) { String signalMetricPrefix; @@ -87,16 +90,16 @@ void testInternalTelemetry(StandardComponentId.ExporterType exporterType) { .put(SemConvAttributes.SERVER_PORT, 1234) .build(); - GrpcSender mockSender = Mockito.mock(GrpcSender.class); + GrpcSender mockSender = Mockito.mock(GrpcSender.class); Marshaler mockMarshaller = Mockito.mock(Marshaler.class); - GrpcExporter exporter = - new GrpcExporter( + GrpcExporter exporter = + new GrpcExporter( mockSender, InternalTelemetryVersion.LATEST, id, () -> meterProvider, - "http://testing:1234"); + URI.create("http://testing:1234")); doAnswer( invoc -> { @@ -117,7 +120,9 @@ void testInternalTelemetry(StandardComponentId.ExporterType exporterType) { pa.hasAttributes(expectedAttributes) .hasValue(42)))); - onResponse.accept(GrpcResponse.create(0, null)); + onResponse.accept( + ImmutableGrpcResponse.create(GrpcStatusCode.OK, null, new byte[0])); + return null; }) .when(mockSender) @@ -128,8 +133,8 @@ void testInternalTelemetry(StandardComponentId.ExporterType exporterType) { doAnswer( invoc -> { Consumer onResponse = invoc.getArgument(1); - onResponse.accept( - GrpcResponse.create(GrpcExporterUtil.GRPC_STATUS_UNAVAILABLE, null)); + onResponse.accept(ImmutableGrpcResponse.create(UNAVAILABLE, null, new byte[0])); + return null; }) .when(mockSender) @@ -171,7 +176,7 @@ void testInternalTelemetry(StandardComponentId.ExporterType exporterType) { expectedAttributes.toBuilder() .put( SemConvAttributes.ERROR_TYPE, - "" + GrpcExporterUtil.GRPC_STATUS_UNAVAILABLE) + "" + UNAVAILABLE.getValue()) .build()) .hasValue(15), pa -> @@ -201,10 +206,10 @@ void testInternalTelemetry(StandardComponentId.ExporterType exporterType) { expectedAttributes.toBuilder() .put( SemConvAttributes.ERROR_TYPE, - "" + GrpcExporterUtil.GRPC_STATUS_UNAVAILABLE) + "" + UNAVAILABLE.getValue()) .put( SemConvAttributes.RPC_GRPC_STATUS_CODE, - GrpcExporterUtil.GRPC_STATUS_UNAVAILABLE) + UNAVAILABLE.getValue()) .build()) .hasBucketCounts(1), pa -> diff --git a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilderTest.java b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilderTest.java index c924dcd9af1..f8a1ba4eab2 100644 --- a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilderTest.java +++ b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilderTest.java @@ -9,9 +9,8 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.opentelemetry.common.ComponentLoader; -import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.compressor.Compressor; import io.opentelemetry.exporter.internal.compression.GzipCompressor; -import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.internal.StandardComponentId; import java.net.URL; import java.net.URLClassLoader; @@ -20,12 +19,12 @@ class HttpExporterBuilderTest { - private HttpExporterBuilder builder; + private HttpExporterBuilder builder; @BeforeEach void setUp() { builder = - new HttpExporterBuilder<>( + new HttpExporterBuilder( StandardComponentId.ExporterType.OTLP_HTTP_SPAN_EXPORTER, "http://localhost:4318"); } diff --git a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/http/HttpExporterTest.java b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/http/HttpExporterTest.java index 7dcfa3de68e..493b52bbb79 100644 --- a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/http/HttpExporterTest.java +++ b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/http/HttpExporterTest.java @@ -8,10 +8,11 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doAnswer; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.exporter.http.HttpResponse; +import io.opentelemetry.exporter.http.HttpSender; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InternalTelemetryVersion; @@ -21,6 +22,7 @@ import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import java.io.IOException; +import java.net.URI; import java.util.function.Consumer; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -33,7 +35,7 @@ class HttpExporterTest { void build_NoHttpSenderProvider() { assertThatThrownBy( () -> - new HttpExporterBuilder<>( + new HttpExporterBuilder( StandardComponentId.ExporterType.OTLP_HTTP_SPAN_EXPORTER, "http://localhost") .build()) @@ -85,17 +87,18 @@ void testInternalTelemetry(StandardComponentId.ExporterType exporterType) { HttpSender mockSender = Mockito.mock(HttpSender.class); Marshaler mockMarshaller = Mockito.mock(Marshaler.class); - HttpExporter exporter = - new HttpExporter( + HttpExporter exporter = + new HttpExporter( id, mockSender, () -> meterProvider, InternalTelemetryVersion.LATEST, - "http://testing:1234"); + URI.create("http://testing:1234"), + false); doAnswer( invoc -> { - Consumer onResponse = invoc.getArgument(2); + Consumer onResponse = invoc.getArgument(1); assertThat(inMemoryMetrics.collectAllMetrics()) .hasSize(1) @@ -116,28 +119,28 @@ void testInternalTelemetry(StandardComponentId.ExporterType exporterType) { return null; }) .when(mockSender) - .send(any(), anyInt(), any(), any()); + .send(any(), any(), any()); exporter.export(mockMarshaller, 42); doAnswer( invoc -> { - Consumer onResponse = invoc.getArgument(2); + Consumer onResponse = invoc.getArgument(1); onResponse.accept(new FakeHttpResponse(404, "Not Found")); return null; }) .when(mockSender) - .send(any(), anyInt(), any(), any()); + .send(any(), any(), any()); exporter.export(mockMarshaller, 15); doAnswer( invoc -> { - Consumer onError = invoc.getArgument(3); + Consumer onError = invoc.getArgument(2); onError.accept(new IOException("Computer says no")); return null; }) .when(mockSender) - .send(any(), anyInt(), any(), any()); + .send(any(), any(), any()); exporter.export(mockMarshaller, 7); assertThat(inMemoryMetrics.collectAllMetrics()) @@ -210,7 +213,7 @@ void testInternalTelemetry(StandardComponentId.ExporterType exporterType) { } } - private static class FakeHttpResponse implements HttpSender.Response { + private static class FakeHttpResponse implements HttpResponse { final int statusCode; final String statusMessage; @@ -221,17 +224,17 @@ private static class FakeHttpResponse implements HttpSender.Response { } @Override - public int statusCode() { + public int getStatusCode() { return statusCode; } @Override - public String statusMessage() { + public String getStatusMessage() { return statusMessage; } @Override - public byte[] responseBody() throws IOException { + public byte[] getResponseBody() { return new byte[0]; } } diff --git a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/metrics/ExporterInstrumentationTest.java b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/metrics/ExporterInstrumentationTest.java index 298f1a65c88..1a7098f7223 100644 --- a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/metrics/ExporterInstrumentationTest.java +++ b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/metrics/ExporterInstrumentationTest.java @@ -24,6 +24,7 @@ import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.export.CollectionRegistration; import io.opentelemetry.sdk.metrics.export.MetricReader; +import java.net.URI; import java.util.function.Supplier; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -69,7 +70,7 @@ public AggregationTemporality getAggregationTemporality( schemaVersion, meterProviderSupplier, ComponentId.generateLazy(StandardComponentId.ExporterType.OTLP_GRPC_SPAN_EXPORTER), - "http://testing:1234"); + URI.create("http://testing:1234")); verifyNoInteractions(meterProviderSupplier); // Ensure lazy // Verify the supplier is only called once per underlying meter. @@ -93,7 +94,7 @@ void noopMeterProvider(InternalTelemetryVersion schemaVersion) { schemaVersion, meterProviderSupplier, ComponentId.generateLazy(StandardComponentId.ExporterType.OTLP_GRPC_SPAN_EXPORTER), - "http://testing:1234"); + URI.create("http://testing:1234")); verifyNoInteractions(meterProviderSupplier); // Ensure lazy // Verify the supplier is invoked multiple times since it returns a noop meter. @@ -107,25 +108,18 @@ void noopMeterProvider(InternalTelemetryVersion schemaVersion) { verify(meterProviderSupplier, atLeastOnce()).get(); } - @Test - void serverAttributesInvalidUrl() { - assertThat(ExporterInstrumentation.extractServerAttributes("^")).isEmpty(); - } - - @Test - void serverAttributesEmptyUrl() { - assertThat(ExporterInstrumentation.extractServerAttributes("")).isEmpty(); - } - @Test void serverAttributesHttps() { - assertThat(ExporterInstrumentation.extractServerAttributes("https://example.com/foo/bar?a=b")) + assertThat( + ExporterInstrumentation.extractServerAttributes( + URI.create("https://example.com/foo/bar?a=b"))) .hasSize(2) .containsEntry(SemConvAttributes.SERVER_ADDRESS, "example.com") .containsEntry(SemConvAttributes.SERVER_PORT, 443); assertThat( - ExporterInstrumentation.extractServerAttributes("https://example.com:1234/foo/bar?a=b")) + ExporterInstrumentation.extractServerAttributes( + URI.create("https://example.com:1234/foo/bar?a=b"))) .hasSize(2) .containsEntry(SemConvAttributes.SERVER_ADDRESS, "example.com") .containsEntry(SemConvAttributes.SERVER_PORT, 1234); @@ -133,13 +127,16 @@ void serverAttributesHttps() { @Test void serverAttributesHttp() { - assertThat(ExporterInstrumentation.extractServerAttributes("http://example.com/foo/bar?a=b")) + assertThat( + ExporterInstrumentation.extractServerAttributes( + URI.create("http://example.com/foo/bar?a=b"))) .hasSize(2) .containsEntry(SemConvAttributes.SERVER_ADDRESS, "example.com") .containsEntry(SemConvAttributes.SERVER_PORT, 80); assertThat( - ExporterInstrumentation.extractServerAttributes("http://example.com:1234/foo/bar?a=b")) + ExporterInstrumentation.extractServerAttributes( + URI.create("http://example.com:1234/foo/bar?a=b"))) .hasSize(2) .containsEntry(SemConvAttributes.SERVER_ADDRESS, "example.com") .containsEntry(SemConvAttributes.SERVER_PORT, 1234); @@ -147,11 +144,11 @@ void serverAttributesHttp() { @Test void serverAttributesUnknownScheme() { - assertThat(ExporterInstrumentation.extractServerAttributes("custom://foo")) + assertThat(ExporterInstrumentation.extractServerAttributes(URI.create("custom://foo"))) .hasSize(1) .containsEntry(SemConvAttributes.SERVER_ADDRESS, "foo"); - assertThat(ExporterInstrumentation.extractServerAttributes("custom://foo:1234")) + assertThat(ExporterInstrumentation.extractServerAttributes(URI.create("custom://foo:1234"))) .hasSize(2) .containsEntry(SemConvAttributes.SERVER_ADDRESS, "foo") .containsEntry(SemConvAttributes.SERVER_PORT, 1234); diff --git a/exporters/common/src/testGrpcSenderProvider/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterTest.java b/exporters/common/src/testGrpcSenderProvider/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterTest.java index 238d4a2ce83..4cb89a6826a 100644 --- a/exporters/common/src/testGrpcSenderProvider/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterTest.java +++ b/exporters/common/src/testGrpcSenderProvider/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterTest.java @@ -9,21 +9,14 @@ import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.SettableFuture; import io.github.netmikey.logunit.api.LogCapturer; -import io.grpc.CallOptions; -import io.grpc.Channel; import io.grpc.ManagedChannelBuilder; -import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; -import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.sender.grpc.managedchannel.internal.UpstreamGrpcSender; import io.opentelemetry.exporter.sender.okhttp.internal.OkHttpGrpcSender; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.internal.StandardComponentId; import java.net.URI; import java.net.URISyntaxException; -import javax.annotation.Nullable; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.junitpioneer.jupiter.SetSystemProperty; @@ -39,35 +32,35 @@ class GrpcExporterTest { void build_multipleSendersNoConfiguration() { assertThatCode( () -> - new GrpcExporterBuilder<>( + new GrpcExporterBuilder( StandardComponentId.ExporterType.OTLP_GRPC_SPAN_EXPORTER, 10, new URI("http://localhost"), - () -> DummyServiceFutureStub::newFutureStub, - "/path") + "io.opentelemetry.Dummy", + "Method") .setChannel(ManagedChannelBuilder.forTarget("localhost").build()) .build()) .doesNotThrowAnyException(); logCapturer.assertContains( "Multiple GrpcSenderProvider found. Please include only one, " - + "or specify preference setting io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider " + + "or specify preference setting io.opentelemetry.exporter.grpc.GrpcSenderProvider " + "to the FQCN of the preferred provider."); } @Test @SetSystemProperty( - key = "io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider", + key = "io.opentelemetry.exporter.grpc.GrpcSenderProvider", value = "io.opentelemetry.exporter.sender.grpc.managedchannel.internal.UpstreamGrpcSenderProvider") void build_multipleSendersWithUpstream() throws URISyntaxException { assertThat( - new GrpcExporterBuilder<>( + new GrpcExporterBuilder( StandardComponentId.ExporterType.OTLP_GRPC_SPAN_EXPORTER, 10, new URI("http://localhost"), - () -> DummyServiceFutureStub::newFutureStub, - "/path") + "io.opentelemetry.Dummy", + "Method") .setChannel(ManagedChannelBuilder.forTarget("localhost").build()) .build()) .extracting("grpcSender") @@ -78,16 +71,16 @@ void build_multipleSendersWithUpstream() throws URISyntaxException { @Test @SetSystemProperty( - key = "io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider", + key = "io.opentelemetry.exporter.grpc.GrpcSenderProvider", value = "io.opentelemetry.exporter.sender.okhttp.internal.OkHttpGrpcSenderProvider") void build_multipleSendersWithOkHttp() throws URISyntaxException { assertThat( - new GrpcExporterBuilder<>( + new GrpcExporterBuilder( StandardComponentId.ExporterType.OTLP_GRPC_SPAN_EXPORTER, 10, new URI("http://localhost"), - () -> DummyServiceFutureStub::newFutureStub, - "/path") + "io.opentelemetry.Dummy", + "Method") .setChannel(ManagedChannelBuilder.forTarget("localhost").build()) .build()) .extracting("grpcSender") @@ -97,61 +90,22 @@ void build_multipleSendersWithOkHttp() throws URISyntaxException { } @Test - @SetSystemProperty( - key = "io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider", - value = "foo") + @SetSystemProperty(key = "io.opentelemetry.exporter.grpc.GrpcSenderProvider", value = "foo") void build_multipleSendersNoMatch() { assertThatThrownBy( () -> - new GrpcExporterBuilder<>( + new GrpcExporterBuilder( StandardComponentId.ExporterType.OTLP_GRPC_SPAN_EXPORTER, 10, new URI("http://localhost"), - () -> DummyServiceFutureStub::newFutureStub, - "/path") + "io.opentelemetry.Dummy", + "Method") .setChannel(ManagedChannelBuilder.forTarget("localhost").build()) .build()) .isInstanceOf(IllegalStateException.class) .hasMessage( - "No GrpcSenderProvider matched configured io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider: foo"); + "No GrpcSenderProvider matched configured io.opentelemetry.exporter.grpc.GrpcSenderProvider: foo"); assertThat(logCapturer.getEvents()).isEmpty(); } - - private static class DummyServiceFutureStub - extends MarshalerServiceStub { - - private DummyServiceFutureStub(Channel channel, CallOptions callOptions) { - super(channel, callOptions); - } - - @Override - public ListenableFuture export(DummyMarshaler request) { - SettableFuture future = SettableFuture.create(); - future.set(new Object()); - return future; - } - - @Override - protected DummyServiceFutureStub build(Channel channel, CallOptions callOptions) { - return new DummyServiceFutureStub(channel, callOptions); - } - - private static DummyServiceFutureStub newFutureStub( - io.grpc.Channel channel, @Nullable String authorityOverride) { - return DummyServiceFutureStub.newStub( - (c, options) -> new DummyServiceFutureStub(c, options.withAuthority(authorityOverride)), - channel); - } - } - - private static class DummyMarshaler extends MarshalerWithSize { - - private DummyMarshaler() { - super(0); - } - - @Override - protected void writeTo(Serializer output) {} - } } diff --git a/exporters/common/src/testHttpSenderProvider/java/io/opentelemetry/exporter/internal/http/HttpExporterTest.java b/exporters/common/src/testHttpSenderProvider/java/io/opentelemetry/exporter/internal/http/HttpExporterTest.java index 033d8f15ad3..5022e7f22ef 100644 --- a/exporters/common/src/testHttpSenderProvider/java/io/opentelemetry/exporter/internal/http/HttpExporterTest.java +++ b/exporters/common/src/testHttpSenderProvider/java/io/opentelemetry/exporter/internal/http/HttpExporterTest.java @@ -29,7 +29,7 @@ class HttpExporterTest { void build_multipleSendersNoConfiguration() { Assertions.assertThatCode( () -> - new HttpExporterBuilder<>( + new HttpExporterBuilder( StandardComponentId.ExporterType.OTLP_HTTP_SPAN_EXPORTER, "http://localhost") .build()) @@ -37,17 +37,17 @@ void build_multipleSendersNoConfiguration() { logCapturer.assertContains( "Multiple HttpSenderProvider found. Please include only one, " - + "or specify preference setting io.opentelemetry.exporter.internal.http.HttpSenderProvider " + + "or specify preference setting io.opentelemetry.exporter.http.HttpSenderProvider " + "to the FQCN of the preferred provider."); } @Test @SetSystemProperty( - key = "io.opentelemetry.exporter.internal.http.HttpSenderProvider", + key = "io.opentelemetry.exporter.http.HttpSenderProvider", value = "io.opentelemetry.exporter.sender.jdk.internal.JdkHttpSenderProvider") void build_multipleSendersWithJdk() { assertThat( - new HttpExporterBuilder<>( + new HttpExporterBuilder( StandardComponentId.ExporterType.OTLP_HTTP_SPAN_EXPORTER, "http://localhost") .build()) .extracting("httpSender") @@ -58,11 +58,11 @@ void build_multipleSendersWithJdk() { @Test @SetSystemProperty( - key = "io.opentelemetry.exporter.internal.http.HttpSenderProvider", + key = "io.opentelemetry.exporter.http.HttpSenderProvider", value = "io.opentelemetry.exporter.sender.okhttp.internal.OkHttpHttpSenderProvider") void build_multipleSendersWithOkHttp() { assertThat( - new HttpExporterBuilder<>( + new HttpExporterBuilder( StandardComponentId.ExporterType.OTLP_HTTP_SPAN_EXPORTER, "http://localhost") .build()) .extracting("httpSender") @@ -72,19 +72,17 @@ void build_multipleSendersWithOkHttp() { } @Test - @SetSystemProperty( - key = "io.opentelemetry.exporter.internal.http.HttpSenderProvider", - value = "foo") + @SetSystemProperty(key = "io.opentelemetry.exporter.http.HttpSenderProvider", value = "foo") void build_multipleSendersNoMatch() { assertThatThrownBy( () -> - new HttpExporterBuilder<>( + new HttpExporterBuilder( StandardComponentId.ExporterType.OTLP_HTTP_SPAN_EXPORTER, "http://localhost") .build()) .isInstanceOf(IllegalStateException.class) .hasMessage( - "No HttpSenderProvider matched configured io.opentelemetry.exporter.internal.http.HttpSenderProvider: foo"); + "No HttpSenderProvider matched configured io.opentelemetry.exporter.http.HttpSenderProvider: foo"); assertThat(logCapturer.getEvents()).isEmpty(); } diff --git a/exporters/otlp/all/build.gradle.kts b/exporters/otlp/all/build.gradle.kts index d6a51932a0d..856157fa133 100644 --- a/exporters/otlp/all/build.gradle.kts +++ b/exporters/otlp/all/build.gradle.kts @@ -94,7 +94,7 @@ testing { all { testTask { systemProperty( - "io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider", + "io.opentelemetry.exporter.grpc.GrpcSenderProvider", "io.opentelemetry.exporter.sender.grpc.managedchannel.internal.UpstreamGrpcSenderProvider" ) } @@ -114,7 +114,7 @@ testing { all { testTask { systemProperty( - "io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider", + "io.opentelemetry.exporter.grpc.GrpcSenderProvider", "io.opentelemetry.exporter.sender.grpc.managedchannel.internal.UpstreamGrpcSenderProvider" ) } @@ -134,7 +134,7 @@ testing { all { testTask { systemProperty( - "io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider", + "io.opentelemetry.exporter.grpc.GrpcSenderProvider", "io.opentelemetry.exporter.sender.grpc.managedchannel.internal.UpstreamGrpcSenderProvider" ) } @@ -152,7 +152,7 @@ testing { all { testTask { systemProperty( - "io.opentelemetry.exporter.internal.http.HttpSenderProvider", + "io.opentelemetry.exporter.http.HttpSenderProvider", "io.opentelemetry.exporter.sender.jdk.internal.JdkHttpSenderProvider" ) enabled = !testJavaVersion.equals("8") diff --git a/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java b/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java index 586fe4e9960..302826af452 100644 --- a/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java +++ b/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java @@ -15,8 +15,6 @@ import io.opentelemetry.exporter.internal.grpc.GrpcExporter; import io.opentelemetry.exporter.internal.http.HttpExporter; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; -import io.opentelemetry.exporter.internal.marshal.Marshaler; -import io.opentelemetry.exporter.internal.otlp.traces.TraceRequestMarshaler; import io.opentelemetry.exporter.sender.grpc.managedchannel.internal.UpstreamGrpcSender; import io.opentelemetry.exporter.sender.okhttp.internal.OkHttpGrpcSender; import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest; @@ -71,9 +69,9 @@ public void export( private static ManagedChannel defaultGrpcChannel; - private static GrpcExporter upstreamGrpcExporter; - private static GrpcExporter okhttpGrpcSender; - private static HttpExporter httpExporter; + private static GrpcExporter upstreamGrpcExporter; + private static GrpcExporter okhttpGrpcSender; + private static HttpExporter httpExporter; @Setup(Level.Trial) public void setUp() { @@ -84,9 +82,12 @@ public void setUp() { .usePlaintext() .build(); upstreamGrpcExporter = - new GrpcExporter<>( - new UpstreamGrpcSender<>( - MarshalerTraceServiceGrpc.newFutureStub(defaultGrpcChannel, null), + new GrpcExporter( + new UpstreamGrpcSender( + defaultGrpcChannel, + "opentelemetry.proto.collector.trace.v1.TraceService", + "Export", + null, /* shutdownChannel= */ false, 10, Collections::emptyMap, @@ -94,13 +95,13 @@ public void setUp() { InternalTelemetryVersion.LATEST, ComponentId.generateLazy(StandardComponentId.ExporterType.OTLP_GRPC_SPAN_EXPORTER), MeterProvider::noop, - "http://localhost"); + URI.create("http://localhost")); okhttpGrpcSender = - new GrpcExporter<>( - new OkHttpGrpcSender<>( + new GrpcExporter( + new OkHttpGrpcSender( URI.create("http://localhost:" + server.activeLocalPort()) - .resolve(OtlpGrpcSpanExporterBuilder.GRPC_ENDPOINT_PATH) + .resolve("opentelemetry.proto.collector.trace.v1.TraceService/Export") .toString(), null, 10, @@ -113,10 +114,10 @@ public void setUp() { InternalTelemetryVersion.LATEST, ComponentId.generateLazy(StandardComponentId.ExporterType.OTLP_GRPC_SPAN_EXPORTER), MeterProvider::noop, - "http://localhost"); + URI.create("http://localhost")); httpExporter = - new HttpExporterBuilder( + new HttpExporterBuilder( StandardComponentId.ExporterType.OTLP_HTTP_SPAN_EXPORTER, "http://localhost:" + server.activeLocalPort() + "/v1/traces") .build(); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporter.java index dcc8b4bcc7a..459ed970ae5 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporter.java @@ -7,7 +7,6 @@ import io.opentelemetry.exporter.internal.http.HttpExporter; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; -import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.internal.otlp.logs.LogReusableDataMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.MemoryMode; @@ -25,14 +24,12 @@ @ThreadSafe public final class OtlpHttpLogRecordExporter implements LogRecordExporter { - private final HttpExporterBuilder builder; - private final HttpExporter delegate; + private final HttpExporterBuilder builder; + private final HttpExporter delegate; private final LogReusableDataMarshaler marshaler; OtlpHttpLogRecordExporter( - HttpExporterBuilder builder, - HttpExporter delegate, - MemoryMode memoryMode) { + HttpExporterBuilder builder, HttpExporter delegate, MemoryMode memoryMode) { this.builder = builder; this.delegate = delegate; this.marshaler = new LogReusableDataMarshaler(memoryMode, delegate::export); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index b9606919075..71c6cfd0524 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -11,9 +11,8 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.common.ComponentLoader; -import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.compressor.Compressor; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; -import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; import io.opentelemetry.sdk.common.InternalTelemetryVersion; import io.opentelemetry.sdk.common.export.MemoryMode; @@ -39,10 +38,10 @@ public final class OtlpHttpLogRecordExporterBuilder { private static final String DEFAULT_ENDPOINT = "http://localhost:4318/v1/logs"; private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; - private final HttpExporterBuilder delegate; + private final HttpExporterBuilder delegate; private MemoryMode memoryMode; - OtlpHttpLogRecordExporterBuilder(HttpExporterBuilder delegate, MemoryMode memoryMode) { + OtlpHttpLogRecordExporterBuilder(HttpExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; this.memoryMode = memoryMode; OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeaders); @@ -50,7 +49,7 @@ public final class OtlpHttpLogRecordExporterBuilder { OtlpHttpLogRecordExporterBuilder() { this( - new HttpExporterBuilder<>( + new HttpExporterBuilder( StandardComponentId.ExporterType.OTLP_HTTP_LOG_EXPORTER, DEFAULT_ENDPOINT), DEFAULT_MEMORY_MODE); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporter.java index 0d9ff4c1b01..0f65acd3472 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporter.java @@ -7,7 +7,6 @@ import io.opentelemetry.exporter.internal.http.HttpExporter; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; -import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.internal.otlp.metrics.MetricReusableDataMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.MemoryMode; @@ -30,8 +29,8 @@ @ThreadSafe public final class OtlpHttpMetricExporter implements MetricExporter { - private final HttpExporterBuilder builder; - private final HttpExporter delegate; + private final HttpExporterBuilder builder; + private final HttpExporter delegate; // Visible for testing final AggregationTemporalitySelector aggregationTemporalitySelector; // Visible for testing @@ -39,8 +38,8 @@ public final class OtlpHttpMetricExporter implements MetricExporter { private final MetricReusableDataMarshaler marshaler; OtlpHttpMetricExporter( - HttpExporterBuilder builder, - HttpExporter delegate, + HttpExporterBuilder builder, + HttpExporter delegate, AggregationTemporalitySelector aggregationTemporalitySelector, DefaultAggregationSelector defaultAggregationSelector, MemoryMode memoryMode) { diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index 07f24dac91c..2e1b0d5a824 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -11,9 +11,8 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.common.ComponentLoader; -import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.compressor.Compressor; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; -import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; import io.opentelemetry.sdk.common.InternalTelemetryVersion; import io.opentelemetry.sdk.common.export.MemoryMode; @@ -48,14 +47,14 @@ public final class OtlpHttpMetricExporterBuilder { AggregationTemporalitySelector.alwaysCumulative(); private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; - private final HttpExporterBuilder delegate; + private final HttpExporterBuilder delegate; private AggregationTemporalitySelector aggregationTemporalitySelector; private DefaultAggregationSelector defaultAggregationSelector; private MemoryMode memoryMode; OtlpHttpMetricExporterBuilder( - HttpExporterBuilder delegate, + HttpExporterBuilder delegate, AggregationTemporalitySelector aggregationTemporalitySelector, DefaultAggregationSelector defaultAggregationSelector, MemoryMode memoryMode) { @@ -68,7 +67,7 @@ public final class OtlpHttpMetricExporterBuilder { OtlpHttpMetricExporterBuilder() { this( - new HttpExporterBuilder<>( + new HttpExporterBuilder( StandardComponentId.ExporterType.OTLP_HTTP_METRIC_EXPORTER, DEFAULT_ENDPOINT), DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR, DefaultAggregationSelector.getDefault(), diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporter.java index 71870e12b54..9a2f7df798f 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporter.java @@ -7,7 +7,6 @@ import io.opentelemetry.exporter.internal.http.HttpExporter; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; -import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.internal.otlp.traces.SpanReusableDataMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.MemoryMode; @@ -25,14 +24,11 @@ @ThreadSafe public final class OtlpHttpSpanExporter implements SpanExporter { - private final HttpExporterBuilder builder; - private final HttpExporter delegate; + private final HttpExporterBuilder builder; + private final HttpExporter delegate; private final SpanReusableDataMarshaler marshaler; - OtlpHttpSpanExporter( - HttpExporterBuilder builder, - HttpExporter delegate, - MemoryMode memoryMode) { + OtlpHttpSpanExporter(HttpExporterBuilder builder, HttpExporter delegate, MemoryMode memoryMode) { this.builder = builder; this.delegate = delegate; this.marshaler = new SpanReusableDataMarshaler(memoryMode, delegate::export); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index f8289010b5b..284f8b417f0 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -11,9 +11,8 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.common.ComponentLoader; -import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.compressor.Compressor; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; -import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; import io.opentelemetry.sdk.common.InternalTelemetryVersion; import io.opentelemetry.sdk.common.export.MemoryMode; @@ -39,10 +38,10 @@ public final class OtlpHttpSpanExporterBuilder { private static final String DEFAULT_ENDPOINT = "http://localhost:4318/v1/traces"; private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; - private final HttpExporterBuilder delegate; + private final HttpExporterBuilder delegate; private MemoryMode memoryMode; - OtlpHttpSpanExporterBuilder(HttpExporterBuilder delegate, MemoryMode memoryMode) { + OtlpHttpSpanExporterBuilder(HttpExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; this.memoryMode = memoryMode; OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeaders); @@ -50,7 +49,7 @@ public final class OtlpHttpSpanExporterBuilder { OtlpHttpSpanExporterBuilder() { this( - new HttpExporterBuilder<>( + new HttpExporterBuilder( StandardComponentId.ExporterType.OTLP_HTTP_SPAN_EXPORTER, DEFAULT_ENDPOINT), DEFAULT_MEMORY_MODE); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/MarshalerLogsServiceGrpc.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/MarshalerLogsServiceGrpc.java deleted file mode 100644 index 451e5abae32..00000000000 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/MarshalerLogsServiceGrpc.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.otlp.logs; - -import static io.grpc.MethodDescriptor.generateFullMethodName; - -import com.google.common.util.concurrent.ListenableFuture; -import io.grpc.CallOptions; -import io.grpc.Channel; -import io.grpc.MethodDescriptor; -import io.grpc.stub.ClientCalls; -import io.opentelemetry.exporter.internal.grpc.MarshalerInputStream; -import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; -import io.opentelemetry.exporter.internal.marshal.Marshaler; -import java.io.InputStream; -import javax.annotation.Nullable; - -// Adapted from the protoc generated code for LogsServiceGrpc. -final class MarshalerLogsServiceGrpc { - - private static final String SERVICE_NAME = "opentelemetry.proto.collector.logs.v1.LogsService"; - - private static final MethodDescriptor.Marshaller REQUEST_MARSHALLER = - new MethodDescriptor.Marshaller() { - @Override - public InputStream stream(Marshaler value) { - return new MarshalerInputStream(value); - } - - @Override - public Marshaler parse(InputStream stream) { - throw new UnsupportedOperationException("Only for serializing"); - } - }; - - private static final MethodDescriptor.Marshaller RESPONSE_MARSHALER = - new MethodDescriptor.Marshaller() { - @Override - public InputStream stream(ExportLogsServiceResponse value) { - throw new UnsupportedOperationException("Only for parsing"); - } - - @Override - public ExportLogsServiceResponse parse(InputStream stream) { - return ExportLogsServiceResponse.INSTANCE; - } - }; - - private static final MethodDescriptor getExportMethod = - MethodDescriptor.newBuilder() - .setType(MethodDescriptor.MethodType.UNARY) - .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Export")) - .setRequestMarshaller(REQUEST_MARSHALLER) - .setResponseMarshaller(RESPONSE_MARSHALER) - .build(); - - static LogsServiceFutureStub newFutureStub(Channel channel, @Nullable String authorityOverride) { - return LogsServiceFutureStub.newStub( - (c, options) -> new LogsServiceFutureStub(c, options.withAuthority(authorityOverride)), - channel); - } - - static final class LogsServiceFutureStub - extends MarshalerServiceStub { - private LogsServiceFutureStub(Channel channel, CallOptions callOptions) { - super(channel, callOptions); - } - - @Override - protected MarshalerLogsServiceGrpc.LogsServiceFutureStub build( - Channel channel, CallOptions callOptions) { - return new MarshalerLogsServiceGrpc.LogsServiceFutureStub(channel, callOptions); - } - - @Override - public ListenableFuture export(Marshaler request) { - return ClientCalls.futureUnaryCall( - getChannel().newCall(getExportMethod, getCallOptions()), request); - } - } - - private MarshalerLogsServiceGrpc() {} -} diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporter.java index e85cb76b78f..4a5cd7ea3d3 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporter.java @@ -7,7 +7,6 @@ import io.opentelemetry.exporter.internal.grpc.GrpcExporter; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; -import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.internal.otlp.logs.LogReusableDataMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.MemoryMode; @@ -25,8 +24,8 @@ @ThreadSafe public final class OtlpGrpcLogRecordExporter implements LogRecordExporter { - private final GrpcExporterBuilder builder; - private final GrpcExporter delegate; + private final GrpcExporterBuilder builder; + private final GrpcExporter delegate; private final LogReusableDataMarshaler marshaler; /** @@ -51,9 +50,7 @@ public static OtlpGrpcLogRecordExporterBuilder builder() { } OtlpGrpcLogRecordExporter( - GrpcExporterBuilder builder, - GrpcExporter delegate, - MemoryMode memoryMode) { + GrpcExporterBuilder builder, GrpcExporter delegate, MemoryMode memoryMode) { this.builder = builder; this.delegate = delegate; this.marshaler = new LogReusableDataMarshaler(memoryMode, delegate::export); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index 467aa0cd6a9..1c0cc8160ea 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -12,9 +12,8 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.common.ComponentLoader; -import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.compressor.Compressor; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; -import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; import io.opentelemetry.sdk.common.InternalTelemetryVersion; import io.opentelemetry.sdk.common.export.MemoryMode; @@ -39,8 +38,7 @@ public final class OtlpGrpcLogRecordExporterBuilder { private static final String GRPC_SERVICE_NAME = "opentelemetry.proto.collector.logs.v1.LogsService"; - // Visible for testing - static final String GRPC_ENDPOINT_PATH = "/" + GRPC_SERVICE_NAME + "/Export"; + private static final String GRPC_METHOD_NAME = "Export"; private static final String DEFAULT_ENDPOINT_URL = "http://localhost:4317"; private static final URI DEFAULT_ENDPOINT = URI.create(DEFAULT_ENDPOINT_URL); @@ -48,10 +46,10 @@ public final class OtlpGrpcLogRecordExporterBuilder { private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; // Visible for testing - final GrpcExporterBuilder delegate; + final GrpcExporterBuilder delegate; private MemoryMode memoryMode; - OtlpGrpcLogRecordExporterBuilder(GrpcExporterBuilder delegate, MemoryMode memoryMode) { + OtlpGrpcLogRecordExporterBuilder(GrpcExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; this.memoryMode = memoryMode; OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); @@ -59,12 +57,12 @@ public final class OtlpGrpcLogRecordExporterBuilder { OtlpGrpcLogRecordExporterBuilder() { this( - new GrpcExporterBuilder<>( + new GrpcExporterBuilder( StandardComponentId.ExporterType.OTLP_GRPC_LOG_EXPORTER, DEFAULT_TIMEOUT_SECS, DEFAULT_ENDPOINT, - () -> MarshalerLogsServiceGrpc::newFutureStub, - GRPC_ENDPOINT_PATH), + GRPC_SERVICE_NAME, + GRPC_METHOD_NAME), DEFAULT_MEMORY_MODE); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/MarshalerMetricsServiceGrpc.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/MarshalerMetricsServiceGrpc.java deleted file mode 100644 index af70c6bd175..00000000000 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/MarshalerMetricsServiceGrpc.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.otlp.metrics; - -import static io.grpc.MethodDescriptor.generateFullMethodName; - -import com.google.common.util.concurrent.ListenableFuture; -import io.grpc.CallOptions; -import io.grpc.Channel; -import io.grpc.MethodDescriptor; -import io.grpc.stub.ClientCalls; -import io.opentelemetry.exporter.internal.grpc.MarshalerInputStream; -import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; -import io.opentelemetry.exporter.internal.marshal.Marshaler; -import java.io.InputStream; -import javax.annotation.Nullable; - -// Adapted from the protoc generated code for MetricsServiceGrpc. -final class MarshalerMetricsServiceGrpc { - - private static final String SERVICE_NAME = - "opentelemetry.proto.collector.metrics.v1.MetricsService"; - - private static final MethodDescriptor.Marshaller REQUEST_MARSHALLER = - new MethodDescriptor.Marshaller() { - @Override - public InputStream stream(Marshaler value) { - return new MarshalerInputStream(value); - } - - @Override - public Marshaler parse(InputStream stream) { - throw new UnsupportedOperationException("Only for serializing"); - } - }; - - private static final MethodDescriptor.Marshaller - RESPONSE_MARSHALER = - new MethodDescriptor.Marshaller() { - @Override - public InputStream stream(ExportMetricsServiceResponse value) { - throw new UnsupportedOperationException("Only for parsing"); - } - - @Override - public ExportMetricsServiceResponse parse(InputStream stream) { - return ExportMetricsServiceResponse.INSTANCE; - } - }; - - private static final MethodDescriptor getExportMethod = - MethodDescriptor.newBuilder() - .setType(MethodDescriptor.MethodType.UNARY) - .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Export")) - .setRequestMarshaller(REQUEST_MARSHALLER) - .setResponseMarshaller(RESPONSE_MARSHALER) - .build(); - - static MetricsServiceFutureStub newFutureStub( - Channel channel, @Nullable String authorityOverride) { - return MetricsServiceFutureStub.newStub( - (c, options) -> new MetricsServiceFutureStub(c, options.withAuthority(authorityOverride)), - channel); - } - - static final class MetricsServiceFutureStub - extends MarshalerServiceStub< - Marshaler, ExportMetricsServiceResponse, MetricsServiceFutureStub> { - private MetricsServiceFutureStub(Channel channel, CallOptions callOptions) { - super(channel, callOptions); - } - - @Override - protected MarshalerMetricsServiceGrpc.MetricsServiceFutureStub build( - Channel channel, CallOptions callOptions) { - return new MarshalerMetricsServiceGrpc.MetricsServiceFutureStub(channel, callOptions); - } - - @Override - public ListenableFuture export(Marshaler request) { - return ClientCalls.futureUnaryCall( - getChannel().newCall(getExportMethod, getCallOptions()), request); - } - } - - private MarshalerMetricsServiceGrpc() {} -} diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporter.java index ec6dc1af65a..75fe1d461d0 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporter.java @@ -7,7 +7,6 @@ import io.opentelemetry.exporter.internal.grpc.GrpcExporter; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; -import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.internal.otlp.metrics.MetricReusableDataMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.MemoryMode; @@ -30,8 +29,8 @@ @ThreadSafe public final class OtlpGrpcMetricExporter implements MetricExporter { - private final GrpcExporterBuilder builder; - private final GrpcExporter delegate; + private final GrpcExporterBuilder builder; + private final GrpcExporter delegate; // Visible for testing final AggregationTemporalitySelector aggregationTemporalitySelector; // Visible for testing @@ -60,8 +59,8 @@ public static OtlpGrpcMetricExporterBuilder builder() { } OtlpGrpcMetricExporter( - GrpcExporterBuilder builder, - GrpcExporter delegate, + GrpcExporterBuilder builder, + GrpcExporter delegate, AggregationTemporalitySelector aggregationTemporalitySelector, DefaultAggregationSelector defaultAggregationSelector, MemoryMode memoryMode) { diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java index ef3403c7353..ef45c90cbcc 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java @@ -12,9 +12,8 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.common.ComponentLoader; -import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.compressor.Compressor; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; -import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; import io.opentelemetry.sdk.common.InternalTelemetryVersion; import io.opentelemetry.sdk.common.export.MemoryMode; @@ -45,8 +44,7 @@ public final class OtlpGrpcMetricExporterBuilder { private static final String GRPC_SERVICE_NAME = "opentelemetry.proto.collector.metrics.v1.MetricsService"; - // Visible for testing - static final String GRPC_ENDPOINT_PATH = "/" + GRPC_SERVICE_NAME + "/Export"; + private static final String GRPC_METHOD_NAME = "Export"; private static final String DEFAULT_ENDPOINT_URL = "http://localhost:4317"; private static final URI DEFAULT_ENDPOINT = URI.create(DEFAULT_ENDPOINT_URL); @@ -56,14 +54,14 @@ public final class OtlpGrpcMetricExporterBuilder { private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; // Visible for testing - final GrpcExporterBuilder delegate; + final GrpcExporterBuilder delegate; private AggregationTemporalitySelector aggregationTemporalitySelector; private DefaultAggregationSelector defaultAggregationSelector; private MemoryMode memoryMode; OtlpGrpcMetricExporterBuilder( - GrpcExporterBuilder delegate, + GrpcExporterBuilder delegate, AggregationTemporalitySelector aggregationTemporalitySelector, DefaultAggregationSelector defaultAggregationSelector, MemoryMode memoryMode) { @@ -76,12 +74,12 @@ public final class OtlpGrpcMetricExporterBuilder { OtlpGrpcMetricExporterBuilder() { this( - new GrpcExporterBuilder<>( + new GrpcExporterBuilder( StandardComponentId.ExporterType.OTLP_GRPC_METRIC_EXPORTER, DEFAULT_TIMEOUT_SECS, DEFAULT_ENDPOINT, - () -> MarshalerMetricsServiceGrpc::newFutureStub, - GRPC_ENDPOINT_PATH), + GRPC_SERVICE_NAME, + GRPC_METHOD_NAME), DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR, DefaultAggregationSelector.getDefault(), DEFAULT_MEMORY_MODE); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/MarshalerTraceServiceGrpc.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/MarshalerTraceServiceGrpc.java deleted file mode 100644 index 784eae98a49..00000000000 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/MarshalerTraceServiceGrpc.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.otlp.trace; - -import static io.grpc.MethodDescriptor.generateFullMethodName; - -import io.grpc.MethodDescriptor; -import io.opentelemetry.exporter.internal.grpc.MarshalerInputStream; -import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; -import io.opentelemetry.exporter.internal.marshal.Marshaler; -import java.io.InputStream; -import javax.annotation.Nullable; - -// Adapted from the protoc generated code for TraceServiceGrpc. -final class MarshalerTraceServiceGrpc { - - private static final String SERVICE_NAME = "opentelemetry.proto.collector.trace.v1.TraceService"; - - private static final MethodDescriptor.Marshaller REQUEST_MARSHALLER = - new MethodDescriptor.Marshaller() { - @Override - public InputStream stream(Marshaler value) { - return new MarshalerInputStream(value); - } - - @Override - public Marshaler parse(InputStream stream) { - throw new UnsupportedOperationException("Only for serializing"); - } - }; - - private static final MethodDescriptor.Marshaller RESPONSE_MARSHALER = - new MethodDescriptor.Marshaller() { - @Override - public InputStream stream(ExportTraceServiceResponse value) { - throw new UnsupportedOperationException("Only for parsing"); - } - - @Override - public ExportTraceServiceResponse parse(InputStream stream) { - return ExportTraceServiceResponse.INSTANCE; - } - }; - - private static final io.grpc.MethodDescriptor - getExportMethod = - io.grpc.MethodDescriptor.newBuilder() - .setType(io.grpc.MethodDescriptor.MethodType.UNARY) - .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Export")) - .setRequestMarshaller(REQUEST_MARSHALLER) - .setResponseMarshaller(RESPONSE_MARSHALER) - .build(); - - static TraceServiceFutureStub newFutureStub( - io.grpc.Channel channel, @Nullable String authorityOverride) { - return TraceServiceFutureStub.newStub( - (c, options) -> new TraceServiceFutureStub(c, options.withAuthority(authorityOverride)), - channel); - } - - static final class TraceServiceFutureStub - extends MarshalerServiceStub { - private TraceServiceFutureStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { - super(channel, callOptions); - } - - @java.lang.Override - protected MarshalerTraceServiceGrpc.TraceServiceFutureStub build( - io.grpc.Channel channel, io.grpc.CallOptions callOptions) { - return new MarshalerTraceServiceGrpc.TraceServiceFutureStub(channel, callOptions); - } - - @Override - public com.google.common.util.concurrent.ListenableFuture export( - Marshaler request) { - return io.grpc.stub.ClientCalls.futureUnaryCall( - getChannel().newCall(getExportMethod, getCallOptions()), request); - } - } - - private MarshalerTraceServiceGrpc() {} -} diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporter.java index 6d0d3d2fffa..5e0ee18759f 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporter.java @@ -7,7 +7,6 @@ import io.opentelemetry.exporter.internal.grpc.GrpcExporter; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; -import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.internal.otlp.traces.SpanReusableDataMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.MemoryMode; @@ -21,8 +20,8 @@ @ThreadSafe public final class OtlpGrpcSpanExporter implements SpanExporter { - private final GrpcExporterBuilder builder; - private final GrpcExporter delegate; + private final GrpcExporterBuilder builder; + private final GrpcExporter delegate; private final SpanReusableDataMarshaler marshaler; /** @@ -46,10 +45,7 @@ public static OtlpGrpcSpanExporterBuilder builder() { return new OtlpGrpcSpanExporterBuilder(); } - OtlpGrpcSpanExporter( - GrpcExporterBuilder builder, - GrpcExporter delegate, - MemoryMode memoryMode) { + OtlpGrpcSpanExporter(GrpcExporterBuilder builder, GrpcExporter delegate, MemoryMode memoryMode) { this.builder = builder; this.delegate = delegate; this.marshaler = new SpanReusableDataMarshaler(memoryMode, delegate::export); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java index fa7523b5b9e..ca1d51ad8ac 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java @@ -12,9 +12,8 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.common.ComponentLoader; -import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.compressor.Compressor; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; -import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; import io.opentelemetry.sdk.common.InternalTelemetryVersion; import io.opentelemetry.sdk.common.export.MemoryMode; @@ -35,8 +34,7 @@ public final class OtlpGrpcSpanExporterBuilder { // Visible for testing static final String GRPC_SERVICE_NAME = "opentelemetry.proto.collector.trace.v1.TraceService"; - // Visible for testing - static final String GRPC_ENDPOINT_PATH = "/" + GRPC_SERVICE_NAME + "/Export"; + private static final String GRPC_METHOD_NAME = "Export"; private static final String DEFAULT_ENDPOINT_URL = "http://localhost:4317"; private static final URI DEFAULT_ENDPOINT = URI.create(DEFAULT_ENDPOINT_URL); @@ -44,10 +42,10 @@ public final class OtlpGrpcSpanExporterBuilder { private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; // Visible for testing - final GrpcExporterBuilder delegate; + final GrpcExporterBuilder delegate; private MemoryMode memoryMode; - OtlpGrpcSpanExporterBuilder(GrpcExporterBuilder delegate, MemoryMode memoryMode) { + OtlpGrpcSpanExporterBuilder(GrpcExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; this.memoryMode = memoryMode; OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); @@ -55,12 +53,12 @@ public final class OtlpGrpcSpanExporterBuilder { OtlpGrpcSpanExporterBuilder() { this( - new GrpcExporterBuilder<>( + new GrpcExporterBuilder( StandardComponentId.ExporterType.OTLP_GRPC_SPAN_EXPORTER, DEFAULT_TIMEOUT_SECS, DEFAULT_ENDPOINT, - () -> MarshalerTraceServiceGrpc::newFutureStub, - GRPC_ENDPOINT_PATH), + GRPC_SERVICE_NAME, + GRPC_METHOD_NAME), DEFAULT_MEMORY_MODE); } diff --git a/exporters/otlp/all/src/testGrpcOkhttp/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcNettyOkHttpLogRecordExporterTest.java b/exporters/otlp/all/src/testGrpcOkhttp/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcOkHttpLogRecordExporterTest.java similarity index 96% rename from exporters/otlp/all/src/testGrpcOkhttp/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcNettyOkHttpLogRecordExporterTest.java rename to exporters/otlp/all/src/testGrpcOkhttp/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcOkHttpLogRecordExporterTest.java index bd55df876b7..3464b391bbf 100644 --- a/exporters/otlp/all/src/testGrpcOkhttp/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcNettyOkHttpLogRecordExporterTest.java +++ b/exporters/otlp/all/src/testGrpcOkhttp/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcOkHttpLogRecordExporterTest.java @@ -23,10 +23,10 @@ import java.util.List; import org.junit.jupiter.api.Test; -class OtlpGrpcNettyOkHttpLogRecordExporterTest +class OtlpGrpcOkHttpLogRecordExporterTest extends AbstractGrpcTelemetryExporterTest { - OtlpGrpcNettyOkHttpLogRecordExporterTest() { + OtlpGrpcOkHttpLogRecordExporterTest() { super("log", ResourceLogs.getDefaultInstance()); } diff --git a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/MarshalerInputStreamBenchmarks.java b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/MarshalerInputStreamBenchmarks.java index 1953abe3a24..c7cc935ff65 100644 --- a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/MarshalerInputStreamBenchmarks.java +++ b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/MarshalerInputStreamBenchmarks.java @@ -33,7 +33,8 @@ public class MarshalerInputStreamBenchmarks { @Threads(1) public void marshalToNettyBuffer(RequestMarshalState state) throws IOException { MarshalerInputStream stream = - new MarshalerInputStream(TraceRequestMarshaler.create(state.spanDataList)); + new MarshalerInputStream( + TraceRequestMarshaler.create(state.spanDataList).toGrpcRequestBodyWriter()); // Roughly reproduce how grpc-netty should behave. ByteBuf buf = PooledByteBufAllocator.DEFAULT.buffer(stream.available()); stream.drainTo(new ByteBufOutputStream(buf)); @@ -44,7 +45,8 @@ public void marshalToNettyBuffer(RequestMarshalState state) throws IOException { @Threads(1) public void marshalToByteArray(RequestMarshalState state) throws IOException { MarshalerInputStream stream = - new MarshalerInputStream(TraceRequestMarshaler.create(state.spanDataList)); + new MarshalerInputStream( + TraceRequestMarshaler.create(state.spanDataList).toGrpcRequestBodyWriter()); stream.drainTo(new ByteArrayOutputStream(stream.available())); } } diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/MarshalerProfilesServiceGrpc.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/MarshalerProfilesServiceGrpc.java deleted file mode 100644 index 6f0bdd6ae5d..00000000000 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/MarshalerProfilesServiceGrpc.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.otlp.profiles; - -import static io.grpc.MethodDescriptor.generateFullMethodName; - -import com.google.common.util.concurrent.ListenableFuture; -import io.grpc.CallOptions; -import io.grpc.Channel; -import io.grpc.MethodDescriptor; -import io.grpc.stub.ClientCalls; -import io.opentelemetry.exporter.internal.grpc.MarshalerInputStream; -import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; -import io.opentelemetry.exporter.internal.marshal.Marshaler; -import java.io.InputStream; -import javax.annotation.Nullable; - -// Adapted from the protoc generated code for ProfilesServiceGrpc. -final class MarshalerProfilesServiceGrpc { - - private static final String SERVICE_NAME = - "opentelemetry.proto.collector.profiles.v1development.ProfilesService"; - - private static final MethodDescriptor.Marshaller REQUEST_MARSHALLER = - new MethodDescriptor.Marshaller() { - @Override - public InputStream stream(Marshaler value) { - return new MarshalerInputStream(value); - } - - @Override - public Marshaler parse(InputStream stream) { - throw new UnsupportedOperationException("Only for serializing"); - } - }; - - private static final MethodDescriptor.Marshaller - RESPONSE_MARSHALER = - new MethodDescriptor.Marshaller() { - @Override - public InputStream stream(ExportProfilesServiceResponse value) { - throw new UnsupportedOperationException("Only for parsing"); - } - - @Override - public ExportProfilesServiceResponse parse(InputStream stream) { - return ExportProfilesServiceResponse.INSTANCE; - } - }; - - private static final MethodDescriptor getExportMethod = - MethodDescriptor.newBuilder() - .setType(MethodDescriptor.MethodType.UNARY) - .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Export")) - .setRequestMarshaller(REQUEST_MARSHALLER) - .setResponseMarshaller(RESPONSE_MARSHALER) - .build(); - - static ProfilesServiceFutureStub newFutureStub( - Channel channel, @Nullable String authorityOverride) { - return ProfilesServiceFutureStub.newStub( - (c, options) -> new ProfilesServiceFutureStub(c, options.withAuthority(authorityOverride)), - channel); - } - - static final class ProfilesServiceFutureStub - extends MarshalerServiceStub< - Marshaler, ExportProfilesServiceResponse, ProfilesServiceFutureStub> { - private ProfilesServiceFutureStub(Channel channel, CallOptions callOptions) { - super(channel, callOptions); - } - - @Override - protected MarshalerProfilesServiceGrpc.ProfilesServiceFutureStub build( - Channel channel, CallOptions callOptions) { - return new MarshalerProfilesServiceGrpc.ProfilesServiceFutureStub(channel, callOptions); - } - - @Override - public ListenableFuture export(Marshaler request) { - return ClientCalls.futureUnaryCall( - getChannel().newCall(getExportMethod, getCallOptions()), request); - } - } - - private MarshalerProfilesServiceGrpc() {} -} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfileExporter.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfileExporter.java index a598c8b1a84..3510b204293 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfileExporter.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfileExporter.java @@ -7,7 +7,6 @@ import io.opentelemetry.exporter.internal.grpc.GrpcExporter; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; -import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import java.util.Collection; import java.util.StringJoiner; @@ -17,8 +16,8 @@ @ThreadSafe public class OtlpGrpcProfileExporter implements ProfileExporter { - private final GrpcExporterBuilder builder; - private final GrpcExporter delegate; + private final GrpcExporterBuilder builder; + private final GrpcExporter delegate; /** * Returns a new {@link OtlpGrpcProfileExporter} using the default values. @@ -41,8 +40,7 @@ public static OtlpGrpcProfilesExporterBuilder builder() { return new OtlpGrpcProfilesExporterBuilder(); } - OtlpGrpcProfileExporter( - GrpcExporterBuilder builder, GrpcExporter delegate) { + OtlpGrpcProfileExporter(GrpcExporterBuilder builder, GrpcExporter delegate) { this.builder = builder; this.delegate = delegate; } diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java index 18e19ca51bd..0906a05186b 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java @@ -11,9 +11,8 @@ import io.grpc.ManagedChannel; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.common.ComponentLoader; -import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.compressor.Compressor; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; -import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.internal.StandardComponentId; @@ -30,11 +29,9 @@ /** Builder utility for this exporter. */ public final class OtlpGrpcProfilesExporterBuilder { - // Visible for testing - static final String GRPC_SERVICE_NAME = + private static final String GRPC_SERVICE_NAME = "opentelemetry.proto.collector.profiles.v1development.ProfilesService"; - // Visible for testing - static final String GRPC_ENDPOINT_PATH = "/" + GRPC_SERVICE_NAME + "/Export"; + private static final String GRPC_METHOD_NAME = "Export"; private static final String DEFAULT_ENDPOINT_URL = "http://localhost:4317"; private static final URI DEFAULT_ENDPOINT = URI.create(DEFAULT_ENDPOINT_URL); @@ -43,9 +40,9 @@ public final class OtlpGrpcProfilesExporterBuilder { // TODO maybe make more efficient by adding support for MEMORY_MODE // Visible for testing - final GrpcExporterBuilder delegate; + final GrpcExporterBuilder delegate; - OtlpGrpcProfilesExporterBuilder(GrpcExporterBuilder delegate) { + OtlpGrpcProfilesExporterBuilder(GrpcExporterBuilder delegate) { this.delegate = delegate; delegate.setMeterProvider(MeterProvider::noop); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); @@ -53,12 +50,12 @@ public final class OtlpGrpcProfilesExporterBuilder { OtlpGrpcProfilesExporterBuilder() { this( - new GrpcExporterBuilder<>( + new GrpcExporterBuilder( StandardComponentId.ExporterType.OTLP_GRPC_PROFILES_EXPORTER, DEFAULT_TIMEOUT_SECS, DEFAULT_ENDPOINT, - () -> MarshalerProfilesServiceGrpc::newFutureStub, - GRPC_ENDPOINT_PATH)); + GRPC_SERVICE_NAME, + GRPC_METHOD_NAME)); } /** diff --git a/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfileExporterTest.java b/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfileExporterTest.java index eec37eeab17..02049157d39 100644 --- a/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfileExporterTest.java +++ b/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfileExporterTest.java @@ -7,6 +7,7 @@ import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.exporter.grpc.GrpcStatusCode; import io.opentelemetry.exporter.internal.grpc.GrpcExporter; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.otlp.testing.internal.AbstractGrpcTelemetryExporterTest; @@ -41,7 +42,7 @@ void usingOkHttp() throws Exception { @Override // whilst profile signal type is in development it uses a different error message @SuppressLogger(GrpcExporter.class) protected void testExport_Unimplemented() { - addGrpcError(12, "UNIMPLEMENTED"); + addGrpcError(GrpcStatusCode.UNIMPLEMENTED, "UNIMPLEMENTED"); TelemetryExporter exporter = nonRetryingExporter(); diff --git a/exporters/otlp/testing-internal/build.gradle.kts b/exporters/otlp/testing-internal/build.gradle.kts index f4459686389..1d6bff53854 100644 --- a/exporters/otlp/testing-internal/build.gradle.kts +++ b/exporters/otlp/testing-internal/build.gradle.kts @@ -30,6 +30,7 @@ dependencies { implementation("com.squareup.okhttp3:okhttp") implementation("org.junit.jupiter:junit-jupiter-params") + implementation("com.linecorp.armeria:armeria-grpc") implementation("com.linecorp.armeria:armeria-grpc-protocol") implementation("com.linecorp.armeria:armeria-junit5") implementation("io.github.netmikey.logunit:logunit-jul") diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java index 908dd454631..8d822babf87 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java @@ -15,36 +15,41 @@ import static org.junit.jupiter.api.Named.named; import static org.junit.jupiter.params.provider.Arguments.arguments; -import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; import com.linecorp.armeria.common.HttpRequest; +import com.linecorp.armeria.common.HttpResponse; import com.linecorp.armeria.common.TlsKeyPair; import com.linecorp.armeria.common.grpc.protocol.ArmeriaStatusException; import com.linecorp.armeria.server.ServerBuilder; import com.linecorp.armeria.server.ServiceRequestContext; -import com.linecorp.armeria.server.grpc.protocol.AbstractUnaryGrpcService; -import com.linecorp.armeria.server.logging.LoggingService; +import com.linecorp.armeria.server.SimpleDecoratingHttpService; +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.github.netmikey.logunit.api.LogCapturer; +import io.grpc.Decompressor; +import io.grpc.DecompressorRegistry; import io.grpc.ManagedChannel; +import io.grpc.stub.StreamObserver; +import io.opentelemetry.exporter.grpc.GrpcResponse; +import io.opentelemetry.exporter.grpc.GrpcStatusCode; import io.opentelemetry.exporter.internal.FailedExportException; import io.opentelemetry.exporter.internal.TlsUtil; -import io.opentelemetry.exporter.internal.compression.GzipCompressor; import io.opentelemetry.exporter.internal.grpc.GrpcExporter; -import io.opentelemetry.exporter.internal.grpc.GrpcResponse; -import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; import io.opentelemetry.exporter.internal.marshal.Marshaler; -import io.opentelemetry.exporter.otlp.testing.internal.compressor.Base64Compressor; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest; import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceResponse; +import io.opentelemetry.proto.collector.logs.v1.LogsServiceGrpc; import io.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest; import io.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceResponse; +import io.opentelemetry.proto.collector.metrics.v1.MetricsServiceGrpc; import io.opentelemetry.proto.collector.profiles.v1development.ExportProfilesServiceRequest; import io.opentelemetry.proto.collector.profiles.v1development.ExportProfilesServiceResponse; +import io.opentelemetry.proto.collector.profiles.v1development.ProfilesServiceGrpc; 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.common.CompletableResultCode; import io.opentelemetry.sdk.common.InternalTelemetryVersion; import io.opentelemetry.sdk.common.export.RetryPolicy; @@ -55,6 +60,7 @@ import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.UncheckedIOException; import java.lang.reflect.Field; import java.net.URL; @@ -64,16 +70,14 @@ import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; +import java.util.Base64; import java.util.Collections; import java.util.Enumeration; import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.Nullable; @@ -84,7 +88,6 @@ import javax.net.ssl.X509TrustManager; import org.assertj.core.api.Assertions; import org.assertj.core.api.InstanceOfAssertFactories; -import org.assertj.core.api.iterable.ThrowingExtractor; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; @@ -132,71 +135,110 @@ public abstract class AbstractGrpcTelemetryExporterTest { @Override protected void configure(ServerBuilder sb) { sb.service( - "/opentelemetry.proto.collector.trace.v1.TraceService/Export", - new CollectorService<>( - ExportTraceServiceRequest::parseFrom, - ExportTraceServiceRequest::getResourceSpansList, - ExportTraceServiceResponse.getDefaultInstance().toByteArray())); - sb.service( - "/opentelemetry.proto.collector.metrics.v1.MetricsService/Export", - new CollectorService<>( - ExportMetricsServiceRequest::parseFrom, - ExportMetricsServiceRequest::getResourceMetricsList, - ExportMetricsServiceResponse.getDefaultInstance().toByteArray())); - sb.service( - "/opentelemetry.proto.collector.logs.v1.LogsService/Export", - new CollectorService<>( - ExportLogsServiceRequest::parseFrom, - ExportLogsServiceRequest::getResourceLogsList, - ExportLogsServiceResponse.getDefaultInstance().toByteArray())); - sb.service( - "/opentelemetry.proto.collector.profiles.v1development.ProfilesService/Export", - new CollectorService<>( - ExportProfilesServiceRequest::parseFrom, - ExportProfilesServiceRequest::getResourceProfilesList, - ExportProfilesServiceResponse.getDefaultInstance().toByteArray())); + GrpcService.builder() + .addService( + new LogsServiceGrpc.LogsServiceImplBase() { + @Override + public void export( + ExportLogsServiceRequest request, + StreamObserver responseObserver) { + exportedResourceTelemetry.addAll(request.getResourceLogsList()); + ArmeriaStatusException grpcError = grpcErrors.poll(); + if (grpcError != null) { + responseObserver.onError(grpcError); + } else { + responseObserver.onNext(ExportLogsServiceResponse.getDefaultInstance()); + responseObserver.onCompleted(); + } + } + }) + .addService( + new MetricsServiceGrpc.MetricsServiceImplBase() { + @Override + public void export( + ExportMetricsServiceRequest request, + StreamObserver responseObserver) { + exportedResourceTelemetry.addAll(request.getResourceMetricsList()); + ArmeriaStatusException grpcError = grpcErrors.poll(); + if (grpcError != null) { + responseObserver.onError(grpcError); + } else { + responseObserver.onNext( + ExportMetricsServiceResponse.getDefaultInstance()); + responseObserver.onCompleted(); + } + } + }) + .addService( + new TraceServiceGrpc.TraceServiceImplBase() { + @Override + public void export( + ExportTraceServiceRequest request, + StreamObserver responseObserver) { + exportedResourceTelemetry.addAll(request.getResourceSpansList()); + ArmeriaStatusException grpcError = grpcErrors.poll(); + if (grpcError != null) { + responseObserver.onError(grpcError); + } else { + responseObserver.onNext( + ExportTraceServiceResponse.getDefaultInstance()); + responseObserver.onCompleted(); + } + } + }) + .addService( + new ProfilesServiceGrpc.ProfilesServiceImplBase() { + @Override + public void export( + ExportProfilesServiceRequest request, + StreamObserver responseObserver) { + exportedResourceTelemetry.addAll(request.getResourceProfilesList()); + ArmeriaStatusException grpcError = grpcErrors.poll(); + if (grpcError != null) { + responseObserver.onError(grpcError); + } else { + responseObserver.onNext( + ExportProfilesServiceResponse.getDefaultInstance()); + responseObserver.onCompleted(); + } + } + }) + .decompressorRegistry( + DecompressorRegistry.getDefaultInstance() + .with( + new Decompressor() { + @Override + public String getMessageEncoding() { + return "base64"; + } + + @Override + public InputStream decompress(InputStream is) { + return Base64.getDecoder().wrap(is); + } + }, + true)) + .build(), + service -> + new SimpleDecoratingHttpService(service) { + @Override + public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) + throws Exception { + httpRequests.add(req); + attempts.incrementAndGet(); + return unwrap().serve(ctx, req); + } + }); sb.http(0); sb.https(0); sb.tls(TlsKeyPair.of(certificate.privateKey(), certificate.certificate())); sb.tlsCustomizer(ssl -> ssl.trustManager(clientCertificate.certificate())); - sb.decorator(LoggingService.newDecorator()); + // Uncomment for detailed request / response logs from server + // sb.decorator(LoggingService.newDecorator()); } }; - private static class CollectorService extends AbstractUnaryGrpcService { - private final ThrowingExtractor parse; - private final Function> getResourceTelemetry; - private final byte[] successResponse; - - private CollectorService( - ThrowingExtractor parse, - Function> getResourceTelemetry, - byte[] successResponse) { - this.parse = parse; - this.getResourceTelemetry = getResourceTelemetry; - this.successResponse = successResponse; - } - - @Override - protected CompletionStage handleMessage(ServiceRequestContext ctx, byte[] message) { - httpRequests.add(ctx.request()); - attempts.incrementAndGet(); - T request; - try { - request = parse.extractThrows(message); - } catch (InvalidProtocolBufferException e) { - throw new UncheckedIOException(e); - } - exportedResourceTelemetry.addAll(getResourceTelemetry.apply(request)); - ArmeriaStatusException grpcError = grpcErrors.poll(); - if (grpcError != null) { - throw grpcError; - } - return CompletableFuture.completedFuture(successResponse); - } - } - @RegisterExtension protected LogCapturer logs = LogCapturer.create().captureForType(GrpcExporter.class); @@ -268,10 +310,9 @@ void minimalChannel() { assertThat(exporter.shutdown().join(10, TimeUnit.SECONDS).isSuccess()).isTrue(); assertThat(exporter.unwrap()) .extracting( - "delegate.grpcSender.stub", - as(InstanceOfAssertFactories.type(MarshalerServiceStub.class))) - .satisfies( - stub -> assertThat(((ManagedChannel) stub.getChannel()).isShutdown()).isTrue()); + "delegate.grpcSender.channel", + as(InstanceOfAssertFactories.type(ManagedChannel.class))) + .satisfies(channel -> assertThat(channel.isShutdown()).isTrue()); } } @@ -306,11 +347,16 @@ void multipleItems() { void compressionWithNone() { try (TelemetryExporter exporter = exporterBuilder().setEndpoint(server.httpUri().toString()).setCompression("none").build()) { - // UpstreamGrpcSender doesn't support compression, so we skip the assertion - assumeThat(exporter.unwrap()) - .extracting("delegate.grpcSender") - .matches(sender -> sender.getClass().getSimpleName().equals("OkHttpGrpcSender")); - assertThat(exporter.unwrap()).extracting("delegate.grpcSender.compressor").isNull(); + + assertThat( + exporter + .export(Collections.singletonList(generateFakeTelemetry())) + .join(10, TimeUnit.SECONDS) + .isSuccess()) + .isTrue(); + assertThat(httpRequests) + .singleElement() + .satisfies(req -> assertThat(req.headers().get("grpc-encoding")).isNull()); } } @@ -318,13 +364,16 @@ void compressionWithNone() { void compressionWithGzip() { try (TelemetryExporter exporter = exporterBuilder().setEndpoint(server.httpUri().toString()).setCompression("gzip").build()) { - // UpstreamGrpcSender doesn't support compression, so we skip the assertion - assumeThat(exporter.unwrap()) - .extracting("delegate.grpcSender") - .matches(sender -> sender.getClass().getSimpleName().equals("OkHttpGrpcSender")); - assertThat(exporter.unwrap()) - .extracting("delegate.grpcSender.compressor") - .isEqualTo(GzipCompressor.getInstance()); + + assertThat( + exporter + .export(Collections.singletonList(generateFakeTelemetry())) + .join(10, TimeUnit.SECONDS) + .isSuccess()) + .isTrue(); + assertThat(httpRequests) + .singleElement() + .satisfies(req -> assertThat(req.headers().get("grpc-encoding")).isEqualTo("gzip")); } } @@ -335,13 +384,15 @@ void compressionWithSpiCompressor() { .setEndpoint(server.httpUri().toString()) .setCompression("base64") .build()) { - // UpstreamGrpcSender doesn't support compression, so we skip the assertion - assumeThat(exporter.unwrap()) - .extracting("delegate.grpcSender") - .matches(sender -> sender.getClass().getSimpleName().equals("OkHttpGrpcSender")); - assertThat(exporter.unwrap()) - .extracting("delegate.grpcSender.compressor") - .isEqualTo(Base64Compressor.getInstance()); + assertThat( + exporter + .export(Collections.singletonList(generateFakeTelemetry())) + .join(10, TimeUnit.SECONDS) + .isSuccess()) + .isTrue(); + assertThat(httpRequests) + .singleElement() + .satisfies(req -> assertThat(req.headers().get("grpc-encoding")).isEqualTo("base64")); } } @@ -550,7 +601,7 @@ void doubleShutdown() { @Test @SuppressLogger(GrpcExporter.class) void error() { - int statusCode = 13; + GrpcStatusCode statusCode = GrpcStatusCode.INTERNAL; addGrpcError(statusCode, null); try (TelemetryExporter exporter = nonRetryingExporter()) { @@ -569,7 +620,7 @@ void error() { ex -> { assertThat(ex.getResponse()) .isNotNull() - .extracting(GrpcResponse::grpcStatusValue) + .extracting(GrpcResponse::getStatusCode) .isEqualTo(statusCode); assertThat(ex.getCause()).isNull(); @@ -587,7 +638,7 @@ void error() { @Test @SuppressLogger(GrpcExporter.class) void errorWithUnknownError() { - addGrpcError(2, null); + addGrpcError(GrpcStatusCode.UNKNOWN, null); try (TelemetryExporter exporter = nonRetryingExporter()) { assertThat( @@ -610,7 +661,7 @@ void errorWithUnknownError() { @Test @SuppressLogger(GrpcExporter.class) void errorWithMessage() { - addGrpcError(8, "out of quota"); + addGrpcError(GrpcStatusCode.RESOURCE_EXHAUSTED, "out of quota"); try (TelemetryExporter exporter = nonRetryingExporter()) { assertThat( @@ -631,7 +682,7 @@ void errorWithMessage() { @Test @SuppressLogger(GrpcExporter.class) void errorWithEscapedMessage() { - addGrpcError(5, "クマ🐻"); + addGrpcError(GrpcStatusCode.NOT_FOUND, "クマ🐻"); try (TelemetryExporter exporter = nonRetryingExporter()) { assertThat( @@ -652,7 +703,7 @@ void errorWithEscapedMessage() { @Test @SuppressLogger(GrpcExporter.class) void testExport_Unavailable() { - addGrpcError(14, null); + addGrpcError(GrpcStatusCode.UNAVAILABLE, null); try (TelemetryExporter exporter = nonRetryingExporter()) { assertThat( @@ -674,7 +725,7 @@ void testExport_Unavailable() { @Test @SuppressLogger(GrpcExporter.class) protected void testExport_Unimplemented() { - addGrpcError(12, "UNIMPLEMENTED"); + addGrpcError(GrpcStatusCode.UNIMPLEMENTED, "UNIMPLEMENTED"); try (TelemetryExporter exporter = nonRetryingExporter()) { assertThat( @@ -720,7 +771,7 @@ protected void testExport_Unimplemented() { @ValueSource(ints = {1, 4, 8, 10, 11, 14, 15}) @SuppressLogger(GrpcExporter.class) void retryableError(int code) { - addGrpcError(code, null); + addGrpcError(GrpcStatusCode.fromValue(code), null); assertThat( exporter @@ -735,8 +786,8 @@ void retryableError(int code) { @Test @SuppressLogger(GrpcExporter.class) void retryableError_tooManyAttempts() { - addGrpcError(1, null); - addGrpcError(1, null); + addGrpcError(GrpcStatusCode.CANCELLED, null); + addGrpcError(GrpcStatusCode.CANCELLED, null); assertThat( exporter @@ -752,7 +803,7 @@ void retryableError_tooManyAttempts() { @ValueSource(ints = {2, 3, 5, 6, 7, 9, 12, 13, 16}) @SuppressLogger(GrpcExporter.class) void nonRetryableError(int code) { - addGrpcError(code, null); + addGrpcError(GrpcStatusCode.fromValue(code), null); assertThat( exporter @@ -877,7 +928,7 @@ void customServiceClassLoader() { assertThat(classLoaderSpy.getResourcesNames) .isEqualTo( Collections.singletonList( - "META-INF/services/io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider")); + "META-INF/services/io.opentelemetry.exporter.grpc.GrpcSenderProvider")); } } @@ -1018,7 +1069,8 @@ void stringRepresentation() throws IOException, CertificateEncodingException { .matches( "OtlpGrpc[a-zA-Z]*Exporter\\{" + "endpoint=http://localhost:4317, " - + "endpointPath=.*, " + + "fullServiceName=.*, " + + "methodName=.*, " + "timeoutNanos=" + TimeUnit.SECONDS.toNanos(10) + ", " @@ -1054,7 +1106,8 @@ void stringRepresentation() throws IOException, CertificateEncodingException { .matches( "OtlpGrpc[a-zA-Z]*Exporter\\{" + "endpoint=http://example:4317, " - + "endpointPath=.*, " + + "fullServiceName=.*, " + + "methodName=.*, " + "timeoutNanos=" + TimeUnit.SECONDS.toNanos(5) + ", " @@ -1221,7 +1274,7 @@ protected TelemetryExporter nonRetryingExporter() { return exporterBuilder().setEndpoint(server.httpUri().toString()).setRetryPolicy(null).build(); } - protected static void addGrpcError(int code, @Nullable String message) { - grpcErrors.add(new ArmeriaStatusException(code, message)); + protected static void addGrpcError(GrpcStatusCode code, @Nullable String message) { + grpcErrors.add(new ArmeriaStatusException(code.getValue(), message)); } } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java index 4714ea5a542..2e23599ee69 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java @@ -30,11 +30,8 @@ import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.internal.FailedExportException; import io.opentelemetry.exporter.internal.TlsUtil; -import io.opentelemetry.exporter.internal.compression.GzipCompressor; import io.opentelemetry.exporter.internal.http.HttpExporter; -import io.opentelemetry.exporter.internal.http.HttpSender; import io.opentelemetry.exporter.internal.marshal.Marshaler; -import io.opentelemetry.exporter.otlp.testing.internal.compressor.Base64Compressor; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest; import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceResponse; @@ -315,7 +312,6 @@ void multipleItems() { void compressionWithNone() { try (TelemetryExporter exporter = exporterBuilder().setEndpoint(server.httpUri() + path).setCompression("none").build()) { - assertThat(exporter.unwrap()).extracting("delegate.httpSender.compressor").isNull(); CompletableResultCode result = exporter.export(Collections.singletonList(generateFakeTelemetry())); @@ -330,9 +326,6 @@ void compressionWithNone() { void compressionWithGzip() { try (TelemetryExporter exporter = exporterBuilder().setEndpoint(server.httpUri() + path).setCompression("gzip").build()) { - assertThat(exporter.unwrap()) - .extracting("delegate.httpSender.compressor") - .isEqualTo(GzipCompressor.getInstance()); CompletableResultCode result = exporter.export(Collections.singletonList(generateFakeTelemetry())); @@ -347,9 +340,6 @@ void compressionWithGzip() { void compressionWithSpiCompressor() { try (TelemetryExporter exporter = exporterBuilder().setEndpoint(server.httpUri() + path).setCompression("base64").build()) { - assertThat(exporter.unwrap()) - .extracting("delegate.httpSender.compressor") - .isEqualTo(Base64Compressor.getInstance()); CompletableResultCode result = exporter.export(Collections.singletonList(generateFakeTelemetry())); @@ -582,10 +572,10 @@ void error() { .satisfies( response -> { assertThat(response) - .extracting(HttpSender.Response::statusCode) + .extracting(io.opentelemetry.exporter.http.HttpResponse::getStatusCode) .isEqualTo(statusCode); - assertThatCode(response::responseBody).doesNotThrowAnyException(); + assertThatCode(response::getResponseBody).doesNotThrowAnyException(); }); assertThat(ex.getCause()).isNull(); @@ -887,7 +877,7 @@ void customServiceClassLoader() { assertThat(classLoaderSpy.getResourcesNames) .isEqualTo( Collections.singletonList( - "META-INF/services/io.opentelemetry.exporter.internal.http.HttpSenderProvider")); + "META-INF/services/io.opentelemetry.exporter.http.HttpSenderProvider")); } } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/compressor/Base64Compressor.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/compressor/Base64Compressor.java index b0b3121d635..77c207bc883 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/compressor/Base64Compressor.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/compressor/Base64Compressor.java @@ -5,7 +5,7 @@ package io.opentelemetry.exporter.otlp.testing.internal.compressor; -import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.compressor.Compressor; import java.io.OutputStream; import java.util.Base64; diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/compressor/Base64CompressorProvider.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/compressor/Base64CompressorProvider.java index 8d4b4a6cdbc..e0977043c20 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/compressor/Base64CompressorProvider.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/compressor/Base64CompressorProvider.java @@ -5,8 +5,8 @@ package io.opentelemetry.exporter.otlp.testing.internal.compressor; -import io.opentelemetry.exporter.internal.compression.Compressor; -import io.opentelemetry.exporter.internal.compression.CompressorProvider; +import io.opentelemetry.exporter.compressor.Compressor; +import io.opentelemetry.exporter.compressor.CompressorProvider; public class Base64CompressorProvider implements CompressorProvider { diff --git a/exporters/otlp/testing-internal/src/main/resources/META-INF/services/io.opentelemetry.exporter.internal.compression.CompressorProvider b/exporters/otlp/testing-internal/src/main/resources/META-INF/services/io.opentelemetry.exporter.compressor.CompressorProvider similarity index 100% rename from exporters/otlp/testing-internal/src/main/resources/META-INF/services/io.opentelemetry.exporter.internal.compression.CompressorProvider rename to exporters/otlp/testing-internal/src/main/resources/META-INF/services/io.opentelemetry.exporter.compressor.CompressorProvider diff --git a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java index 85a677d1894..7bf0687c3e9 100644 --- a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java +++ b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java @@ -5,20 +5,34 @@ package io.opentelemetry.exporter.sender.grpc.managedchannel.internal; +import static io.grpc.MethodDescriptor.generateFullMethodName; + import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.MoreExecutors; +import io.grpc.CallOptions; +import io.grpc.Channel; +import io.grpc.ClientInterceptors; +import io.grpc.Compressor; +import io.grpc.CompressorRegistry; import io.grpc.ManagedChannel; import io.grpc.Metadata; +import io.grpc.MethodDescriptor; import io.grpc.Status; import io.grpc.StatusException; import io.grpc.StatusRuntimeException; +import io.grpc.stub.ClientCalls; import io.grpc.stub.MetadataUtils; -import io.opentelemetry.exporter.internal.grpc.GrpcResponse; -import io.opentelemetry.exporter.internal.grpc.GrpcSender; -import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; -import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.grpc.GrpcMessageWriter; +import io.opentelemetry.exporter.grpc.GrpcResponse; +import io.opentelemetry.exporter.grpc.GrpcSender; +import io.opentelemetry.exporter.grpc.GrpcStatusCode; +import io.opentelemetry.exporter.internal.grpc.ImmutableGrpcResponse; +import io.opentelemetry.exporter.internal.grpc.MarshalerInputStream; import io.opentelemetry.sdk.common.CompletableResultCode; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.time.Duration; import java.util.List; import java.util.Map; @@ -34,9 +48,37 @@ *

This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ -public final class UpstreamGrpcSender implements GrpcSender { +public final class UpstreamGrpcSender implements GrpcSender { + + private static final MethodDescriptor.Marshaller REQUEST_MARSHALER = + new MethodDescriptor.Marshaller() { + @Override + public InputStream stream(GrpcMessageWriter value) { + return new MarshalerInputStream(value); + } + + @Override + public GrpcMessageWriter parse(InputStream stream) { + throw new UnsupportedOperationException("Only for serializing"); + } + }; + + private static final MethodDescriptor.Marshaller RESPONSE_MARSHALER = + new MethodDescriptor.Marshaller() { + @Override + public InputStream stream(byte[] value) { + throw new UnsupportedOperationException("Only for parsing"); + } + + @Override + public byte[] parse(InputStream stream) { + return new byte[] {}; // TODO: drain input to byte array + } + }; - private final MarshalerServiceStub stub; + private final ManagedChannel channel; + private final MethodDescriptor methodDescriptor; + @Nullable private final String compressorName; private final boolean shutdownChannel; private final long timeoutNanos; private final Supplier>> headersSupplier; @@ -44,12 +86,40 @@ public final class UpstreamGrpcSender implements GrpcSender /** Creates a new {@link UpstreamGrpcSender}. */ public UpstreamGrpcSender( - MarshalerServiceStub stub, + ManagedChannel channel, + String fullServiceName, + String methodName, + @Nullable io.opentelemetry.exporter.compressor.Compressor compressor, boolean shutdownChannel, long timeoutNanos, Supplier>> headersSupplier, @Nullable ExecutorService executorService) { - this.stub = stub; + this.channel = channel; + this.methodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(fullServiceName, methodName)) + .setRequestMarshaller(REQUEST_MARSHALER) + .setResponseMarshaller(RESPONSE_MARSHALER) + .build(); + if (compressor != null) { + CompressorRegistry.getDefaultInstance() + .register( + new Compressor() { + @Override + public String getMessageEncoding() { + return compressor.getEncoding(); + } + + @Override + public OutputStream compress(OutputStream os) throws IOException { + return compressor.compress(os); + } + }); + this.compressorName = compressor.getEncoding(); + } else { + this.compressorName = null; + } this.shutdownChannel = shutdownChannel; this.timeoutNanos = timeoutNanos; this.headersSupplier = headersSupplier; @@ -57,29 +127,48 @@ public UpstreamGrpcSender( } @Override - public void send(T request, Consumer onResponse, Consumer onError) { - MarshalerServiceStub stub = this.stub; + public void send( + GrpcMessageWriter messageWriter, + Consumer onResponse, + Consumer onError) { + CallOptions requestCallOptions = CallOptions.DEFAULT; + Channel requestChannel = channel; if (timeoutNanos > 0) { - stub = stub.withDeadlineAfter(Duration.ofNanos(timeoutNanos)); + requestCallOptions = requestCallOptions.withDeadlineAfter(Duration.ofNanos(timeoutNanos)); } + Metadata metadata = new Metadata(); Map> headers = headersSupplier.get(); if (headers != null) { - Metadata metadata = new Metadata(); for (Map.Entry> entry : headers.entrySet()) { metadata.put( Metadata.Key.of(entry.getKey(), Metadata.ASCII_STRING_MARSHALLER), String.join(",", entry.getValue())); } - stub = stub.withInterceptors(MetadataUtils.newAttachHeadersInterceptor(metadata)); + requestChannel = + ClientInterceptors.intercept( + requestChannel, MetadataUtils.newAttachHeadersInterceptor(metadata)); + + List hostHeaders = headers.get("host"); + if (hostHeaders != null && !hostHeaders.isEmpty()) { + requestCallOptions = requestCallOptions.withAuthority(hostHeaders.get(0)); + } + } + if (this.compressorName != null) { + requestCallOptions = requestCallOptions.withCompression(compressorName); } Futures.addCallback( - stub.export(request), - new FutureCallback() { + ClientCalls.futureUnaryCall( + requestChannel.newCall(methodDescriptor, requestCallOptions), messageWriter), + new FutureCallback() { @Override - public void onSuccess(@Nullable Object unused) { + public void onSuccess(@Nullable byte[] result) { + // TODO: evaluate null case onResponse.accept( - GrpcResponse.create(Status.OK.getCode().value(), Status.OK.getDescription())); + ImmutableGrpcResponse.create( + GrpcStatusCode.OK, + Status.OK.getDescription(), + result == null ? new byte[0] : result)); } @Override @@ -89,7 +178,10 @@ public void onFailure(Throwable t) { onError.accept(t); } else { onResponse.accept( - GrpcResponse.create(status.getCode().value(), status.getDescription())); + ImmutableGrpcResponse.create( + GrpcStatusCode.fromValue(status.getCode().value()), + status.getDescription(), + new byte[0])); } } }, @@ -116,7 +208,6 @@ private static Status fromThrowable(Throwable cause) { @Override public CompletableResultCode shutdown() { if (shutdownChannel) { - ManagedChannel channel = (ManagedChannel) stub.getChannel(); channel.shutdownNow(); } return CompletableResultCode.ofSuccess(); diff --git a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java index 3b26aeedbfd..66e577bf7ac 100644 --- a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java +++ b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java @@ -5,22 +5,13 @@ package io.opentelemetry.exporter.sender.grpc.managedchannel.internal; -import io.grpc.Channel; -import io.grpc.Codec; -import io.grpc.CompressorRegistry; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; -import io.opentelemetry.exporter.internal.compression.Compressor; -import io.opentelemetry.exporter.internal.grpc.GrpcSender; -import io.opentelemetry.exporter.internal.grpc.GrpcSenderConfig; -import io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider; -import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; -import io.opentelemetry.exporter.internal.marshal.Marshaler; -import java.io.IOException; -import java.io.OutputStream; +import io.opentelemetry.exporter.grpc.GrpcSender; +import io.opentelemetry.exporter.grpc.GrpcSenderConfig; +import io.opentelemetry.exporter.grpc.GrpcSenderProvider; +import io.opentelemetry.exporter.internal.grpc.ExtendedGrpcSenderConfig; import java.net.URI; -import java.util.List; -import java.util.Map; /** * {@link GrpcSender} SPI implementation for {@link UpstreamGrpcSender}. @@ -31,57 +22,35 @@ public class UpstreamGrpcSenderProvider implements GrpcSenderProvider { @Override - public GrpcSender createSender(GrpcSenderConfig grpcSenderConfig) { + public GrpcSender createSender(GrpcSenderConfig grpcSenderConfig) { + if (!(grpcSenderConfig instanceof ExtendedGrpcSenderConfig)) { + throw new IllegalStateException("TODO"); + } + ExtendedGrpcSenderConfig extendedSenderConfig = (ExtendedGrpcSenderConfig) grpcSenderConfig; + boolean shutdownChannel = false; - Object managedChannel = grpcSenderConfig.getManagedChannel(); - if (managedChannel == null) { + Object configManagedChannel = extendedSenderConfig.getMangedChannel(); + ManagedChannel managedChannel; + if (configManagedChannel != null) { + if (!(configManagedChannel instanceof ManagedChannel)) { + throw new IllegalStateException("TODO"); + } + managedChannel = (ManagedChannel) configManagedChannel; + } else { // Shutdown the channel as part of the exporter shutdown sequence if shutdownChannel = true; managedChannel = minimalFallbackManagedChannel(grpcSenderConfig.getEndpoint()); } - String authorityOverride = null; - Map> headers = grpcSenderConfig.getHeadersSupplier().get(); - if (headers != null) { - for (Map.Entry> entry : headers.entrySet()) { - if (entry.getKey().equals("host") && !entry.getValue().isEmpty()) { - authorityOverride = entry.getValue().get(0); - } - } - } - - String compression = Codec.Identity.NONE.getMessageEncoding(); - Compressor compressor = grpcSenderConfig.getCompressor(); - if (compressor != null) { - CompressorRegistry.getDefaultInstance() - .register( - new io.grpc.Compressor() { - @Override - public String getMessageEncoding() { - return compressor.getEncoding(); - } - - @Override - public OutputStream compress(OutputStream os) throws IOException { - return compressor.compress(os); - } - }); - compression = compressor.getEncoding(); - } - - MarshalerServiceStub stub = - grpcSenderConfig - .getStubFactory() - .get() - .apply((Channel) managedChannel, authorityOverride) - .withCompression(compression); - - return new UpstreamGrpcSender<>( - stub, + return new UpstreamGrpcSender( + managedChannel, + extendedSenderConfig.getFullServiceName(), + extendedSenderConfig.getMethodName(), + extendedSenderConfig.getCompressor(), shutdownChannel, - grpcSenderConfig.getTimeoutNanos(), - grpcSenderConfig.getHeadersSupplier(), - grpcSenderConfig.getExecutorService()); + extendedSenderConfig.getTimeoutNanos(), + extendedSenderConfig.getHeadersSupplier(), + extendedSenderConfig.getExecutorService()); } /** diff --git a/exporters/sender/grpc-managed-channel/src/main/resources/META-INF/services/io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider b/exporters/sender/grpc-managed-channel/src/main/resources/META-INF/services/io.opentelemetry.exporter.grpc.GrpcSenderProvider similarity index 100% rename from exporters/sender/grpc-managed-channel/src/main/resources/META-INF/services/io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider rename to exporters/sender/grpc-managed-channel/src/main/resources/META-INF/services/io.opentelemetry.exporter.grpc.GrpcSenderProvider diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java index 4f1f91e7619..4f3305dc08a 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java @@ -7,9 +7,9 @@ import static java.util.stream.Collectors.joining; -import io.opentelemetry.exporter.internal.compression.Compressor; -import io.opentelemetry.exporter.internal.http.HttpSender; -import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.compressor.Compressor; +import io.opentelemetry.exporter.http.HttpRequestBodyWriter; +import io.opentelemetry.exporter.http.HttpSender; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; @@ -19,7 +19,6 @@ import java.io.OutputStream; import java.io.UncheckedIOException; import java.net.URI; -import java.net.URISyntaxException; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; @@ -66,10 +65,9 @@ public final class JdkHttpSender implements HttpSender { private final boolean managedExecutor; private final ExecutorService executorService; private final HttpClient client; - private final URI uri; - @Nullable private final Compressor compressor; - private final boolean exportAsJson; + private final URI endpoint; private final String contentType; + @Nullable private final Compressor compressor; private final long timeoutNanos; private final Supplier>> headerSupplier; @Nullable private final RetryPolicy retryPolicy; @@ -78,23 +76,17 @@ public final class JdkHttpSender implements HttpSender { // Visible for testing JdkHttpSender( HttpClient client, - String endpoint, - @Nullable Compressor compressor, - boolean exportAsJson, + URI endpoint, String contentType, + @Nullable Compressor compressor, long timeoutNanos, Supplier>> headerSupplier, @Nullable RetryPolicy retryPolicy, @Nullable ExecutorService executorService) { this.client = client; - try { - this.uri = new URI(endpoint); - } catch (URISyntaxException e) { - throw new IllegalArgumentException(e); - } - this.compressor = compressor; - this.exportAsJson = exportAsJson; + this.endpoint = endpoint; this.contentType = contentType; + this.compressor = compressor; this.timeoutNanos = timeoutNanos; this.headerSupplier = headerSupplier; this.retryPolicy = retryPolicy; @@ -112,10 +104,9 @@ public final class JdkHttpSender implements HttpSender { } JdkHttpSender( - String endpoint, - @Nullable Compressor compressor, - boolean exportAsJson, + URI endpoint, String contentType, + @Nullable Compressor compressor, long timeoutNanos, long connectTimeoutNanos, Supplier>> headerSupplier, @@ -126,9 +117,8 @@ public final class JdkHttpSender implements HttpSender { this( configureClient(sslContext, connectTimeoutNanos, proxyOptions), endpoint, - compressor, - exportAsJson, contentType, + compressor, timeoutNanos, headerSupplier, retryPolicy, @@ -162,15 +152,14 @@ private static HttpClient configureClient( @Override public void send( - Marshaler marshaler, - int contentLength, - Consumer onResponse, + HttpRequestBodyWriter requestBodyWriter, + Consumer onResponse, Consumer onError) { CompletableFuture> unused = CompletableFuture.supplyAsync( () -> { try { - return sendInternal(marshaler); + return sendInternal(requestBodyWriter); } catch (IOException e) { throw new UncheckedIOException(e); } @@ -187,10 +176,10 @@ public void send( } // Visible for testing - HttpResponse sendInternal(Marshaler marshaler) throws IOException { + HttpResponse sendInternal(HttpRequestBodyWriter requestBodyWriter) throws IOException { long startTimeNanos = System.nanoTime(); HttpRequest.Builder requestBuilder = - HttpRequest.newBuilder().uri(uri).timeout(Duration.ofNanos(timeoutNanos)); + HttpRequest.newBuilder().uri(endpoint).timeout(Duration.ofNanos(timeoutNanos)); Map> headers = headerSupplier.get(); if (headers != null) { headers.forEach((key, values) -> values.forEach(value -> requestBuilder.header(key, value))); @@ -202,12 +191,12 @@ HttpResponse sendInternal(Marshaler marshaler) throws IOException { if (compressor != null) { requestBuilder.header("Content-Encoding", compressor.getEncoding()); try (OutputStream compressed = compressor.compress(os)) { - write(marshaler, compressed); + requestBodyWriter.writeRequestBody(compressed); } catch (IOException e) { throw new IllegalStateException(e); } } else { - write(marshaler, os); + requestBodyWriter.writeRequestBody(os); } ByteBufferPool byteBufferPool = threadLocalByteBufPool.get(); @@ -297,14 +286,6 @@ private static String responseStringRepresentation(HttpResponse response) { return joiner.toString(); } - private void write(Marshaler marshaler, OutputStream os) throws IOException { - if (exportAsJson) { - marshaler.writeJsonTo(os); - } else { - marshaler.writeBinaryTo(os); - } - } - private HttpResponse sendRequest( HttpRequest.Builder requestBuilder, ByteBufferPool byteBufferPool) throws IOException { try { @@ -340,20 +321,21 @@ private byte[] buf() { } } - private static Response toHttpResponse(HttpResponse response) { - return new Response() { + private static io.opentelemetry.exporter.http.HttpResponse toHttpResponse( + HttpResponse response) { + return new io.opentelemetry.exporter.http.HttpResponse() { @Override - public int statusCode() { + public int getStatusCode() { return response.statusCode(); } @Override - public String statusMessage() { + public String getStatusMessage() { return String.valueOf(response.statusCode()); } @Override - public byte[] responseBody() { + public byte[] getResponseBody() { return response.body(); } }; diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java index 35b7f819aa2..1054fdb6d34 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java @@ -5,9 +5,9 @@ package io.opentelemetry.exporter.sender.jdk.internal; -import io.opentelemetry.exporter.internal.http.HttpSender; -import io.opentelemetry.exporter.internal.http.HttpSenderConfig; -import io.opentelemetry.exporter.internal.http.HttpSenderProvider; +import io.opentelemetry.exporter.http.HttpSender; +import io.opentelemetry.exporter.http.HttpSenderConfig; +import io.opentelemetry.exporter.http.HttpSenderProvider; /** * {@link HttpSender} SPI implementation for {@link JdkHttpSender}. @@ -21,9 +21,8 @@ public final class JdkHttpSenderProvider implements HttpSenderProvider { public HttpSender createSender(HttpSenderConfig httpSenderConfig) { return new JdkHttpSender( httpSenderConfig.getEndpoint(), - httpSenderConfig.getCompressor(), - httpSenderConfig.getExportAsJson(), httpSenderConfig.getContentType(), + httpSenderConfig.getCompressor(), httpSenderConfig.getTimeoutNanos(), httpSenderConfig.getConnectTimeoutNanos(), httpSenderConfig.getHeadersSupplier(), diff --git a/exporters/sender/jdk/src/main/resources/META-INF/services/io.opentelemetry.exporter.internal.http.HttpSenderProvider b/exporters/sender/jdk/src/main/resources/META-INF/services/io.opentelemetry.exporter.http.HttpSenderProvider similarity index 100% rename from exporters/sender/jdk/src/main/resources/META-INF/services/io.opentelemetry.exporter.internal.http.HttpSenderProvider rename to exporters/sender/jdk/src/main/resources/META-INF/services/io.opentelemetry.exporter.http.HttpSenderProvider diff --git a/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java b/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java index b93a561743b..52fbb3d6dfd 100644 --- a/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java +++ b/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java @@ -14,14 +14,15 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import io.opentelemetry.exporter.internal.marshal.Marshaler; -import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.http.HttpRequestBodyWriter; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.io.IOException; +import java.io.OutputStream; import java.lang.reflect.Method; import java.net.ConnectException; import java.net.ServerSocket; +import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpConnectTimeoutException; import java.time.Duration; @@ -59,10 +60,9 @@ void setup() throws IOException, InterruptedException { new JdkHttpSender( mockHttpClient, // Connecting to a non-routable IP address to trigger connection timeout - "http://10.255.255.1", - null, - false, + URI.create("http://10.255.255.1"), "text/plain", + null, Duration.ofSeconds(10).toNanos(), Collections::emptyMap, RetryPolicy.builder().setMaxAttempts(2).setInitialBackoff(Duration.ofMillis(1)).build(), @@ -98,7 +98,7 @@ void testShutdownException() throws Exception { @Test void sendInternal_RetryableConnectTimeoutException() throws IOException, InterruptedException { - assertThatThrownBy(() -> sender.sendInternal(new NoOpMarshaler())) + assertThatThrownBy(() -> sender.sendInternal(new NoOpRequestBodyWriter())) .isInstanceOf(HttpConnectTimeoutException.class); verify(mockHttpClient, times(2)).send(any(), any()); @@ -112,16 +112,15 @@ void sendInternal_RetryableConnectException() throws IOException, InterruptedExc // Connecting to localhost on an unused port address to trigger // java.net.ConnectException (or java.net.http.HttpConnectTimeoutException on linux java // 11+) - "http://localhost:" + freePort(), - null, - false, + URI.create("http://localhost:" + freePort()), "text/plain", + null, Duration.ofSeconds(10).toNanos(), Collections::emptyMap, RetryPolicy.builder().setMaxAttempts(2).setInitialBackoff(Duration.ofMillis(1)).build(), null); - assertThatThrownBy(() -> sender.sendInternal(new NoOpMarshaler())) + assertThatThrownBy(() -> sender.sendInternal(new NoOpRequestBodyWriter())) .satisfies( e -> assertThat( @@ -144,7 +143,7 @@ private static int freePort() { void sendInternal_RetryableIoException() throws IOException, InterruptedException { doThrow(new IOException("error!")).when(mockHttpClient).send(any(), any()); - assertThatThrownBy(() -> sender.sendInternal(new NoOpMarshaler())) + assertThatThrownBy(() -> sender.sendInternal(new NoOpRequestBodyWriter())) .isInstanceOf(IOException.class) .hasMessage("error!"); @@ -155,7 +154,7 @@ void sendInternal_RetryableIoException() throws IOException, InterruptedExceptio void sendInternal_NonRetryableException() throws IOException, InterruptedException { doThrow(new SSLException("unknown error")).when(mockHttpClient).send(any(), any()); - assertThatThrownBy(() -> sender.sendInternal(new NoOpMarshaler())) + assertThatThrownBy(() -> sender.sendInternal(new NoOpRequestBodyWriter())) .isInstanceOf(IOException.class) .hasMessage("unknown error"); @@ -166,10 +165,9 @@ void sendInternal_NonRetryableException() throws IOException, InterruptedExcepti void connectTimeout() { sender = new JdkHttpSender( - "http://localhost", - null, - false, + URI.create("http://localhost"), "text/plain", + null, 1, TimeUnit.SECONDS.toNanos(10), Collections::emptyMap, @@ -185,14 +183,13 @@ void connectTimeout() { assertThat(httpClient.connectTimeout().get()).isEqualTo(Duration.ofSeconds(10))); } - private static class NoOpMarshaler extends Marshaler { + private static class NoOpRequestBodyWriter implements HttpRequestBodyWriter { + @Override + public void writeRequestBody(OutputStream output) {} @Override - public int getBinarySerializedSize() { + public int contentLength() { return 0; } - - @Override - protected void writeTo(Serializer output) {} } } diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/GrpcRequestBody.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/GrpcRequestBody.java index 7baa5c4dce0..4fb43cfe98d 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/GrpcRequestBody.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/GrpcRequestBody.java @@ -5,7 +5,8 @@ package io.opentelemetry.exporter.sender.okhttp.internal; -import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.compressor.Compressor; +import io.opentelemetry.exporter.grpc.GrpcMessageWriter; import io.opentelemetry.exporter.internal.marshal.Marshaler; import java.io.IOException; import javax.annotation.Nullable; @@ -30,17 +31,17 @@ public final class GrpcRequestBody extends RequestBody { private static final MediaType GRPC_MEDIA_TYPE = MediaType.parse("application/grpc"); - private final Marshaler marshaler; + private final GrpcMessageWriter requestBodyWriter; private final int messageSize; private final int contentLength; @Nullable private final Compressor compressor; /** Creates a new {@link GrpcRequestBody}. */ - public GrpcRequestBody(Marshaler marshaler, @Nullable Compressor compressor) { - this.marshaler = marshaler; + public GrpcRequestBody(GrpcMessageWriter requestBodyWriter, @Nullable Compressor compressor) { + this.requestBodyWriter = requestBodyWriter; this.compressor = compressor; - messageSize = marshaler.getBinarySerializedSize(); + messageSize = requestBodyWriter.contentLength(); if (compressor != null) { // Content length not known since we want to compress on the I/O thread. contentLength = -1; @@ -65,12 +66,12 @@ public void writeTo(BufferedSink sink) throws IOException { if (compressor == null) { sink.writeByte(UNCOMPRESSED_FLAG); sink.writeInt(messageSize); - marshaler.writeBinaryTo(sink.outputStream()); + requestBodyWriter.writeMessage(sink.outputStream()); } else { try (Buffer compressedBody = new Buffer()) { try (BufferedSink compressedSink = Okio.buffer(Okio.sink(compressor.compress(compressedBody.outputStream())))) { - marshaler.writeBinaryTo(compressedSink.outputStream()); + requestBodyWriter.writeMessage(compressedSink.outputStream()); } sink.writeByte(COMPRESSED_FLAG); int compressedBytes = (int) compressedBody.size(); diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java index b8c7bc13992..9284b5d3931 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java @@ -24,12 +24,12 @@ package io.opentelemetry.exporter.sender.okhttp.internal; import io.opentelemetry.api.internal.InstrumentationUtil; +import io.opentelemetry.exporter.compressor.Compressor; +import io.opentelemetry.exporter.grpc.GrpcMessageWriter; +import io.opentelemetry.exporter.grpc.GrpcResponse; +import io.opentelemetry.exporter.grpc.GrpcSender; +import io.opentelemetry.exporter.grpc.GrpcStatusCode; import io.opentelemetry.exporter.internal.RetryUtil; -import io.opentelemetry.exporter.internal.compression.Compressor; -import io.opentelemetry.exporter.internal.grpc.GrpcExporterUtil; -import io.opentelemetry.exporter.internal.grpc.GrpcResponse; -import io.opentelemetry.exporter.internal.grpc.GrpcSender; -import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.io.IOException; @@ -56,6 +56,7 @@ import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; +import okhttp3.ResponseBody; /** * A {@link GrpcSender} which uses OkHttp instead of grpc-java. @@ -63,7 +64,7 @@ *

This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ -public final class OkHttpGrpcSender implements GrpcSender { +public final class OkHttpGrpcSender implements GrpcSender { private static final String GRPC_STATUS = "grpc-status"; private static final String GRPC_MESSAGE = "grpc-message"; @@ -71,8 +72,8 @@ public final class OkHttpGrpcSender implements GrpcSender>> headersSupplier; @Nullable private final Compressor compressor; + private final Supplier>> headersSupplier; /** Creates a new {@link OkHttpGrpcSender}. */ @SuppressWarnings("TooManyParameters") @@ -122,13 +123,16 @@ public OkHttpGrpcSender( } this.client = clientBuilder.build(); + this.compressor = compressor; this.headersSupplier = headersSupplier; this.url = HttpUrl.get(endpoint); - this.compressor = compressor; } @Override - public void send(T request, Consumer onResponse, Consumer onError) { + public void send( + GrpcMessageWriter messageWriter, + Consumer onResponse, + Consumer onError) { Request.Builder requestBuilder = new Request.Builder().url(url); Map> headers = headersSupplier.get(); @@ -140,7 +144,7 @@ public void send(T request, Consumer onResponse, Consumer GrpcSender createSender(GrpcSenderConfig grpcSenderConfig) { - return new OkHttpGrpcSender<>( - grpcSenderConfig.getEndpoint().resolve(grpcSenderConfig.getEndpointPath()).toString(), + public GrpcSender createSender(GrpcSenderConfig grpcSenderConfig) { + return new OkHttpGrpcSender( + grpcSenderConfig + .getEndpoint() + .resolve(grpcSenderConfig.getFullServiceName() + "/" + grpcSenderConfig.getMethodName()) + .toString(), grpcSenderConfig.getCompressor(), grpcSenderConfig.getTimeoutNanos(), grpcSenderConfig.getConnectTimeoutNanos(), diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java index 7b5e2081ec4..c4767e5bfe0 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java @@ -6,14 +6,16 @@ package io.opentelemetry.exporter.sender.okhttp.internal; import io.opentelemetry.api.internal.InstrumentationUtil; +import io.opentelemetry.exporter.compressor.Compressor; +import io.opentelemetry.exporter.http.HttpRequestBodyWriter; +import io.opentelemetry.exporter.http.HttpResponse; +import io.opentelemetry.exporter.http.HttpSender; import io.opentelemetry.exporter.internal.RetryUtil; -import io.opentelemetry.exporter.internal.compression.Compressor; -import io.opentelemetry.exporter.internal.http.HttpSender; -import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.io.IOException; +import java.net.URI; import java.time.Duration; import java.util.Collections; import java.util.List; @@ -48,18 +50,16 @@ public final class OkHttpHttpSender implements HttpSender { private final boolean managedExecutor; private final OkHttpClient client; private final HttpUrl url; - @Nullable private final Compressor compressor; - private final boolean exportAsJson; private final Supplier>> headerSupplier; private final MediaType mediaType; + @Nullable private final Compressor compressor; /** Create a sender. */ @SuppressWarnings("TooManyParameters") public OkHttpHttpSender( - String endpoint, - @Nullable Compressor compressor, - boolean exportAsJson, + URI endpoint, String contentType, + @Nullable Compressor compressor, long timeoutNanos, long connectionTimeoutNanos, Supplier>> headerSupplier, @@ -96,7 +96,7 @@ public OkHttpHttpSender( builder.addInterceptor(new RetryInterceptor(retryPolicy, OkHttpHttpSender::isRetryable)); } - boolean isPlainHttp = endpoint.startsWith("http://"); + boolean isPlainHttp = endpoint.toString().startsWith("http://"); if (isPlainHttp) { builder.connectionSpecs(Collections.singletonList(ConnectionSpec.CLEARTEXT)); } else if (sslContext != null && trustManager != null) { @@ -105,17 +105,15 @@ public OkHttpHttpSender( this.client = builder.build(); this.url = HttpUrl.get(endpoint); - this.compressor = compressor; - this.exportAsJson = exportAsJson; this.mediaType = MediaType.parse(contentType); + this.compressor = compressor; this.headerSupplier = headerSupplier; } @Override public void send( - Marshaler marshaler, - int contentLength, - Consumer onResponse, + HttpRequestBodyWriter requestBodyWriter, + Consumer onResponse, Consumer onError) { Request.Builder requestBuilder = new Request.Builder().url(url); @@ -124,13 +122,10 @@ public void send( headers.forEach( (key, values) -> values.forEach(value -> requestBuilder.addHeader(key, value))); } - RequestBody body = new RawRequestBody(marshaler, exportAsJson, contentLength, mediaType); if (compressor != null) { requestBuilder.addHeader("Content-Encoding", compressor.getEncoding()); - requestBuilder.post(new CompressedRequestBody(compressor, body)); - } else { - requestBuilder.post(body); } + requestBuilder.post(new RequestBodyImpl(requestBodyWriter, compressor, mediaType)); InstrumentationUtil.suppressInstrumentation( () -> @@ -147,23 +142,28 @@ public void onFailure(Call call, IOException e) { public void onResponse(Call call, okhttp3.Response response) { try (ResponseBody body = response.body()) { onResponse.accept( - new Response() { + new HttpResponse() { @Nullable private byte[] bodyBytes; @Override - public int statusCode() { + public int getStatusCode() { return response.code(); } @Override - public String statusMessage() { + public String getStatusMessage() { return response.message(); } @Override - public byte[] responseBody() throws IOException { + public byte[] getResponseBody() { if (bodyBytes == null) { - bodyBytes = body.bytes(); + try { + bodyBytes = body.bytes(); + } catch (IOException e) { + // TODO: suspicious ignored exception + bodyBytes = new byte[0]; + } } return bodyBytes; } @@ -187,24 +187,24 @@ static boolean isRetryable(okhttp3.Response response) { return RetryUtil.retryableHttpResponseCodes().contains(response.code()); } - private static class RawRequestBody extends RequestBody { + private static class RequestBodyImpl extends RequestBody { - private final Marshaler marshaler; - private final boolean exportAsJson; - private final int contentLength; + private final HttpRequestBodyWriter requestBodyWriter; + @Nullable private final Compressor compressor; private final MediaType mediaType; - private RawRequestBody( - Marshaler marshaler, boolean exportAsJson, int contentLength, MediaType mediaType) { - this.marshaler = marshaler; - this.exportAsJson = exportAsJson; - this.contentLength = contentLength; + private RequestBodyImpl( + HttpRequestBodyWriter requestBodyWriter, + @Nullable Compressor compressor, + MediaType mediaType) { + this.requestBodyWriter = requestBodyWriter; + this.compressor = compressor; this.mediaType = mediaType; } @Override public long contentLength() { - return contentLength; + return compressor == null ? requestBodyWriter.contentLength() : -1; } @Override @@ -214,39 +214,14 @@ public MediaType contentType() { @Override public void writeTo(BufferedSink bufferedSink) throws IOException { - if (exportAsJson) { - marshaler.writeJsonTo(bufferedSink.outputStream()); + if (compressor != null) { + BufferedSink compressedSink = + Okio.buffer(Okio.sink(compressor.compress(bufferedSink.outputStream()))); + requestBodyWriter.writeRequestBody(compressedSink.outputStream()); + compressedSink.close(); } else { - marshaler.writeBinaryTo(bufferedSink.outputStream()); + requestBodyWriter.writeRequestBody(bufferedSink.outputStream()); } } } - - private static class CompressedRequestBody extends RequestBody { - private final Compressor compressor; - private final RequestBody requestBody; - - private CompressedRequestBody(Compressor compressor, RequestBody requestBody) { - this.compressor = compressor; - this.requestBody = requestBody; - } - - @Override - public MediaType contentType() { - return requestBody.contentType(); - } - - @Override - public long contentLength() { - return -1; - } - - @Override - public void writeTo(BufferedSink bufferedSink) throws IOException { - BufferedSink compressedSink = - Okio.buffer(Okio.sink(compressor.compress(bufferedSink.outputStream()))); - requestBody.writeTo(compressedSink); - compressedSink.close(); - } - } } diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java index 8c7c3aa0f4b..c54838be48b 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java @@ -5,9 +5,9 @@ package io.opentelemetry.exporter.sender.okhttp.internal; -import io.opentelemetry.exporter.internal.http.HttpSender; -import io.opentelemetry.exporter.internal.http.HttpSenderConfig; -import io.opentelemetry.exporter.internal.http.HttpSenderProvider; +import io.opentelemetry.exporter.http.HttpSender; +import io.opentelemetry.exporter.http.HttpSenderConfig; +import io.opentelemetry.exporter.http.HttpSenderProvider; /** * {@link HttpSender} SPI implementation for {@link OkHttpHttpSender}. @@ -21,9 +21,8 @@ public final class OkHttpHttpSenderProvider implements HttpSenderProvider { public HttpSender createSender(HttpSenderConfig httpSenderConfig) { return new OkHttpHttpSender( httpSenderConfig.getEndpoint(), - httpSenderConfig.getCompressor(), - httpSenderConfig.getExportAsJson(), httpSenderConfig.getContentType(), + httpSenderConfig.getCompressor(), httpSenderConfig.getTimeoutNanos(), httpSenderConfig.getConnectTimeoutNanos(), httpSenderConfig.getHeadersSupplier(), diff --git a/exporters/sender/okhttp/src/main/resources/META-INF/services/io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider b/exporters/sender/okhttp/src/main/resources/META-INF/services/io.opentelemetry.exporter.grpc.GrpcSenderProvider similarity index 100% rename from exporters/sender/okhttp/src/main/resources/META-INF/services/io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider rename to exporters/sender/okhttp/src/main/resources/META-INF/services/io.opentelemetry.exporter.grpc.GrpcSenderProvider diff --git a/exporters/sender/okhttp/src/main/resources/META-INF/services/io.opentelemetry.exporter.internal.http.HttpSenderProvider b/exporters/sender/okhttp/src/main/resources/META-INF/services/io.opentelemetry.exporter.http.HttpSenderProvider similarity index 100% rename from exporters/sender/okhttp/src/main/resources/META-INF/services/io.opentelemetry.exporter.internal.http.HttpSenderProvider rename to exporters/sender/okhttp/src/main/resources/META-INF/services/io.opentelemetry.exporter.http.HttpSenderProvider diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderTest.java index c1a61a8aea5..d637d245449 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderTest.java @@ -8,8 +8,8 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +import io.opentelemetry.exporter.grpc.GrpcStatusCode; import io.opentelemetry.exporter.internal.RetryUtil; -import io.opentelemetry.exporter.internal.grpc.GrpcExporterUtil; import java.util.Set; import okhttp3.MediaType; import okhttp3.Protocol; @@ -40,7 +40,7 @@ void isRetryable_RetryableGrpcStatus(String retryableGrpcStatus) { @Test void isRetryable_NonRetryableGrpcStatus() { String nonRetryableGrpcStatus = - Integer.valueOf(GrpcExporterUtil.GRPC_STATUS_UNKNOWN).toString(); // INVALID_ARGUMENT + Integer.valueOf(GrpcStatusCode.UNKNOWN.getValue()).toString(); // INVALID_ARGUMENT Response response = createResponse(503, nonRetryableGrpcStatus, "Non-retryable"); boolean isRetryable = OkHttpGrpcSender.isRetryable(response); assertFalse(isRetryable); diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java index 39457f4e2de..18a1546e2e4 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java @@ -5,32 +5,32 @@ package io.opentelemetry.exporter.sender.okhttp.internal; -import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; -import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.grpc.GrpcMessageWriter; +import java.io.IOException; +import java.io.OutputStream; import java.util.Collections; -class OkHttpGrpcSuppressionTest - extends AbstractOkHttpSuppressionTest< - OkHttpGrpcSender> { +class OkHttpGrpcSuppressionTest extends AbstractOkHttpSuppressionTest { @Override - void send(OkHttpGrpcSender sender, Runnable onSuccess, Runnable onFailure) { - sender.send(new DummyMarshaler(), grpcResponse -> {}, throwable -> onFailure.run()); + void send(OkHttpGrpcSender sender, Runnable onSuccess, Runnable onFailure) { + sender.send( + new GrpcMessageWriter() { + @Override + public void writeMessage(OutputStream output) throws IOException {} + + @Override + public int contentLength() { + return 0; + } + }, + grpcResponse -> {}, + throwable -> onFailure.run()); } @Override - OkHttpGrpcSender createSender(String endpoint) { - return new OkHttpGrpcSender<>( + OkHttpGrpcSender createSender(String endpoint) { + return new OkHttpGrpcSender( "https://localhost", null, 10L, 10L, Collections::emptyMap, null, null, null, null); } - - protected static class DummyMarshaler extends MarshalerWithSize { - - protected DummyMarshaler() { - super(0); - } - - @Override - protected void writeTo(Serializer output) {} - } } diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java index 38686c36526..66cca1ace31 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java @@ -5,10 +5,10 @@ package io.opentelemetry.exporter.sender.okhttp.internal; -import io.opentelemetry.exporter.internal.marshal.Marshaler; -import io.opentelemetry.exporter.internal.marshal.ProtoFieldInfo; -import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.http.HttpRequestBodyWriter; import java.io.IOException; +import java.io.OutputStream; +import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.Collections; @@ -17,29 +17,27 @@ class OkHttpHttpSuppressionTest extends AbstractOkHttpSuppressionTest onSuccess.run(), (error) -> onFailure.run()); + sender.send(requestBodyWriter, (response) -> onSuccess.run(), (error) -> onFailure.run()); } @Override OkHttpHttpSender createSender(String endpoint) { return new OkHttpHttpSender( - endpoint, - null, - false, + URI.create(endpoint), "text/plain", + null, 10L, 10L, Collections::emptyMap, diff --git a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporter.java b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporter.java index afd7bce4286..8ac12c41e9a 100644 --- a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporter.java +++ b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporter.java @@ -16,6 +16,7 @@ import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.export.SpanExporter; import java.io.IOException; +import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -72,7 +73,7 @@ public final class ZipkinSpanExporter implements SpanExporter { internalTelemetryVersion, meterProviderSupplier, ComponentId.generateLazy(exporterType), - endpoint); + URI.create(endpoint)); } @Override diff --git a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerBuilder.java b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerBuilder.java index 24dfac82acc..adc286ce824 100644 --- a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerBuilder.java +++ b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerBuilder.java @@ -199,7 +199,7 @@ private static GrpcService buildWithChannel(ManagedChannel channel) { return new UpstreamGrpcService( "remoteSampling", channel, - MarshallerRemoteSamplerServiceGrpc.newFutureStub(channel), + MarshallerRemoteSamplerServiceGrpc.getPostSpansMethod, TimeUnit.SECONDS.toNanos(DEFAULT_TIMEOUT_SECS)); } } diff --git a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/MarshallerRemoteSamplerServiceGrpc.java b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/MarshallerRemoteSamplerServiceGrpc.java index cfec3ff6cdd..89b20270411 100644 --- a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/MarshallerRemoteSamplerServiceGrpc.java +++ b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/MarshallerRemoteSamplerServiceGrpc.java @@ -7,13 +7,8 @@ import static io.grpc.MethodDescriptor.generateFullMethodName; -import com.google.common.util.concurrent.ListenableFuture; -import io.grpc.CallOptions; -import io.grpc.Channel; import io.grpc.MethodDescriptor; -import io.grpc.stub.ClientCalls; import io.opentelemetry.exporter.internal.grpc.MarshalerInputStream; -import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -27,7 +22,7 @@ class MarshallerRemoteSamplerServiceGrpc { new MethodDescriptor.Marshaller() { @Override public InputStream stream(SamplingStrategyParametersMarshaler value) { - return new MarshalerInputStream(value); + return new MarshalerInputStream(value.toGrpcRequestBodyWriter()); } @Override @@ -59,7 +54,7 @@ public SamplingStrategyResponseUnMarshaler parse(InputStream stream) { } }; - private static final MethodDescriptor< + static final MethodDescriptor< SamplingStrategyParametersMarshaler, SamplingStrategyResponseUnMarshaler> getPostSpansMethod = MethodDescriptor @@ -71,33 +66,6 @@ public SamplingStrategyResponseUnMarshaler parse(InputStream stream) { .setResponseMarshaller(RESPONSE_MARSHALLER) .build(); - static SamplingManagerFutureStub newFutureStub(Channel channel) { - return SamplingManagerFutureStub.newStub(SamplingManagerFutureStub::new, channel); - } - - static final class SamplingManagerFutureStub - extends MarshalerServiceStub< - SamplingStrategyParametersMarshaler, - SamplingStrategyResponseUnMarshaler, - SamplingManagerFutureStub> { - - private SamplingManagerFutureStub(Channel channel, CallOptions callOptions) { - super(channel, callOptions); - } - - @Override - protected SamplingManagerFutureStub build(Channel channel, CallOptions callOptions) { - return new SamplingManagerFutureStub(channel, callOptions); - } - - @Override - public ListenableFuture export( - SamplingStrategyParametersMarshaler request) { - return ClientCalls.futureUnaryCall( - getChannel().newCall(getPostSpansMethod, getCallOptions()), request); - } - } - private static byte[] readAllBytes(InputStream inputStream) throws IOException { int bufLen = 4 * 0x400; // 4KB byte[] buf = new byte[bufLen]; diff --git a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/OkHttpGrpcService.java b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/OkHttpGrpcService.java index ca1455ad3f3..d416c5b7436 100644 --- a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/OkHttpGrpcService.java +++ b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/OkHttpGrpcService.java @@ -5,8 +5,8 @@ package io.opentelemetry.sdk.extension.trace.jaeger.sampler; +import io.opentelemetry.exporter.grpc.GrpcStatusCode; import io.opentelemetry.exporter.internal.RetryUtil; -import io.opentelemetry.exporter.internal.grpc.GrpcExporterUtil; import io.opentelemetry.exporter.sender.okhttp.internal.GrpcRequestBody; import io.opentelemetry.sdk.common.CompletableResultCode; import java.io.ByteArrayInputStream; @@ -53,7 +53,7 @@ public SamplingStrategyResponseUnMarshaler execute( SamplingStrategyResponseUnMarshaler responseUnmarshaller) { Request.Builder requestBuilder = new Request.Builder().url(url).headers(headers); - RequestBody requestBody = new GrpcRequestBody(exportRequest, null); + RequestBody requestBody = new GrpcRequestBody(exportRequest.toGrpcRequestBodyWriter(), null); requestBuilder.post(requestBody); try { @@ -69,6 +69,7 @@ public SamplingStrategyResponseUnMarshaler execute( // HTTP error. } + // TODO: convert to enum earlier String status = grpcStatus(response); if ("0".equals(status)) { if (bodyBytes.length > 5) { @@ -93,7 +94,7 @@ public SamplingStrategyResponseUnMarshaler execute( status != null ? "gRPC status code " + status : "HTTP status code " + response.code(); String errorMessage = grpcMessage(response); - if (String.valueOf(GrpcExporterUtil.GRPC_STATUS_UNIMPLEMENTED).equals(status)) { + if (String.valueOf(GrpcStatusCode.UNIMPLEMENTED.getValue()).equals(status)) { logger.log( Level.SEVERE, "Failed to execute " @@ -101,7 +102,7 @@ public SamplingStrategyResponseUnMarshaler execute( + "s. Server responded with UNIMPLEMENTED. " + "Full error message: " + errorMessage); - } else if (String.valueOf(GrpcExporterUtil.GRPC_STATUS_UNAVAILABLE).equals(status)) { + } else if (String.valueOf(GrpcStatusCode.UNAVAILABLE.getValue()).equals(status)) { logger.log( Level.SEVERE, "Failed to execute " diff --git a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/UpstreamGrpcService.java b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/UpstreamGrpcService.java index 2976ff1302c..a6ef1e56e0c 100644 --- a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/UpstreamGrpcService.java +++ b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/UpstreamGrpcService.java @@ -6,10 +6,12 @@ package io.opentelemetry.sdk.extension.trace.jaeger.sampler; import com.google.common.util.concurrent.Futures; +import io.grpc.CallOptions; import io.grpc.ManagedChannel; +import io.grpc.MethodDescriptor; import io.grpc.Status; +import io.grpc.stub.ClientCalls; import io.opentelemetry.exporter.internal.grpc.ManagedChannelUtil; -import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; import io.opentelemetry.sdk.common.CompletableResultCode; import java.time.Duration; import java.util.Objects; @@ -22,38 +24,40 @@ final class UpstreamGrpcService implements GrpcService { private final String type; private final ManagedChannel managedChannel; - private final MarshalerServiceStub< - SamplingStrategyParametersMarshaler, SamplingStrategyResponseUnMarshaler, ?> - stub; + private final MethodDescriptor< + SamplingStrategyParametersMarshaler, SamplingStrategyResponseUnMarshaler> + methodDescriptor; private final long timeoutNanos; /** Creates a new {@link UpstreamGrpcService}. */ UpstreamGrpcService( String type, ManagedChannel channel, - MarshalerServiceStub< - SamplingStrategyParametersMarshaler, SamplingStrategyResponseUnMarshaler, ?> - stub, + MethodDescriptor + methodDescriptor, long timeoutNanos) { this.type = type; this.managedChannel = channel; this.timeoutNanos = timeoutNanos; - this.stub = stub; + this.methodDescriptor = methodDescriptor; } @Override public SamplingStrategyResponseUnMarshaler execute( SamplingStrategyParametersMarshaler exportRequest, SamplingStrategyResponseUnMarshaler responseUnmarshaller) { - MarshalerServiceStub< - SamplingStrategyParametersMarshaler, SamplingStrategyResponseUnMarshaler, ?> - stub = this.stub; + + CallOptions callOptions = CallOptions.DEFAULT; + if (timeoutNanos > 0) { - stub = stub.withDeadlineAfter(Duration.ofNanos(timeoutNanos)); + callOptions = callOptions.withDeadlineAfter(Duration.ofNanos(timeoutNanos)); } try { - return Objects.requireNonNull(Futures.getUnchecked(stub.export(exportRequest))); + return Objects.requireNonNull( + Futures.getUnchecked( + ClientCalls.futureUnaryCall( + managedChannel.newCall(methodDescriptor, callOptions), exportRequest))); } catch (Throwable t) { Status status = Status.fromThrowable(t);