diff --git a/sdk/src/main/java/io/dapr/client/DaprHttp.java b/sdk/src/main/java/io/dapr/client/DaprHttp.java index 9398adafad..bcdd3f6c4b 100644 --- a/sdk/src/main/java/io/dapr/client/DaprHttp.java +++ b/sdk/src/main/java/io/dapr/client/DaprHttp.java @@ -23,13 +23,16 @@ import reactor.util.context.Context; import java.io.IOException; +import java.lang.reflect.Array; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -50,6 +53,12 @@ public class DaprHttp implements AutoCloseable { */ private static final String DEFAULT_HTTP_SCHEME = "http"; + /** + * Context entries allowed to be in HTTP Headers. + */ + private static final Set ALLOWED_CONTEXT_IN_HEADERS = + Collections.unmodifiableSet(new HashSet<>(Arrays.asList("grpc-trace-bin", "traceparent", "tracestate"))); + /** * HTTP Methods supported. */ @@ -267,8 +276,9 @@ private CompletableFuture doInvokeApi(String method, .url(urlBuilder.build()) .addHeader(HEADER_DAPR_REQUEST_ID, requestId); if (context != null) { - context.stream().forEach( - entry -> requestBuilder.addHeader(entry.getKey().toString(), entry.getValue().toString())); + context.stream() + .filter(entry -> ALLOWED_CONTEXT_IN_HEADERS.contains(entry.getKey().toString().toLowerCase())) + .forEach(entry -> requestBuilder.addHeader(entry.getKey().toString(), entry.getValue().toString())); } if (HttpMethods.GET.name().equals(method)) { requestBuilder.get(); diff --git a/sdk/src/test/java/io/dapr/client/DaprClientHttpTest.java b/sdk/src/test/java/io/dapr/client/DaprClientHttpTest.java index 8760794572..54de6f3baa 100644 --- a/sdk/src/test/java/io/dapr/client/DaprClientHttpTest.java +++ b/sdk/src/test/java/io/dapr/client/DaprClientHttpTest.java @@ -14,6 +14,7 @@ import io.dapr.client.domain.GetStateRequest; import io.dapr.client.domain.GetStateRequestBuilder; import io.dapr.client.domain.HttpExtension; +import io.dapr.client.domain.InvokeMethodRequest; import io.dapr.client.domain.PublishEventRequest; import io.dapr.client.domain.PublishEventRequestBuilder; import io.dapr.client.domain.State; @@ -36,6 +37,7 @@ import org.junit.Test; import org.mockito.Mockito; import reactor.core.publisher.Mono; +import reactor.util.context.Context; import java.io.IOException; import java.net.ServerSocket; @@ -388,6 +390,28 @@ public void invokeServiceNoHotMono() { // No exception should be thrown because did not call block() on mono above. } + @Test + public void invokeServiceWithContext() { + String traceparent = "00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01"; + String tracestate = "congo=ucfJifl5GOE,rojo=00f067aa0ba902b7"; + Context context = Context.empty() + .put("traceparent", traceparent) + .put("tracestate", tracestate) + .put("not_added", "xyz"); + mockInterceptor.addRule() + .post("http://127.0.0.1:3000/v1.0/invoke/41/method/neworder") + .header("traceparent", traceparent) + .header("tracestate", tracestate) + .respond(new byte[0]); + + InvokeMethodRequest req = new InvokeMethodRequest("41", "neworder") + .setBody("request") + .setHttpExtension(HttpExtension.POST); + Mono result = daprClientHttp.invokeMethod(req, TypeRef.get(Void.class)) + .subscriberContext(it -> it.putAll(context)); + result.block(); + } + @Test public void invokeBinding() { Map map = new HashMap<>();