diff --git a/.github/native-tests.json b/.github/native-tests.json
index bb65386d34e64..385c17c24407b 100644
--- a/.github/native-tests.json
+++ b/.github/native-tests.json
@@ -111,7 +111,7 @@
{
"category": "Misc3",
"timeout": 65,
- "test-modules": "kubernetes-client, openshift-client, smallrye-config, smallrye-graphql, smallrye-graphql-client, smallrye-metrics",
+ "test-modules": "kubernetes-client, openshift-client, smallrye-config, smallrye-graphql, smallrye-graphql-client, smallrye-metrics, smallrye-opentracing",
"os-name": "ubuntu-latest"
},
{
diff --git a/bom/application/pom.xml b/bom/application/pom.xml
index 4141d71810dc3..647070f7435c9 100644
--- a/bom/application/pom.xml
+++ b/bom/application/pom.xml
@@ -2864,6 +2864,21 @@
jaeger-thrift
${jaeger.version}
+
+ io.jaegertracing
+ jaeger-zipkin
+ ${jaeger.version}
+
+
+ commons-logging
+ commons-logging
+
+
+ javax.annotation
+ javax.annotation-api
+
+
+
com.h2database
h2
diff --git a/docs/src/main/asciidoc/opentracing.adoc b/docs/src/main/asciidoc/opentracing.adoc
index 080b90378e910..79e850829723d 100644
--- a/docs/src/main/asciidoc/opentracing.adoc
+++ b/docs/src/main/asciidoc/opentracing.adoc
@@ -282,6 +282,27 @@ Following the link:mongodb[MongoDB guide], the command listener will be register
quarkus.mongodb.tracing.enabled=true
----
+=== Zipkin compatibility mode
+
+To enable it, add the following dependency to your pom.xml:
+
+[source, xml]
+----
+
+ io.jaegertracing
+ jaeger-zipkin
+
+----
+
+It contains the dependencies to convert the request to zipkin format.
+The zipkin compatibility mode will be activated after defining the config property as follows:
+
+[source, properties]
+----
+# Enable zipkin compatibility mode
+quarkus.jaeger.zipkin.compatibility-mode=true
+----
+
[[configuration-reference]]
== Jaeger Configuration Reference
diff --git a/extensions/jaeger/deployment/pom.xml b/extensions/jaeger/deployment/pom.xml
index d016032ea322d..4b901e141b351 100644
--- a/extensions/jaeger/deployment/pom.xml
+++ b/extensions/jaeger/deployment/pom.xml
@@ -34,13 +34,22 @@
io.quarkus
quarkus-arc-deployment
- test
io.quarkus
quarkus-smallrye-metrics-deployment
test
+
+ org.mockito
+ mockito-inline
+ test
+
+
+ io.jaegertracing
+ jaeger-zipkin
+ test
+
diff --git a/extensions/jaeger/deployment/src/main/java/io/quarkus/jaeger/deployment/JaegerProcessor.java b/extensions/jaeger/deployment/src/main/java/io/quarkus/jaeger/deployment/JaegerProcessor.java
index 1d83c719d8971..2a473af8d648e 100644
--- a/extensions/jaeger/deployment/src/main/java/io/quarkus/jaeger/deployment/JaegerProcessor.java
+++ b/extensions/jaeger/deployment/src/main/java/io/quarkus/jaeger/deployment/JaegerProcessor.java
@@ -15,6 +15,7 @@
import io.quarkus.jaeger.runtime.JaegerBuildTimeConfig;
import io.quarkus.jaeger.runtime.JaegerConfig;
import io.quarkus.jaeger.runtime.JaegerDeploymentRecorder;
+import io.quarkus.jaeger.runtime.ZipkinConfig;
import io.quarkus.runtime.ApplicationConfig;
import io.quarkus.runtime.metrics.MetricsFactory;
@@ -29,18 +30,18 @@ void setVersion(JaegerDeploymentRecorder jdr) {
@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
ExtensionSslNativeSupportBuildItem setupTracer(JaegerDeploymentRecorder jdr, JaegerBuildTimeConfig buildTimeConfig,
- JaegerConfig jaeger,
- ApplicationConfig appConfig, Optional metricsCapability) {
+ JaegerConfig jaeger, ApplicationConfig appConfig, Optional metricsCapability,
+ ZipkinConfig zipkinConfig) {
if (buildTimeConfig.enabled) {
if (buildTimeConfig.metricsEnabled && metricsCapability.isPresent()) {
if (metricsCapability.get().metricsSupported(MetricsFactory.MICROMETER)) {
- jdr.registerTracerWithMicrometerMetrics(jaeger, appConfig);
+ jdr.registerTracerWithMicrometerMetrics(jaeger, appConfig, zipkinConfig);
} else {
- jdr.registerTracerWithMpMetrics(jaeger, appConfig);
+ jdr.registerTracerWithMpMetrics(jaeger, appConfig, zipkinConfig);
}
} else {
- jdr.registerTracerWithoutMetrics(jaeger, appConfig);
+ jdr.registerTracerWithoutMetrics(jaeger, appConfig, zipkinConfig);
}
}
@@ -58,7 +59,6 @@ public ReflectiveClassBuildItem reflectiveClasses() {
return ReflectiveClassBuildItem
.builder("io.jaegertracing.internal.samplers.http.SamplingStrategyResponse",
"io.jaegertracing.internal.samplers.http.ProbabilisticSamplingStrategy")
- .finalFieldsWritable(true)
- .build();
+ .finalFieldsWritable(true).build();
}
}
diff --git a/extensions/jaeger/deployment/src/main/java/io/quarkus/jaeger/deployment/ZipkinProcessor.java b/extensions/jaeger/deployment/src/main/java/io/quarkus/jaeger/deployment/ZipkinProcessor.java
new file mode 100644
index 0000000000000..aa506fa5bdf8b
--- /dev/null
+++ b/extensions/jaeger/deployment/src/main/java/io/quarkus/jaeger/deployment/ZipkinProcessor.java
@@ -0,0 +1,33 @@
+package io.quarkus.jaeger.deployment;
+
+import java.util.function.BooleanSupplier;
+
+import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
+import io.quarkus.deployment.annotations.BuildProducer;
+import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.jaeger.runtime.JaegerDeploymentRecorder;
+import io.quarkus.jaeger.runtime.ZipkinConfig;
+import io.quarkus.jaeger.runtime.ZipkinReporterProvider;
+
+public class ZipkinProcessor {
+
+ static final String REGISTRY_CLASS_NAME = "zipkin2.reporter.urlconnection.URLConnectionSender";
+ static final Class> REGISTRY_CLASS = JaegerDeploymentRecorder.getClassForName(REGISTRY_CLASS_NAME);
+
+ public static class ZipkinEnabled implements BooleanSupplier {
+ ZipkinConfig config;
+
+ public boolean getAsBoolean() {
+ return REGISTRY_CLASS != null && config.compatibilityMode;
+ }
+ }
+
+ @BuildStep(onlyIf = ZipkinEnabled.class)
+ void addZipkinClasses(BuildProducer additionalBeans) {
+
+ // Add Zipkin classes
+ additionalBeans.produce(AdditionalBeanBuildItem.builder().addBeanClass(ZipkinReporterProvider.class)
+ .setUnremovable().build());
+
+ }
+}
diff --git a/extensions/jaeger/deployment/src/test/java/io/quarkus/jaeger/test/QuarkusJaegerTracerTest.java b/extensions/jaeger/deployment/src/test/java/io/quarkus/jaeger/test/QuarkusJaegerTracerTest.java
new file mode 100644
index 0000000000000..302e586faf822
--- /dev/null
+++ b/extensions/jaeger/deployment/src/test/java/io/quarkus/jaeger/test/QuarkusJaegerTracerTest.java
@@ -0,0 +1,98 @@
+package io.quarkus.jaeger.test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+import javax.enterprise.inject.Default;
+import javax.enterprise.inject.Instance;
+import javax.enterprise.inject.spi.CDI;
+
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+
+import io.jaegertracing.Configuration;
+import io.jaegertracing.internal.JaegerTracer;
+import io.jaegertracing.internal.JaegerTracer.Builder;
+import io.jaegertracing.spi.Reporter;
+import io.jaegertracing.zipkin.ZipkinV2Reporter;
+import io.opentracing.Tracer;
+import io.quarkus.jaeger.runtime.QuarkusJaegerTracer;
+import io.quarkus.jaeger.runtime.ReporterFactory;
+import io.quarkus.jaeger.runtime.ZipkinReporterFactoryImpl;
+
+public class QuarkusJaegerTracerTest {
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void withzipkinCompatibilityMode() {
+
+ try (MockedStatic mockedStaticConfiguration = Mockito.mockStatic(Configuration.class);
+ MockedStatic mockedStaticCDI = Mockito.mockStatic(CDI.class)) {
+
+ CDI
+
+ io.quarkus
+ quarkus-arc
+
+
+ io.jaegertracing
+ jaeger-zipkin
+ true
+
jakarta.activation
diff --git a/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/JaegerDeploymentRecorder.java b/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/JaegerDeploymentRecorder.java
index 7140d386f2219..cb86e3fbc09d9 100644
--- a/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/JaegerDeploymentRecorder.java
+++ b/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/JaegerDeploymentRecorder.java
@@ -25,21 +25,25 @@ public void setJaegerVersion(String version) {
}
/* RUNTIME_INIT */
- public void registerTracerWithoutMetrics(JaegerConfig jaeger, ApplicationConfig appConfig) {
- registerTracer(jaeger, appConfig, new NoopMetricsFactory());
+ public void registerTracerWithoutMetrics(JaegerConfig jaeger, ApplicationConfig appConfig,
+ ZipkinConfig zipkinConfig) {
+ registerTracer(jaeger, appConfig, new NoopMetricsFactory(), zipkinConfig);
}
/* RUNTIME_INIT */
- public void registerTracerWithMpMetrics(JaegerConfig jaeger, ApplicationConfig appConfig) {
- registerTracer(jaeger, appConfig, new QuarkusJaegerMpMetricsFactory());
+ public void registerTracerWithMpMetrics(JaegerConfig jaeger, ApplicationConfig appConfig,
+ ZipkinConfig zipkinConfig) {
+ registerTracer(jaeger, appConfig, new QuarkusJaegerMpMetricsFactory(), zipkinConfig);
}
/* RUNTIME_INIT */
- public void registerTracerWithMicrometerMetrics(JaegerConfig jaeger, ApplicationConfig appConfig) {
- registerTracer(jaeger, appConfig, new QuarkusJaegerMicrometerFactory());
+ public void registerTracerWithMicrometerMetrics(JaegerConfig jaeger, ApplicationConfig appConfig,
+ ZipkinConfig zipkinConfig) {
+ registerTracer(jaeger, appConfig, new QuarkusJaegerMicrometerFactory(), zipkinConfig);
}
- private synchronized void registerTracer(JaegerConfig jaeger, ApplicationConfig appConfig, MetricsFactory metricsFactory) {
+ private synchronized void registerTracer(JaegerConfig jaeger, ApplicationConfig appConfig,
+ MetricsFactory metricsFactory, ZipkinConfig zipkinConfig) {
if (!jaeger.serviceName.isPresent()) {
if (appConfig.name.isPresent()) {
jaeger.serviceName = appConfig.name;
@@ -47,7 +51,7 @@ private synchronized void registerTracer(JaegerConfig jaeger, ApplicationConfig
jaeger.serviceName = UNKNOWN_SERVICE_NAME;
}
}
- initTracerConfig(jaeger);
+ initTracerConfig(jaeger, zipkinConfig);
quarkusTracer.setMetricsFactory(metricsFactory);
quarkusTracer.reset();
// register Quarkus tracer to GlobalTracer.
@@ -60,8 +64,11 @@ private synchronized void registerTracer(JaegerConfig jaeger, ApplicationConfig
}
}
- private void initTracerConfig(JaegerConfig jaeger) {
+ private void initTracerConfig(JaegerConfig jaeger, ZipkinConfig zipkinConfig) {
initTracerProperty("JAEGER_ENDPOINT", jaeger.endpoint, uri -> uri.toString());
+ if (jaeger.endpoint.isPresent()) {
+ quarkusTracer.setEndpoint(jaeger.endpoint.get().toString());
+ }
initTracerProperty("JAEGER_AUTH_TOKEN", jaeger.authToken, token -> token);
initTracerProperty("JAEGER_USER", jaeger.user, user -> user);
initTracerProperty("JAEGER_PASSWORD", jaeger.password, pw -> pw);
@@ -79,6 +86,7 @@ private void initTracerConfig(JaegerConfig jaeger) {
initTracerProperty("JAEGER_PROPAGATION", jaeger.propagation, format -> format.toString());
initTracerProperty("JAEGER_SENDER_FACTORY", jaeger.senderFactory, sender -> sender);
quarkusTracer.setLogTraceContext(jaeger.logTraceContext);
+ quarkusTracer.setZipkinCompatibilityMode(zipkinConfig.compatibilityMode);
}
private void initTracerProperty(String property, Optional value, Function accessor) {
@@ -92,4 +100,15 @@ private void initTracerProperty(String property, OptionalInt value, Function getClassForName(String className) {
+ Class> clazz = null;
+ try {
+ clazz = Class.forName(className, false, Thread.currentThread().getContextClassLoader());
+ } catch (ClassNotFoundException e) {
+ // Ignore exception
+ }
+ log.debugf("getClass: TCCL: %s ## %s : %s", Thread.currentThread().getContextClassLoader(), className, (clazz != null));
+ return clazz;
+ }
}
diff --git a/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/QuarkusJaegerTracer.java b/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/QuarkusJaegerTracer.java
index 49f64a7ee2b24..1e9ef522778e0 100644
--- a/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/QuarkusJaegerTracer.java
+++ b/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/QuarkusJaegerTracer.java
@@ -1,8 +1,15 @@
package io.quarkus.jaeger.runtime;
+import javax.enterprise.inject.Default;
+import javax.enterprise.inject.Instance;
+import javax.enterprise.inject.spi.CDI;
+
+import org.jboss.logging.Logger;
+
import io.jaegertracing.Configuration;
import io.jaegertracing.internal.JaegerTracer;
import io.jaegertracing.spi.MetricsFactory;
+import io.jaegertracing.spi.Reporter;
import io.opentracing.Scope;
import io.opentracing.ScopeManager;
import io.opentracing.Span;
@@ -17,6 +24,10 @@ public class QuarkusJaegerTracer implements Tracer {
private boolean logTraceContext;
private MetricsFactory metricsFactory;
+ private boolean zipkinCompatibilityMode = false;
+ private String endpoint = null;
+
+ private static final Logger log = Logger.getLogger(QuarkusJaegerTracer.class);
private final ScopeManager scopeManager = new ScopeManager() {
@@ -75,6 +86,7 @@ private Tracer tracer() {
.withMetricsFactory(metricsFactory)
.getTracerBuilder()
.withScopeManager(scopeManager)
+ .withReporter(createReporter())
.build();
}
}
@@ -82,6 +94,25 @@ private Tracer tracer() {
return tracer;
}
+ private Reporter createReporter() {
+ Reporter reporter = null;
+ if (zipkinCompatibilityMode) {
+ Instance registries = CDI.current().select(ReporterFactory.class,
+ Default.Literal.INSTANCE);
+ ReporterFactory factory = null;
+ if (registries.isAmbiguous()) {
+ factory = registries.iterator().next();
+ log.warnf("Multiple reporters present, using %s", factory.getClass().getName());
+ } else if (!registries.isUnsatisfied()) {
+ factory = registries.get();
+ }
+ if (factory != null) {
+ reporter = factory.createReporter(endpoint);
+ }
+ }
+ return reporter;
+ }
+
private ScopeManager getScopeManager() {
ScopeManager scopeManager = new ThreadLocalScopeManager();
if (logTraceContext) {
@@ -124,4 +155,12 @@ public Span activeSpan() {
public Scope activateSpan(final Span span) {
return tracer.activateSpan(span);
}
+
+ public void setZipkinCompatibilityMode(boolean zipkinCompatibilityMode) {
+ this.zipkinCompatibilityMode = zipkinCompatibilityMode;
+ }
+
+ public void setEndpoint(String endpoint) {
+ this.endpoint = endpoint;
+ }
}
diff --git a/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/ReporterFactory.java b/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/ReporterFactory.java
new file mode 100644
index 0000000000000..d061a6f69b26a
--- /dev/null
+++ b/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/ReporterFactory.java
@@ -0,0 +1,9 @@
+package io.quarkus.jaeger.runtime;
+
+import io.jaegertracing.spi.Reporter;
+
+public interface ReporterFactory {
+
+ Reporter createReporter(String endpoint);
+
+}
diff --git a/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/ZipkinConfig.java b/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/ZipkinConfig.java
new file mode 100644
index 0000000000000..5a1f2039ecfc6
--- /dev/null
+++ b/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/ZipkinConfig.java
@@ -0,0 +1,18 @@
+package io.quarkus.jaeger.runtime;
+
+import io.quarkus.runtime.annotations.ConfigItem;
+import io.quarkus.runtime.annotations.ConfigPhase;
+import io.quarkus.runtime.annotations.ConfigRoot;
+
+/**
+ * The Zipkin Jaeger configuration.
+ */
+@ConfigRoot(phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED, name = "jaeger.zipkin")
+public class ZipkinConfig {
+
+ /**
+ * Whether jaeger should run in zipkin compatibility mode
+ */
+ @ConfigItem(defaultValue = "false")
+ public Boolean compatibilityMode;
+}
diff --git a/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/ZipkinReporterFactoryImpl.java b/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/ZipkinReporterFactoryImpl.java
new file mode 100644
index 0000000000000..dbc5d3ba58151
--- /dev/null
+++ b/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/ZipkinReporterFactoryImpl.java
@@ -0,0 +1,16 @@
+package io.quarkus.jaeger.runtime;
+
+import io.jaegertracing.spi.Reporter;
+import io.jaegertracing.zipkin.ZipkinV2Reporter;
+import zipkin2.reporter.AsyncReporter;
+import zipkin2.reporter.urlconnection.URLConnectionSender;
+
+public class ZipkinReporterFactoryImpl implements ReporterFactory {
+
+ public Reporter createReporter(String endpoint) {
+
+ return new ZipkinV2Reporter(AsyncReporter.create(URLConnectionSender.create(endpoint)));
+
+ }
+
+}
diff --git a/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/ZipkinReporterProvider.java b/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/ZipkinReporterProvider.java
new file mode 100644
index 0000000000000..5f94d47fa4e33
--- /dev/null
+++ b/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/ZipkinReporterProvider.java
@@ -0,0 +1,13 @@
+package io.quarkus.jaeger.runtime;
+
+import javax.enterprise.inject.Produces;
+import javax.inject.Singleton;
+
+@Singleton
+public class ZipkinReporterProvider {
+ @Produces
+ @Singleton
+ public ReporterFactory reporter() {
+ return new ZipkinReporterFactoryImpl();
+ }
+}
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index 086e7db5e0aa6..e4d6324b4b29b 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -142,6 +142,7 @@
smallrye-metrics
smallrye-graphql
smallrye-graphql-client
+ smallrye-opentracing
jpa-without-entity
quartz
redis-client
@@ -328,4 +329,3 @@
-
diff --git a/integration-tests/smallrye-opentracing/pom.xml b/integration-tests/smallrye-opentracing/pom.xml
new file mode 100644
index 0000000000000..d7d6aec813b56
--- /dev/null
+++ b/integration-tests/smallrye-opentracing/pom.xml
@@ -0,0 +1,139 @@
+
+
+
+ quarkus-integration-tests-parent
+ io.quarkus
+ 999-SNAPSHOT
+
+ 4.0.0
+ quarkus-integration-test-smallrye-opentracing
+ Quarkus - Integration Tests - Smallrye Opentracing
+
+
+
+
+ io.quarkus
+ quarkus-resteasy
+
+
+ io.quarkus
+ quarkus-smallrye-opentracing
+
+
+
+
+ io.quarkus
+ quarkus-rest-client
+
+
+
+ io.quarkus
+ quarkus-junit5
+ test
+
+
+ io.rest-assured
+ rest-assured
+ test
+
+
+ com.github.tomakehurst
+ wiremock-jre8
+ test
+
+
+
+
+ io.quarkus
+ quarkus-rest-client-deployment
+ ${project.version}
+ pom
+ test
+
+
+ *
+ *
+
+
+
+
+ io.quarkus
+ quarkus-resteasy-deployment
+ ${project.version}
+ pom
+ test
+
+
+ *
+ *
+
+
+
+
+ io.quarkus
+ quarkus-smallrye-opentracing-deployment
+ ${project.version}
+ pom
+ test
+
+
+ *
+ *
+
+
+
+
+ io.jaegertracing
+ jaeger-zipkin
+
+
+
+
+
+
+
+ src/main/resources
+ true
+
+
+
+
+ io.quarkus
+ quarkus-maven-plugin
+
+
+
+ build
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+
+
+
+
+ native-image
+
+
+ native
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+
+
+
+
+
+
+
diff --git a/integration-tests/smallrye-opentracing/src/main/java/io/quarkus/it/rest/client/server/EchoService.java b/integration-tests/smallrye-opentracing/src/main/java/io/quarkus/it/rest/client/server/EchoService.java
new file mode 100644
index 0000000000000..3818ccc09b75a
--- /dev/null
+++ b/integration-tests/smallrye-opentracing/src/main/java/io/quarkus/it/rest/client/server/EchoService.java
@@ -0,0 +1,16 @@
+package io.quarkus.it.rest.client.server;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@Path("/echo")
+public class EchoService {
+
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public String echo() {
+ return "result";
+ }
+}
\ No newline at end of file
diff --git a/integration-tests/smallrye-opentracing/src/main/resources/application.properties b/integration-tests/smallrye-opentracing/src/main/resources/application.properties
new file mode 100644
index 0000000000000..cdb302678cee7
--- /dev/null
+++ b/integration-tests/smallrye-opentracing/src/main/resources/application.properties
@@ -0,0 +1,5 @@
+quarkus.jaeger.service-name=encryptions
+quarkus.jaeger.sampler-type=const
+quarkus.jaeger.sampler-param=1
+quarkus.jaeger.propagation=b3
+quarkus.jaeger.zipkin.compatibility-mode=true
\ No newline at end of file
diff --git a/integration-tests/smallrye-opentracing/src/test/java/io/quarkus/it/rest/client/WireMockZipkin.java b/integration-tests/smallrye-opentracing/src/test/java/io/quarkus/it/rest/client/WireMockZipkin.java
new file mode 100644
index 0000000000000..02b977c380a21
--- /dev/null
+++ b/integration-tests/smallrye-opentracing/src/test/java/io/quarkus/it/rest/client/WireMockZipkin.java
@@ -0,0 +1,39 @@
+package io.quarkus.it.rest.client;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.*;
+
+import java.util.Collections;
+import java.util.Map;
+
+import com.github.tomakehurst.wiremock.WireMockServer;
+
+import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
+
+public class WireMockZipkin implements QuarkusTestResourceLifecycleManager {
+
+ private static WireMockServer wireMockServer;
+
+ @Override
+ public Map start() {
+ wireMockServer = new WireMockServer();
+ wireMockServer.start();
+
+ stubFor(post(anyUrl()).withRequestBody(equalToJson(
+ "[{\"name\": \"get:io.quarkus.it.rest.client.server.echoservice.echo\",\"tags\": {\"component\": \"jaxrs\",\"http.method\": \"GET\",\"http.status_code\": \"200\",\"sampler.param\": \"true\",\"sampler.type\": \"const\"}}]",
+ true, true)).willReturn(aResponse().withStatus(200)));
+
+ return Collections.singletonMap("quarkus.jaeger.endpoint", wireMockServer.baseUrl() + "/zipkin");
+ }
+
+ @Override
+ public void stop() {
+ if (null != wireMockServer) {
+ wireMockServer.stop();
+ }
+ }
+
+ public static WireMockServer getWireMockServer() {
+ return wireMockServer;
+ }
+
+}
diff --git a/integration-tests/smallrye-opentracing/src/test/java/io/quarkus/it/rest/client/ZipkinIntegrationTest.java b/integration-tests/smallrye-opentracing/src/test/java/io/quarkus/it/rest/client/ZipkinIntegrationTest.java
new file mode 100644
index 0000000000000..5e9381baeeeb5
--- /dev/null
+++ b/integration-tests/smallrye-opentracing/src/test/java/io/quarkus/it/rest/client/ZipkinIntegrationTest.java
@@ -0,0 +1,46 @@
+package io.quarkus.it.rest.client;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
+import static com.github.tomakehurst.wiremock.client.WireMock.verify;
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.Date;
+
+import org.junit.jupiter.api.Test;
+
+import com.github.tomakehurst.wiremock.client.VerificationException;
+
+import io.quarkus.test.common.QuarkusTestResource;
+import io.quarkus.test.junit.QuarkusTest;
+
+@QuarkusTest
+@QuarkusTestResource(WireMockZipkin.class)
+public class ZipkinIntegrationTest {
+
+ @Test
+ public void testZipkinIntegration() {
+
+ given().when().get("/echo").then().statusCode(200).body(containsString("result"));
+
+ boolean continues = true;
+ long current = new Date().getTime();
+ while (continues) {
+ try {
+ verify(postRequestedFor(urlEqualTo("/zipkin")));
+ continues = false;
+ } catch (VerificationException e) {
+ // Because the request to zipkin is asynchronous we should wait maximum 10
+ // seconds.
+ if (new Date().getTime() - current > 10000) {
+ throw e;
+ }
+ }
+ }
+
+ assertEquals(0, WireMockZipkin.getWireMockServer().findAllUnmatchedRequests().size());
+ }
+
+}
diff --git a/integration-tests/smallrye-opentracing/src/test/java/io/quarkus/it/rest/client/ZipkinIntegrationTestIT.java b/integration-tests/smallrye-opentracing/src/test/java/io/quarkus/it/rest/client/ZipkinIntegrationTestIT.java
new file mode 100644
index 0000000000000..cd89e385e6350
--- /dev/null
+++ b/integration-tests/smallrye-opentracing/src/test/java/io/quarkus/it/rest/client/ZipkinIntegrationTestIT.java
@@ -0,0 +1,7 @@
+package io.quarkus.it.rest.client;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+public class ZipkinIntegrationTestIT extends ZipkinIntegrationTest {
+}