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

apupier pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 25784633387d78a00fab4cdeb640a814e34912f2
Author: smjain <[email protected]>
AuthorDate: Wed Nov 4 12:55:17 2026 +0530

    CAMEL-26432: camel-chaos - review: an address only after a real scheme (not 
a colon in the query of a scheme alias), the netty-http failure gives the 
address, docs since CAMEL-26487
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 .../org/apache/camel/catalog/docs/chaos.adoc       | 10 +--
 components/camel-chaos/src/main/docs/chaos.adoc    | 10 +--
 .../apache/camel/component/chaos/ChaosFaults.java  | 15 ++++-
 .../camel/component/chaos/ChaosPatterns.java       | 32 ++++++---
 .../camel/component/chaos/ChaosPatternsTest.java   | 78 ++++++++++++++++++++++
 5 files changed, 126 insertions(+), 19 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/chaos.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/chaos.adoc
index 5875de042a65..84a54c419cd6 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/chaos.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/chaos.adoc
@@ -161,11 +161,11 @@ which ignore case and can be regular expressions: a rule, 
also one from a tool,
 `endpoint=` pattern is matched against the endpoint URI, with or without its 
query parameters, and the `//` after the
 scheme does not count (`kafka:orders*` matches `kafka://orders?brokers=b1`). A 
`component=` pattern is matched against
 the scheme of the URI. Some components give their endpoints the URI of their 
address:
-`netty-http:http://inventory/stock` and `undertow:http://inventory/stock` have 
the endpoint URI
-`http://inventory/stock`. When the scheme of the endpoint URI is not a name of 
the component in the context, chaos puts
-the default name of the component in front, and matches 
`netty-http:http://inventory/stock` (with
-`component=netty-http`, not `component=http`; a camel-netty-http component 
added under another name is matched as
-`netty-http` too). A `route=` pattern is matched against the route id, and a 
`step=` pattern against the id of the step
+`undertow:http://inventory/stock` has the endpoint URI 
`http://inventory/stock`. When the scheme of the endpoint URI is
+not a name of the component in the context, chaos puts the default name of the 
component in front, and matches
+`undertow:http://inventory/stock` (with `component=undertow`, not 
`component=http`). A camel-netty-http endpoint has
+the endpoint URI `netty-http://http://inventory/stock`, and a camel-netty-http 
component added under another name is
+matched with `netty-http` in front too. A `route=` pattern is matched against 
the route id, and a `step=` pattern against the id of the step
 (`to1`, or the id set with `id("enrich")`).
 
 A rule gets an id when it is added (`r1`, `r2`, ...), which change and remove 
take. A change replaces the rule with a
diff --git a/components/camel-chaos/src/main/docs/chaos.adoc 
b/components/camel-chaos/src/main/docs/chaos.adoc
index 5875de042a65..84a54c419cd6 100644
--- a/components/camel-chaos/src/main/docs/chaos.adoc
+++ b/components/camel-chaos/src/main/docs/chaos.adoc
@@ -161,11 +161,11 @@ which ignore case and can be regular expressions: a rule, 
also one from a tool,
 `endpoint=` pattern is matched against the endpoint URI, with or without its 
query parameters, and the `//` after the
 scheme does not count (`kafka:orders*` matches `kafka://orders?brokers=b1`). A 
`component=` pattern is matched against
 the scheme of the URI. Some components give their endpoints the URI of their 
address:
-`netty-http:http://inventory/stock` and `undertow:http://inventory/stock` have 
the endpoint URI
-`http://inventory/stock`. When the scheme of the endpoint URI is not a name of 
the component in the context, chaos puts
-the default name of the component in front, and matches 
`netty-http:http://inventory/stock` (with
-`component=netty-http`, not `component=http`; a camel-netty-http component 
added under another name is matched as
-`netty-http` too). A `route=` pattern is matched against the route id, and a 
`step=` pattern against the id of the step
+`undertow:http://inventory/stock` has the endpoint URI 
`http://inventory/stock`. When the scheme of the endpoint URI is
+not a name of the component in the context, chaos puts the default name of the 
component in front, and matches
+`undertow:http://inventory/stock` (with `component=undertow`, not 
`component=http`). A camel-netty-http endpoint has
+the endpoint URI `netty-http://http://inventory/stock`, and a camel-netty-http 
component added under another name is
+matched with `netty-http` in front too. A `route=` pattern is matched against 
the route id, and a `step=` pattern against the id of the step
 (`to1`, or the id set with `id("enrich")`).
 
 A rule gets an id when it is added (`r1`, `r2`, ...), which change and remove 
