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

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


The following commit(s) were added to refs/heads/main by this push:
     new 6ddd8978d26 chore(components): platform http endpoints resume
6ddd8978d26 is described below

commit 6ddd8978d26e2622c41523f180eb495162c9f91f
Author: Pasquale Congiusti <[email protected]>
AuthorDate: Wed Apr 30 11:49:22 2025 +0200

    chore(components): platform http endpoints resume
    
    * Reverted the change done in b19a5f690b920b0936f00f560c6be6b82dec48f8
    * Added a data structure to hold management endpoints
    
    Closes CAMEL-22025
---
 .../prometheus/MicrometerPrometheus.java           |  17 ++--
 .../platform/http/main/MainHttpServer.java         |   9 ++
 .../platform/http/main/MainHttpServerUtil.java     | 110 +++++++++++++++++++++
 .../platform/http/main/ManagementHttpServer.java   |  19 +++-
 .../platform/http/PlatformHttpComponent.java       |  38 ++++++-
 5 files changed, 179 insertions(+), 14 deletions(-)

diff --git 
a/components/camel-micrometer-prometheus/src/main/java/org/apache/camel/component/micrometer/prometheus/MicrometerPrometheus.java
 
b/components/camel-micrometer-prometheus/src/main/java/org/apache/camel/component/micrometer/prometheus/MicrometerPrometheus.java
index 44484fd2569..adac6691298 100644
--- 
a/components/camel-micrometer-prometheus/src/main/java/org/apache/camel/component/micrometer/prometheus/MicrometerPrometheus.java
+++ 
b/components/camel-micrometer-prometheus/src/main/java/org/apache/camel/component/micrometer/prometheus/MicrometerPrometheus.java
@@ -430,7 +430,7 @@ public class MicrometerPrometheus extends ServiceSupport 
implements CamelMetrics
         if (mainServer != null && mainServer.isMetricsEnabled() && 
platformHttpComponent != null) {
             mainRouter = mainServer.getRouter();
             if (mainRouter != null) {
-                setupHttpScraper(mainRouter);
+                setupHttpScraper(mainRouter, false);
                 LOG.info("MicrometerPrometheus enabled with HTTP scraping on 
port {} on path {}",
                         mainServer.getPort(), path);
                 enabled = true;
@@ -441,8 +441,8 @@ public class MicrometerPrometheus extends ServiceSupport 
implements CamelMetrics
         if (managementServer != null && managementServer.isMetricsEnabled() && 
platformHttpComponent != null) {
             managementRouter = managementServer.getRouter();
             if (managementRouter != null) {
-                setupHttpScraper(managementRouter);
-                LOG.info("MicrometerPrometheus enabled with HTTP scraping on 
port {} on path {}",
+                setupHttpScraper(managementRouter, true);
+                LOG.info("MicrometerPrometheus enabled with HTTP scraping on 
management port {} on path {}",
                         managementServer.getPort(), path);
                 enabled = true;
             }
@@ -480,7 +480,7 @@ public class MicrometerPrometheus extends ServiceSupport 
implements CamelMetrics
         createdBinders.clear();
     }
 
-    protected void setupHttpScraper(VertxPlatformHttpRouter router) {
+    protected void setupHttpScraper(VertxPlatformHttpRouter router, boolean 
isManagementPort) {
         Route metrics = router.route(path);
         metrics.method(HttpMethod.GET);
 
@@ -507,7 +507,12 @@ public class MicrometerPrometheus extends ServiceSupport 
implements CamelMetrics
         // use blocking handler as the task can take longer time to complete
         metrics.handler(new BlockingHandlerDecorator(handler, true));
 
-        platformHttpComponent.addHttpEndpoint(path, "GET",
-                null, format, null);
+        if (isManagementPort) {
+            platformHttpComponent.addHttpManagementEndpoint(path, "GET",
+                    null, format, null);
+        } else {
+            platformHttpComponent.addHttpEndpoint(path, "GET",
+                    null, format, null);
+        }
     }
 }
diff --git 
a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServer.java
 
b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServer.java
index 6e5531741c2..15d45f59937 100644
--- 
a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServer.java
+++ 
b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServer.java
@@ -451,6 +451,7 @@ public class MainHttpServer extends ServiceSupport 
implements CamelContextAware,
         platformHttpComponent = camelContext.getComponent("platform-http", 
PlatformHttpComponent.class);
 
         setupConsoles();
+        setupStartupSummary();
     }
 
     @Override
@@ -1397,4 +1398,12 @@ public class MainHttpServer extends ServiceSupport 
implements CamelContextAware,
         ctx.end(jo.toJson());
     }
 
+    protected void setupStartupSummary() throws Exception {
+        MainHttpServerUtil.setupStartupSummary(
+                camelContext,
+                platformHttpComponent.getHttpEndpoints(),
+                (server != null ? server.getPort() : getPort()),
+                "HTTP endpoints summary");
+    }
+
 }
