mirror of https://github.com/dapr/java-sdk.git
Add support for DAPR_API_TOKEN (#330)
* Add supoort for DAPR_API_TOKEN * Add tests for dapr api token * Move interceptor logic * Remove additional interceptor * Fix check style voilation * Add dapr api token as system property
This commit is contained in:
parent
eede480403
commit
7b174d88e8
|
@ -84,6 +84,12 @@
|
||||||
<version>1.3.2</version>
|
<version>1.3.2</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.stefanbirkner</groupId>
|
||||||
|
<artifactId>system-rules</artifactId>
|
||||||
|
<version>1.19.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-engine</artifactId>
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
|
|
@ -21,6 +21,8 @@ import io.dapr.client.domain.SaveStateRequest;
|
||||||
import io.dapr.client.domain.State;
|
import io.dapr.client.domain.State;
|
||||||
import io.dapr.client.domain.StateOptions;
|
import io.dapr.client.domain.StateOptions;
|
||||||
import io.dapr.serializer.DaprObjectSerializer;
|
import io.dapr.serializer.DaprObjectSerializer;
|
||||||
|
import io.dapr.utils.Constants;
|
||||||
|
import io.dapr.utils.Properties;
|
||||||
import io.dapr.utils.TypeRef;
|
import io.dapr.utils.TypeRef;
|
||||||
import io.dapr.v1.CommonProtos;
|
import io.dapr.v1.CommonProtos;
|
||||||
import io.dapr.v1.DaprGrpc;
|
import io.dapr.v1.DaprGrpc;
|
||||||
|
@ -32,6 +34,7 @@ import io.grpc.ClientInterceptor;
|
||||||
import io.grpc.Context;
|
import io.grpc.Context;
|
||||||
import io.grpc.ForwardingClientCall;
|
import io.grpc.ForwardingClientCall;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
|
import io.grpc.Metadata.Key;
|
||||||
import io.grpc.MethodDescriptor;
|
import io.grpc.MethodDescriptor;
|
||||||
import io.opencensus.implcore.trace.propagation.PropagationComponentImpl;
|
import io.opencensus.implcore.trace.propagation.PropagationComponentImpl;
|
||||||
import io.opencensus.implcore.trace.propagation.TraceContextFormat;
|
import io.opencensus.implcore.trace.propagation.TraceContextFormat;
|
||||||
|
@ -483,8 +486,14 @@ public class DaprClientGrpc extends AbstractDaprClient {
|
||||||
SpanContext opencensusSpanContext = extractOpenCensusSpanContext(context);
|
SpanContext opencensusSpanContext = extractOpenCensusSpanContext(context);
|
||||||
if (opencensusSpanContext != null) {
|
if (opencensusSpanContext != null) {
|
||||||
byte[] grpcTraceBin = OPENCENSUS_BINARY_FORMAT.toByteArray(opencensusSpanContext);
|
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);
|
super.start(responseListener, headers);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,6 +9,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import io.dapr.exceptions.DaprError;
|
import io.dapr.exceptions.DaprError;
|
||||||
import io.dapr.exceptions.DaprException;
|
import io.dapr.exceptions.DaprException;
|
||||||
import io.dapr.utils.Constants;
|
import io.dapr.utils.Constants;
|
||||||
|
import io.dapr.utils.Properties;
|
||||||
import io.grpc.Context;
|
import io.grpc.Context;
|
||||||
import io.opentelemetry.OpenTelemetry;
|
import io.opentelemetry.OpenTelemetry;
|
||||||
import io.opentelemetry.context.propagation.HttpTextFormat;
|
import io.opentelemetry.context.propagation.HttpTextFormat;
|
||||||
|
@ -258,6 +259,12 @@ public class DaprHttp implements Closeable {
|
||||||
} else {
|
} else {
|
||||||
requestBuilder.method(method, body);
|
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) {
|
if (headers != null) {
|
||||||
Optional.ofNullable(headers.entrySet()).orElse(Collections.emptySet()).stream()
|
Optional.ofNullable(headers.entrySet()).orElse(Collections.emptySet()).stream()
|
||||||
.forEach(header -> {
|
.forEach(header -> {
|
||||||
|
@ -308,4 +315,4 @@ public class DaprHttp implements Closeable {
|
||||||
return EMPTY_BYTES;
|
return EMPTY_BYTES;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -60,6 +60,16 @@ public final class Constants {
|
||||||
*/
|
*/
|
||||||
public static final String ACTOR_TIMER_RELATIVE_URL_FORMAT = ACTORS_BASE_URL + "/%s/%s/timers/%s";
|
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.
|
* Base path to invoke methods.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -35,6 +35,13 @@ public class Properties {
|
||||||
*/
|
*/
|
||||||
private static final String DEFAULT_STRING_CHARSET = StandardCharsets.UTF_8.name();
|
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<String> DAPR_API_TOKEN = () -> getStringOrDefault(
|
||||||
|
"dapr.api.token",
|
||||||
|
Constants.DAPR_API_TOKEN, null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HTTP port for Dapr after checking system property and environment variable.
|
* 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).
|
* @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));
|
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).
|
* @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));
|
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).
|
* @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);
|
return getValueOrDefault(propName, envName, defaultValue, s -> s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ package io.dapr.client;
|
||||||
|
|
||||||
import io.dapr.exceptions.DaprException;
|
import io.dapr.exceptions.DaprException;
|
||||||
import io.dapr.utils.Constants;
|
import io.dapr.utils.Constants;
|
||||||
|
import io.dapr.utils.Properties;
|
||||||
import io.grpc.Context;
|
import io.grpc.Context;
|
||||||
import okhttp3.MediaType;
|
import okhttp3.MediaType;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
|
@ -13,6 +14,8 @@ import okhttp3.ResponseBody;
|
||||||
import okhttp3.mock.Behavior;
|
import okhttp3.mock.Behavior;
|
||||||
import okhttp3.mock.MockInterceptor;
|
import okhttp3.mock.MockInterceptor;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.contrib.java.lang.system.EnvironmentVariables;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
@ -27,6 +30,9 @@ import static org.junit.Assert.fail;
|
||||||
|
|
||||||
public class DaprHttpTest {
|
public class DaprHttpTest {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final EnvironmentVariables environmentVariables = new EnvironmentVariables();
|
||||||
|
|
||||||
private static final String EXPECTED_RESULT =
|
private static final String EXPECTED_RESULT =
|
||||||
"{\"data\":\"ewoJCSJwcm9wZXJ0eUEiOiAidmFsdWVBIiwKCQkicHJvcGVydHlCIjogInZhbHVlQiIKCX0=\"}";
|
"{\"data\":\"ewoJCSJwcm9wZXJ0eUEiOiAidmFsdWVBIiwKCQkicHJvcGVydHlCIjogInZhbHVlQiIKCX0=\"}";
|
||||||
|
|
||||||
|
@ -42,6 +48,38 @@ public class DaprHttpTest {
|
||||||
okHttpClient = new OkHttpClient.Builder().addInterceptor(mockInterceptor).build();
|
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<DaprHttp.Response> 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<DaprHttp.Response> 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
|
@Test
|
||||||
public void invokeMethod() throws IOException {
|
public void invokeMethod() throws IOException {
|
||||||
Map<String, String> headers = new HashMap<>();
|
Map<String, String> headers = new HashMap<>();
|
||||||
|
|
Loading…
Reference in New Issue