take. A change replaces the rule with a
diff --git 
a/components/camel-chaos/src/main/java/org/apache/camel/component/chaos/ChaosFaults.java
 
b/components/camel-chaos/src/main/java/org/apache/camel/component/chaos/ChaosFaults.java
index 551fe94e6368..c4b29e28bb0f 100644
--- 
a/components/camel-chaos/src/main/java/org/apache/camel/component/chaos/ChaosFaults.java
+++ 
b/components/camel-chaos/src/main/java/org/apache/camel/component/chaos/ChaosFaults.java
@@ -195,7 +195,20 @@ final class ChaosFaults {
         return (Throwable) type
                 .getConstructor(String.class, int.class, String.class, 
String.class,
                         resolve(endpoint, 
"io.netty.handler.codec.http.HttpContent"))
-                .newInstance(endpoint.getEndpointBaseUri(), rule.status, 
statusText(rule.status), location(rule), response);
+                .newInstance(nettyHttpAddress(endpoint), rule.status, 
statusText(rule.status), location(rule), response);
+    }
+
+    /**
+     * The address that camel-netty-http calls, as the url of its failure: 
since CAMEL-26487 the endpoint URI of a
+     * camel-netty-http endpoint is its whole URI ({@code 
netty-http://http://host/path}) and its address is
+     * {@code getAddressUri()}.
+     */
+    private static String nettyHttpAddress(Endpoint endpoint) {
+        try {
+            return (String) 
endpoint.getClass().getMethod("getAddressUri").invoke(endpoint);
+        } catch (ReflectiveOperationException | ClassCastException e) {
+            return endpoint.getEndpointBaseUri();
+        }
     }
 
     private static Class<?> resolve(Endpoint endpoint, String name) throws 
