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

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


The following commit(s) were added to refs/heads/master by this push:
     new 6705fdd  CAMEL-15048: SupervisingRouteController - Exhausted routes 
should be kept which allows management to provide information about exhausted 
routes and why they failed.
6705fdd is described below

commit 6705fdd9a366ef82c97ed399524a8024d99b64d5
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu May 14 17:25:40 2020 +0200

    CAMEL-15048: SupervisingRouteController - Exhausted routes should be kept 
which allows management to provide information about exhausted routes and why 
they failed.
---
 .../camel/spi/SupervisingRouteController.java      |  5 +++
 .../engine/DefaultSupervisingRouteController.java  | 25 +++++++++++++--
 .../ManagedSupervisingRouteControllerMBean.java    | 10 ++++--
 .../mbean/ManagedSupervisingRouteController.java   | 37 +++++++++++++++++++---
 .../ManagedSupervisingRouteControllerTest.java     | 16 +++++++---
 5 files changed, 78 insertions(+), 15 deletions(-)

diff --git 
a/core/camel-api/src/main/java/org/apache/camel/spi/SupervisingRouteController.java
 
b/core/camel-api/src/main/java/org/apache/camel/spi/SupervisingRouteController.java
index cb6e6e1..c10a383 100644
--- 
a/core/camel-api/src/main/java/org/apache/camel/spi/SupervisingRouteController.java
+++ 
b/core/camel-api/src/main/java/org/apache/camel/spi/SupervisingRouteController.java
@@ -125,6 +125,11 @@ public interface SupervisingRouteController extends 
RouteController {
     Collection<Route> getRestartingRoutes();
 
     /**
+     * Return the list of routes that have failed all attempts to startup and 
are now exhausted.
+     */
+    Collection<Route> getExhaustedRoutes();
+
+    /**
      * Gets the state of the backoff for the given route if its managed and 
under restarting.
      *
      * @param routeId  the route id
diff --git 
a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultSupervisingRouteController.java
 
b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultSupervisingRouteController.java
index 8944856..ae6ae63 100644
--- 
a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultSupervisingRouteController.java
+++ 
b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultSupervisingRouteController.java
@@ -330,6 +330,13 @@ public class DefaultSupervisingRouteController extends 
DefaultRouteController im
     }
 
     @Override
+    public Collection<Route> getExhaustedRoutes() {
+        return routeManager.exhausted.keySet().stream()
+                .map(RouteHolder::get)
+                .collect(Collectors.toList());
+    }
+
+    @Override
     public BackOffTimer.Task getRestartingRouteState(String routeId) {
         return routeManager.getBackOffContext(routeId).orElse(null);
     }
@@ -437,10 +444,11 @@ public class DefaultSupervisingRouteController extends 
DefaultRouteController im
             }
         }
 
-        LOG.info("Total managed routes: {} of which {} successfully started 
and {} re-starting",
+        LOG.info("Total managed routes: {} of which {} successfully started 
(restarting: {}, exhausted: {})",
             routes.size(),
             routes.stream().filter(r -> r.getStatus() == 
ServiceStatus.Started).count(),
-            routeManager.routes.size()
+            routeManager.routes.size(),
+            routeManager.exhausted.size()
         );
     }
 
@@ -455,11 +463,13 @@ public class DefaultSupervisingRouteController extends 
DefaultRouteController im
     private class RouteManager {
         private final Logger logger;
         private final ConcurrentMap<RouteHolder, BackOffTimer.Task> routes;
+        private final ConcurrentMap<RouteHolder, BackOffTimer.Task> exhausted;
         private final ConcurrentMap<String, Throwable> exceptions;
 
         RouteManager() {
             this.logger = LoggerFactory.getLogger(RouteManager.class);
             this.routes = new ConcurrentHashMap<>();
+            this.exhausted = new ConcurrentHashMap<>();
             this.exceptions = new ConcurrentHashMap<>();
         }
 
@@ -506,6 +516,8 @@ public class DefaultSupervisingRouteController extends 
DefaultRouteController im
                                                     + " and the route is no 
longer supervised by this route controller and remains as stopped.",
                                             route.getId(), 
backOffTask.getCurrentAttempts() - 1);
                                     r.get().setRouteController(null);
+                                    // remember exhausted routes
+                                    routeManager.exhausted.put(r, task);
                                 }
                             }
                         }
@@ -530,10 +542,17 @@ public class DefaultSupervisingRouteController extends 
DefaultRouteController im
         }
 
         public Optional<BackOffTimer.Task> getBackOffContext(String id) {
-            return routes.entrySet().stream()
+            Optional<BackOffTimer.Task> answer = routes.entrySet().stream()
                 .filter(e -> ObjectHelper.equal(e.getKey().getId(), id))
                 .findFirst()
                 .map(Map.Entry::getValue);
+            if (!answer.isPresent()) {
+                answer = exhausted.entrySet().stream()
+                    .filter(e -> ObjectHelper.equal(e.getKey().getId(), id))
+                    .findFirst()
+                    .map(Map.Entry::getValue);
+            }
+            return answer;
         }
     }
 
diff --git 
a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedSupervisingRouteControllerMBean.java
 
b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedSupervisingRouteControllerMBean.java
index 3853216..f1131f9 100644
--- 
a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedSupervisingRouteControllerMBean.java
+++ 
b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedSupervisingRouteControllerMBean.java
@@ -61,10 +61,16 @@ public interface ManagedSupervisingRouteControllerMBean 
extends ManagedRouteCont
     @ManagedAttribute(description = "Number of routes which have failed to 
startup and are currently managed to be restarted")
     int getNumberOfRestartingRoutes();
 
-    @ManagedAttribute(description = "Controlled Routes")
+    @ManagedAttribute(description = "Number of routes which have failed all 
attempts to startup and are now exhausted")
+    int getNumberOfExhaustedRoutes();
+
+    @ManagedAttribute(description = "Exhausted routes")
+    Collection<String> getExhaustedRoutes();
+
+    @ManagedAttribute(description = "Routes that are restarting or scheduled 
to restart")
     Collection<String> getRestartingRoutes();
 
     @ManagedOperation(description = "Lists detailed status about all the 
routes (incl failure details for routes failed to start)")
-    TabularData routeStatus(boolean restartingOnly, boolean includeStacktrace);
+    TabularData routeStatus(boolean exhausted, boolean restarting, boolean 
includeStacktrace);
 
 }
diff --git 
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedSupervisingRouteController.java
 
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedSupervisingRouteController.java
index 7947687..32799ff 100644
--- 
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedSupervisingRouteController.java
+++ 
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedSupervisingRouteController.java
@@ -20,8 +20,10 @@ import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Comparator;
+import java.util.Set;
+import java.util.TreeSet;
 import java.util.stream.Collectors;
-
 import javax.management.openmbean.CompositeData;
 import javax.management.openmbean.CompositeDataSupport;
 import javax.management.openmbean.CompositeType;
@@ -113,6 +115,11 @@ public class ManagedSupervisingRouteController extends 
ManagedService implements
     }
 
     @Override
+    public int getNumberOfExhaustedRoutes() {
+        return controller.getExhaustedRoutes().size();
+    }
+
+    @Override
     public Collection<String> getControlledRoutes() {
         if (controller != null) {
             return controller.getControlledRoutes().stream()
@@ -135,12 +142,31 @@ public class ManagedSupervisingRouteController extends 
ManagedService implements
     }
 
     @Override
-    public TabularData routeStatus(boolean restartingOnly, boolean 
includeStacktrace) {
+    public Collection<String> getExhaustedRoutes() {
+        if (controller != null) {
+            return controller.getExhaustedRoutes().stream()
+                    .map(Route::getId)
+                    .collect(Collectors.toList());
+        }
+
+        return Collections.emptyList();
+    }
+
+    @Override
+    public TabularData routeStatus(boolean exhausted, boolean restarting, 
boolean includeStacktrace) {
         try {
             TabularData answer = new 
TabularDataSupport(CamelOpenMBeanTypes.supervisingRouteControllerRouteStatusTabularType());
 
             int index = 0;
-            Collection<Route> routes = restartingOnly ? 
controller.getRestartingRoutes() : controller.getControlledRoutes();
+            Set<Route> routes = new 
TreeSet<>(Comparator.comparing(Route::getId));
+            routes.addAll(controller.getControlledRoutes());
+            if (exhausted) {
+                routes.addAll(controller.getExhaustedRoutes());
+            }
+            if (restarting) {
+                routes.addAll(controller.getRestartingRoutes());
+            }
+
             for (Route route : routes) {
                 CompositeType ct = 
CamelOpenMBeanTypes.supervisingRouteControllerRouteStatusCompositeType();
 
@@ -151,12 +177,13 @@ public class ManagedSupervisingRouteController extends 
ManagedService implements
                 long attempts = state != null ? state.getCurrentAttempts() : 0;
                 String elapsed = "";
                 String last = "";
-                long time = state != null ? state.getFirstAttemptTime() : 0;
+                // we can only track elapsed/time for active supervised routes
+                long time = state != null && BackOffTimer.Task.Status.Active 
== state.getStatus() ? state.getFirstAttemptTime() : 0;
                 if (time > 0) {
                     long delta = System.currentTimeMillis() - time;
                     elapsed = TimeUtils.printDuration(delta);
                 }
-                time = state != null ? state.getLastAttemptTime() : 0;
+                time = state != null && BackOffTimer.Task.Status.Active == 
state.getStatus() ? state.getLastAttemptTime() : 0;
                 if (time > 0) {
                     long delta = System.currentTimeMillis() - time;
                     last = TimeUtils.printDuration(delta);
diff --git 
a/core/camel-management/src/test/java/org/apache/camel/management/ManagedSupervisingRouteControllerTest.java
 
b/core/camel-management/src/test/java/org/apache/camel/management/ManagedSupervisingRouteControllerTest.java
index 61f5159..a5d2fdd 100644
--- 
a/core/camel-management/src/test/java/org/apache/camel/management/ManagedSupervisingRouteControllerTest.java
+++ 
b/core/camel-management/src/test/java/org/apache/camel/management/ManagedSupervisingRouteControllerTest.java
@@ -44,8 +44,8 @@ public class ManagedSupervisingRouteControllerTest extends 
ManagementTestSupport
         CamelContext context = super.createCamelContext();
         SupervisingRouteController src = new 
DefaultSupervisingRouteController();
         src.setThreadPoolSize(2);
-        src.setBackOffDelay(250);
-        src.setBackOffMaxAttempts(100);
+        src.setBackOffDelay(100);
+        src.setBackOffMaxAttempts(50);
         context.setRouteController(src);
         return context;
     }
@@ -71,7 +71,7 @@ public class ManagedSupervisingRouteControllerTest extends 
ManagementTestSupport
         assertEquals(2, threadPoolSize.intValue());
 
         Long backOffDelay = (Long) mbeanServer.getAttribute(on, 
"BackOffDelay");
-        assertEquals(250, backOffDelay.intValue());
+        assertEquals(100, backOffDelay.intValue());
 
         Integer routes = (Integer) mbeanServer.getAttribute(on, 
"NumberOfControlledRoutes");
         assertEquals(3, routes.intValue());
@@ -81,9 +81,15 @@ public class ManagedSupervisingRouteControllerTest extends 
ManagementTestSupport
             assertEquals(2, restarting.intValue());
         });
 
-        TabularData data = (TabularData) mbeanServer.invoke(on, "routeStatus", 
new Object[]{true, true}, new String[]{"boolean", "boolean"});
+        // wait for routes to be exhausted
+        await().atMost(10, TimeUnit.SECONDS).untilAsserted(() -> {
+            Integer exhausted = (Integer) mbeanServer.getAttribute(on, 
"NumberOfExhaustedRoutes");
+            assertEquals(2, exhausted.intValue());
+        });
+
+        TabularData data = (TabularData) mbeanServer.invoke(on, "routeStatus", 
new Object[]{true, true, true}, new String[]{"boolean", "boolean", "boolean"});
         assertNotNull(data);
-        assertEquals(2, data.size());
+        assertEquals(3, data.size());
     }
 
     @Override

Reply via email to