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 <[email protected]> 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();
