davsclaus commented on code in PR #29521:
URL: https://github.com/apache/camel/pull/29521#discussion_r4519199136


##########
dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/ChaosHttpFeed.java:
##########
@@ -0,0 +1,356 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.common;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.camel.cli.connector.RepeatedSend;
+import org.apache.camel.dsl.jbang.core.commands.ai.HttpEndpoints;
+import org.apache.camel.util.json.JsonObject;
+
+/**
+ * The feed of a chaos experiment for a route that serves HTTP (CAMEL-26793): 
such a route starts from platform-http or
+ * the REST DSL, which has no producer, so it is fed with HTTP requests to the 
integration's own server (localhost and
+ * the port of its HTTP server, as the status has them). The experiment sends 
them while it waits for the verdict, and
+ * its traffic counts the status codes the clients got.
+ */
+public final class ChaosHttpFeed {
+
+    /** Where the requests go: the method and the URL on the integration's own 
server. */
+    public record Target(String method, String url) {
+
+        @Override
+        public String toString() {
+            return method + " " + url;
+        }
+    }
+
+    // a path to call, with an optional method: /orders/42, PUT /orders/42
+    private static final Pattern PATH
+            = 
Pattern.compile("(?:(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\s+)?(/\\S*)", 
Pattern.CASE_INSENSITIVE);
+
+    private ChaosHttpFeed() {
+    }
+
+    /** Whether the feed is a path to call, such as /orders/42 or PUT 
/orders/42, rather than a route or endpoint. */
+    public static boolean isPath(String feed) {
+        return feed != null && PATH.matcher(feed.strip()).matches();
+    }
+
+    /** Whether the route starts from an input that is fed over the HTTP 
server of Camel: platform-http or rest. */
+    static boolean servedByCamel(String from) {
+        return from != null && (from.startsWith("platform-http:") || 
from.startsWith("rest:"));
+    }
+
+    // an HTTP server with its own address in the URI: 
netty-http:http://0.0.0.0:9000/hooks
+    private static final Pattern OWN_ADDRESS = Pattern.compile(
+            
"(?:netty-http|undertow|jetty|vertx-http):(?://)?(https?)://([^/:?]+)(:\\d+)?([^?]*)(?:\\?.*)?");
+    private static final Set<String> LOCAL_HOSTS = Set.of("localhost", 
"127.0.0.1", "0.0.0.0", "::1", "[::1]");
+
+    /**
+     * The URL to call for a route that starts from an HTTP server with its 
own address on this machine (netty-http,
+     * undertow, jetty), or null: the host it listens on is called as 
localhost.
+     */
+    static String ownAddress(String from) {
+        Matcher m = from != null ? OWN_ADDRESS.matcher(from) : null;
+        if (m == null || !m.matches() || !LOCAL_HOSTS.contains(m.group(2))) {
+            return null;
+        }
+        String path = m.group(4).isEmpty() ? "/" : m.group(4);
+        return m.group(1) + "://localhost" + (m.group(3) != null ? m.group(3) 
: "") + path;
+    }
+
+    /**
+     * Where the requests of the feed go: for a path to call, or for a route 
that starts from platform-http or rest (by
+     * its id or endpoint); null when the feed is for another route.
+     *
+     * @throws IllegalArgumentException when the feed is for HTTP but cannot 
be sent, with the reason
+     */
+    public static Target target(JsonObject status, JsonObject route, String 
feed) {
+        Matcher m = PATH.matcher(feed.strip());
+        String method;
+        String path;
+        String routeId = null;
+        if (m.matches()) {
+            method = m.group(1);
+            path = m.group(2);
+        } else if (route != null && ownAddress(route.getString("from")) != 
null) {
+            // its own server on this machine: no port to look up
+            String from = route.getString("from");
+            String m0 = method(from);
+            return new Target(m0 != null ? m0 : "POST", ownAddress(from));

Review Comment:
   Done in aab7370ef999: the address is bound once with a pattern match.
   
   _Claude Code on behalf of davsclaus_



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to