diff --git a/sdk-tests/pom.xml b/sdk-tests/pom.xml
index b274bf9907..467e7ce06c 100644
--- a/sdk-tests/pom.xml
+++ b/sdk-tests/pom.xml
@@ -30,6 +30,7 @@
${project.basedir}/proto
1.33.1
3.13.0
+ 0.14.0
@@ -63,6 +64,21 @@
protoc-jar-maven-plugin
3.10.1
+
+ io.opentelemetry
+ opentelemetry-sdk
+ ${opentelemetry.version}
+
+
+ io.opentelemetry
+ opentelemetry-exporter-logging
+ ${opentelemetry.version}
+
+
+ io.opentelemetry
+ opentelemetry-exporter-zipkin
+ ${opentelemetry.version}
+
io.dapr
dapr-sdk
@@ -105,6 +121,12 @@
2.3.5.RELEASE
test
+
+ com.jayway.jsonpath
+ json-path
+ 2.4.0
+ test
+
com.bettercloud
diff --git a/sdk-tests/src/test/java/io/dapr/it/tracing/OpenTelemetry.java b/sdk-tests/src/test/java/io/dapr/it/tracing/OpenTelemetry.java
new file mode 100644
index 0000000000..7b8c7a77c6
--- /dev/null
+++ b/sdk-tests/src/test/java/io/dapr/it/tracing/OpenTelemetry.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) Microsoft Corporation and Dapr Contributors.
+ * Licensed under the MIT License.
+ */
+
+package io.dapr.it.tracing;
+
+import io.opentelemetry.api.GlobalOpenTelemetry;
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
+import io.opentelemetry.context.Context;
+import io.opentelemetry.context.propagation.ContextPropagators;
+import io.opentelemetry.context.propagation.TextMapPropagator;
+import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter;
+import io.opentelemetry.sdk.OpenTelemetrySdk;
+import io.opentelemetry.sdk.trace.SdkTracerProvider;
+import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.Map;
+
+public class OpenTelemetry {
+
+ private static final int ZIPKIN_PORT = 9411;
+
+ private static final String ENDPOINT_V2_SPANS = "/api/v2/spans";
+
+ /**
+ * Creates an opentelemetry instance.
+ * @param serviceName Name of the service in Zipkin
+ * @return OpenTelemetry.
+ */
+ public static io.opentelemetry.api.OpenTelemetry createOpenTelemetry(String serviceName) {
+ // Only exports to Zipkin if it is up. Otherwise, ignore it.
+ // This is helpful to avoid exceptions for examples that do not require Zipkin.
+ if (isZipkinUp()) {
+ String httpUrl = String.format("http://localhost:%d", ZIPKIN_PORT);
+ ZipkinSpanExporter zipkinExporter =
+ ZipkinSpanExporter.builder()
+ .setEndpoint(httpUrl + ENDPOINT_V2_SPANS)
+ .setServiceName(serviceName)
+ .build();
+
+ SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
+ .addSpanProcessor(SimpleSpanProcessor.create(zipkinExporter))
+ .build();
+
+ return OpenTelemetrySdk.builder()
+ .setTracerProvider(sdkTracerProvider)
+ .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
+ .buildAndRegisterGlobal();
+ } else {
+ System.out.println("WARNING: Zipkin is not available.");
+ }
+
+ return null;
+ }
+
+ /**
+ * Converts current OpenTelemetry's context into Reactor's context.
+ * @return Reactor's context.
+ */
+ public static reactor.util.context.Context getReactorContext() {
+ return getReactorContext(Context.current());
+ }
+
+ /**
+ * Converts given OpenTelemetry's context into Reactor's context.
+ * @param context OpenTelemetry's context.
+ * @return Reactor's context.
+ */
+ public static reactor.util.context.Context getReactorContext(Context context) {
+ Map map = new HashMap<>();
+ TextMapPropagator.Setter