diff --git a/sdk/pom.xml b/sdk/pom.xml
index ebc02e516..efbc58811 100644
--- a/sdk/pom.xml
+++ b/sdk/pom.xml
@@ -84,6 +84,12 @@
1.3.2
test
+
+ com.github.stefanbirkner
+ system-rules
+ 1.19.0
+ test
+
org.junit.jupiter
junit-jupiter-engine
diff --git a/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java b/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java
index 527117708..79581a7c4 100644
--- a/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java
+++ b/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java
@@ -21,6 +21,8 @@ import io.dapr.client.domain.SaveStateRequest;
import io.dapr.client.domain.State;
import io.dapr.client.domain.StateOptions;
import io.dapr.serializer.DaprObjectSerializer;
+import io.dapr.utils.Constants;
+import io.dapr.utils.Properties;
import io.dapr.utils.TypeRef;
import io.dapr.v1.CommonProtos;
import io.dapr.v1.DaprGrpc;
@@ -32,6 +34,7 @@ import io.grpc.ClientInterceptor;
import io.grpc.Context;
import io.grpc.ForwardingClientCall;
import io.grpc.Metadata;
+import io.grpc.Metadata.Key;
import io.grpc.MethodDescriptor;
import io.opencensus.implcore.trace.propagation.PropagationComponentImpl;
import io.opencensus.implcore.trace.propagation.TraceContextFormat;
@@ -483,8 +486,14 @@ public class DaprClientGrpc extends AbstractDaprClient {
SpanContext opencensusSpanContext = extractOpenCensusSpanContext(context);
if (opencensusSpanContext != null) {
byte[] grpcTraceBin = OPENCENSUS_BINARY_FORMAT.toByteArray(opencensusSpanContext);
- headers.put(Metadata.Key.of("grpc-trace-bin", Metadata.BINARY_BYTE_MARSHALLER), grpcTraceBin);
+ headers.put(Key.of("grpc-trace-bin", Metadata.BINARY_BYTE_MARSHALLER), grpcTraceBin);
}
+
+ String daprApiToken = Properties.DAPR_API_TOKEN.get();
+ if (daprApiToken != null) {
+ headers.put(Key.of(Constants.DAPR_API_TOKEN_HEADER, Metadata.ASCII_STRING_MARSHALLER), daprApiToken);
+ }
+
super.start(responseListener, headers);
}
};
diff --git a/sdk/src/main/java/io/dapr/client/DaprHttp.java b/sdk/src/main/java/io/dapr/client/DaprHttp.java
index 73e33946c..7962c0be2 100644
--- a/sdk/src/main/java/io/dapr/client/DaprHttp.java
+++ b/sdk/src/main/java/io/dapr/client/DaprHttp.java
@@ -9,6 +9,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import io.dapr.exceptions.DaprError;
import io.dapr.exceptions.DaprException;
import io.dapr.utils.Constants;
+import io.dapr.utils.Properties;
import io.grpc.Context;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.context.propagation.HttpTextFormat;
@@ -258,6 +259,12 @@ public class DaprHttp implements Closeable {
} else {
requestBuilder.method(method, body);
}
+
+ String daprApiToken = Properties.DAPR_API_TOKEN.get();
+ if (daprApiToken != null) {
+ requestBuilder.addHeader(Constants.DAPR_API_TOKEN_HEADER, daprApiToken);
+ }
+
if (headers != null) {
Optional.ofNullable(headers.entrySet()).orElse(Collections.emptySet()).stream()
.forEach(header -> {
@@ -308,4 +315,4 @@ public class DaprHttp implements Closeable {
return EMPTY_BYTES;
}
-}
+}
\ No newline at end of file
diff --git a/sdk/src/main/java/io/dapr/utils/Constants.java b/sdk/src/main/java/io/dapr/utils/Constants.java
index 481463052..218fa9259 100644
--- a/sdk/src/main/java/io/dapr/utils/Constants.java
+++ b/sdk/src/main/java/io/dapr/utils/Constants.java
@@ -60,6 +60,16 @@ public final class Constants {
*/
public static final String ACTOR_TIMER_RELATIVE_URL_FORMAT = ACTORS_BASE_URL + "/%s/%s/timers/%s";
+ /**
+ * Environment variable name for dapr api token.
+ */
+ public static final String DAPR_API_TOKEN = "DAPR_API_TOKEN";
+
+ /**
+ * Header name for the dapr api token environment variable name.
+ */
+ public static final String DAPR_API_TOKEN_HEADER = "dapr-api-token";
+
/**
* Base path to invoke methods.
*/
diff --git a/sdk/src/main/java/io/dapr/utils/Properties.java b/sdk/src/main/java/io/dapr/utils/Properties.java
index 2f0ce7774..6009c3005 100644
--- a/sdk/src/main/java/io/dapr/utils/Properties.java
+++ b/sdk/src/main/java/io/dapr/utils/Properties.java
@@ -35,6 +35,13 @@ public class Properties {
*/
private static final String DEFAULT_STRING_CHARSET = StandardCharsets.UTF_8.name();
+ /**
+ * API token for Dapr after checking system property and environment variable.
+ */
+ public static final Supplier DAPR_API_TOKEN = () -> getStringOrDefault(
+ "dapr.api.token",
+ Constants.DAPR_API_TOKEN, null);
+
/**
* HTTP port for Dapr after checking system property and environment variable.
*/
@@ -70,7 +77,7 @@ public class Properties {
*
* @return Integer from system property (1st) or env variable (2nd) or default (last).
*/
- public static Integer getIntOrDefault(String propName, String envName, Integer defaultValue) {
+ private static Integer getIntOrDefault(String propName, String envName, Integer defaultValue) {
return getValueOrDefault(propName, envName, defaultValue, s -> Integer.valueOf(s));
}
@@ -82,7 +89,7 @@ public class Properties {
*
* @return Boolean from system property (1st) or env variable (2nd) or default (last).
*/
- public static Boolean getBooleanOrDefault(String propName, String envName, Boolean defaultValue) {
+ private static Boolean getBooleanOrDefault(String propName, String envName, Boolean defaultValue) {
return getValueOrDefault(propName, envName, defaultValue, s -> Boolean.valueOf(s));
}
@@ -94,7 +101,7 @@ public class Properties {
*
* @return String from system property (1st) or env variable (2nd) or default (last).
*/
- public static String getStringOrDefault(String propName, String envName, String defaultValue) {
+ private static String getStringOrDefault(String propName, String envName, String defaultValue) {
return getValueOrDefault(propName, envName, defaultValue, s -> s);
}
diff --git a/sdk/src/test/java/io/dapr/client/DaprHttpTest.java b/sdk/src/test/java/io/dapr/client/DaprHttpTest.java
index 57726827f..ba2415935 100644
--- a/sdk/src/test/java/io/dapr/client/DaprHttpTest.java
+++ b/sdk/src/test/java/io/dapr/client/DaprHttpTest.java
@@ -6,6 +6,7 @@ package io.dapr.client;
import io.dapr.exceptions.DaprException;
import io.dapr.utils.Constants;
+import io.dapr.utils.Properties;
import io.grpc.Context;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
@@ -13,6 +14,8 @@ import okhttp3.ResponseBody;
import okhttp3.mock.Behavior;
import okhttp3.mock.MockInterceptor;
import org.junit.Before;
+import org.junit.contrib.java.lang.system.EnvironmentVariables;
+import org.junit.Rule;
import org.junit.Test;
import reactor.core.publisher.Mono;
@@ -27,6 +30,9 @@ import static org.junit.Assert.fail;
public class DaprHttpTest {
+ @Rule
+ public final EnvironmentVariables environmentVariables = new EnvironmentVariables();
+
private static final String EXPECTED_RESULT =
"{\"data\":\"ewoJCSJwcm9wZXJ0eUEiOiAidmFsdWVBIiwKCQkicHJvcGVydHlCIjogInZhbHVlQiIKCX0=\"}";
@@ -42,6 +48,38 @@ public class DaprHttpTest {
okHttpClient = new OkHttpClient.Builder().addInterceptor(mockInterceptor).build();
}
+ @Test
+ public void invokeApi_daprApiToken_present() throws IOException {
+ mockInterceptor.addRule()
+ .post("http://127.0.0.1:3500/v1.0/state")
+ .hasHeader(Constants.DAPR_API_TOKEN_HEADER)
+ .respond(serializer.serialize(EXPECTED_RESULT));
+ environmentVariables.set(Constants.DAPR_API_TOKEN, "xyz");
+ assertEquals("xyz", Properties.DAPR_API_TOKEN.get());
+ DaprHttp daprHttp = new DaprHttp(3500, okHttpClient);
+ Mono mono =
+ daprHttp.invokeApi("POST", "v1.0/state", null, (byte[]) null, null, Context.current());
+ DaprHttp.Response response = mono.block();
+ String body = serializer.deserialize(response.getBody(), String.class);
+ assertEquals(EXPECTED_RESULT, body);
+ }
+
+ @Test
+ public void invokeApi_daprApiToken_absent() throws IOException {
+ mockInterceptor.addRule()
+ .post("http://127.0.0.1:3500/v1.0/state")
+ .not()
+ .hasHeader(Constants.DAPR_API_TOKEN_HEADER)
+ .respond(serializer.serialize(EXPECTED_RESULT));
+ assertNull(Properties.DAPR_API_TOKEN.get());
+ DaprHttp daprHttp = new DaprHttp(3500, okHttpClient);
+ Mono mono =
+ daprHttp.invokeApi("POST", "v1.0/state", null, (byte[]) null, null, Context.current());
+ DaprHttp.Response response = mono.block();
+ String body = serializer.deserialize(response.getBody(), String.class);
+ assertEquals(EXPECTED_RESULT, body);
+ }
+
@Test
public void invokeMethod() throws IOException {
Map headers = new HashMap<>();