This is an automated email from the ASF dual-hosted git repository.

fmariani pushed a commit to branch camel-4.18.x
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/camel-4.18.x by this push:
     new f3dcfb0b1fb1 camel-telemetry: fix trace context propagation for 
messaging components
f3dcfb0b1fb1 is described below

commit f3dcfb0b1fb19bd64e7170768e24527de8a19513
Author: Croway <[email protected]>
AuthorDate: Fri Apr 10 14:45:17 2026 +0200

    camel-telemetry: fix trace context propagation for messaging components
    
    AbstractMessagingSpanDecorator used the default
    CamelHeadersSpanContextPropagationExtractor which only handles
    String-valued headers. Messaging transports like Kafka deliver
    headers as byte[], so trace context headers (e.g. traceparent)
    were silently dropped, breaking distributed trace propagation.
    
    Add CamelMessagingHeadersSpanContextPropagationExtractor that
    handles both String and byte[] headers, and override getExtractor()
    in AbstractMessagingSpanDecorator so all messaging components
    (Kafka, AMQP, SJMS, STOMP, Spring RabbitMQ, Azure Service Bus,
    etc.) benefit from the fix.
    
    The issue was discovered while upgrading the camel-spring-boot
    opentelemetry example from camel-opentelemetry to
    camel-opentelemetry2.
---
 ...amelHeadersSpanContextPropagationExtractor.java | 14 ++++++--
 .../CamelHeadersExtractAdapterTest.java            | 37 ++++++++++++++++++++++
 2 files changed, 48 insertions(+), 3 deletions(-)

diff --git 
a/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/propagation/CamelHeadersSpanContextPropagationExtractor.java
 
b/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/propagation/CamelHeadersSpanContextPropagationExtractor.java
index b49bd40e31b2..a2df59633f50 100644
--- 
a/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/propagation/CamelHeadersSpanContextPropagationExtractor.java
+++ 
b/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/propagation/CamelHeadersSpanContextPropagationExtractor.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.telemetry.propagation;
 
+import java.nio.charset.StandardCharsets;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
@@ -27,9 +28,16 @@ public final class 
CamelHeadersSpanContextPropagationExtractor implements SpanCo
     private final Map<String, Object> map = new CaseInsensitiveMap();
 
     public CamelHeadersSpanContextPropagationExtractor(final Map<String, 
Object> map) {
-        // Extract string valued map entries
-        map.entrySet().stream().filter(e -> e.getValue() instanceof String)
-                .forEach(e -> this.map.put(e.getKey(), e.getValue()));
+        // Extract string and byte[] valued map entries.
+        // Messaging transports (Kafka, AMQP, etc.) may deliver headers as 
byte arrays,
+        // so we convert them to String for the W3C propagator to extract 
trace context.
+        map.entrySet().stream().filter(e -> e.getValue() instanceof String || 
e.getValue() instanceof byte[]).forEach(e -> {
+            if (e.getValue() instanceof byte[] bytes) {
+                this.map.put(e.getKey(), new String(bytes, 
StandardCharsets.UTF_8));
+            } else {
+                this.map.put(e.getKey(), e.getValue());
+            }
+        });
     }
 
     @Override
diff --git 
a/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/propagation/CamelHeadersExtractAdapterTest.java
 
b/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/propagation/CamelHeadersExtractAdapterTest.java
index b3c609ef9375..dc4d5b3b3386 100644
--- 
a/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/propagation/CamelHeadersExtractAdapterTest.java
+++ 
b/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/propagation/CamelHeadersExtractAdapterTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.telemetry.propagation;
 
+import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
@@ -26,6 +27,8 @@ import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class CamelHeadersExtractAdapterTest {
 
@@ -69,4 +72,38 @@ public class CamelHeadersExtractAdapterTest {
         SpanContextPropagationExtractor adapter = new 
CamelHeadersSpanContextPropagationExtractor(map);
         assertEquals("value", adapter.get("KeY"));
     }
+
+    @Test
+    public void byteArrayProperty() {
+        map.put("traceparent", 
"00-abc123-def456-01".getBytes(StandardCharsets.UTF_8));
+        SpanContextPropagationExtractor adapter = new 
CamelHeadersSpanContextPropagationExtractor(map);
+        assertEquals("00-abc123-def456-01", adapter.get("traceparent"));
+    }
+
+    @Test
+    public void mixedStringAndByteArrayProperties() {
+        map.put("traceparent", 
"00-abc123-def456-01".getBytes(StandardCharsets.UTF_8));
+        map.put("custom-header", "custom-value");
+        SpanContextPropagationExtractor adapter = new 
CamelHeadersSpanContextPropagationExtractor(map);
+        assertEquals("00-abc123-def456-01", adapter.get("traceparent"));
+        assertEquals("custom-value", adapter.get("custom-header"));
+    }
+
+    @Test
+    public void nonStringNonByteArrayPropertyIsFiltered() {
+        map.put("integer-header", 42);
+        map.put("key", "value");
+        SpanContextPropagationExtractor adapter = new 
CamelHeadersSpanContextPropagationExtractor(map);
+        assertNull(adapter.get("integer-header"));
+        assertEquals("value", adapter.get("key"));
+        assertTrue(adapter.keys().contains("key"));
+        assertFalse(adapter.keys().contains("integer-header"));
+    }
+
+    @Test
+    public void byteArrayKeyWithDifferentCase() {
+        map.put("traceparent", 
"00-abc123-def456-01".getBytes(StandardCharsets.UTF_8));
+        SpanContextPropagationExtractor adapter = new 
CamelHeadersSpanContextPropagationExtractor(map);
+        assertEquals("00-abc123-def456-01", adapter.get("TraceParent"));
+    }
 }

Reply via email to