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/12/17 12:53:04 UTC

[camel] 03/03: CAMEL-17340: camel-management - JMX MBean operation to get mapping between node ids and their source location/line-number for tooling.

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 5891131bd553f05a70988bd34fc88413d1f20e8d
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Fri Dec 17 13:51:24 2021 +0100

    CAMEL-17340: camel-management - JMX MBean operation to get mapping between node ids and their source location/line-number for tooling.
---
 .../management/mbean/ManagedCamelContextMBean.java |  3 +
 .../api/management/mbean/ManagedRouteMBean.java    |  7 +-
 .../management/mbean/ManagedBacklogDebugger.java   | 20 +++---
 .../management/mbean/ManagedCamelContext.java      | 76 +++++++++++++++++++++-
 .../camel/management/mbean/ManagedRoute.java       | 51 +++++++++++++++
 5 files changed, 144 insertions(+), 13 deletions(-)

diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
index e0c31d4..2213cfc 100644
--- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
+++ b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
@@ -211,6 +211,9 @@ public interface ManagedCamelContextMBean extends ManagedPerformanceCounterMBean
     @ManagedOperation(description = "Dumps the route templates as XML")
     String dumpRouteTemplatesAsXml() throws Exception;
 
+    @ManagedOperation(description = "Dumps all routes with mappings between node ids and their source location/line-number (currently only XML and YAML routes supported) as XML")
+    String dumpRoutesSourceLocationsAsXml() throws Exception;
+
     /**
      * Creates the endpoint by the given uri
      *
diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
index dc0ef4b..c49ea7ae 100644
--- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
+++ b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
@@ -117,12 +117,15 @@ public interface ManagedRouteMBean extends ManagedPerformanceCounterMBean {
     @ManagedOperation(description = "Updates the route from XML")
     void updateRouteFromXml(String xml) throws Exception;
 
-    @ManagedOperation(description = "Dumps the routes stats as XML")
+    @ManagedOperation(description = "Dumps the route stats as XML")
     String dumpRouteStatsAsXml(boolean fullStats, boolean includeProcessors) throws Exception;
 
-    @ManagedOperation(description = "Dumps the routes and steps stats as XML")
+    @ManagedOperation(description = "Dumps the route and steps stats as XML")
     String dumpStepStatsAsXml(boolean fullStats) throws Exception;
 
+    @ManagedOperation(description = "Dumps the route with mappings between node ids and their source location/line-number (currently only XML and YAML routes supported) as XML")
+    String dumpRouteSourceLocationsAsXml() throws Exception;
+
     @ManagedOperation(description = "Reset counters")
     void reset(boolean includeProcessors) throws Exception;
 
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedBacklogDebugger.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedBacklogDebugger.java
index f9d8eeb..0fa8f21 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedBacklogDebugger.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedBacklogDebugger.java
@@ -333,16 +333,6 @@ public class ManagedBacklogDebugger implements ManagedBacklogDebuggerMBean {
         return null;
     }
 
-    private static boolean isSerializable(Object obj) {
-        final ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
-        try (ObjectOutputStream out = new ObjectOutputStream(baos)) {
-            out.writeObject(obj);
-            return true;
-        } catch (Exception e) {
-            return false;
-        }
-    }
-
     private String dumpExchangePropertiesAsXml(String id) {
         StringBuilder sb = new StringBuilder();
         sb.append("  <exchangeProperties>\n");
@@ -377,4 +367,14 @@ public class ManagedBacklogDebugger implements ManagedBacklogDebuggerMBean {
         return sb.toString();
     }
 
+    private static boolean isSerializable(Object obj) {
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
+        try (ObjectOutputStream out = new ObjectOutputStream(baos)) {
+            out.writeObject(obj);
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
 }
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
index 9ed0a37..6132961 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
@@ -47,6 +47,7 @@ import org.apache.camel.api.management.mbean.ManagedProcessorMBean;
 import org.apache.camel.api.management.mbean.ManagedRouteMBean;
 import org.apache.camel.api.management.mbean.ManagedStepMBean;
 import org.apache.camel.model.Model;
+import org.apache.camel.model.ModelCamelContext;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.model.RouteTemplateDefinition;
 import org.apache.camel.model.RouteTemplatesDefinition;
@@ -436,7 +437,7 @@ public class ManagedCamelContext extends ManagedPerformanceCounter implements Ti
             return null;
         }
 
-        // use a routes definition to dump the routes
+        // use routes definition to dump the routes
         RoutesDefinition def = new RoutesDefinition();
         def.setRoutes(routes);
 
@@ -652,6 +653,68 @@ public class ManagedCamelContext extends ManagedPerformanceCounter implements Ti
     }
 
     @Override
+    public String dumpRoutesSourceLocationsAsXml() throws Exception {
+        StringBuilder sb = new StringBuilder();
+        sb.append("<routeLocations>");
+
+        MBeanServer server = getContext().getManagementStrategy().getManagementAgent().getMBeanServer();
+        if (server != null) {
+            // gather all the routes for this CamelContext, which requires JMX
+            List<ManagedRouteMBean> routes = new ArrayList<>();
+            String prefix = getContext().getManagementStrategy().getManagementAgent().getIncludeHostName() ? "*/" : "";
+            ObjectName query = ObjectName
+                    .getInstance(jmxDomain + ":context=" + prefix + getContext().getManagementName() + ",type=routes,*");
+            Set<ObjectName> names = server.queryNames(query, null);
+            for (ObjectName on : names) {
+                ManagedRouteMBean route
+                        = context.getManagementStrategy().getManagementAgent().newProxyClient(on, ManagedRouteMBean.class);
+                routes.add(route);
+            }
+            routes.sort(new RouteMBeans());
+
+            List<ManagedProcessorMBean> processors = new ArrayList<>();
+            // gather all the processors for this CamelContext, which requires JMX
+            query = ObjectName
+                    .getInstance(jmxDomain + ":context=" + prefix + getContext().getManagementName() + ",type=processors,*");
+            names = server.queryNames(query, null);
+            for (ObjectName on : names) {
+                ManagedProcessorMBean processor
+                        = context.getManagementStrategy().getManagementAgent().newProxyClient(on, ManagedProcessorMBean.class);
+                processors.add(processor);
+            }
+            processors.sort(new OrderProcessorMBeans());
+
+            // loop the routes, and append the node ids (via processor)
+            for (ManagedRouteMBean route : routes) {
+                // grab route consumer
+                RouteDefinition rd = context.adapt(ModelCamelContext.class).getRouteDefinition(route.getRouteId());
+                if (rd != null) {
+                    String id = rd.getRouteId();
+                    int line = rd.getInput().getLineNumber();
+                    String location = route.getSourceLocation() != null ? route.getSourceLocation() : "";
+                    sb.append("\n    <routeLocation")
+                            .append(String.format(
+                                    " routeId=\"%s\" id=\"%s\" index=\"%s\" sourceLocation=\"%s\" sourceLineNumber=\"%s\"/>",
+                                    route.getRouteId(), id, 0, location, line));
+                }
+                for (ManagedProcessorMBean processor : processors) {
+                    // the step must belong to this route
+                    if (route.getRouteId().equals(processor.getRouteId())) {
+                        int line = processor.getSourceLineNumber() != null ? processor.getSourceLineNumber() : -1;
+                        String location = route.getSourceLocation() != null ? route.getSourceLocation() : "";
+                        sb.append("\n    <routeLocation")
+                                .append(String.format(
+                                        " routeId=\"%s\" id=\"%s\" index=\"%s\" sourceLocation=\"%s\" sourceLineNumber=\"%s\"/>",
+                                        route.getRouteId(), processor.getProcessorId(), processor.getIndex(), location, line));
+                    }
+                }
+            }
+        }
+        sb.append("\n</routeLocations>");
+        return sb.toString();
+    }
+
+    @Override
     public boolean createEndpoint(String uri) throws Exception {
         if (context.hasEndpoint(uri) != null) {
             // endpoint already exists
@@ -733,4 +796,15 @@ public class ManagedCamelContext extends ManagedPerformanceCounter implements Ti
         }
     }
 