diff --git 
a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServerUtil.java
 
b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServerUtil.java
new file mode 100644
index 00000000000..2b2b53bbcd9
--- /dev/null
+++ 
b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServerUtil.java
@@ -0,0 +1,110 @@
+/*
+ * 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.component.platform.http.main;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.StartupListener;
+import org.apache.camel.component.platform.http.HttpEndpointModel;
+import org.apache.camel.spi.CamelEvent;
+import org.apache.camel.support.SimpleEventNotifierSupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MainHttpServerUtil {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(MainHttpServerUtil.class);
+
+    protected static void setupStartupSummary(
+            CamelContext camelContext, Set<HttpEndpointModel> endpoints, int 
serverPort, String header)
+            throws Exception {
+        camelContext.addStartupListener(new StartupListener() {
+            private volatile Set<HttpEndpointModel> last;
+
+            private void logSummary() {
+                if (endpoints.isEmpty()) {
+                    return;
+                }
+                // log only if changed
+                if (last == null || last.size() != endpoints.size() || 
!last.containsAll(endpoints)) {
+                    LOG.info(header);
+                    int longestEndpoint = 0;
+                    for (HttpEndpointModel u : endpoints) {
+                        String endpoint = getEndpoint(u);
+                        if (endpoint.length() > longestEndpoint) {
+                            longestEndpoint = endpoint.length();
+                        }
+                    }
+                    int spacing = 3;
+                    String formatTemplate = "%-" + (longestEndpoint + spacing) 
+ "s %-8s %s";
+                    for (HttpEndpointModel u : endpoints) {
+                        String endpoint = getEndpoint(u);
+                        String formattedVerbs = "";
+                        if (u.getVerbs() != null) {
+                            formattedVerbs = "(" + u.getVerbs() + ")";
+                        }
+                        String formattedMediaTypes = "";
+                        if (u.getConsumes() != null || u.getProduces() != 
null) {
+                            formattedMediaTypes = String.format("(%s%s%s)",
+                                    u.getConsumes() != null ? "accept:" + 
u.getConsumes() : "",
+                                    u.getProduces() != null && u.getConsumes() 
!= null ? " " : "",
+                                    u.getProduces() != null ? "produce:" + 
u.getProduces() : "");
+                        }
+                        LOG.info("    {}", String.format(formatTemplate, 
endpoint, formattedVerbs, formattedMediaTypes));
+                    }
+                }
+
+                // use a defensive copy of last known endpoints
+                last = new HashSet<>(endpoints);
+            }
+
+            private String getEndpoint(HttpEndpointModel httpEndpointModel) {
+                return "http://0.0.0.0:"; + serverPort + 
httpEndpointModel.getUri();
+            }
+
+            @Override
+            public void onCamelContextStarted(CamelContext context, boolean 
alreadyStarted) {
+                if (alreadyStarted) {
+                    logSummary();
+                }
+                camelContext.getManagementStrategy().addEventNotifier(new 
SimpleEventNotifierSupport() {
+                    @Override
+                    public boolean isEnabled(CamelEvent event) {
+                        return event instanceof 
CamelEvent.CamelContextStartedEvent
+                                || event instanceof 
CamelEvent.RouteReloadedEvent;
+                    }
+
+                    @Override
+                    public void notify(CamelEvent event) {
+                        // when reloading then there may be more routes in the 
same batch, so we only want
+                        // to log the summary at the end
+                        if (event instanceof CamelEvent.RouteReloadedEvent) {
+                            CamelEvent.RouteReloadedEvent re = 
(CamelEvent.RouteReloadedEvent) event;
+                            if (re.getIndex() < re.getTotal()) {
+                                return;
+                            }
+                        }
+                        logSummary();
+                    }
+                });
+            }
+        });
+    }
+
+}
diff --git 
a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/ManagementHttpServer.java
 
b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/ManagementHttpServer.java
index c96c05f638c..d3f80dbbec1 100644
--- 
a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/ManagementHttpServer.java
+++ 
b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/ManagementHttpServer.java
@@ -348,6 +348,7 @@ public class ManagementHttpServer extends ServiceSupport 
implements CamelContext
         platformHttpComponent = camelContext.getComponent("platform-http", 
PlatformHttpComponent.class);
 
         setupConsoles();
+        setupStartupSummary();
     }
 
     @Override
@@ -495,7 +496,7 @@ public class ManagementHttpServer extends ServiceSupport 
implements CamelContext
         // use blocking handler as the task can take longer time to complete
         info.handler(new BlockingHandlerDecorator(handler, true));
 
-        platformHttpComponent.addHttpEndpoint("/q/info", "GET", null,
+        platformHttpComponent.addHttpManagementEndpoint("/q/info", "GET", null,
                 "application/json", null);
     }
 
@@ -569,7 +570,7 @@ public class ManagementHttpServer extends ServiceSupport 
implements CamelContext
         live.handler(new BlockingHandlerDecorator(handler, true));
         ready.handler(new BlockingHandlerDecorator(handler, true));
 
-        platformHttpComponent.addHttpEndpoint(this.healthPath, "GET", null,
+        platformHttpComponent.addHttpManagementEndpoint(this.healthPath, 
"GET", null,
                 "application/json", null);
     }
 
@@ -586,7 +587,7 @@ public class ManagementHttpServer extends ServiceSupport 
implements CamelContext
         Handler<RoutingContext> handler = (Handler<RoutingContext>) 
jolokiaPlugin.getHandler();
         jolokia.handler(new BlockingHandlerDecorator(handler, true));
 
-        platformHttpComponent.addHttpEndpoint(jolokiaPath, "GET,POST", null,
+        platformHttpComponent.addHttpManagementEndpoint(jolokiaPath, 
"GET,POST", null,
                 "text/plain,application/json", null);
     }
 
@@ -614,7 +615,7 @@ public class ManagementHttpServer extends ServiceSupport 
implements CamelContext
         // use blocking handler as the task can take longer time to complete
         send.handler(new BlockingHandlerDecorator(handler, true));
 
-        platformHttpComponent.addHttpEndpoint("/q/send", "GET,POST",
+        platformHttpComponent.addHttpManagementEndpoint("/q/send", "GET,POST",
                 null, "application/json", null);
     }
 
@@ -856,7 +857,7 @@ public class ManagementHttpServer extends ServiceSupport 
implements CamelContext
         dev.handler(new BlockingHandlerDecorator(handler, true));
         devSub.handler(new BlockingHandlerDecorator(handler, true));
 
-        platformHttpComponent.addHttpEndpoint("/q/dev", "GET", null,
+        platformHttpComponent.addHttpManagementEndpoint("/q/dev", "GET", null,
                 "text/plain,application/json", null);
     }
 
@@ -1019,4 +1020,12 @@ public class ManagementHttpServer extends ServiceSupport 
implements CamelContext
         ctx.end(jo.toJson());
     }
 
+    protected void setupStartupSummary() throws Exception {
+        MainHttpServerUtil.setupStartupSummary(
+                camelContext,
+                platformHttpComponent.getHttpManagementEndpoints(),
+                (server != null ? server.getPort() : getPort()),
+                "HTTP Management endpoints summary");
+    }
+
 }
diff --git 
a/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpComponent.java
 
b/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpComponent.java
index ef7b49eaac8..ef551a891a7 100644
--- 
a/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpComponent.java
+++ 
b/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpComponent.java
@@ -63,6 +63,7 @@ public class PlatformHttpComponent extends 
HeaderFilterStrategyComponent
     private boolean handleWriteResponseError;
 
     private final Set<HttpEndpointModel> httpEndpoints = new TreeSet<>();
+    private final Set<HttpEndpointModel> httpManagementEndpoints = new 
TreeSet<>();
     private final List<PlatformHttpListener> listeners = new ArrayList<>();
     private volatile boolean localEngine;
 
@@ -119,8 +120,20 @@ public class PlatformHttpComponent extends 
HeaderFilterStrategyComponent
      * Adds a known http endpoint managed by this component.
      */
     public void addHttpEndpoint(String uri, String verbs, String consumes, 
String produces, Consumer consumer) {
+        this.addHttpEndpoint(this.httpEndpoints, uri, verbs, consumes, 
produces, consumer);
+    }
+
+    /**
+     * Adds a known http management endpoint managed by this component.
+     */
+    public void addHttpManagementEndpoint(String uri, String verbs, String 
consumes, String produces, Consumer consumer) {
+        this.addHttpEndpoint(this.httpManagementEndpoints, uri, verbs, 
consumes, produces, consumer);
+    }
+
+    private void addHttpEndpoint(
+            Set<HttpEndpointModel> endpoints, String uri, String verbs, String 
consumes, String produces, Consumer consumer) {
         HttpEndpointModel model = new HttpEndpointModel(uri, verbs, consumes, 
produces, consumer);
-        httpEndpoints.add(model);
+        endpoints.add(model);
         for (PlatformHttpListener listener : listeners) {
             try {
                 listener.registerHttpEndpoint(model);
@@ -134,8 +147,19 @@ public class PlatformHttpComponent extends 
HeaderFilterStrategyComponent
      * Removes a known http endpoint managed by this component.
      */
     public void removeHttpEndpoint(String uri) {
+        this.removeHttpEndpoint(this.httpEndpoints, uri);
+    }
+
+    /**
+     * Removes a known http endpoint managed by this component.
+     */
+    public void removeHttpManagementEndpoint(String uri) {
+        this.removeHttpEndpoint(this.httpManagementEndpoints, uri);
+    }
+
+    private void removeHttpEndpoint(Set<HttpEndpointModel> endpoints, String 
uri) {
         List<HttpEndpointModel> toRemove = new ArrayList<>();
-        httpEndpoints.stream().filter(e -> 
e.getUri().equals(uri)).forEach(model -> {
+        endpoints.stream().filter(e -> e.getUri().equals(uri)).forEach(model 
-> {
             toRemove.add(model);
             for (PlatformHttpListener listener : listeners) {
                 try {
@@ -145,7 +169,7 @@ public class PlatformHttpComponent extends 
HeaderFilterStrategyComponent
                 }
             }
         });
-        toRemove.forEach(httpEndpoints::remove);
+        toRemove.forEach(endpoints::remove);
     }
 
     /**
@@ -169,6 +193,14 @@ public class PlatformHttpComponent extends 
HeaderFilterStrategyComponent
         return Collections.unmodifiableSet(httpEndpoints);
     }
 
+    /**
+     * Lists the known http management endpoints managed by this component. 
The endpoints are without
+     * host:port/[context-path]
+     */
+    public Set<HttpEndpointModel> getHttpManagementEndpoints() {
+        return Collections.unmodifiableSet(httpManagementEndpoints);
+    }
+
     @Override
     protected void doStart() throws Exception {
         super.doStart();

Reply via email to