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 2023/06/12 13:01:05 UTC

[camel] branch main updated: CAMEL-18597: Add dev console for route circuit breaker and support in the jbang command.

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


The following commit(s) were added to refs/heads/main by this push:
     new e2f29dc7293 CAMEL-18597: Add dev console for route circuit breaker and support in the jbang command.
e2f29dc7293 is described below

commit e2f29dc7293fd7f490a6f2c4ca5b57a110645e44
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Jun 12 14:59:22 2023 +0200

    CAMEL-18597: Add dev console for route circuit breaker and support in the jbang command.
---
 .../apache/camel/dev-console/route-circuit-breaker |  2 +
 .../console/RouteCircuitBreakerDevConsole.java     | 79 ++++++++++++++++++++++
 .../throttling/ThrottlingExceptionRoutePolicy.java | 15 +++-
 .../camel/cli/connector/LocalCliConnector.java     |  7 ++
 .../core/commands/process/ListCircuitBreaker.java  | 19 +++++-
 5 files changed, 119 insertions(+), 3 deletions(-)

diff --git a/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/route-circuit-breaker b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/route-circuit-breaker
new file mode 100644
index 00000000000..8500cb624bb
--- /dev/null
+++ b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/route-circuit-breaker
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.impl.console.RouteCircuitBreakerDevConsole
diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteCircuitBreakerDevConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteCircuitBreakerDevConsole.java
new file mode 100644
index 00000000000..89754acf0d6
--- /dev/null
+++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteCircuitBreakerDevConsole.java
@@ -0,0 +1,79 @@
+/*
+ * 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.impl.console;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.camel.Route;
+import org.apache.camel.spi.RoutePolicy;
+import org.apache.camel.spi.annotations.DevConsole;
+import org.apache.camel.support.console.AbstractDevConsole;
+import org.apache.camel.throttling.ThrottlingExceptionRoutePolicy;
+import org.apache.camel.util.TimeUtils;
+import org.apache.camel.util.json.JsonObject;
+
+@DevConsole("route-circuit-breaker")
+public class RouteCircuitBreakerDevConsole extends AbstractDevConsole {
+
+    public RouteCircuitBreakerDevConsole() {
+        super("camel", "route-circuit-breaker", "Route Circuit Breaker", "Display circuit breaker information");
+    }
+
+    @Override
+    protected String doCallText(Map<String, Object> options) {
+        StringBuilder sb = new StringBuilder();
+
+        for (Route route : getCamelContext().getRoutes()) {
+            for (RoutePolicy rp : route.getRoutePolicyList()) {
+                if (rp instanceof ThrottlingExceptionRoutePolicy cb) {
+                    String rid = route.getRouteId();
+                    String state = cb.getStateAsString();
+                    int sc = cb.getSuccess();
+                    int fc = cb.getFailures();
+                    String lastFailure = cb.getLastFailure() > 0 ? TimeUtils.printSince(cb.getLastFailure()) : "n/a";
+                    sb.append(String.format("    %s: %s (success: %d failure: %d last-failure: %s)\n", rid, state, sc, fc, lastFailure));
+                }
+            }
+        }
+
+        return sb.toString();
+    }
+
+    @Override
+    protected Map<String, Object> doCallJson(Map<String, Object> options) {
+        JsonObject root = new JsonObject();
+
+        final List<JsonObject> list = new ArrayList<>();
+        for (Route route : getCamelContext().getRoutes()) {
+            for (RoutePolicy rp : route.getRoutePolicyList()) {
+                if (rp instanceof ThrottlingExceptionRoutePolicy cb) {
+                    JsonObject jo = new JsonObject();
+                    jo.put("routeId", route.getRouteId());
+                    jo.put("state", cb.getStateAsString());
+                    jo.put("successfulCalls", cb.getSuccess());
+                    jo.put("failedCalls", cb.getFailures());
+                    list.add(jo);
+                }
+            }
+        }
+        root.put("circuitBreakers", list);
+
+        return root;
+    }
+}
diff --git a/core/camel-support/src/main/java/org/apache/camel/throttling/ThrottlingExceptionRoutePolicy.java b/core/camel-support/src/main/java/org/apache/camel/throttling/ThrottlingExceptionRoutePolicy.java
index 4f1b7f8ed5a..8384f8a53cd 100644
--- a/core/camel-support/src/main/java/org/apache/camel/throttling/ThrottlingExceptionRoutePolicy.java
+++ b/core/camel-support/src/main/java/org/apache/camel/throttling/ThrottlingExceptionRoutePolicy.java
@@ -70,6 +70,7 @@ public class ThrottlingExceptionRoutePolicy extends RoutePolicySupport implement
 
     // stateful information
     private final AtomicInteger failures = new AtomicInteger();
+    private final AtomicInteger success = new AtomicInteger();
     private final AtomicInteger state = new AtomicInteger(STATE_CLOSED);
     private final AtomicBoolean keepOpen = new AtomicBoolean();
     private volatile Timer halfOpenTimer;
@@ -139,6 +140,8 @@ public class ThrottlingExceptionRoutePolicy extends RoutePolicySupport implement
                 // record the failure
                 failures.incrementAndGet();
                 lastFailure = System.currentTimeMillis();
+            } else {
+                success.incrementAndGet();
             }
 
             // check for state change
@@ -278,6 +281,7 @@ public class ThrottlingExceptionRoutePolicy extends RoutePolicySupport implement
             lock.lock();
             resumeOrStartConsumer(route.getConsumer());
             failures.set(0);
+            success.set(0);
             lastFailure = 0;
             openedAt = 0;
             state.set(STATE_CLOSED);
@@ -295,9 +299,12 @@ public class ThrottlingExceptionRoutePolicy extends RoutePolicySupport implement
         }
     }
 
+    public String getStateAsString() {
+        return stateAsString(state.get());
+    }
+
     public String dumpState() {
-        int num = state.get();
-        String routeState = stateAsString(num);
+        String routeState = getStateAsString();
         if (failures.get() > 0) {
             return String.format("State %s, failures %d, last failure %d ms ago", routeState, failures.get(),
                     System.currentTimeMillis() - lastFailure);
@@ -374,6 +381,10 @@ public class ThrottlingExceptionRoutePolicy extends RoutePolicySupport implement
         return failures.get();
     }
 
+    public int getSuccess() {
+        return success.get();
+    }
+
     public long getLastFailure() {
         return lastFailure;
     }
diff --git a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
index 2459a6cf476..dfb52400226 100644
--- a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
+++ b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
@@ -582,6 +582,13 @@ public class LocalCliConnector extends ServiceSupport implements CliConnector, C
                         root.put("fault-tolerance", json);
                     }
                 }
+                DevConsole dc12a = dcr.resolveById("route-circuit-breaker");
+                if (dc12a != null) {
+                    JsonObject json = (JsonObject) dc12a.call(DevConsole.MediaType.JSON);
+                    if (json != null && !json.isEmpty()) {
+                        root.put("route-circuit-breaker", json);
+                    }
+                }
                 DevConsole dc12 = camelContext.getCamelContextExtension().getContextPlugin(DevConsoleRegistry.class)
                         .resolveById("trace");
                 if (dc12 != null) {
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListCircuitBreaker.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListCircuitBreaker.java
index 1d27e4c249d..b96f39b82ae 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListCircuitBreaker.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListCircuitBreaker.java
@@ -108,6 +108,23 @@ public class ListCircuitBreaker extends ProcessWatchCommand {
                                 }
                             }
                         }
+                        mo = (JsonObject) root.get("route-circuit-breaker");
+                        if (mo != null) {
+                            JsonArray arr = (JsonArray) mo.get("circuitBreakers");
+                            if (arr != null) {
+                                for (int i = 0; i < arr.size(); i++) {
+                                    row = baseRow.copy();
+                                    JsonObject jo = (JsonObject) arr.get(i);
+                                    row.component = "core";
+                                    row.id = jo.getString("routeId");
+                                    row.routeId = jo.getString("routeId");
+                                    row.state = jo.getString("state");
+                                    row.successfulCalls = jo.getInteger("successfulCalls");
+                                    row.failedCalls = jo.getInteger("failedCalls");
+                                    rows.add(row);
+                                }
+                            }
+                        }
                     }
                 });
 
@@ -173,7 +190,7 @@ public class ListCircuitBreaker extends ProcessWatchCommand {
     }
 
     private String getSuccess(Row r) {
-        if ("resilience4j".equals(r.component)) {
+        if ("resilience4j".equals(r.component) || "core".equals(r.component)) {
             return Integer.toString(r.successfulCalls);
         }
         return "";