+    /**
+     * Used for sorting the routes mbeans accordingly to their ids.
+     */
+    private static final class RouteMBeans implements Comparator<ManagedRouteMBean> {
+
+        @Override
+        public int compare(ManagedRouteMBean o1, ManagedRouteMBean o2) {
+            return o1.getRouteId().compareToIgnoreCase(o2.getRouteId());
+        }
+    }
+
 }
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
index b53524c..b1dcf6f 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
@@ -53,6 +53,7 @@ import org.apache.camel.api.management.mbean.ManagedRouteMBean;
 import org.apache.camel.api.management.mbean.ManagedStepMBean;
 import org.apache.camel.api.management.mbean.RouteError;
 import org.apache.camel.model.Model;
+import org.apache.camel.model.ModelCamelContext;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.model.RoutesDefinition;
 import org.apache.camel.spi.InflightRepository;
@@ -570,6 +571,56 @@ public class ManagedRoute extends ManagedPerformanceCounter implements TimerList
     }
 
     @Override
+    public String dumpRouteSourceLocationsAsXml() throws Exception {
+        StringBuilder sb = new StringBuilder();
+        sb.append("<routeLocations>");
+
+        MBeanServer server = getContext().getManagementStrategy().getManagementAgent().getMBeanServer();
+        if (server != null) {
+            String prefix = getContext().getManagementStrategy().getManagementAgent().getIncludeHostName() ? "*/" : "";
+            List<ManagedProcessorMBean> processors = new ArrayList<>();
+            // gather all the processors for this CamelContext, which requires JMX
+            ObjectName query = ObjectName
+                    .getInstance(jmxDomain + ":context=" + prefix + getContext().getManagementName() + ",type=processors,*");
+            Set<ObjectName> names = server.queryNames(query, null);
+            for (ObjectName on : names) {
+                ManagedProcessorMBean processor
+                        = context.getManagementStrategy().getManagementAgent().newProxyClient(on, ManagedProcessorMBean.class);
+                // the processor must belong to this route
+                if (getRouteId().equals(processor.getRouteId())) {
+                    processors.add(processor);
+                }
+            }
+            processors.sort(new OrderProcessorMBeans());
+
+            // grab route consumer
+            RouteDefinition rd = context.adapt(ModelCamelContext.class).getRouteDefinition(route.getRouteId());
+            if (rd != null) {
+                String id = rd.getRouteId();
+                int line = rd.getInput().getLineNumber();
+                String location = getSourceLocation() != null ? getSourceLocation() : "";
+                sb.append("\n    <routeLocation")
+                        .append(String.format(
+                                " routeId=\"%s\" id=\"%s\" index=\"%s\" sourceLocation=\"%s\" sourceLineNumber=\"%s\"/>",
+                                route.getRouteId(), id, 0, location, line));
+            }
+            for (ManagedProcessorMBean processor : processors) {
+                // the step must belong to this route
+                if (route.getRouteId().equals(processor.getRouteId())) {
+                    int line = processor.getSourceLineNumber() != null ? processor.getSourceLineNumber() : -1;
+                    String location = getSourceLocation() != null ? getSourceLocation() : "";
+                    sb.append("\n    <routeLocation")
+                            .append(String.format(
+                                    " routeId=\"%s\" id=\"%s\" index=\"%s\" sourceLocation=\"%s\" sourceLineNumber=\"%s\"/>",
+                                    route.getRouteId(), processor.getProcessorId(), processor.getIndex(), location, line));
+                }
+            }
+        }
+        sb.append("\n</routeLocations>");
+        return sb.toString();
+    }
+
+    @Override
     public void reset(boolean includeProcessors) throws Exception {
         reset();