From 8d49759e7832507e3824997ff11564342ede384d Mon Sep 17 00:00:00 2001 From: Matthew Li Date: Thu, 24 Jul 2025 13:35:58 -0400 Subject: [PATCH 1/6] adding check for repeated baggage --- .../.kotlin/errors/errors-1753377059848.log | 4 +++ .../grpc/client/GrpcInjectAdapter.java | 5 +++- .../core/propagation/HttpInjectorTest.groovy | 29 +++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 buildSrc/.kotlin/errors/errors-1753377059848.log diff --git a/buildSrc/.kotlin/errors/errors-1753377059848.log b/buildSrc/.kotlin/errors/errors-1753377059848.log new file mode 100644 index 00000000000..1219b509f09 --- /dev/null +++ b/buildSrc/.kotlin/errors/errors-1753377059848.log @@ -0,0 +1,4 @@ +kotlin version: 2.0.21 +error message: The daemon has terminated unexpectedly on startup attempt #1 with error code: 0. The daemon process output: + 1. Kotlin compile daemon is ready + diff --git a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/GrpcInjectAdapter.java b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/GrpcInjectAdapter.java index 72799867c90..12039f1188d 100644 --- a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/GrpcInjectAdapter.java +++ b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/GrpcInjectAdapter.java @@ -11,6 +11,9 @@ public final class GrpcInjectAdapter implements CarrierSetter { @Override public void set(final Metadata carrier, final String key, final String value) { - carrier.put(Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER), value); + Metadata.Key metadataKey = Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER); + if(!key.startsWith("ot-baggage-*") || !carrier.containsKey(metadataKey)){ + carrier.put(metadataKey, value); + } } } diff --git a/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/HttpInjectorTest.groovy b/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/HttpInjectorTest.groovy index 4274be2af55..e7b641e2c42 100644 --- a/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/HttpInjectorTest.groovy +++ b/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/HttpInjectorTest.groovy @@ -218,6 +218,35 @@ class HttpInjectorTest extends DDCoreSpecification { style << [DATADOG, TRACECONTEXT, HAYSTACK] } + def "inject ot-baggage-* in http headers only once"() { + setup: + Config config = Mock(Config) + def baggage = [ + 'k1': 'v1', + 'k2': 'v2', + ] + def mapping = baggage.keySet().collectEntries { [(it):it]} as Map + def injector = HttpCodec.createInjector(config, [DATADOG, TRACECONTEXT].toSet(), mapping) + def traceId = DDTraceId.ONE + def spanId = 2 + def writer = new ListWriter() + def tracer = tracerBuilder().writer(writer).build() + final DDSpanContext mockedContext = mockedContext(tracer, traceId, spanId, UNSET, null, baggage) + final Map carrier = Mock() + mockedContext.beginEndToEnd() + + when: + injector.inject(mockedContext, carrier, MapSetter.INSTANCE) + + then: + 1 * carrier.put('k1', 'v1') + 1 * carrier.put('k2', 'v2') + 1 * carrier.put('ot-baggage-t0', "${(long) (mockedContext.endToEndStartTime / 1000000L)}") + + cleanup: + tracer.close() + } + static DDSpanContext mockedContext(CoreTracer tracer, DDTraceId traceId, long spanId, int samplingPriority, String origin, Map baggage) { return new DDSpanContext( traceId, From 8ce88fd58194ef30d12d9a70da656405cec8eacf Mon Sep 17 00:00:00 2001 From: Matthew Li Date: Fri, 25 Jul 2025 13:36:08 -0400 Subject: [PATCH 2/6] writing unit tests --- .../grpc/client/GrpcInjectAdapter.java | 2 +- .../test/groovy/GrpcInjectAdapterTest.groovy | 47 +++++++++++++++++++ .../grpc/client/GrpcInjectAdapter.java | 5 +- .../test/groovy/GrpcInjectAdapterTest.groovy | 47 +++++++++++++++++++ .../core/propagation/HttpInjectorTest.groovy | 29 ------------ 5 files changed, 99 insertions(+), 31 deletions(-) create mode 100644 dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/test/groovy/GrpcInjectAdapterTest.groovy create mode 100644 dd-java-agent/instrumentation/grpc-1.5/src/test/groovy/GrpcInjectAdapterTest.groovy diff --git a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/GrpcInjectAdapter.java b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/GrpcInjectAdapter.java index 12039f1188d..a027619f859 100644 --- a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/GrpcInjectAdapter.java +++ b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/GrpcInjectAdapter.java @@ -12,7 +12,7 @@ public final class GrpcInjectAdapter implements CarrierSetter { @Override public void set(final Metadata carrier, final String key, final String value) { Metadata.Key metadataKey = Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER); - if(!key.startsWith("ot-baggage-*") || !carrier.containsKey(metadataKey)){ + if (!key.startsWith("ot-baggage-") || !carrier.containsKey(metadataKey)) { carrier.put(metadataKey, value); } } diff --git a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/test/groovy/GrpcInjectAdapterTest.groovy b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/test/groovy/GrpcInjectAdapterTest.groovy new file mode 100644 index 00000000000..e7714d53dbd --- /dev/null +++ b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/test/groovy/GrpcInjectAdapterTest.groovy @@ -0,0 +1,47 @@ +import datadog.trace.agent.test.naming.VersionedNamingTestBase +import io.grpc.Metadata +import static datadog.trace.instrumentation.grpc.client.GrpcInjectAdapter.SETTER + +class GrpcInjectAdapterTest extends VersionedNamingTestBase { + def "carrier set is called only once per unique ot-baggage-* key"() { + setup: + def carrier = new Metadata() + + def baggage = [ + ["ot-baggage-foo", "v1"], + ["ot-baggage-foo", "v2"], + ["ot-baggage-bar", "v3"] + ] + + when: + baggage.each { pair -> + def (key, value) = pair + SETTER.set(carrier, key, value) + } + + then: + carrier.headerCount() == 2 + carrier.get(getKey("ot-baggage-foo")) == "v1" // first value wins + carrier.get(getKey("ot-baggage-bar")) == "v3" + } + + Metadata.Key getKey(String key){ + Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER) + } + + + @Override + int version() { + return 0 + } + + @Override + String service() { + return null + } + + @Override + String operation() { + return null + } +} diff --git a/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/GrpcInjectAdapter.java b/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/GrpcInjectAdapter.java index 392e5647398..4280683af5e 100644 --- a/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/GrpcInjectAdapter.java +++ b/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/GrpcInjectAdapter.java @@ -10,6 +10,9 @@ public final class GrpcInjectAdapter implements CarrierSetter { @Override public void set(final Metadata carrier, final String key, final String value) { - carrier.put(Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER), value); + Metadata.Key metadataKey = Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER); + if (!key.startsWith("ot-baggage-") || !carrier.containsKey(metadataKey)) { + carrier.put(metadataKey, value); + } } } diff --git a/dd-java-agent/instrumentation/grpc-1.5/src/test/groovy/GrpcInjectAdapterTest.groovy b/dd-java-agent/instrumentation/grpc-1.5/src/test/groovy/GrpcInjectAdapterTest.groovy new file mode 100644 index 00000000000..e7714d53dbd --- /dev/null +++ b/dd-java-agent/instrumentation/grpc-1.5/src/test/groovy/GrpcInjectAdapterTest.groovy @@ -0,0 +1,47 @@ +import datadog.trace.agent.test.naming.VersionedNamingTestBase +import io.grpc.Metadata +import static datadog.trace.instrumentation.grpc.client.GrpcInjectAdapter.SETTER + +class GrpcInjectAdapterTest extends VersionedNamingTestBase { + def "carrier set is called only once per unique ot-baggage-* key"() { + setup: + def carrier = new Metadata() + + def baggage = [ + ["ot-baggage-foo", "v1"], + ["ot-baggage-foo", "v2"], + ["ot-baggage-bar", "v3"] + ] + + when: + baggage.each { pair -> + def (key, value) = pair + SETTER.set(carrier, key, value) + } + + then: + carrier.headerCount() == 2 + carrier.get(getKey("ot-baggage-foo")) == "v1" // first value wins + carrier.get(getKey("ot-baggage-bar")) == "v3" + } + + Metadata.Key getKey(String key){ + Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER) + } + + + @Override + int version() { + return 0 + } + + @Override + String service() { + return null + } + + @Override + String operation() { + return null + } +} diff --git a/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/HttpInjectorTest.groovy b/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/HttpInjectorTest.groovy index e7b641e2c42..4274be2af55 100644 --- a/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/HttpInjectorTest.groovy +++ b/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/HttpInjectorTest.groovy @@ -218,35 +218,6 @@ class HttpInjectorTest extends DDCoreSpecification { style << [DATADOG, TRACECONTEXT, HAYSTACK] } - def "inject ot-baggage-* in http headers only once"() { - setup: - Config config = Mock(Config) - def baggage = [ - 'k1': 'v1', - 'k2': 'v2', - ] - def mapping = baggage.keySet().collectEntries { [(it):it]} as Map - def injector = HttpCodec.createInjector(config, [DATADOG, TRACECONTEXT].toSet(), mapping) - def traceId = DDTraceId.ONE - def spanId = 2 - def writer = new ListWriter() - def tracer = tracerBuilder().writer(writer).build() - final DDSpanContext mockedContext = mockedContext(tracer, traceId, spanId, UNSET, null, baggage) - final Map carrier = Mock() - mockedContext.beginEndToEnd() - - when: - injector.inject(mockedContext, carrier, MapSetter.INSTANCE) - - then: - 1 * carrier.put('k1', 'v1') - 1 * carrier.put('k2', 'v2') - 1 * carrier.put('ot-baggage-t0', "${(long) (mockedContext.endToEndStartTime / 1000000L)}") - - cleanup: - tracer.close() - } - static DDSpanContext mockedContext(CoreTracer tracer, DDTraceId traceId, long spanId, int samplingPriority, String origin, Map baggage) { return new DDSpanContext( traceId, From 772512296d10945ab2ac54bc6bfd8340ab96bdbd Mon Sep 17 00:00:00 2001 From: Matthew Li Date: Fri, 25 Jul 2025 13:37:19 -0400 Subject: [PATCH 3/6] pushing removal of error log --- buildSrc/.kotlin/errors/errors-1753377059848.log | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 buildSrc/.kotlin/errors/errors-1753377059848.log diff --git a/buildSrc/.kotlin/errors/errors-1753377059848.log b/buildSrc/.kotlin/errors/errors-1753377059848.log deleted file mode 100644 index 1219b509f09..00000000000 --- a/buildSrc/.kotlin/errors/errors-1753377059848.log +++ /dev/null @@ -1,4 +0,0 @@ -kotlin version: 2.0.21 -error message: The daemon has terminated unexpectedly on startup attempt #1 with error code: 0. The daemon process output: - 1. Kotlin compile daemon is ready - From 59288cd39165e27c1dd39cdaaf5b434dd07cd211 Mon Sep 17 00:00:00 2001 From: Matthew Li Date: Fri, 25 Jul 2025 13:46:43 -0400 Subject: [PATCH 4/6] adding test to verify allowing repeated non-baggage keys to be set --- .../test/groovy/GrpcInjectAdapterTest.groovy | 18 ++++++++++++++++++ .../test/groovy/GrpcInjectAdapterTest.groovy | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/test/groovy/GrpcInjectAdapterTest.groovy b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/test/groovy/GrpcInjectAdapterTest.groovy index e7714d53dbd..0bc5e731ad3 100644 --- a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/test/groovy/GrpcInjectAdapterTest.groovy +++ b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/test/groovy/GrpcInjectAdapterTest.groovy @@ -25,6 +25,24 @@ class GrpcInjectAdapterTest extends VersionedNamingTestBase { carrier.get(getKey("ot-baggage-bar")) == "v3" } + def "carrier set is can set repeated keys that are not ot-baggage-*"() { + setup: + def carrier = new Metadata() + + def baggage = [["foo", "v1"], ["foo", "v2"], ["bar", "v3"]] + + when: + baggage.each { pair -> + def (key, value) = pair + SETTER.set(carrier, key, value) + } + + then: + carrier.headerCount() == 3 + carrier.get(getKey("foo")) == "v2" // last value wins + carrier.get(getKey("bar")) == "v3" + } + Metadata.Key getKey(String key){ Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER) } diff --git a/dd-java-agent/instrumentation/grpc-1.5/src/test/groovy/GrpcInjectAdapterTest.groovy b/dd-java-agent/instrumentation/grpc-1.5/src/test/groovy/GrpcInjectAdapterTest.groovy index e7714d53dbd..0bc5e731ad3 100644 --- a/dd-java-agent/instrumentation/grpc-1.5/src/test/groovy/GrpcInjectAdapterTest.groovy +++ b/dd-java-agent/instrumentation/grpc-1.5/src/test/groovy/GrpcInjectAdapterTest.groovy @@ -25,6 +25,24 @@ class GrpcInjectAdapterTest extends VersionedNamingTestBase { carrier.get(getKey("ot-baggage-bar")) == "v3" } + def "carrier set is can set repeated keys that are not ot-baggage-*"() { + setup: + def carrier = new Metadata() + + def baggage = [["foo", "v1"], ["foo", "v2"], ["bar", "v3"]] + + when: + baggage.each { pair -> + def (key, value) = pair + SETTER.set(carrier, key, value) + } + + then: + carrier.headerCount() == 3 + carrier.get(getKey("foo")) == "v2" // last value wins + carrier.get(getKey("bar")) == "v3" + } + Metadata.Key getKey(String key){ Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER) } From 7ee1712b7694886615e789d0175b768d10fbb640 Mon Sep 17 00:00:00 2001 From: Matthew Li Date: Mon, 28 Jul 2025 10:24:07 -0400 Subject: [PATCH 5/6] update GRPC inject to not allow all repeated keys --- .../armeria/grpc/client/GrpcInjectAdapter.java | 2 +- .../test/groovy/GrpcInjectAdapterTest.groovy | 18 ------------------ .../grpc/client/GrpcInjectAdapter.java | 2 +- .../test/groovy/GrpcInjectAdapterTest.groovy | 18 ------------------ 4 files changed, 2 insertions(+), 38 deletions(-) diff --git a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/GrpcInjectAdapter.java b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/GrpcInjectAdapter.java index a027619f859..ca5b472a3be 100644 --- a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/GrpcInjectAdapter.java +++ b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/GrpcInjectAdapter.java @@ -12,7 +12,7 @@ public final class GrpcInjectAdapter implements CarrierSetter { @Override public void set(final Metadata carrier, final String key, final String value) { Metadata.Key metadataKey = Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER); - if (!key.startsWith("ot-baggage-") || !carrier.containsKey(metadataKey)) { + if (!carrier.containsKey(metadataKey)) { carrier.put(metadataKey, value); } } diff --git a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/test/groovy/GrpcInjectAdapterTest.groovy b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/test/groovy/GrpcInjectAdapterTest.groovy index 0bc5e731ad3..e7714d53dbd 100644 --- a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/test/groovy/GrpcInjectAdapterTest.groovy +++ b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/test/groovy/GrpcInjectAdapterTest.groovy @@ -25,24 +25,6 @@ class GrpcInjectAdapterTest extends VersionedNamingTestBase { carrier.get(getKey("ot-baggage-bar")) == "v3" } - def "carrier set is can set repeated keys that are not ot-baggage-*"() { - setup: - def carrier = new Metadata() - - def baggage = [["foo", "v1"], ["foo", "v2"], ["bar", "v3"]] - - when: - baggage.each { pair -> - def (key, value) = pair - SETTER.set(carrier, key, value) - } - - then: - carrier.headerCount() == 3 - carrier.get(getKey("foo")) == "v2" // last value wins - carrier.get(getKey("bar")) == "v3" - } - Metadata.Key getKey(String key){ Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER) } diff --git a/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/GrpcInjectAdapter.java b/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/GrpcInjectAdapter.java index 4280683af5e..d46b6d55cb1 100644 --- a/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/GrpcInjectAdapter.java +++ b/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/GrpcInjectAdapter.java @@ -11,7 +11,7 @@ public final class GrpcInjectAdapter implements CarrierSetter { @Override public void set(final Metadata carrier, final String key, final String value) { Metadata.Key metadataKey = Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER); - if (!key.startsWith("ot-baggage-") || !carrier.containsKey(metadataKey)) { + if (!carrier.containsKey(metadataKey)) { carrier.put(metadataKey, value); } } diff --git a/dd-java-agent/instrumentation/grpc-1.5/src/test/groovy/GrpcInjectAdapterTest.groovy b/dd-java-agent/instrumentation/grpc-1.5/src/test/groovy/GrpcInjectAdapterTest.groovy index 0bc5e731ad3..e7714d53dbd 100644 --- a/dd-java-agent/instrumentation/grpc-1.5/src/test/groovy/GrpcInjectAdapterTest.groovy +++ b/dd-java-agent/instrumentation/grpc-1.5/src/test/groovy/GrpcInjectAdapterTest.groovy @@ -25,24 +25,6 @@ class GrpcInjectAdapterTest extends VersionedNamingTestBase { carrier.get(getKey("ot-baggage-bar")) == "v3" } - def "carrier set is can set repeated keys that are not ot-baggage-*"() { - setup: - def carrier = new Metadata() - - def baggage = [["foo", "v1"], ["foo", "v2"], ["bar", "v3"]] - - when: - baggage.each { pair -> - def (key, value) = pair - SETTER.set(carrier, key, value) - } - - then: - carrier.headerCount() == 3 - carrier.get(getKey("foo")) == "v2" // last value wins - carrier.get(getKey("bar")) == "v3" - } - Metadata.Key getKey(String key){ Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER) } From e0d11ad90af2afec21a61d195e10a7613163dbd3 Mon Sep 17 00:00:00 2001 From: Matthew Li Date: Wed, 30 Jul 2025 12:36:04 -0400 Subject: [PATCH 6/6] final updates --- .../armeria/grpc/client/GrpcInjectAdapter.java | 6 ++++-- .../src/test/groovy/GrpcInjectAdapterTest.groovy | 4 ++-- .../instrumentation/grpc/client/GrpcInjectAdapter.java | 6 ++++-- .../grpc-1.5/src/test/groovy/GrpcInjectAdapterTest.groovy | 4 ++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/GrpcInjectAdapter.java b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/GrpcInjectAdapter.java index ca5b472a3be..931d729c6e1 100644 --- a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/GrpcInjectAdapter.java +++ b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/GrpcInjectAdapter.java @@ -12,8 +12,10 @@ public final class GrpcInjectAdapter implements CarrierSetter { @Override public void set(final Metadata carrier, final String key, final String value) { Metadata.Key metadataKey = Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER); - if (!carrier.containsKey(metadataKey)) { - carrier.put(metadataKey, value); + if (carrier.containsKey(metadataKey)) { + carrier.removeAll( + metadataKey); // Remove existing to ensure identical behavior with other carriers } + carrier.put(metadataKey, value); } } diff --git a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/test/groovy/GrpcInjectAdapterTest.groovy b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/test/groovy/GrpcInjectAdapterTest.groovy index e7714d53dbd..abb6ad7db8c 100644 --- a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/test/groovy/GrpcInjectAdapterTest.groovy +++ b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/test/groovy/GrpcInjectAdapterTest.groovy @@ -3,7 +3,7 @@ import io.grpc.Metadata import static datadog.trace.instrumentation.grpc.client.GrpcInjectAdapter.SETTER class GrpcInjectAdapterTest extends VersionedNamingTestBase { - def "carrier set is called only once per unique ot-baggage-* key"() { + def "carrier overrides values for duplicate keys"() { setup: def carrier = new Metadata() @@ -21,7 +21,7 @@ class GrpcInjectAdapterTest extends VersionedNamingTestBase { then: carrier.headerCount() == 2 - carrier.get(getKey("ot-baggage-foo")) == "v1" // first value wins + carrier.get(getKey("ot-baggage-foo")) == "v2" // overridden value wins carrier.get(getKey("ot-baggage-bar")) == "v3" } diff --git a/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/GrpcInjectAdapter.java b/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/GrpcInjectAdapter.java index d46b6d55cb1..a969dcb8771 100644 --- a/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/GrpcInjectAdapter.java +++ b/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/GrpcInjectAdapter.java @@ -11,8 +11,10 @@ public final class GrpcInjectAdapter implements CarrierSetter { @Override public void set(final Metadata carrier, final String key, final String value) { Metadata.Key metadataKey = Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER); - if (!carrier.containsKey(metadataKey)) { - carrier.put(metadataKey, value); + if (carrier.containsKey(metadataKey)) { + carrier.removeAll( + metadataKey); // Remove existing to ensure identical behavior with other carriers } + carrier.put(metadataKey, value); } } diff --git a/dd-java-agent/instrumentation/grpc-1.5/src/test/groovy/GrpcInjectAdapterTest.groovy b/dd-java-agent/instrumentation/grpc-1.5/src/test/groovy/GrpcInjectAdapterTest.groovy index e7714d53dbd..abb6ad7db8c 100644 --- a/dd-java-agent/instrumentation/grpc-1.5/src/test/groovy/GrpcInjectAdapterTest.groovy +++ b/dd-java-agent/instrumentation/grpc-1.5/src/test/groovy/GrpcInjectAdapterTest.groovy @@ -3,7 +3,7 @@ import io.grpc.Metadata import static datadog.trace.instrumentation.grpc.client.GrpcInjectAdapter.SETTER class GrpcInjectAdapterTest extends VersionedNamingTestBase { - def "carrier set is called only once per unique ot-baggage-* key"() { + def "carrier overrides values for duplicate keys"() { setup: def carrier = new Metadata() @@ -21,7 +21,7 @@ class GrpcInjectAdapterTest extends VersionedNamingTestBase { then: carrier.headerCount() == 2 - carrier.get(getKey("ot-baggage-foo")) == "v1" // first value wins + carrier.get(getKey("ot-baggage-foo")) == "v2" // overridden value wins carrier.get(getKey("ot-baggage-bar")) == "v3" }