You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2021/11/26 08:33:38 UTC

[camel] branch main updated (6eab08e -> 606586a)

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

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


    from 6eab08e  Sync deps
     new c36fd03  CAMEL-17233: Reduce logging noise when reloading routes.
     new 606586a  CAMEL-17233: Ensure route definition is removed when a route is removed

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../main/java/org/apache/camel/CamelContext.java   |   2 +-
 .../java/org/apache/camel/spi/RouteController.java |   7 ++
 .../camel/impl/engine/AbstractCamelContext.java    | 106 ++++++++++++++++-----
 .../camel/impl/engine/DefaultRouteController.java  |   5 +
 .../camel/impl/engine/InternalRouteController.java |   7 +-
 .../org/apache/camel/impl/DefaultCamelContext.java |  14 +++
 .../impl/lw/LightweightRuntimeCamelContext.java    |   5 +
 .../apache/camel/impl/engine/RouteRemove2Test.java |  23 +++--
 .../camel/support/RouteWatcherReloadStrategy.java  |  36 +++++--
 9 files changed, 161 insertions(+), 44 deletions(-)

[camel] 02/02: CAMEL-17233: Ensure route definition is removed when a route is removed

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 606586abd5b722da3eb991e1d75fd76ddc2db852
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Fri Nov 26 09:21:34 2021 +0100

    CAMEL-17233: Ensure route definition is removed when a route is removed
---
 .../main/java/org/apache/camel/CamelContext.java   |  2 +-
 .../org/apache/camel/impl/DefaultCamelContext.java | 14 +++++++++++++
 .../apache/camel/impl/engine/RouteRemove2Test.java | 23 ++++++++++++----------
 3 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/core/camel-api/src/main/java/org/apache/camel/CamelContext.java b/core/camel-api/src/main/java/org/apache/camel/CamelContext.java
index 436c270..8ef73c0 100644
--- a/core/camel-api/src/main/java/org/apache/camel/CamelContext.java
+++ b/core/camel-api/src/main/java/org/apache/camel/CamelContext.java
@@ -600,7 +600,7 @@ public interface CamelContext extends CamelContextLifecycle, RuntimeConfiguratio
      *
      * @param  routeId   the route id
      * @return           <tt>true</tt> if the route was removed, <tt>false</tt> if the route could not be removed
-     *                   because its not stopped
+     *                   because it's not stopped
      * @throws Exception is thrown if the route could not be shutdown for whatever reason
      */
     boolean removeRoute(String routeId) throws Exception;
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
index d66704f..a1601fb 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
@@ -29,6 +29,7 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.Expression;
 import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.FailedToStartRouteException;
+import org.apache.camel.LoggingLevel;
 import org.apache.camel.Predicate;
 import org.apache.camel.Processor;
 import org.apache.camel.Route;
@@ -945,6 +946,19 @@ public class DefaultCamelContext extends SimpleCamelContext implements ModelCame
         getTransformerRegistry().put(createTransformerKey(def), transformer);
     }
 
