This is an automated email from the ASF dual-hosted git repository.
davsclaus 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 eb13e893d87a [backport camel-4.18.x] CAMEL-26490: camel-telemetry,
camel-tracing - present the http.url, url.path and server.address span
attributes like camel.uri (#28995)
eb13e893d87a is described below
commit eb13e893d87ae19a20ba9cc84c08386ea88152b4
Author: Guillaume Nodet <[email protected]>
AuthorDate: Tue Nov 3 08:56:32 2026 +0100
[backport camel-4.18.x] CAMEL-26490: camel-telemetry, camel-tracing -
present the http.url, url.path and server.address span attributes like
camel.uri (#28995)
Backport of #28867 (cherry-pick of b59a37efd89c).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
---
.../decorators/AbstractHttpSpanDecorator.java | 41 ++++++++--
.../decorators/AbstractSpanDecorator.java | 21 ++++-
.../decorators/AbstractHttpSpanDecoratorTest.java | 95 ++++++++++++++++++++--
.../decorators/AbstractSpanDecoratorTest.java | 56 +++++++++++++
.../decorators/AbstractHttpSpanDecorator.java | 41 ++++++++--
.../tracing/decorators/AbstractSpanDecorator.java | 21 ++++-
.../decorators/AbstractHttpSpanDecoratorTest.java | 95 ++++++++++++++++++++--
.../decorators/AbstractSpanDecoratorTest.java | 56 +++++++++++++
.../ROOT/pages/camel-4x-upgrade-guide-4_18.adoc | 17 ++++
9 files changed, 411 insertions(+), 32 deletions(-)
diff --git
a/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/decorators/AbstractHttpSpanDecorator.java
b/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/decorators/AbstractHttpSpanDecorator.java
index 24a1216e796c..0e3029674ab5 100644
---
a/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/decorators/AbstractHttpSpanDecorator.java
+++
b/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/decorators/AbstractHttpSpanDecorator.java
@@ -19,9 +19,12 @@ package org.apache.camel.telemetry.decorators;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
import org.apache.camel.Message;
+import org.apache.camel.spi.EndpointServiceLocation;
import org.apache.camel.telemetry.Op;
import org.apache.camel.telemetry.Span;
import org.apache.camel.telemetry.TagConstants;
+import org.apache.camel.util.StringHelper;
+import org.apache.camel.util.URISupport;
public abstract class AbstractHttpSpanDecorator extends AbstractSpanDecorator {
@@ -76,22 +79,46 @@ public abstract class AbstractHttpSpanDecorator extends
AbstractSpanDecorator {
}
protected String getHttpURL(Exchange exchange, Endpoint endpoint) {
+ // the url is presented the same way as the camel.uri tag
Object url = exchange.getIn().getHeader(Exchange.HTTP_URL);
if (url instanceof String str) {
- return str;
+ return URISupport.sanitizeUri(str);
} else {
Object uri = exchange.getIn().getHeader(Exchange.HTTP_URI);
if (uri instanceof String str) {
- return str;
+ return URISupport.sanitizeUri(str);
} else {
// Try to obtain from endpoint
- int index = endpoint.getEndpointUri().lastIndexOf("http:");
- if (index != -1) {
- return endpoint.getEndpointUri().substring(index);
- }
+ return URISupport.sanitizeUri(getHttpAddress(endpoint));
+ }
+ }
+ }
+
+ /**
+ * The HTTP address the endpoint sends to, without the endpoint options.
+ */
+ private static String getHttpAddress(Endpoint endpoint) {
+ // the service url of an HTTP endpoint is its HTTP address with the
query parameters that are sent
+ if (endpoint instanceof EndpointServiceLocation esl) {
+ String url = esl.getServiceUrl();
+ if (isHttpAddress(url)) {
+ return url;
}
}
- return null;
+ // otherwise take the endpoint uri, without the component scheme in
front of the HTTP address
+ // (such as netty-http:http://host or vertx-http://https://host) and
without the endpoint options
+ String uri = endpoint.getEndpointUri();
+ if (!isHttpAddress(uri)) {
+ uri = StringHelper.after(uri, ":");
+ if (uri != null && uri.startsWith("//")) {
+ uri = uri.substring(2);
+ }
+ }
+ return isHttpAddress(uri) ? URISupport.stripQuery(uri) : null;
+ }
+
+ private static boolean isHttpAddress(String uri) {
+ return uri != null && (uri.startsWith("http://") ||
uri.startsWith("https://"));
}
@Override
diff --git
a/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/decorators/AbstractSpanDecorator.java
b/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/decorators/AbstractSpanDecorator.java
index 352b3974fd4c..4cba91594b27 100644
---
a/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/decorators/AbstractSpanDecorator.java
+++
b/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/decorators/AbstractSpanDecorator.java
@@ -89,6 +89,22 @@ public abstract class AbstractSpanDecorator implements
SpanDecorator {
return Collections.emptyMap();
}
+ /**
+ * The path of the endpoint URI without the scheme, the user info in front
of the host and the options.
+ */
+ private static String getUrlPath(Endpoint endpoint) {
+ String path = stripSchemeAndOptions(endpoint);
+ // the user info ends at the last @ before the first /
+ int colon = path.indexOf(':');
+ int slash = path.indexOf('/');
+ int at = slash == -1 ? path.lastIndexOf('@') : path.lastIndexOf('@',
slash);
+ if (colon != -1 && colon < at) {
+ path = path.substring(at + 1);
+ }
+ // presented the same way as the camel.uri tag, for a path that is
another uri (such as netty-http:http://host)
+ return URISupport.sanitizeUri(path);
+ }
+
private static String getComponentName(Endpoint endpoint) {
String answer = endpoint.getComponent() != null ?
endpoint.getComponent().getDefaultName() : null;
if (answer == null) {
@@ -123,7 +139,7 @@ public abstract class AbstractSpanDecorator implements
SpanDecorator {
// have been provided, for subsequent analysis
String uri = endpoint.toString(); // toString will sanitize
span.setTag("camel.uri", uri);
- span.setTag(TagConstants.URL_PATH, stripSchemeAndOptions(endpoint));
+ span.setTag(TagConstants.URL_PATH, getUrlPath(endpoint));
String query = URISupport.extractQuery(uri);
if (query != null) {
span.setTag(TagConstants.URL_QUERY, query);
@@ -133,7 +149,8 @@ public abstract class AbstractSpanDecorator implements
SpanDecorator {
if (endpoint instanceof EndpointServiceLocation ela) {
String adr = ela.getServiceUrl();
if (adr != null) {
- span.setTag(TagConstants.SERVER_ADDRESS, adr);
+ // the address is presented the same way as the camel.uri tag
+ span.setTag(TagConstants.SERVER_ADDRESS,
URISupport.sanitizeUri(adr));
}
String ap = ela.getServiceProtocol();
if (ap != null) {
diff --git
a/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/decorators/AbstractHttpSpanDecoratorTest.java
b/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/decorators/AbstractHttpSpanDecoratorTest.java
index 9e7314b4e255..6b05fed0994c 100644
---
a/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/decorators/AbstractHttpSpanDecoratorTest.java
+++
b/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/decorators/AbstractHttpSpanDecoratorTest.java
@@ -19,6 +19,7 @@ package org.apache.camel.telemetry.decorators;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
import org.apache.camel.Message;
+import org.apache.camel.spi.EndpointServiceLocation;
import org.apache.camel.telemetry.TagConstants;
import org.apache.camel.telemetry.mock.MockSpanAdapter;
import org.junit.jupiter.api.BeforeEach;
@@ -150,9 +151,9 @@ public class AbstractHttpSpanDecoratorTest {
Exchange exchange = Mockito.mock(Exchange.class);
Message message = Mockito.mock(Message.class);
- Mockito.when(endpoint.getEndpointUri()).thenReturn(TEST_URI);
+
Mockito.when(endpoint.getEndpointUri()).thenReturn("http://localhost:8080/endpoint");
Mockito.when(exchange.getIn()).thenReturn(message);
- Mockito.when(message.getHeader(Exchange.HTTP_URI,
String.class)).thenReturn(TEST_URI);
+
Mockito.when(message.getHeader(Exchange.HTTP_URI)).thenReturn(TEST_URI);
MockSpanAdapter span = new MockSpanAdapter();
@@ -168,10 +169,10 @@ public class AbstractHttpSpanDecoratorTest {
Exchange exchange = Mockito.mock(Exchange.class);
Message message = Mockito.mock(Message.class);
- Mockito.when(endpoint.getEndpointUri()).thenReturn(TEST_URI);
+
Mockito.when(endpoint.getEndpointUri()).thenReturn("http://localhost:8080/endpoint");
Mockito.when(exchange.getIn()).thenReturn(message);
- Mockito.when(message.getHeader(Exchange.HTTP_URI,
String.class)).thenReturn("Another URL");
- Mockito.when(message.getHeader(Exchange.HTTP_URL,
String.class)).thenReturn(TEST_URI);
+ Mockito.when(message.getHeader(Exchange.HTTP_URI)).thenReturn("Another
URL");
+
Mockito.when(message.getHeader(Exchange.HTTP_URL)).thenReturn(TEST_URI);
assertEquals(TEST_URI, decorator.getHttpURL(exchange, endpoint));
}
@@ -182,13 +183,26 @@ public class AbstractHttpSpanDecoratorTest {
Exchange exchange = Mockito.mock(Exchange.class);
Message message = Mockito.mock(Message.class);
- Mockito.when(endpoint.getEndpointUri()).thenReturn(TEST_URI);
+
Mockito.when(endpoint.getEndpointUri()).thenReturn("http://localhost:8080/endpoint");
Mockito.when(exchange.getIn()).thenReturn(message);
- Mockito.when(message.getHeader(Exchange.HTTP_URI,
String.class)).thenReturn(TEST_URI);
+
Mockito.when(message.getHeader(Exchange.HTTP_URI)).thenReturn(TEST_URI);
assertEquals(TEST_URI, decorator.getHttpURL(exchange, endpoint));
}
+ @Test
+ public void testGetHttpURLFromHeaderUrlPresentedLikeCamelUri() {
+ Endpoint endpoint = Mockito.mock(Endpoint.class);
+ Exchange exchange = Mockito.mock(Exchange.class);
+ Message message = Mockito.mock(Message.class);
+
+ Mockito.when(endpoint.getEndpointUri()).thenReturn(TEST_URI);
+ Mockito.when(exchange.getIn()).thenReturn(message);
+
Mockito.when(message.getHeader(Exchange.HTTP_URL)).thenReturn("http://scott:tiger@localhost:8080/test");
+
+ assertEquals("http://scott:xxxxxx@localhost:8080/test",
decorator.getHttpURL(exchange, endpoint));
+ }
+
@Test
public void testGetHttpURLFromEndpointUri() {
Endpoint endpoint = Mockito.mock(Endpoint.class);
@@ -213,6 +227,73 @@ public class AbstractHttpSpanDecoratorTest {
assertEquals(TEST_URI, decorator.getHttpURL(exchange, endpoint));
}
+ @Test
+ public void testGetHttpURLFromEndpointUriWithoutEndpointOptions() {
+ Endpoint endpoint = Mockito.mock(Endpoint.class);
+ Exchange exchange = Mockito.mock(Exchange.class);
+ Message message = Mockito.mock(Message.class);
+
+ Mockito.when(endpoint.getEndpointUri()).thenReturn(TEST_URI +
"?connectTimeout=5000&throwExceptionOnFailure=false");
+ Mockito.when(exchange.getIn()).thenReturn(message);
+
+ assertEquals(TEST_URI, decorator.getHttpURL(exchange, endpoint));
+ }
+
+ @Test
+ public void
testGetHttpURLFromEndpointUriWithComponentSchemeAndHttpsAddress() {
+ Endpoint endpoint = Mockito.mock(Endpoint.class);
+ Exchange exchange = Mockito.mock(Exchange.class);
+ Message message = Mockito.mock(Message.class);
+
+
Mockito.when(endpoint.getEndpointUri()).thenReturn("vertx-http://https://localhost:8443/test?connectTimeout=5000");
+ Mockito.when(exchange.getIn()).thenReturn(message);
+
+ assertEquals("https://localhost:8443/test",
decorator.getHttpURL(exchange, endpoint));
+ }
+
+ @Test
+ public void testGetHttpURLFromServiceUrl() {
+ Endpoint endpoint = Mockito.mock(Endpoint.class,
Mockito.withSettings().extraInterfaces(EndpointServiceLocation.class));
+ Exchange exchange = Mockito.mock(Exchange.class);
+ Message message = Mockito.mock(Message.class);
+
+
Mockito.when(endpoint.getEndpointUri()).thenReturn("https://localhost:8443/test?q=1&connectTimeout=5000");
+ Mockito.when(((EndpointServiceLocation)
endpoint).getServiceUrl()).thenReturn("https://localhost:8443/test?q=1");
+ Mockito.when(exchange.getIn()).thenReturn(message);
+
+ assertEquals("https://localhost:8443/test?q=1",
decorator.getHttpURL(exchange, endpoint));
+ }
+
+ @Test
+ public void testGetHttpURLFromEndpointUriWhenServiceUrlIsNotHttpAddress() {
+ Endpoint endpoint = Mockito.mock(Endpoint.class,
Mockito.withSettings().extraInterfaces(EndpointServiceLocation.class));
+ Exchange exchange = Mockito.mock(Exchange.class);
+ Message message = Mockito.mock(Message.class);
+
+ Mockito.when(endpoint.getEndpointUri()).thenReturn("netty-http:" +
TEST_URI);
+ Mockito.when(((EndpointServiceLocation)
endpoint).getServiceUrl()).thenReturn("http:localhost:8080");
+ Mockito.when(exchange.getIn()).thenReturn(message);
+
+ assertEquals(TEST_URI, decorator.getHttpURL(exchange, endpoint));
+ }
+
+ @Test
+ public void testPreHttpsEndpoint() {
+ Endpoint endpoint = Mockito.mock(Endpoint.class,
Mockito.withSettings().extraInterfaces(EndpointServiceLocation.class));
+ Exchange exchange = Mockito.mock(Exchange.class);
+ Message message = Mockito.mock(Message.class);
+
+
Mockito.when(endpoint.getEndpointUri()).thenReturn("https://localhost:8443/test?connectTimeout=5000");
+ Mockito.when(((EndpointServiceLocation)
endpoint).getServiceUrl()).thenReturn("https://localhost:8443/test");
+ Mockito.when(exchange.getIn()).thenReturn(message);
+
+ MockSpanAdapter span = new MockSpanAdapter();
+
+ decorator.beforeTracingEvent(span, exchange, endpoint);
+
+ assertEquals("https://localhost:8443/test",
span.tags().get(TagConstants.HTTP_URL));
+ }
+
@Test
public void testPostResponseCode() {
Exchange exchange = Mockito.mock(Exchange.class);
diff --git
a/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/decorators/AbstractSpanDecoratorTest.java
b/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/decorators/AbstractSpanDecoratorTest.java
index 5bcf53a26b91..5fb9154abbc5 100644
---
a/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/decorators/AbstractSpanDecoratorTest.java
+++
b/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/decorators/AbstractSpanDecoratorTest.java
@@ -18,6 +18,7 @@ package org.apache.camel.telemetry.decorators;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
+import org.apache.camel.spi.EndpointServiceLocation;
import org.apache.camel.telemetry.SpanDecorator;
import org.apache.camel.telemetry.TagConstants;
import org.apache.camel.telemetry.mock.MockSpanAdapter;
@@ -85,6 +86,61 @@ public class AbstractSpanDecoratorTest {
assertEquals("myRouteId", span.tags().get(TagConstants.ROUTE_ID));
}
+ @Test
+ public void testPreUrlPathWithoutUserInfo() {
+ Endpoint endpoint = Mockito.mock(Endpoint.class);
+ Exchange exchange = Mockito.mock(Exchange.class);
+
+
Mockito.when(endpoint.getEndpointUri()).thenReturn("ftp://scott:tiger@localhost:2121/inbox?binary=true");
+
Mockito.when(endpoint.toString()).thenReturn("ftp://scott:xxxxxx@localhost:2121/inbox?binary=true");
+
+ SpanDecorator decorator = new AbstractSpanDecorator() {
+ @Override
+ public String getComponent() {
+ return null;
+ }
+
+ @Override
+ public String getComponentClassName() {
+ return null;
+ }
+ };
+
+ MockSpanAdapter span = new MockSpanAdapter();
+
+ decorator.beforeTracingEvent(span, exchange, endpoint);
+
+ assertEquals("localhost:2121/inbox",
span.tags().get(TagConstants.URL_PATH));
+ assertEquals("binary=true", span.tags().get(TagConstants.URL_QUERY));
+ }
+
+ @Test
+ public void testPreServerAddressPresentedLikeCamelUri() {
+ Endpoint endpoint = Mockito.mock(Endpoint.class,
Mockito.withSettings().extraInterfaces(EndpointServiceLocation.class));
+ Exchange exchange = Mockito.mock(Exchange.class);
+
+ Mockito.when(endpoint.getEndpointUri()).thenReturn("amqp:queue:foo");
+ Mockito.when(((EndpointServiceLocation)
endpoint).getServiceUrl()).thenReturn("amqp://scott:tiger@localhost:5672");
+
+ SpanDecorator decorator = new AbstractSpanDecorator() {
+ @Override
+ public String getComponent() {
+ return null;
+ }
+
+ @Override
+ public String getComponentClassName() {
+ return null;
+ }
+ };
+
+ MockSpanAdapter span = new MockSpanAdapter();
+
+ decorator.beforeTracingEvent(span, exchange, endpoint);
+
+ assertEquals("amqp://scott:xxxxxx@localhost:5672",
span.tags().get(TagConstants.SERVER_ADDRESS));
+ }
+
@Test
public void testPostExchangeFailed() {
Exchange exchange = Mockito.mock(Exchange.class);
diff --git
a/components/camel-tracing/src/main/java/org/apache/camel/tracing/decorators/AbstractHttpSpanDecorator.java
b/components/camel-tracing/src/main/java/org/apache/camel/tracing/decorators/AbstractHttpSpanDecorator.java
index 058c4e660b69..b56f669b15db 100644
---
a/components/camel-tracing/src/main/java/org/apache/camel/tracing/decorators/AbstractHttpSpanDecorator.java
+++
b/components/camel-tracing/src/main/java/org/apache/camel/tracing/decorators/AbstractHttpSpanDecorator.java
@@ -19,8 +19,11 @@ package org.apache.camel.tracing.decorators;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
import org.apache.camel.Message;
+import org.apache.camel.spi.EndpointServiceLocation;
import org.apache.camel.tracing.SpanAdapter;
import org.apache.camel.tracing.TagConstants;
+import org.apache.camel.util.StringHelper;
+import org.apache.camel.util.URISupport;
public abstract class AbstractHttpSpanDecorator extends AbstractSpanDecorator {
@@ -75,22 +78,46 @@ public abstract class AbstractHttpSpanDecorator extends
AbstractSpanDecorator {
}
protected String getHttpURL(Exchange exchange, Endpoint endpoint) {
+ // the url is presented the same way as the camel.uri tag
Object url = exchange.getIn().getHeader(Exchange.HTTP_URL);
if (url instanceof String) {
- return (String) url;
+ return URISupport.sanitizeUri((String) url);
} else {
Object uri = exchange.getIn().getHeader(Exchange.HTTP_URI);
if (uri instanceof String) {
- return (String) uri;
+ return URISupport.sanitizeUri((String) uri);
} else {
// Try to obtain from endpoint
- int index = endpoint.getEndpointUri().lastIndexOf("http:");
- if (index != -1) {
- return endpoint.getEndpointUri().substring(index);
- }
+ return URISupport.sanitizeUri(getHttpAddress(endpoint));
}
}
- return null;
+ }
+
+ /**
+ * The HTTP address the endpoint sends to, without the endpoint options.
+ */
+ private static String getHttpAddress(Endpoint endpoint) {
+ // the service url of an HTTP endpoint is its HTTP address with the
query parameters that are sent
+ if (endpoint instanceof EndpointServiceLocation esl) {
+ String url = esl.getServiceUrl();
+ if (isHttpAddress(url)) {
+ return url;
+ }
+ }
+ // otherwise take the endpoint uri, without the component scheme in
front of the HTTP address
+ // (such as netty-http:http://host or vertx-http://https://host) and
without the endpoint options
+ String uri = endpoint.getEndpointUri();
+ if (!isHttpAddress(uri)) {
+ uri = StringHelper.after(uri, ":");
+ if (uri != null && uri.startsWith("//")) {
+ uri = uri.substring(2);
+ }
+ }
+ return isHttpAddress(uri) ? URISupport.stripQuery(uri) : null;
+ }
+
+ private static boolean isHttpAddress(String uri) {
+ return uri != null && (uri.startsWith("http://") ||
uri.startsWith("https://"));
}
@Override
diff --git
a/components/camel-tracing/src/main/java/org/apache/camel/tracing/decorators/AbstractSpanDecorator.java
b/components/camel-tracing/src/main/java/org/apache/camel/tracing/decorators/AbstractSpanDecorator.java
index cefb3445f8d8..f3670c375490 100644
---
a/components/camel-tracing/src/main/java/org/apache/camel/tracing/decorators/AbstractSpanDecorator.java
+++
b/components/camel-tracing/src/main/java/org/apache/camel/tracing/decorators/AbstractSpanDecorator.java
@@ -87,6 +87,22 @@ public abstract class AbstractSpanDecorator implements
SpanDecorator {
return Collections.emptyMap();
}
+ /**
+ * The path of the endpoint URI without the scheme, the user info in front
of the host and the options.
+ */
+ private static String getUrlPath(Endpoint endpoint) {
+ String path = stripSchemeAndOptions(endpoint);
+ // the user info ends at the last @ before the first /
+ int colon = path.indexOf(':');
+ int slash = path.indexOf('/');
+ int at = slash == -1 ? path.lastIndexOf('@') : path.lastIndexOf('@',
slash);
+ if (colon != -1 && colon < at) {
+ path = path.substring(at + 1);
+ }
+ // presented the same way as the camel.uri tag, for a path that is
another uri (such as netty-http:http://host)
+ return URISupport.sanitizeUri(path);
+ }
+
private static String getComponentName(Endpoint endpoint) {
String answer = endpoint.getComponent() != null ?
endpoint.getComponent().getDefaultName() : null;
if (answer == null) {
@@ -128,7 +144,7 @@ public abstract class AbstractSpanDecorator implements
SpanDecorator {
// have been provided, for subsequent analysis
String uri = endpoint.toString(); // toString will sanitize
span.setTag("camel.uri", uri);
- span.setTag(TagConstants.URL_PATH, stripSchemeAndOptions(endpoint));
+ span.setTag(TagConstants.URL_PATH, getUrlPath(endpoint));
String query = URISupport.extractQuery(uri);
if (query != null) {
span.setTag(TagConstants.URL_QUERY, query);
@@ -138,7 +154,8 @@ public abstract class AbstractSpanDecorator implements
SpanDecorator {
if (endpoint instanceof EndpointServiceLocation ela) {
String adr = ela.getServiceUrl();
if (adr != null) {
- span.setTag(TagConstants.SERVER_ADDRESS, adr);
+ // the address is presented the same way as the camel.uri tag
+ span.setTag(TagConstants.SERVER_ADDRESS,
URISupport.sanitizeUri(adr));
}
String ap = ela.getServiceProtocol();
if (ap != null) {
diff --git
a/components/camel-tracing/src/test/java/org/apache/camel/tracing/decorators/AbstractHttpSpanDecoratorTest.java
b/components/camel-tracing/src/test/java/org/apache/camel/tracing/decorators/AbstractHttpSpanDecoratorTest.java
index c48d8751f28f..fe97b5f8affa 100644
---
a/components/camel-tracing/src/test/java/org/apache/camel/tracing/decorators/AbstractHttpSpanDecoratorTest.java
+++
b/components/camel-tracing/src/test/java/org/apache/camel/tracing/decorators/AbstractHttpSpanDecoratorTest.java
@@ -19,6 +19,7 @@ package org.apache.camel.tracing.decorators;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
import org.apache.camel.Message;
+import org.apache.camel.spi.EndpointServiceLocation;
import org.apache.camel.tracing.MockSpanAdapter;
import org.apache.camel.tracing.TagConstants;
import org.junit.jupiter.api.BeforeEach;
@@ -152,9 +153,9 @@ public class AbstractHttpSpanDecoratorTest {
Exchange exchange = Mockito.mock(Exchange.class);
Message message = Mockito.mock(Message.class);
- Mockito.when(endpoint.getEndpointUri()).thenReturn(TEST_URI);
+
Mockito.when(endpoint.getEndpointUri()).thenReturn("http://localhost:8080/endpoint");
Mockito.when(exchange.getIn()).thenReturn(message);
- Mockito.when(message.getHeader(Exchange.HTTP_URI,
String.class)).thenReturn(TEST_URI);
+
Mockito.when(message.getHeader(Exchange.HTTP_URI)).thenReturn(TEST_URI);
MockSpanAdapter span = new MockSpanAdapter();
@@ -170,10 +171,10 @@ public class AbstractHttpSpanDecoratorTest {
Exchange exchange = Mockito.mock(Exchange.class);
Message message = Mockito.mock(Message.class);
- Mockito.when(endpoint.getEndpointUri()).thenReturn(TEST_URI);
+
Mockito.when(endpoint.getEndpointUri()).thenReturn("http://localhost:8080/endpoint");
Mockito.when(exchange.getIn()).thenReturn(message);
- Mockito.when(message.getHeader(Exchange.HTTP_URI,
String.class)).thenReturn("Another URL");
- Mockito.when(message.getHeader(Exchange.HTTP_URL,
String.class)).thenReturn(TEST_URI);
+ Mockito.when(message.getHeader(Exchange.HTTP_URI)).thenReturn("Another
URL");
+
Mockito.when(message.getHeader(Exchange.HTTP_URL)).thenReturn(TEST_URI);
assertEquals(TEST_URI, decorator.getHttpURL(exchange, endpoint));
}
@@ -184,13 +185,26 @@ public class AbstractHttpSpanDecoratorTest {
Exchange exchange = Mockito.mock(Exchange.class);
Message message = Mockito.mock(Message.class);
- Mockito.when(endpoint.getEndpointUri()).thenReturn(TEST_URI);
+
Mockito.when(endpoint.getEndpointUri()).thenReturn("http://localhost:8080/endpoint");
Mockito.when(exchange.getIn()).thenReturn(message);
- Mockito.when(message.getHeader(Exchange.HTTP_URI,
String.class)).thenReturn(TEST_URI);
+
Mockito.when(message.getHeader(Exchange.HTTP_URI)).thenReturn(TEST_URI);
assertEquals(TEST_URI, decorator.getHttpURL(exchange, endpoint));
}
+ @Test
+ public void testGetHttpURLFromHeaderUrlPresentedLikeCamelUri() {
+ Endpoint endpoint = Mockito.mock(Endpoint.class);
+ Exchange exchange = Mockito.mock(Exchange.class);
+ Message message = Mockito.mock(Message.class);
+
+ Mockito.when(endpoint.getEndpointUri()).thenReturn(TEST_URI);
+ Mockito.when(exchange.getIn()).thenReturn(message);
+
Mockito.when(message.getHeader(Exchange.HTTP_URL)).thenReturn("http://scott:tiger@localhost:8080/test");
+
+ assertEquals("http://scott:xxxxxx@localhost:8080/test",
decorator.getHttpURL(exchange, endpoint));
+ }
+
@Test
public void testGetHttpURLFromEndpointUri() {
Endpoint endpoint = Mockito.mock(Endpoint.class);
@@ -215,6 +229,73 @@ public class AbstractHttpSpanDecoratorTest {
assertEquals(TEST_URI, decorator.getHttpURL(exchange, endpoint));
}
+ @Test
+ public void testGetHttpURLFromEndpointUriWithoutEndpointOptions() {
+ Endpoint endpoint = Mockito.mock(Endpoint.class);
+ Exchange exchange = Mockito.mock(Exchange.class);
+ Message message = Mockito.mock(Message.class);
+
+ Mockito.when(endpoint.getEndpointUri()).thenReturn(TEST_URI +
"?connectTimeout=5000&throwExceptionOnFailure=false");
+ Mockito.when(exchange.getIn()).thenReturn(message);
+
+ assertEquals(TEST_URI, decorator.getHttpURL(exchange, endpoint));
+ }
+
+ @Test
+ public void
testGetHttpURLFromEndpointUriWithComponentSchemeAndHttpsAddress() {
+ Endpoint endpoint = Mockito.mock(Endpoint.class);
+ Exchange exchange = Mockito.mock(Exchange.class);
+ Message message = Mockito.mock(Message.class);
+
+
Mockito.when(endpoint.getEndpointUri()).thenReturn("vertx-http://https://localhost:8443/test?connectTimeout=5000");
+ Mockito.when(exchange.getIn()).thenReturn(message);
+
+ assertEquals("https://localhost:8443/test",
decorator.getHttpURL(exchange, endpoint));
+ }
+
+ @Test
+ public void testGetHttpURLFromServiceUrl() {
+ Endpoint endpoint = Mockito.mock(Endpoint.class,
Mockito.withSettings().extraInterfaces(EndpointServiceLocation.class));
+ Exchange exchange = Mockito.mock(Exchange.class);
+ Message message = Mockito.mock(Message.class);
+
+
Mockito.when(endpoint.getEndpointUri()).thenReturn("https://localhost:8443/test?q=1&connectTimeout=5000");
+ Mockito.when(((EndpointServiceLocation)
endpoint).getServiceUrl()).thenReturn("https://localhost:8443/test?q=1");
+ Mockito.when(exchange.getIn()).thenReturn(message);
+
+ assertEquals("https://localhost:8443/test?q=1",
decorator.getHttpURL(exchange, endpoint));
+ }
+
+ @Test
+ public void testGetHttpURLFromEndpointUriWhenServiceUrlIsNotHttpAddress() {
+ Endpoint endpoint = Mockito.mock(Endpoint.class,
Mockito.withSettings().extraInterfaces(EndpointServiceLocation.class));
+ Exchange exchange = Mockito.mock(Exchange.class);
+ Message message = Mockito.mock(Message.class);
+
+ Mockito.when(endpoint.getEndpointUri()).thenReturn("netty-http:" +
TEST_URI);
+ Mockito.when(((EndpointServiceLocation)
endpoint).getServiceUrl()).thenReturn("http:localhost:8080");
+ Mockito.when(exchange.getIn()).thenReturn(message);
+
+ assertEquals(TEST_URI, decorator.getHttpURL(exchange, endpoint));
+ }
+
+ @Test
+ public void testPreHttpsEndpoint() {
+ Endpoint endpoint = Mockito.mock(Endpoint.class,
Mockito.withSettings().extraInterfaces(EndpointServiceLocation.class));
+ Exchange exchange = Mockito.mock(Exchange.class);
+ Message message = Mockito.mock(Message.class);
+
+
Mockito.when(endpoint.getEndpointUri()).thenReturn("https://localhost:8443/test?connectTimeout=5000");
+ Mockito.when(((EndpointServiceLocation)
endpoint).getServiceUrl()).thenReturn("https://localhost:8443/test");
+ Mockito.when(exchange.getIn()).thenReturn(message);
+
+ MockSpanAdapter span = new MockSpanAdapter();
+
+ decorator.pre(span, exchange, endpoint);
+
+ assertEquals("https://localhost:8443/test",
span.tags().get(TagConstants.HTTP_URL));
+ }
+
@Test
public void testPostResponseCode() {
Exchange exchange = Mockito.mock(Exchange.class);
diff --git
a/components/camel-tracing/src/test/java/org/apache/camel/tracing/decorators/AbstractSpanDecoratorTest.java
b/components/camel-tracing/src/test/java/org/apache/camel/tracing/decorators/AbstractSpanDecoratorTest.java
index 616ad491b23e..06f923418ac3 100644
---
a/components/camel-tracing/src/test/java/org/apache/camel/tracing/decorators/AbstractSpanDecoratorTest.java
+++
b/components/camel-tracing/src/test/java/org/apache/camel/tracing/decorators/AbstractSpanDecoratorTest.java
@@ -18,6 +18,7 @@ package org.apache.camel.tracing.decorators;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
+import org.apache.camel.spi.EndpointServiceLocation;
import org.apache.camel.tracing.MockSpanAdapter;
import org.apache.camel.tracing.SpanDecorator;
import org.apache.camel.tracing.TagConstants;
@@ -86,6 +87,61 @@ public class AbstractSpanDecoratorTest {
assertEquals("myRouteId", span.tags().get(TagConstants.ROUTE_ID));
}
+ @Test
+ public void testPreUrlPathWithoutUserInfo() {
+ Endpoint endpoint = Mockito.mock(Endpoint.class);
+ Exchange exchange = Mockito.mock(Exchange.class);
+
+
Mockito.when(endpoint.getEndpointUri()).thenReturn("ftp://scott:tiger@localhost:2121/inbox?binary=true");
+
Mockito.when(endpoint.toString()).thenReturn("ftp://scott:xxxxxx@localhost:2121/inbox?binary=true");
+
+ SpanDecorator decorator = new AbstractSpanDecorator() {
+ @Override
+ public String getComponent() {
+ return null;
+ }
+
+ @Override
+ public String getComponentClassName() {
+ return null;
+ }
+ };
+
+ MockSpanAdapter span = new MockSpanAdapter();
+
+ decorator.pre(span, exchange, endpoint);
+
+ assertEquals("localhost:2121/inbox",
span.tags().get(TagConstants.URL_PATH));
+ assertEquals("binary=true", span.tags().get(TagConstants.URL_QUERY));
+ }
+
+ @Test
+ public void testPreServerAddressPresentedLikeCamelUri() {
+ Endpoint endpoint = Mockito.mock(Endpoint.class,
Mockito.withSettings().extraInterfaces(EndpointServiceLocation.class));
+ Exchange exchange = Mockito.mock(Exchange.class);
+
+ Mockito.when(endpoint.getEndpointUri()).thenReturn("amqp:queue:foo");
+ Mockito.when(((EndpointServiceLocation)
endpoint).getServiceUrl()).thenReturn("amqp://scott:tiger@localhost:5672");
+
+ SpanDecorator decorator = new AbstractSpanDecorator() {
+ @Override
+ public String getComponent() {
+ return null;
+ }
+
+ @Override
+ public String getComponentClassName() {
+ return null;
+ }
+ };
+
+ MockSpanAdapter span = new MockSpanAdapter();
+
+ decorator.pre(span, exchange, endpoint);
+
+ assertEquals("amqp://scott:xxxxxx@localhost:5672",
span.tags().get(TagConstants.SERVER_ADDRESS));
+ }
+
@Test
public void testPostExchangeFailed() {
Exchange exchange = Mockito.mock(Exchange.class);
diff --git
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
index ae0e79663274..a9727cfadb38 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
@@ -2012,3 +2012,20 @@ The producer now discards that session, so the next
exchange opens a fresh one.
The default behaviour is unchanged: `disconnectOnNoReply` defaults to `true`,
which already closed the session on a
timeout. Setting `disconnectOnNoReply=false` no longer keeps the producer
session open after a timeout.
+
+=== camel-telemetry, camel-tracing - the http.url, url.path and server.address
span attributes are presented like camel.uri
+
+This applies to `camel-opentelemetry2`, `camel-micrometer-observability`,
`camel-telemetry-dev`, `camel-opentelemetry`
+and `camel-observation`. The `http.url`, `url.path` and `server.address`
attributes of a span are now presented the same
+way as the `camel.uri` attribute, which shows the endpoint URI as
`Endpoint.toString()` does:
+
+* `http.url`, when the message has neither a `CamelHttpUrl` nor a
`CamelHttpUri` header, is now the HTTP address the
+ endpoint sends to, with the query parameters it sends but without the Camel
endpoint options. Before, it was the
+ endpoint URI from the last `http:` onwards, with all the endpoint options. A
`camel-http` endpoint with an `https`
+ address now sets the attribute as well, and for a `camel-vertx-http`
endpoint with an `https` address the value no
+ longer starts with `http://https://`.
+* `url.path` no longer includes the user info in front of the host of the
endpoint URI.
+* `server.address`, and `http.url` taken from the `CamelHttpUrl` or
`CamelHttpUri` header, are presented as `camel.uri`
+ is.
+
+Dashboards or queries that use the old values may need a change.