Add HttpSenderProvider SPI (#5533)
This commit is contained in:
parent
c42f3df806
commit
8f1a7b1c95
|
@ -0,0 +1,2 @@
|
|||
Comparing source compatibility of against
|
||||
No changes.
|
|
@ -18,7 +18,7 @@ dependencies {
|
|||
|
||||
annotationProcessor("com.google.auto.value:auto-value")
|
||||
|
||||
// We include helpers shared by gRPC or okhttp exporters but do not want to impose these
|
||||
// We include helpers shared by gRPC exporters but do not want to impose these
|
||||
// dependency on all of our consumers.
|
||||
compileOnly("com.fasterxml.jackson.core:jackson-core")
|
||||
compileOnly("com.squareup.okhttp3:okhttp")
|
||||
|
|
|
@ -11,15 +11,17 @@ import io.opentelemetry.exporter.internal.ExporterBuilderUtil;
|
|||
import io.opentelemetry.exporter.internal.TlsConfigHelper;
|
||||
import io.opentelemetry.exporter.internal.auth.Authenticator;
|
||||
import io.opentelemetry.exporter.internal.marshal.Marshaler;
|
||||
import io.opentelemetry.exporter.internal.okhttp.OkHttpHttpSender;
|
||||
import io.opentelemetry.exporter.internal.retry.RetryPolicy;
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
@ -34,6 +36,8 @@ import javax.net.ssl.X509TrustManager;
|
|||
public final class HttpExporterBuilder<T extends Marshaler> {
|
||||
public static final long DEFAULT_TIMEOUT_SECS = 10;
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(HttpExporterBuilder.class.getName());
|
||||
|
||||
private final String exporterName;
|
||||
private final String type;
|
||||
|
||||
|
@ -125,17 +129,28 @@ public final class HttpExporterBuilder<T extends Marshaler> {
|
|||
Map<String, String> headers = this.headers == null ? Collections.emptyMap() : this.headers;
|
||||
Supplier<Map<String, String>> headerSupplier = () -> headers;
|
||||
|
||||
HttpSender httpSender =
|
||||
new OkHttpHttpSender(
|
||||
endpoint,
|
||||
compressionEnabled,
|
||||
exportAsJson ? "application/json" : "application/x-protobuf",
|
||||
timeoutNanos,
|
||||
headerSupplier,
|
||||
authenticator,
|
||||
retryPolicy,
|
||||
tlsConfigHelper.getSslContext(),
|
||||
tlsConfigHelper.getTrustManager());
|
||||
HttpSender httpSender = null;
|
||||
// TODO: once we publish multiple HttpSenderProviders, log warning when multiple are found
|
||||
for (HttpSenderProvider httpSenderProvider :
|
||||
ServiceLoader.load(HttpSenderProvider.class, HttpExporterBuilder.class.getClassLoader())) {
|
||||
httpSender =
|
||||
httpSenderProvider.createSender(
|
||||
endpoint,
|
||||
compressionEnabled,
|
||||
exportAsJson ? "application/json" : "application/x-protobuf",
|
||||
timeoutNanos,
|
||||
headerSupplier,
|
||||
authenticator,
|
||||
retryPolicy,
|
||||
tlsConfigHelper.getSslContext(),
|
||||
tlsConfigHelper.getTrustManager());
|
||||
LOGGER.log(Level.FINE, "Using HttpSender: " + httpSender.getClass().getName());
|
||||
break;
|
||||
}
|
||||
if (httpSender == null) {
|
||||
throw new IllegalStateException(
|
||||
"No HttpSenderProvider found on classpath. Please add dependency on opentelemetry-exporter-http-sender-okhttp");
|
||||
}
|
||||
|
||||
return new HttpExporter<>(exporterName, type, httpSender, meterProviderSupplier, exportAsJson);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.exporter.internal.http;
|
||||
|
||||
import io.opentelemetry.exporter.internal.auth.Authenticator;
|
||||
import io.opentelemetry.exporter.internal.retry.RetryPolicy;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
/**
|
||||
* A service provider interface (SPI) for providing {@link HttpSender}s backed by different HTTP
|
||||
* client libraries.
|
||||
*
|
||||
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
|
||||
* at any time.
|
||||
*/
|
||||
public interface HttpSenderProvider {
|
||||
|
||||
/** Returns a {@link HttpSender} configured with the provided parameters. */
|
||||
HttpSender createSender(
|
||||
String endpoint,
|
||||
boolean compressionEnabled,
|
||||
String contentType,
|
||||
long timeoutNanos,
|
||||
Supplier<Map<String, String>> headerSupplier,
|
||||
@Nullable Authenticator authenticator,
|
||||
@Nullable RetryPolicy retryPolicy,
|
||||
@Nullable SSLContext sslContext,
|
||||
@Nullable X509TrustManager trustManager);
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.exporter.internal.http;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class HttpExporterTest {
|
||||
|
||||
@Test
|
||||
void build_NoHttpSenderProvider() {
|
||||
assertThatThrownBy(() -> new HttpExporterBuilder<>("name", "type", "http://localhost").build())
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage(
|
||||
"No HttpSenderProvider found on classpath. Please add dependency on opentelemetry-exporter-http-sender-okhttp");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
subprojects {
|
||||
// Workaround https://github.com/gradle/gradle/issues/847
|
||||
group = "io.opentelemetry.exporter.httpsender"
|
||||
val proj = this
|
||||
plugins.withId("java") {
|
||||
configure<BasePluginExtension> {
|
||||
archivesName.set("opentelemetry-exporter-http-sender-${proj.name}")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
plugins {
|
||||
id("otel.java-conventions")
|
||||
id("otel.publish-conventions")
|
||||
|
||||
id("otel.animalsniffer-conventions")
|
||||
}
|
||||
|
||||
description = "OpenTelemetry OkHttp HttpSender"
|
||||
otelJava.moduleName.set("io.opentelemetry.exporter.http.okhttp.internal")
|
||||
|
||||
dependencies {
|
||||
implementation(project(":exporters:common"))
|
||||
implementation(project(":sdk:common"))
|
||||
|
||||
implementation("com.squareup.okhttp3:okhttp")
|
||||
|
||||
testImplementation("com.linecorp.armeria:armeria-junit5")
|
||||
}
|
|
@ -3,10 +3,11 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.exporter.internal.okhttp;
|
||||
package io.opentelemetry.exporter.http.okhttp.internal;
|
||||
|
||||
import io.opentelemetry.exporter.internal.auth.Authenticator;
|
||||
import io.opentelemetry.exporter.internal.http.HttpSender;
|
||||
import io.opentelemetry.exporter.internal.okhttp.OkHttpUtil;
|
||||
import io.opentelemetry.exporter.internal.retry.RetryInterceptor;
|
||||
import io.opentelemetry.exporter.internal.retry.RetryPolicy;
|
||||
import io.opentelemetry.exporter.internal.retry.RetryUtil;
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.exporter.http.okhttp.internal;
|
||||
|
||||
import io.opentelemetry.exporter.internal.auth.Authenticator;
|
||||
import io.opentelemetry.exporter.internal.http.HttpSender;
|
||||
import io.opentelemetry.exporter.internal.http.HttpSenderProvider;
|
||||
import io.opentelemetry.exporter.internal.retry.RetryPolicy;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* {@link HttpSender} SPI implementation for {@link OkHttpHttpSender}.
|
||||
*
|
||||
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
|
||||
* at any time.
|
||||
*/
|
||||
public class OkHttpHttpSenderProvider implements HttpSenderProvider {
|
||||
|
||||
@Override
|
||||
public HttpSender createSender(
|
||||
String endpoint,
|
||||
boolean compressionEnabled,
|
||||
String contentType,
|
||||
long timeoutNanos,
|
||||
Supplier<Map<String, String>> headerSupplier,
|
||||
@Nullable Authenticator authenticator,
|
||||
@Nullable RetryPolicy retryPolicy,
|
||||
@Nullable SSLContext sslContext,
|
||||
@Nullable X509TrustManager trustManager) {
|
||||
return new OkHttpHttpSender(
|
||||
endpoint,
|
||||
compressionEnabled,
|
||||
contentType,
|
||||
timeoutNanos,
|
||||
headerSupplier,
|
||||
authenticator,
|
||||
retryPolicy,
|
||||
sslContext,
|
||||
trustManager);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/** Utilities for HTTP exporters. */
|
||||
@ParametersAreNonnullByDefault
|
||||
package io.opentelemetry.exporter.http.okhttp.internal;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
@ -0,0 +1 @@
|
|||
io.opentelemetry.exporter.http.okhttp.internal.OkHttpHttpSenderProvider
|
|
@ -3,7 +3,7 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.exporter.internal.auth;
|
||||
package io.opentelemetry.exporter.http.okhttp.internal;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.exporter.internal.okhttp;
|
||||
package io.opentelemetry.exporter.http.okhttp.internal;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
@ -25,7 +25,11 @@ class HttpExporterBuilderTest {
|
|||
.isInstanceOfSatisfying(
|
||||
HttpExporter.class,
|
||||
otlp ->
|
||||
assertThat(otlp).extracting("httpSender.compressionEnabled").isEqualTo(false));
|
||||
assertThat(otlp)
|
||||
.extracting("httpSender")
|
||||
.isInstanceOf(OkHttpHttpSender.class)
|
||||
.extracting("compressionEnabled")
|
||||
.isEqualTo(false));
|
||||
} finally {
|
||||
exporter.shutdown();
|
||||
}
|
||||
|
@ -39,7 +43,11 @@ class HttpExporterBuilderTest {
|
|||
.isInstanceOfSatisfying(
|
||||
HttpExporter.class,
|
||||
otlp ->
|
||||
assertThat(otlp).extracting("httpSender.compressionEnabled").isEqualTo(false));
|
||||
assertThat(otlp)
|
||||
.extracting("httpSender")
|
||||
.isInstanceOf(OkHttpHttpSender.class)
|
||||
.extracting("compressionEnabled")
|
||||
.isEqualTo(false));
|
||||
} finally {
|
||||
exporter.shutdown();
|
||||
}
|
||||
|
@ -52,7 +60,12 @@ class HttpExporterBuilderTest {
|
|||
assertThat(exporter)
|
||||
.isInstanceOfSatisfying(
|
||||
HttpExporter.class,
|
||||
otlp -> assertThat(otlp).extracting("httpSender.compressionEnabled").isEqualTo(true));
|
||||
otlp ->
|
||||
assertThat(otlp)
|
||||
.extracting("httpSender")
|
||||
.isInstanceOf(OkHttpHttpSender.class)
|
||||
.extracting("compressionEnabled")
|
||||
.isEqualTo(true));
|
||||
} finally {
|
||||
exporter.shutdown();
|
||||
}
|
||||
|
@ -67,7 +80,11 @@ class HttpExporterBuilderTest {
|
|||
.isInstanceOfSatisfying(
|
||||
HttpExporter.class,
|
||||
otlp ->
|
||||
assertThat(otlp).extracting("httpSender.compressionEnabled").isEqualTo(false));
|
||||
assertThat(otlp)
|
||||
.extracting("httpSender")
|
||||
.isInstanceOf(OkHttpHttpSender.class)
|
||||
.extracting("compressionEnabled")
|
||||
.isEqualTo(false));
|
||||
} finally {
|
||||
exporter.shutdown();
|
||||
}
|
|
@ -17,6 +17,7 @@ dependencies {
|
|||
api(project(":sdk:logs"))
|
||||
|
||||
implementation(project(":exporters:otlp:common"))
|
||||
implementation(project(":exporters:http-sender:okhttp"))
|
||||
implementation(project(":sdk-extensions:autoconfigure-spi"))
|
||||
|
||||
implementation("com.squareup.okhttp3:okhttp")
|
||||
|
|
|
@ -32,6 +32,7 @@ include(":extensions:incubator")
|
|||
include(":extensions:kotlin")
|
||||
include(":extensions:trace-propagators")
|
||||
include(":exporters:common")
|
||||
include(":exporters:http-sender:okhttp")
|
||||
include(":exporters:jaeger")
|
||||
include(":exporters:jaeger-proto")
|
||||
include(":exporters:jaeger-thrift")
|
||||
|
|
Loading…
Reference in New Issue