+    @Override
+    protected synchronized boolean removeRoute(String routeId, LoggingLevel loggingLevel) throws Exception {
+        boolean removed = super.removeRoute(routeId, loggingLevel);
+        if (removed) {
+            // must also remove the route definition
+            RouteDefinition def = getRouteDefinition(routeId);
+            if (def != null) {
+                removeRouteDefinition(def);
+            }
+        }
+        return removed;
+    }
+
     private static ValueHolder<String> createTransformerKey(TransformerDefinition def) {
         return ObjectHelper.isNotEmpty(def.getScheme())
                 ? new TransformerKey(def.getScheme())
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/engine/RouteRemove2Test.java b/core/camel-core/src/test/java/org/apache/camel/impl/engine/RouteRemove2Test.java
index 060c627..817e8da 100644
--- a/core/camel-core/src/test/java/org/apache/camel/impl/engine/RouteRemove2Test.java
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/engine/RouteRemove2Test.java
@@ -22,16 +22,18 @@ import org.apache.camel.impl.DefaultCamelContext;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class RouteRemove2Test extends ContextTestSupport {
 
     @Test
     public void testRemove() throws Exception {
         DefaultCamelContext defaultContext = (DefaultCamelContext) context;
-        assertEquals(2, context.getRoutes().size(), "2 routes to start with");
-        assertEquals(2, context.getRouteDefinitions().size(), "2 routes to start with");
-        assertEquals(2, defaultContext.getRouteStartupOrder().size(), "2 routes to start with");
-        assertEquals(2, defaultContext.getRouteServices().size(), "2 routes to start with");
+        assertEquals(2, context.getRoutes().size());
+        assertEquals(2, context.getRouteDefinitions().size());
+        assertEquals(2, defaultContext.getRouteStartupOrder().size());
+        assertEquals(2, defaultContext.getRouteServices().size());
 
         getMockEndpoint("mock:foo").expectedMessageCount(1);
         getMockEndpoint("mock:bar").expectedMessageCount(1);
@@ -54,8 +56,9 @@ public class RouteRemove2Test extends ContextTestSupport {
         assertMockEndpointsSatisfied();
 
         // remove foo route and bar should continue to be functional
-        context.removeRoute("foo");
-        assertEquals(null, context.getRouteController().getRouteStatus("foo"), "There should be no foo route anymore");
+        boolean removed = context.removeRoute("foo");
+        assertTrue(removed, "Route should be removed");
+        assertNull(context.getRouteController().getRouteStatus("foo"), "There should be no foo route anymore");
         assertEquals("Started", context.getRouteController().getRouteStatus("bar").name());
 
         resetMocks();
@@ -66,10 +69,10 @@ public class RouteRemove2Test extends ContextTestSupport {
         template.sendBody("seda:bar", "Hello World");
         assertMockEndpointsSatisfied();
 
-        assertEquals(1, context.getRoutes().size(), "1 routes to end with");
-        assertEquals(1, context.getRouteDefinitions().size(), "1 routes to end with");
-        assertEquals(1, defaultContext.getRouteStartupOrder().size(), "1 routes to end with");
-        assertEquals(1, defaultContext.getRouteServices().size(), "1 routes to end with");
+        assertEquals(1, context.getRoutes().size());
+        assertEquals(1, context.getRouteDefinitions().size());
+        assertEquals(1, defaultContext.getRouteStartupOrder().size());
+        assertEquals(1, defaultContext.getRouteServices().size());
     }
 
     @Override

[camel] 01/02: CAMEL-17233: Reduce logging noise when reloading routes.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit c36fd0370d6d9e07c120717211a1367d1f44db92
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Nov 25 16:09:35 2021 +0100

    CAMEL-17233: Reduce logging noise when reloading routes.
---
 .../java/org/apache/camel/spi/RouteController.java |   7 ++
 .../camel/impl/engine/AbstractCamelContext.java    | 106 ++++++++++++++++-----
 .../camel/impl/engine/DefaultRouteController.java  |   5 +
 .../camel/impl/engine/InternalRouteController.java |   7 +-
 .../impl/lw/LightweightRuntimeCamelContext.java    |   5 +
 .../camel/support/RouteWatcherReloadStrategy.java  |  36 +++++--
 6 files changed, 133 insertions(+), 33 deletions(-)

diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/RouteController.java b/core/camel-api/src/main/java/org/apache/camel/spi/RouteController.java
index 9af937b..911f9c2 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/RouteController.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/RouteController.java
@@ -84,6 +84,13 @@ public interface RouteController extends CamelContextAware, StaticService {
     void stopAllRoutes() throws Exception;
 
     /**
+     * Stops and removes all the routes
+     *
+     * @throws Exception is thrown if a route could not be stopped or removed for whatever reason
+     */
+    void removeAllRoutes() throws Exception;
+
+    /**
      * Indicates whether current thread is starting route(s).
      * <p/>
      * This can be useful to know by {@link LifecycleStrategy} or the likes, in case they need to react differently.
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index 30dbe16..77a07b2 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -91,6 +91,7 @@ import org.apache.camel.spi.BootstrapCloseable;
 import org.apache.camel.spi.CamelBeanPostProcessor;
 import org.apache.camel.spi.CamelContextNameStrategy;
 import org.apache.camel.spi.CamelContextTracker;
+import org.apache.camel.spi.CamelLogger;
 import org.apache.camel.spi.ClassResolver;
 import org.apache.camel.spi.ComponentNameResolver;
 import org.apache.camel.spi.ComponentResolver;
@@ -1210,16 +1211,54 @@ public abstract class AbstractCamelContext extends BaseService
             Route route = order.getRoute();
             boolean stopped = getRouteController().getRouteStatus(route.getRouteId()).isStopped();
             if (!stopped) {
-                stopRoute(route.getRouteId());
+                stopRoute(route.getRouteId(), LoggingLevel.DEBUG);
             }
         }
         // stop any remainder routes
         for (Route route : getRoutes()) {
             boolean stopped = getRouteController().getRouteStatus(route.getRouteId()).isStopped();
             if (!stopped) {
-                stopRoute(route.getRouteId());
+                stopRoute(route.getRouteId(), LoggingLevel.DEBUG);
             }
         }
+
+        if (startupSummaryLevel != StartupSummaryLevel.Classic && startupSummaryLevel != StartupSummaryLevel.Oneline
+                && startupSummaryLevel != StartupSummaryLevel.Off) {
+            logRouteStopSummary(LoggingLevel.INFO);
+        }
+    }
+
+    public void removeAllRoutes() throws Exception {
+        // stop all routes in reverse order that they were started
+        Comparator<RouteStartupOrder> comparator = Comparator.comparingInt(RouteStartupOrder::getStartupOrder);
+        if (shutdownStrategy == null || shutdownStrategy.isShutdownRoutesInReverseOrder()) {
+            comparator = comparator.reversed();
+        }
+        List<RouteStartupOrder> routesOrdered = new ArrayList<>(getRouteStartupOrder());
+        routesOrdered.sort(comparator);
+        for (RouteStartupOrder order : routesOrdered) {
+            Route route = order.getRoute();
+            boolean stopped = getRouteController().getRouteStatus(route.getRouteId()).isStopped();
+            if (!stopped) {
+                stopRoute(route.getRouteId(), LoggingLevel.DEBUG);
+            }
+        }
+        // stop any remainder routes
+        for (Route route : getRoutes()) {
+            boolean stopped = getRouteController().getRouteStatus(route.getRouteId()).isStopped();
+            if (!stopped) {
+                stopRoute(route.getRouteId(), LoggingLevel.DEBUG);
+            }
+        }
+
+        // do not be noisy when removing routes
+        // as this is used by route-reload functionality, so lets be brief
+        logRouteStopSummary(LoggingLevel.DEBUG);
+
+        // remove all routes
+        for (Route route : getRoutes()) {
+            removeRoute(route.getRouteId(), LoggingLevel.DEBUG);
+        }
     }
 
     public synchronized void startRoute(String routeId) throws Exception {
@@ -1259,7 +1298,8 @@ public abstract class AbstractCamelContext extends BaseService
         }
     }
 
-    public synchronized boolean stopRoute(String routeId, long timeout, TimeUnit timeUnit, boolean abortAfterTimeout)
+    public synchronized boolean stopRoute(
+            String routeId, long timeout, TimeUnit timeUnit, boolean abortAfterTimeout, LoggingLevel loggingLevel)
             throws Exception {
         DefaultRouteError.reset(this, routeId);
 
@@ -1271,7 +1311,7 @@ public abstract class AbstractCamelContext extends BaseService
                 boolean completed = getShutdownStrategy().shutdown(this, route, timeout, timeUnit, abortAfterTimeout);
                 if (completed) {
                     // must stop route service as well
-                    stopRouteService(routeService, false);
+                    stopRouteService(routeService, false, loggingLevel);
                 } else {
                     // shutdown was aborted, make sure route is re-started properly
                     startRouteService(routeService, false);
@@ -1287,14 +1327,19 @@ public abstract class AbstractCamelContext extends BaseService
     }
 
     public void stopRoute(String routeId) throws Exception {
-        doShutdownRoute(routeId, getShutdownStrategy().getTimeout(), getShutdownStrategy().getTimeUnit(), false);
+        stopRoute(routeId, LoggingLevel.INFO);
+    }
+
+    public void stopRoute(String routeId, LoggingLevel loggingLevel) throws Exception {
+        doShutdownRoute(routeId, getShutdownStrategy().getTimeout(), getShutdownStrategy().getTimeUnit(), false, loggingLevel);
     }
 
     public void stopRoute(String routeId, long timeout, TimeUnit timeUnit) throws Exception {
-        doShutdownRoute(routeId, timeout, timeUnit, false);
+        doShutdownRoute(routeId, timeout, timeUnit, false, LoggingLevel.INFO);
     }
 
-    protected synchronized void doShutdownRoute(String routeId, long timeout, TimeUnit timeUnit, boolean removingRoutes)
+    protected synchronized void doShutdownRoute(
+            String routeId, long timeout, TimeUnit timeUnit, boolean removingRoutes, LoggingLevel loggingLevel)
             throws Exception {
         DefaultRouteError.reset(this, routeId);
 
@@ -1308,7 +1353,7 @@ public abstract class AbstractCamelContext extends BaseService
                 getShutdownStrategy().shutdown(this, routes, timeout, timeUnit);
                 // must stop route service as well (and remove the routes from
                 // management)
-                stopRouteService(routeService, removingRoutes);
+                stopRouteService(routeService, removingRoutes, loggingLevel);
             } catch (Exception e) {
                 DefaultRouteError.set(this, routeId, removingRoutes ? Phase.SHUTDOWN : Phase.STOP, e);
                 throw e;
@@ -1318,6 +1363,10 @@ public abstract class AbstractCamelContext extends BaseService
 
     @Override
     public synchronized boolean removeRoute(String routeId) throws Exception {
+        return removeRoute(routeId, LoggingLevel.INFO);
+    }
+
+    protected synchronized boolean removeRoute(String routeId, LoggingLevel loggingLevel) throws Exception {
         DefaultRouteError.reset(this, routeId);
 
         // gather a map of all the endpoints in use by the routes, so we can
@@ -1333,7 +1382,7 @@ public abstract class AbstractCamelContext extends BaseService
             if (getRouteStatus(routeId).isStopped()) {
                 try {
                     routeService.setRemovingRoutes(true);
-                    shutdownRouteService(routeService);
+                    shutdownRouteService(routeService, loggingLevel);
                     routeServices.remove(routeId);
                     // remove route from startup order as well, as it was
                     // removed
@@ -3293,7 +3342,7 @@ public abstract class AbstractCamelContext extends BaseService
 
         if (startupSummaryLevel != StartupSummaryLevel.Classic && startupSummaryLevel != StartupSummaryLevel.Oneline
                 && startupSummaryLevel != StartupSummaryLevel.Off) {
-            logRouteStopSummary();
+            logRouteStopSummary(LoggingLevel.INFO);
         }
 
         // do not clear route services or startup listeners as we can start
@@ -3414,8 +3463,9 @@ public abstract class AbstractCamelContext extends BaseService
         // noop
     }
 
-    protected void logRouteStopSummary() {
-        if (LOG.isInfoEnabled()) {
+    protected void logRouteStopSummary(LoggingLevel loggingLevel) {
+        CamelLogger logger = new CamelLogger(LOG, loggingLevel);
+        if (logger.shouldLog()) {
             int total = 0;
             int stopped = 0;
             int forced = 0;
@@ -3443,14 +3493,14 @@ public abstract class AbstractCamelContext extends BaseService
                 lines.add(String.format("    %s %s (%s)", status, id, uri));
             }
             if (forced > 0) {
-                LOG.info("Routes shutdown summary (total:{} stopped:{} forced:{})", total, stopped, forced);
+                logger.log(String.format("Routes stopped summary (total:%s stopped:%s forced:%s)", total, stopped, forced));
             } else {
-                LOG.info("Routes shutdown summary (total:{} stopped:{})", total, stopped);
+                logger.log(String.format("Routes stopped summary (total:%s stopped:%s)", total, stopped));
             }
             // if we are default/verbose then log each route line
             if (startupSummaryLevel == StartupSummaryLevel.Default || startupSummaryLevel == StartupSummaryLevel.Verbose) {
                 for (String line : lines) {
-                    LOG.info(line);
+                    logger.log(line);
                 }
             }
         }
@@ -3603,41 +3653,47 @@ public abstract class AbstractCamelContext extends BaseService
         }
     }
 
-    protected synchronized void stopRouteService(RouteService routeService, boolean removingRoutes) throws Exception {
+    protected synchronized void stopRouteService(RouteService routeService, boolean removingRoutes, LoggingLevel loggingLevel)
+            throws Exception {
         routeService.setRemovingRoutes(removingRoutes);
-        stopRouteService(routeService);
+        stopRouteService(routeService, loggingLevel);
     }
 
-    protected void logRouteState(Route route, String state) {
-        if (LOG.isInfoEnabled()) {
+    protected void logRouteState(Route route, String state, LoggingLevel loggingLevel) {
+        CamelLogger logger = new CamelLogger(LOG, loggingLevel);
+        if (logger.shouldLog()) {
             if (route.getConsumer() != null) {
                 String id = route.getId();
                 String uri = route.getEndpoint().getEndpointBaseUri();
                 uri = URISupport.sanitizeUri(uri);
                 String line = String.format("%s %s (%s)", state, id, uri);
-                LOG.info(line);
+                logger.log(line);
             } else {
                 String id = route.getId();
                 String line = String.format("%s %s", state, id);
-                LOG.info(line);
+                logger.log(line);
             }
         }
     }
 
-    protected synchronized void stopRouteService(RouteService routeService) throws Exception {
+    protected synchronized void stopRouteService(RouteService routeService, LoggingLevel loggingLevel) throws Exception {
         routeService.stop();
-        logRouteState(routeService.getRoute(), "Stopped");
+        logRouteState(routeService.getRoute(), "Stopped", loggingLevel);
     }
 
     protected synchronized void shutdownRouteService(RouteService routeService) throws Exception {
+        shutdownRouteService(routeService, LoggingLevel.INFO);
+    }
+
+    protected synchronized void shutdownRouteService(RouteService routeService, LoggingLevel loggingLevel) throws Exception {
         routeService.shutdown();
-        logRouteState(routeService.getRoute(), "Shutdown");
+        logRouteState(routeService.getRoute(), "Shutdown", loggingLevel);
     }
 
     protected synchronized void suspendRouteService(RouteService routeService) throws Exception {
         routeService.setRemovingRoutes(false);
         routeService.suspend();
-        logRouteState(routeService.getRoute(), "Suspended");
+        logRouteState(routeService.getRoute(), "Suspended", LoggingLevel.INFO);
     }
 
     /**
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultRouteController.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultRouteController.java
index eb270d2..e5401f2 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultRouteController.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultRouteController.java
@@ -100,6 +100,11 @@ public class DefaultRouteController extends ServiceSupport implements RouteContr
     }
 
     @Override
+    public void removeAllRoutes() throws Exception {
+        getInternalRouteController().removeAllRoutes();
+    }
+
+    @Override
     public boolean isStartingRoutes() {
         return getInternalRouteController().isStartingRoutes();
     }
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/InternalRouteController.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/InternalRouteController.java
index d2219f1..95f378e 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/InternalRouteController.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/InternalRouteController.java
@@ -78,6 +78,11 @@ class InternalRouteController implements RouteController {
     }
 
     @Override
+    public void removeAllRoutes() throws Exception {
+        abstractCamelContext.removeAllRoutes();
+    }
+
+    @Override
     public boolean isStartingRoutes() {
         return abstractCamelContext.isStartingRoutes();
     }
@@ -104,7 +109,7 @@ class InternalRouteController implements RouteController {
 
     @Override
     public boolean stopRoute(String routeId, long timeout, TimeUnit timeUnit, boolean abortAfterTimeout) throws Exception {
-        return abstractCamelContext.stopRoute(routeId, timeout, timeUnit, abortAfterTimeout);
+        return abstractCamelContext.stopRoute(routeId, timeout, timeUnit, abortAfterTimeout, LoggingLevel.INFO);
     }
 
     @Override
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
index 910c19d..4460e9d 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
@@ -2004,6 +2004,11 @@ public class LightweightRuntimeCamelContext implements ExtendedCamelContext, Cat
             }
 
             @Override
+            public void removeAllRoutes() throws Exception {
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
             public boolean isStartingRoutes() {
                 return false;
             }
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/RouteWatcherReloadStrategy.java b/core/camel-support/src/main/java/org/apache/camel/support/RouteWatcherReloadStrategy.java
index 25443ef..b974eb7 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/RouteWatcherReloadStrategy.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/RouteWatcherReloadStrategy.java
@@ -17,15 +17,20 @@
 package org.apache.camel.support;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Set;
 import java.util.StringJoiner;
 
 import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.Route;
 import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.ServiceStatus;
+import org.apache.camel.StartupSummaryLevel;
 import org.apache.camel.util.AntPathMatcher;
 import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.URISupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -117,12 +122,8 @@ public class RouteWatcherReloadStrategy extends FileWatcherResourceReloadStrateg
                 try {
                     // should all existing routes be stopped and removed first?
                     if (removeAllRoutes) {
-                        // first stop all routes
-                        getCamelContext().getRouteController().stopAllRoutes();
-                        // then remove all routes
-                        for (Route route : getCamelContext().getRoutes()) {
-                            getCamelContext().removeRoute(route.getRouteId());
-                        }
+                        // first stop and remove all routes
+                        getCamelContext().getRouteController().removeAllRoutes();
                         // remove left-over route templates and endpoints, so we can start on a fresh
                         getCamelContext().removeRouteTemplates("*");
                         getCamelContext().getEndpointRegistry().clear();
@@ -130,7 +131,28 @@ public class RouteWatcherReloadStrategy extends FileWatcherResourceReloadStrateg
                     Set<String> ids
                             = getCamelContext().adapt(ExtendedCamelContext.class).getRoutesLoader().updateRoutes(resource);
                     if (!ids.isEmpty()) {
-                        LOG.info("Reloaded routes: {}", String.join(", ", ids));
+                        List<String> lines = new ArrayList<>();
+                        int total = 0;
+                        int started = 0;
+                        for (String id : ids) {
+                            total++;
+                            String status = getCamelContext().getRouteController().getRouteStatus(id).name();
+                            if (ServiceStatus.Started.name().equals(status)) {
+                                started++;
+                            }
+                            // use basic endpoint uri to not log verbose details or potential sensitive data
+                            String uri = getCamelContext().getRoute(id).getEndpoint().getEndpointBaseUri();
+                            uri = URISupport.sanitizeUri(uri);
+                            lines.add(String.format("    %s %s (%s)", status, id, uri));
+                        }
+                        LOG.info(String.format("Routes reloaded summary (total:%s started:%s)", total, started));
+                        // if we are default/verbose then log each route line
+                        if (getCamelContext().getStartupSummaryLevel() == StartupSummaryLevel.Default
+                                || getCamelContext().getStartupSummaryLevel() == StartupSummaryLevel.Verbose) {
+                            for (String line : lines) {
+                                LOG.info(line);
+                            }
+                        }
                     }
                     // fire events for routes reloaded
                     for (String id : ids) {