ClassNotFoundException {
diff --git 
a/components/camel-chaos/src/main/java/org/apache/camel/component/chaos/ChaosPatterns.java
 
b/components/camel-chaos/src/main/java/org/apache/camel/component/chaos/ChaosPatterns.java
index c78d61ebe351..f7f05d6a2292 100644
--- 
a/components/camel-chaos/src/main/java/org/apache/camel/component/chaos/ChaosPatterns.java
+++ 
b/components/camel-chaos/src/main/java/org/apache/camel/component/chaos/ChaosPatterns.java
@@ -105,11 +105,13 @@ final class ChaosPatterns {
     }
 
     /**
-     * The URI of an endpoint as the rules see it: its endpoint URI, with the 
name of its component in front when the
-     * scheme of that URI is not a name of its component in the context. 
camel-netty-http and camel-undertow give their
-     * endpoints the URI of their address ({@code netty-http:http://host/path} 
has the endpoint URI
-     * {@code http://host/path}), so their endpoints are matched as {@code 
netty-http:http://host/path}, by
-     * {@code component=netty-http} and not by {@code component=http}.
+     * The URI of an endpoint as the rules see it: its endpoint URI, with the 
default name of its component in front
+     * when the URI is the address of the endpoint. camel-undertow gives its 
endpoints the URI of their address
+     * ({@code undertow:http://host/path} has the endpoint URI {@code 
http://host/path}), and a camel-netty-http
+     * component added under another name gives that name and the address 
({@code nh://http://host/path}); both are
+     * matched with the default name of the component ({@code 
undertow:http://host/path},
+     * {@code netty-http://http://host/path}), by {@code component=undertow} 
or {@code component=netty-http} and not by
+     * {@code component=http}.
      */
     static String endpointUri(Endpoint endpoint) {
         String uri = endpoint.getEndpointUri();
@@ -135,10 +137,24 @@ final class ChaosPatterns {
         return name != null && !name.equals(scheme) ? name + ":" + uri : uri;
     }
 
-    /** Whether the text is an address with a scheme of its own ({@code 
http://host/path}). */
+    /**
+     * Whether the text is an address with a scheme of its own ({@code 
http://host/path}, or
+     * {@code //http://host/path}): a scheme (letters, digits, {@code +}, 
{@code -} and {@code .}) then {@code ://}, not
+     * a colon further on, such as one in the query of an ordinary URI.
+     */
     private static boolean isAddress(String text) {
-        int colon = text.indexOf(':');
-        return colon > 0 && text.startsWith("//", colon + 1);
+        int start = text.startsWith("//") ? 2 : 0;
+        int colon = text.indexOf(':', start);
+        if (colon <= start || !text.startsWith("//", colon + 1)) {
+            return false;
+        }
+        for (int i = start; i < colon; i++) {
+            char c = text.charAt(i);
+            if (!Character.isLetterOrDigit(c) && c != '+' && c != '-' && c != 
'.') {
+                return false;
+            }
+        }
+        return true;
     }
 
     /**
diff --git 
a/components/camel-chaos/src/test/java/org/apache/camel/component/chaos/ChaosPatternsTest.java
 
b/components/camel-chaos/src/test/java/org/apache/camel/component/chaos/ChaosPatternsTest.java
index 8dd0a3106cde..5c233c946973 100644
--- 
a/components/camel-chaos/src/test/java/org/apache/camel/component/chaos/ChaosPatternsTest.java
+++ 
b/components/camel-chaos/src/test/java/org/apache/camel/component/chaos/ChaosPatternsTest.java
@@ -18,9 +18,18 @@ package org.apache.camel.component.chaos;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Random;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.camel.CamelContext;
+import org.apache.camel.Consumer;
+import org.apache.camel.Endpoint;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.support.DefaultComponent;
+import org.apache.camel.support.DefaultEndpoint;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Timeout;
 
@@ -131,4 +140,73 @@ class ChaosPatternsTest {
         assertThat(ChaosPatterns.matches("*".repeat(2000) + "b", 
text)).isFalse();
         assertThat(ChaosPatterns.matches("*".repeat(2000), text)).isTrue();
     }
+
+    @Test
+    void anAddressAfterAnotherNameOfTheComponentIsMatchedWithItsDefaultName() 
throws Exception {
+        try (CamelContext context = new DefaultCamelContext()) {
+            // camel-netty-http added as nh: since CAMEL-26487 its endpoint 
URI is nh://http://host/path
+            DefaultComponent nh = new NamedComponent("netty-http");
+            context.addComponent("nh", nh);
+            assertThat(ChaosPatterns.endpointUri(new 
UriEndpoint("nh://http://localhost:9/stock";, nh)))
+                    .isEqualTo("netty-http://http://localhost:9/stock";);
+            assertThat(ChaosPatterns.endpointUri(new 
UriEndpoint("nh:http://localhost:9/stock?muteException=true";, nh)))
+                    
.isEqualTo("netty-http:http://localhost:9/stock?muteException=true";);
+            // the address alone (as camel-undertow gives it) has the default 
name in front
+            assertThat(ChaosPatterns.endpointUri(new 
UriEndpoint("http://localhost:9/stock";, nh)))
+                    .isEqualTo("netty-http:http://localhost:9/stock";);
+        }
+    }
+
+    @Test
+    void aSchemeAliasWithAnAddressInTheQueryKeepsItsScheme() throws Exception {
+        try (CamelContext context = new DefaultCamelContext()) {
+            // as camel-http, whose @Component("http,https") gives the https 
instance the default name http
+            DefaultComponent https = new NamedComponent("http");
+            context.addComponent("https", https);
+            String uri = 
"https://inventory/stock?callback=http://elsewhere/done";;
+            String seen = ChaosPatterns.endpointUri(new UriEndpoint(uri, 
https));
+            assertThat(seen).isEqualTo(uri);
+            assertThat(ChaosPatterns.matches("https:inventory*", 
ChaosPatterns.withoutSlashes(seen))).isTrue();
+            assertThat(ChaosPatterns.matchesScheme("https", seen)).isTrue();
+            // a renamed component whose URI is not an address keeps the name 
it has in the context
+            DefaultComponent myseda = new NamedComponent("seda");
+            context.addComponent("myseda", myseda);
+            assertThat(ChaosPatterns.endpointUri(new 
UriEndpoint("myseda://orders?timeout=0", myseda)))
+                    .isEqualTo("myseda://orders?timeout=0");
+        }
+    }
+
+    private static final class NamedComponent extends DefaultComponent {
+        private final String defaultName;
+
+        NamedComponent(String defaultName) {
+            this.defaultName = defaultName;
+        }
+
+        @Override
+        public String getDefaultName() {
+            return defaultName;
+        }
+
+        @Override
+        protected Endpoint createEndpoint(String uri, String remaining, 
Map<String, Object> parameters) {
+            return new UriEndpoint(uri, this);
+        }
+    }
+
+    private static final class UriEndpoint extends DefaultEndpoint {
+        UriEndpoint(String uri, DefaultComponent component) {
+            super(uri, component);
+        }
+
+        @Override
+        public Producer createProducer() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Consumer createConsumer(Processor processor) {
+            throw new UnsupportedOperationException();
+        }
+    }
 }

Reply via email to